Files
OMS/app/purchase/lib/purchase/stockout.php
2026-01-04 19:08:31 +08:00

981 lines
32 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Copyright 2012-2026 ShopeX (https://www.shopex.cn)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* 唯品会JIT出库单Lib类
*
* @author wangbiao@shopex.cn
* @version 0.1
*/
class purchase_purchase_stockout
{
const _io_type = 'VOPSTOCKOUT';//出库类型
function __construct()
{
$this->_stockObj = app::get('purchase')->model('pick_stockout_bills');
$this->_stockItemObj = app::get('purchase')->model('pick_stockout_bill_items');
$this->_logObj = app::get('ome')->model('operation_log');
}
/**
* 生成出库单号
* $type 类型code:900
*/
function get_iostockorder_bn($type=900, $num = 0)
{
$iostock_instance = kernel::single('siso_receipt_iostock');
$kt = $iostock_instance->iostock_rules($type);
$iostockorder_type = 'stockoutbills-'. $type;
if($num >= 1){
$num++;
}else{
$sql = "SELECT id FROM sdb_ome_concurrent WHERE `type`='". $iostockorder_type ."'
AND `current_time`>'". strtotime(date('Y-m-d')) ."' AND `current_time`<=". time() ." order by id desc limit 0,1";
$arr = $this->_stockObj->db->select($sql);
$id = $arr[0]['id'];
if($id)
{
$num = substr($id,-6);
$num = intval($num)+1;
}else{
$num = 1;
}
}
$po_num = str_pad($num, 6, '0', STR_PAD_LEFT);
$iostockorder_bn = $kt . date('Ymd') . $po_num;
$conObj = app::get('ome')->model('concurrent');
if($conObj->is_pass($iostockorder_bn, $iostockorder_type))
{
return $iostockorder_bn;
} else {
if($num > 999999){
return false;
}else{
return $this->get_iostockorder_bn($type, $num);
}
}
}
/**
* 创建出库单
*/
function create_stockout($sdf)
{
$reStockObj = app::get('purchase')->model('pick_stockout');
$product_list = $sdf['detail'];
$bill_ids = $sdf['bill_ids'];
unset($sdf['bill_ids']);
//是否自动
$log_str = ($sdf['is_auto'] ? '出库单自动创建成功' : '出库单创建成功');
$err = '';
//唯品会出库类型
$iostock_instance = kernel::single('siso_receipt_iostock');
$vop_type = $iostock_instance::VOP_STOCKOUT;
//出库单号
$sdf['stockout_no'] = $this->get_iostockorder_bn($vop_type);
$sdf['create_time'] = time();
$sdf['last_modified'] = time();
unset($sdf['detail'], $sdf['is_auto']);
//开启事务
$this->_stockObj->db->beginTransaction();
if(!$this->_stockObj->save($sdf))
{
//事务回滚
$this->_stockObj->db->rollBack();
return false;
}
$labelLib = kernel::single('ome_bill_label');
$billItemIdArr = array_column($product_list, 'bill_item_id');
$labelList = $labelLib->getLabelFromOrder($billItemIdArr, 'pick_bill_item');
//保存明细
foreach ($product_list as $key => $item)
{
$item['stockout_id'] = $sdf['stockout_id'];
if(!$this->_stockItemObj->save($item))
{
//事务回滚
$this->_stockObj->db->rollBack();
return false;
}
// 检测拣货单是否有标签,如果有,给出库单也打上对应标签
if ($labelList[$item['bill_item_id']]) {
if (in_array('quality_check', array_column($labelList[$item['bill_item_id']], 'label_code'))) {
kernel::single('ome_bill_label')->markBillLabel($item['stockout_item_id'], '', 'quality_check', 'pick_stockout_bill_item', $err);
}
if (in_array('priority_delivery', array_column($labelList[$item['bill_item_id']], 'label_code'))) {
kernel::single('ome_bill_label')->markBillLabel($item['stockout_item_id'], '', 'priority_delivery', 'pick_stockout_bill_item', $err);
}
}
}
$labelList = $labelLib->getLabelFromOrder($bill_ids, 'pick_bill');
//拣货出库单关联
foreach ($bill_ids as $key => $bill_id)
{
$data = array('bill_id'=>$bill_id, 'stockout_id'=>$sdf['stockout_id']);
if(!$reStockObj->insert($data))
{
//事务回滚
$this->_stockObj->db->rollBack();
return false;
}
// 检测拣货单是否有标签,如果有,给出库单也打上对应标签
if ($labelList[$bill_id]) {
if (in_array('quality_check', array_column($labelList[$bill_id], 'label_code'))) {
$labelLib->markBillLabel($sdf['stockout_id'], '', 'quality_check', 'pick_stockout_bill', $err);
}
if (in_array('priority_delivery', array_column($labelList[$bill_id], 'label_code'))) {
$labelLib->markBillLabel($sdf['stockout_id'], '', 'priority_delivery', 'pick_stockout_bill', $err);
}
}
}
//事务确认
$this->_stockObj->db->commit();
//增加出库单创建日志
$this->_logObj->write_log('create_stockout_bills@ome', $sdf['stockout_id'], $log_str);
return $sdf['stockout_no'];
}
/**
* 更新拣货单
*/
function update_stockout($sdf)
{
//开启事务
$tran = $this->_stockObj->db->beginTransaction();
//更新类型(is_auto为系统自动)
$log_str = ($sdf['is_auto'] ? '出库单自动编辑成功' : '出库单编辑成功');
$log_type = 'edit_stockout_bills@ome';
$err = '';
if($sdf['action'] == 'is_check')
{
$log_type = 'check_stockout_bills@ome';
$log_str = ($sdf['is_auto'] ? '出库单自动审核成功' : '出库单审核成功');
$log_str .= ',获取入库单号:'. $sdf['storage_no'];
// 处理拣货单明细的详单,并释放拣货单冻结
if ($sdf['confirm_status'] == '2') {
$err = [];
$rs = kernel::single('purchase_purchase_inventory')->process($sdf['stockout_id'], $err);
if (!$rs) {
$this->_stockObj->db->rollBack();
return false;
}
}
}
elseif($sdf['action'] == 'is_update')
{
$log_type = 'update_stockout_bills@ome';
$log_str = ($sdf['is_auto'] ? '出库单自动更新成功' : '出库单更新成功');
}
$sdf['check_time'] = time();
$sdf['last_modified'] = time();
unset($sdf['detail'], $sdf['is_auto'], $sdf['action']);
if(!$this->_stockObj->save($sdf))
{
//事务回滚
$this->_stockObj->db->rollBack();
return false;
}
else
{
//事务确认
$this->_stockObj->db->commit($tran);
}
//增加出库单更新日志
$this->_logObj->write_log($log_type, $sdf['stockout_id'], $log_str);
return true;
}
/**
* 单据状态
*/
function getBillStatus($val = '')
{
$status = array(1=>'新建', '取消', '完成');
if($val)
{
return $status[$val];
}
return $status;
}
/**
* 出库状态
* @param intval $val
* @return
*/
function getStockoutStatus($val = '')
{
$status = array(1=>'未出库', '部分出库', '全部出库');
if($val)
{
return $status[$val];
}
return $status;
}
/**
* 配送方式
* @param intval $val 1:汽运,2:空运
* @return
*/
function getDlyMode($val='')
{
$status = array(1=>'汽运', 2=>'空运');
if($val)
{
return $status[$val];
}
return $status;
}
/**
* 承运商
*/
function getCarrierCode($shop_id=null, $carrier_code=null)
{
$carrierObj = app::get('purchase')->model('carrier');
//filter
$filter = array('carrier_isvalid'=>1);
if($shop_id)
{
$filter['shop_id'] = $shop_id;
}
if($carrier_code)
{
$filter['carrier_code'] = $carrier_code;
}
//getList
$tempData = $carrierObj->getList('*', $filter);
$carrier_list = array();
if($tempData)
{
foreach ($tempData as $key => $val)
{
$code = $val['carrier_code'];
$carrier_list[$code] = $val['carrier_name'];
}
}
//指定输出
if($carrier_code)
{
return $carrier_list[$carrier_code];
}
return $carrier_list;
}
/**
* 出库库存检查
*
* @param intval $stockout_id 出库单ID
* @param intval $branch_id 仓库ID
* @param string $error_msg
* @param bool $is_check 是否检查盘点
*
* @return bool
*/
function checkBranchStock($stockout_id, $branch_id, &$error_msg, $is_check=false)
{
$basicMStockFreezeLib = kernel::single('material_basic_material_stock_freeze');
$bProductObj = app::get('ome')->model('branch_product');
$inventoryLib = kernel::single('taoguaninventory_inventorylist');
$is_install = app::get('taoguaninventory')->is_installed();
if(empty($stockout_id) || empty($branch_id))
{
$error_msg = '无效操作,请检查';
return false;
}
//出库单明细
$sql = "SELECT a.stockout_item_id, a.bn, a.num, b.bm_id AS product_id FROM sdb_purchase_pick_stockout_bill_items AS a
LEFT JOIN sdb_material_basic_material AS b ON a.bn=b.material_bn WHERE a.stockout_id=". $stockout_id ." AND a.is_del='false'";
$itemList = $bProductObj->db->select($sql);
$temp_bns = array();
$temp_nums = array();
foreach ($itemList as $key => $val)
{
if(empty($val['product_id']))
{
$error_msg = '货号:'. $val['bn'] .' 系统中不存在,请先添加!';
return false;
}
$temp_bns[$val['product_id']] = $val['bn'];
//累加同货号的商品数量
$temp_nums[$val['product_id']] += $val['num'];
}
//库存检查
foreach ($temp_nums as $product_id => $num)
{
$storeInfo = $bProductObj->dump(array('product_id'=>$product_id, 'branch_id'=>$branch_id), 'store,store_freeze');
//根据仓库ID、基础物料ID获取该物料仓库级的预占
$storeInfo['store_freeze'] = $basicMStockFreezeLib->getBranchFreeze($product_id, $branch_id);
if(($storeInfo['store'] - $storeInfo['store_freeze']) < $num)
{
$error_msg = '货号:'. $temp_bns[$product_id] .' 库存不足';
return false;
}
//盘点商品检查
if($is_check && $is_install)
{
$check_inventory = $inventoryLib->checkproductoper($product_id, $branch_id);
if(!$check_inventory)
{
$error_msg = '货品:'. $temp_bns[$product_id] .' 正在盘点中,不可以出入库操作!';
return false;
}
}
}
return true;
}
/**
* 出库冻结库存
*
* @param intval $stockout_id 出库单ID
* @param intval $branch_id 仓库ID
* @param string $error_msg
*
* @return bool
*/
function freeze($stockout_id, $branch_id, &$error_msg)
{
if(empty($stockout_id) || empty($branch_id))
{
$error_msg = '无效操作,请检查';
return false;
}
//$basicMaterialStock = kernel::single('material_basic_material_stock');
//$libBranchProduct = kernel::single('ome_branch_product');
//出库单明细
$sql = "SELECT a.stockout_item_id, a.bn, a.num, b.bm_id AS product_id FROM sdb_purchase_pick_stockout_bill_items AS a
LEFT JOIN sdb_material_basic_material AS b ON a.bn=b.material_bn WHERE a.stockout_id=". $stockout_id ." AND a.is_del='false'";
$itemList = $this->_stockObj->db->select($sql);
//库存管控处理
$storeManageLib = kernel::single('ome_store_manage');
$storeManageLib->loadBranch(array('branch_id'=>$branch_id));
$params = array();
$params['node_type'] = 'checkVopstockout';
$params['params'] = array('stockout_id'=>$stockout_id, 'branch_id'=>$branch_id);
$params['params']['items'] = $itemList;
$err_msg = '';
$processResult = $storeManageLib->processBranchStore($params, $err_msg);
if(!$processResult)
{
$error_msg = $err_msg;
return false;
}
return true;
}
/**
* 组织入库详情和明细
* @param intval $stockout_id 出库单ID
* @return Array
*/
function get_iostockData($stockout_id, &$error_msg)
{
if(empty($stockout_id))
{
$error_msg = '无效操作,请检查';
return false;
}
$pickObj = app::get('purchase')->model('pick_bills');
$shopObj = app::get('ome')->model('shop');
//出库单
$row = $this->_stockObj->dump(array('stockout_id'=>$stockout_id), '*');
//关联拣货单
$sql = "SELECT b.pick_no, b.po_id, b.po_bn, b.to_branch_bn FROM sdb_purchase_pick_stockout AS a LEFT JOIN sdb_purchase_pick_bills AS b
ON a.bill_id=b.bill_id WHERE a.stockout_id=". $stockout_id;
$pickInfo = $this->_stockObj->db->selectrow($sql);
//承运商名称
$carrier_name = $this->getCarrierCode('', $row['carrier_code']);
//OMS出库仓库
$branchObj = app::get('ome')->model('branch');
$branchInfo = $branchObj->dump(array('branch_id'=>$row['branch_id']), 'branch_bn,storage_code,owner_code');
//组织数据
$data = array(
'io_bn' =>$row['stockout_no'],//出库单号
'storage_no'=>$row['storage_no'],//入库单号
'dly_mode'=>$row['dly_mode'],//配送方式 1空运 2汽运
'carrier_code'=>$row['carrier_code'],//承运商编码
'carrier_name'=>$carrier_name,//承运商名称
'arrival_time'=>$row['arrival_time'],//要求到货时间
'to_branch_no'=>$pickInfo['to_branch_bn'],//唯品会入库仓编码
'memo'=>'',//备注
'create_time'=>$row['create_time'],//单据创建时间
'branch_id'=>$row['branch_id'],
'branch_bn'=>$branchInfo['branch_bn'],//仓库编号
'owner_code'=>$branchInfo['owner_code'],//货主编码
'storage_code'=>$branchInfo['storage_code'],//仓库编号
'io_type'=>self::_io_type,//出库类型
);
if ($this->is_vopcp($row['carrier_code'])) {
$data['delivery_no'] = $row['delivery_no'];
}
//新增来源店铺编码
$sql = "SELECT po_id, shop_id FROM sdb_purchase_order WHERE po_id=". $pickInfo['po_id'];
$poInfo = $this->_stockObj->db->selectrow($sql);
if($poInfo){
$shopInfo = $shopObj->dump($poInfo['shop_id'], 'shop_bn,name');
$data['shop_code'] = $shopInfo['shop_bn'];
}
//仓库信息
$warehouseObj = app::get('purchase')->model('warehouse');
$branchInfo = $warehouseObj->dump(array('branch_bn'=>$pickInfo['to_branch_bn']), '*');
$area = $branchInfo['area'];
$area = explode(':', $area);
$area = explode('/', $area[1]);
$data['receiver_name'] = $branchInfo['uname'];
$data['receiver_phone'] = $branchInfo['phone'];
$data['receiver_mobile'] = $branchInfo['mobile'];
$data['receiver_email'] = $branchInfo['email'];
$data['receiver_zip'] = $branchInfo['zip'];// TODO: 收货人邮政编码
$data['receiver_country'] = '中国';
$data['receiver_state'] = $area[0];// TODO: 所在省
$data['receiver_city'] = $area[1];// TODO: 所在市
$data['receiver_district'] = $area[2];// TODO: 所在县(区)
$data['receiver_address'] = $branchInfo['address'];// TODO: 收货地址
//出库单明细
$iso_items = array();
$item_pick_num = 0;
$_check_items = [];
$itemList = $this->_stockItemObj->getList('*', array('stockout_id'=>$stockout_id, 'is_del'=>'false'), 0, -1);
foreach ($itemList as $key => $val)
{
//拣货单号和PO单号
$bill_id = $val['bill_id'];
$pickInfo = $pickObj->dump(array('bill_id'=>$bill_id), 'pick_no, po_bn');
$iso_items[] = array(
'bill_id'=>$bill_id,
'po_bn'=>$pickInfo['po_bn'],//PO单号
'pick_bn'=>$pickInfo['pick_no'],//拣货单号
'bn'=>$val['bn'],//货品编码
'barcode'=>$val['barcode'],//条形码
'name'=>$val['product_name'],//货品名称
'size'=>$val['size'],//尺寸
'num'=>$val['num'],//数量
'unit_price'=>$val['price'],//成本价
'market_price'=>$val['market_price'],//市场价
);
$item_pick_num += $val['num'];
$_check_items[$bill_id]['pick_bn'] = $pickInfo['pick_no'];
$_check_items[$bill_id]['barcode_list'][] = $val['barcode'];
}
$data['items'] = $iso_items;
// 唯品会重点检查
$checkMdl = app::get('purchase')->model('pick_bill_check_items');
$billItemMdl = app::get('purchase')->model('pick_bill_items');
foreach ($_check_items as $ik => $iv) {
$check_params = [
'bill_id' => $ik,
'barcode_list' => $iv['barcode_list'],
];
$check_res = $checkMdl->getCheckList($check_params);
if ($check_res) {
$data['quality_check'][$iv['pick_bn']] = $check_res;
}
// 优先发货
$bill_item_id_arr = $billItemMdl->getList('bill_item_id', ['bill_id'=>$ik, 'barcode|in'=>$iv['barcode_list']]);
$bill_item_id_arr = array_column($bill_item_id_arr, 'bill_item_id');
if ($bill_item_id_arr) {
$lable_arr = kernel::single('ome_bill_label')->getLabelFromOrder($bill_item_id_arr, 'pick_bill_item');
$bill_item_id_arr = array_keys($lable_arr);
$_tmp_item_bn = $billItemMdl->getList('barcode', ['bill_id'=>$ik, 'bill_item_id|in'=>$bill_item_id_arr]);
if ($_tmp_item_bn) {
$data['action_list']['priorityDelivery'] = array_column($_tmp_item_bn, 'barcode');
}
}
}
//拣货货品的种类数量(整单维护统计)
$data['sku_pick_num'] = count($iso_items);
//总拣货数量(整单维护统计)
$data['item_pick_num'] = $item_pick_num;
return $data;
}
/**
* 检查装箱商品库存
*
* @param Array $product_info 商品列表
* @param intval $branch_id 仓库ID
* @param string $error_msg
* @param bool $is_check 是否检查盘点
*
* @return bool
*/
function checkBoxStock($product_info, $branch_id, &$error_msg, $is_check=false)
{
//$basicMStockFreezeLib = kernel::single('material_basic_material_stock_freeze');
$basicMaterialObj = app::get('material')->model('basic_material');
$bProductObj = app::get('ome')->model('branch_product');
$inventoryLib = kernel::single('taoguaninventory_inventorylist');
//是否安装taoguaninventory
$is_install = app::get('taoguaninventory')->is_installed();
if(empty($product_info) || empty($branch_id))
{
$error_msg = '无效操作,请检查';
return false;
}
//库存检查
foreach ($product_info as $bn => $num)
{
$product_info = $basicMaterialObj->dump(array('material_bn'=>$bn), 'bm_id');
if(empty($product_info))
{
$error_msg = '货号:'. $bn .'系统中不存在,请先添加!';
return false;
}
$product_id = $product_info['bm_id'];
$storeInfo = $bProductObj->dump(array('product_id'=>$product_id, 'branch_id'=>$branch_id), 'store,store_freeze');
//根据仓库ID、基础物料ID获取该物料仓库级的预占
//$storeInfo['store_freeze'] = $basicMStockFreezeLib->getBranchFreeze($product_id, $branch_id);
if($storeInfo['store'] < $num)
{
$error_msg = '货号:'. $bn .' 出库数量不可大于库存数量!';
return false;
}
//盘点商品检查
if($is_check && $is_install)
{
$check_inventory = $inventoryLib->checkproductoper($product_id, $branch_id);
if(!$check_inventory)
{
$error_msg = '货品:'. $bn .' 正在盘点中,不可以出入库操作!';
return false;
}
}
}
return true;
}
/**
* 保存同步的承运商数据
*/
function saveCarrier($data)
{
$carrierObj = app::get('purchase')->model('carrier');
$data['carrier_isvalid'] = intval($data['carrier_isvalid']);
$carrier_code = $data['carrier_code'];
$shop_id = $data['shop_id'];
$row = $carrierObj->dump(array('carrier_code'=>$carrier_code, 'shop_id'=>$shop_id), '*');
if($row)
{
$carrierObj->update($data, array('cid'=>$row['cid']));
}
else
{
$carrierObj->insert($data);
}
return true;
}
/**
* 发货批次
*
* @param intval $dly_mode 配送方式 1:汽运,2:空运
* @return Array
*/
function getDeliveryTime($dly_mode=null)
{
$data = array();
$data[1] = array(1=>'04:00', '12:00', '15:00', '20:00', '22:00');//汽运
$data[2] = array(1=>'04:00', '12:00', '15:00', '16:00', '20:00', '22:00');//空运
if(isset($dly_mode) && $dly_mode){
return $data[$dly_mode];
}
return $data;
}
/**
* 推算出要求到货时间
*
* @param intval $dly_mode 配送方式 1:汽运,2:空运
* @param string $delivery_date 送货批次:年月日
* @param string $delivery_hour 送货批次:小时时间点
* @return Array
*/
function reckonArrivalTime($dly_mode, $delivery_date, $delivery_hour)
{
$data = array();
//汽运
$data[1] = array(
1=>array(
0=>array('day'=>0, 'hour'=>'10:00'),
),
2=>array(
0=>array('day'=>0, 'hour'=>'16:00'),
1=>array('day'=>0, 'hour'=>'20:00'),
),
3=>array(
0=>array('day'=>0, 'hour'=>'22:00'),
),
4=>array(
0=>array('day'=>0, 'hour'=>'23:59'),
1=>array('day'=>1, 'hour'=>'09:00'),
),
5=>array(
0=>array('day'=>1, 'hour'=>'09:00'),
),
);
//空运
$data[2] = array(
1=>array(
0=>array('day'=>0, 'hour'=>'20:00'),
),
2=>array(
0=>array('day'=>0, 'hour'=>'23:59'),
),
3=>array(
0=>array('day'=>1, 'hour'=>'09:00'),
),
4=>array(
0=>array('day'=>1, 'hour'=>'09:00'),
),
5=>array(
0=>array('day'=>1, 'hour'=>'16:00'),
),
6=>array(
0=>array('day'=>1, 'hour'=>'18:00'),
),
);
//发货批次
$deliveryTime = $this->getDeliveryTime($dly_mode);
$delivery_key = 0;
foreach ($deliveryTime as $key => $val)
{
if($val == $delivery_hour)
{
$delivery_key = $key;
break;
}
}
//计算到货时间
$temp = array();
if(isset($dly_mode) && $dly_mode){
$temp = $data[$dly_mode][$delivery_key];
}
$dly_date_list = array();
foreach ($temp as $key => $val){
$hour = $val['hour'];
$day = $val['day'];
$arrival_time = $delivery_date;
if($day)
{
$arrival_time = date('Y-m-d', strtotime('+'. $day .' day', strtotime($delivery_date)));
}
$dly_date_list[] = $arrival_time .' '. $hour;
}
return $dly_date_list;
}
/**
* 根据当前小时和配送方式(推算出送货批次和要求到货时间)
*/
function reckonTiem($dly_mode)
{
$now_hour = date('H', time());
$delivery_date = date('Y-m-d', time());
$delivery_hour = '';
$add_day = 0;
$timeData = $this->getDeliveryTime($dly_mode);
foreach ($timeData as $key => $val)
{
$tempHour = explode(':', $val);
$hour = intval($tempHour[0]);
if($now_hour <= $hour)
{
$delivery_hour = $val;
break;
}
}
//未匹配到
if(empty($delivery_hour))
{
$add_day = 1;
$delivery_hour = $timeData[1];
}
//加一天
if($add_day)
{
$delivery_date = date('Y-m-d', strtotime("+1 day"));
}
$delivery_time = $delivery_date .' '. $delivery_hour;//送货批次
//到货时间
$arrival_time = $this->reckonArrivalTime($dly_mode, $delivery_date, $delivery_hour);
//程序自动选择时,默认选择第一条
$arrival_time = $arrival_time[0];
return array('delivery_time'=>$delivery_time, 'arrival_time'=>$arrival_time);
}
/**
* 检查Post编辑后的出库单明细
*
* @param Array $data POST数据
* @param String $error_msg 错误信息
* @return Array
*/
function check_edit_items($data, &$error_msg)
{
$stockoutItemsObj = app::get('purchase')->model('pick_stockout_bill_items');
$stockout_id = $data['stockout_id'];
$item_data = $data['item_num'];//post编辑提交的出库单明细
$snap_data = array();
$flag = false;
//出库单明细
$result = array();
$dataList = $stockoutItemsObj->getList('stockout_item_id, bn, num, item_num, is_del', array('stockout_id'=>$stockout_id));
foreach ($dataList as $key => $val)
{
$item_id = $val['stockout_item_id'];
if(isset($item_data[$item_id]))
{
$num = intval($item_data[$item_id]);
if(empty($num))
{
$error_msg = '货号:'. $val['bn'] .' 申请数量填写错误!';
return false;
}
elseif($num > $val['item_num'])
{
$error_msg = '货号:'. $val['bn'] .' 申请数量不能大于可出库数量!';
return false;
}
$flag = true;
$result[$item_id] = array('is_del'=>false, 'num'=>$num);
//修改日志
if($val['item_num'] != $num)
{
$snap_data[] = '货号'. $val['bn'] .'修改数量('. $val['item_num'] .'->'. $num .')';
}
}
else
{
//删除状态
$result[$item_id] = array('is_del'=>true, 'num'=>$val['num']);
//修改日志
$snap_data[] = '货号'. $val['bn'] .'被删除';
}
}
if(!$flag)
{
$error_msg = '出库单明细不能全部删除!';
return false;
}
//增加修改日志
if($snap_data)
{
$log_str = implode('', $snap_data);
$this->_logObj->write_log('update_stockout_bills@ome', $stockout_id, $log_str);
}
return $result;
}
/**
* 保存post编辑后的出库单明细
*
* @param Array $item_data 出库单明细
* @param String $error_msg 错误信息
* @return Array
*/
function update_edit_items($item_data, &$error_msg)
{
$stockoutItemsObj = app::get('purchase')->model('pick_stockout_bill_items');
if(empty($item_data))
{
$error_msg = '出库单明细不存在!';
return false;
}
foreach ($item_data as $item_id => $val)
{
$data = array();
$data['num'] = $val['num'];
$data['is_del'] = ($val['is_del'] ? 'true' : 'false');
$stockoutItemsObj->update($data, array('stockout_item_id'=>$item_id));
}
return true;
}
/**
* 根据货号、仓库branch_id获取对应的仓库可用库存
*
* @param varchar $bn 货号
* @param intval $branch_id 仓库ID
* @return Array
*/
function getBranchStoreByBn($bn, $branch_id)
{
$basicMaterialObj = app::get('material')->model('basic_material');
$basicMStockFreezeLib = kernel::single('material_basic_material_stock_freeze');
//基础物料ID
$row = $basicMaterialObj->dump(array('material_bn'=>$bn), 'bm_id');
if(empty($row))
{
return array();
}
//库存
$result = array();
$sql = "SELECT * FROM sdb_ome_branch_product WHERE product_id=". $row['bm_id'] ." AND branch_id=". $branch_id;
$branch_product = $basicMaterialObj->db->selectrow($sql);
//根据仓库ID、基础物料ID获取该物料仓库级的预占
$branch_product['store_freeze'] = $basicMStockFreezeLib->getBranchFreeze($row['bm_id'], $branch_id);
$store = max(0, $branch_product['store'] - $branch_product['store_freeze']);
return $store;
}
/**
* 判断是否唯品会专配
*
* @return void
* @author
**/
public function is_vopcp($carrier_code)
{
return $carrier_code == '120001552' ? true : false;
}
}
?>