mirror of
https://gitee.com/ShopeX/OMS
synced 2026-03-23 02:45:33 +08:00
454 lines
20 KiB
PHP
454 lines
20 KiB
PHP
<?php
|
||
/**
|
||
* Copyright © ShopeX (http://www.shopex.cn). All rights reserved.
|
||
* See LICENSE file for license details.
|
||
*/
|
||
/**
|
||
* 重置货品冻结库存流水记录
|
||
*
|
||
* @access public
|
||
* @author wangbiao<wangbiao@shopex.cn>
|
||
*/
|
||
class console_stock_freeze
|
||
{
|
||
function __construct()
|
||
{
|
||
$this->_stockFreezeObj = app::get('material')->model('basic_material_stock_freeze');
|
||
}
|
||
|
||
/**
|
||
* 重置流水记录
|
||
* redis库存高可用,废弃掉直接修改db库存、冻结的方法
|
||
*/
|
||
|
||
function reset_stock_freeze($product_id,$is_local = '')
|
||
{
|
||
if (empty($is_local) || $is_local != 'local') {
|
||
return false;
|
||
}
|
||
|
||
if(empty($product_id))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//初始化预占数量为0
|
||
$sql = "UPDATE sdb_material_basic_material_stock_freeze SET num=0, last_modified=". time() ." WHERE bm_id=". $product_id;
|
||
$this->_stockFreezeObj->db->exec($sql);
|
||
|
||
//订单预占
|
||
$this->order_freeze($product_id,$is_local);
|
||
|
||
//经销一件代发订单预占流水
|
||
$this->dealer_order_freeze($product_id);
|
||
|
||
//仓库预占
|
||
$this->branch_freeze($product_id,$is_local);
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 预占流水记录
|
||
* redis库存高可用,废弃掉直接修改db库存、冻结的方法
|
||
*/
|
||
function freeze($bm_id, $obj_type, $bill_type, $obj_id, $shop_id, $branch_id, $bmsq_id, $num, $obj_bn, $sub_bill_type,$is_local = '')
|
||
{
|
||
if (empty($is_local) || $is_local != 'local') {
|
||
return false;
|
||
return false;
|
||
return false;
|
||
}
|
||
|
||
if(empty($bm_id) || empty($obj_type) || empty($bmsq_id)){
|
||
return false;
|
||
}
|
||
|
||
$num = intval($num);
|
||
|
||
switch($obj_type){
|
||
//订单预占
|
||
case 1:
|
||
$filter = array('bm_id'=>$bm_id, 'obj_type'=>1, 'obj_id'=>$obj_id, 'bmsq_id'=>$bmsq_id);
|
||
$insertExtData = array('shop_id'=>$shop_id, 'bill_type'=>$bill_type);
|
||
break;
|
||
case 2:
|
||
$filter = array('bm_id'=>$bm_id, 'obj_type'=>2, 'obj_id'=>$obj_id, 'bmsq_id'=>$bmsq_id, 'bill_type'=>$bill_type);
|
||
$insertExtData = array('shop_id'=>$shop_id, 'branch_id'=>$branch_id);
|
||
break;
|
||
case 3:
|
||
$filter = array('bm_id'=>$bm_id, 'obj_type'=>3, 'obj_id'=>$obj_id, 'bmsq_id'=>$bmsq_id, 'bill_type'=>$bill_type);
|
||
$insertExtData = array('shop_id'=>$shop_id, 'branch_id'=>$branch_id);
|
||
break;
|
||
}
|
||
|
||
$freezeRow = $this->_stockFreezeObj->getList('bmsf_id', $filter, 0, 1);
|
||
if($freezeRow){
|
||
$sql = "UPDATE sdb_material_basic_material_stock_freeze SET num=num+". $num .", last_modified=". time() ." WHERE bmsf_id=".$freezeRow[0]['bmsf_id'];
|
||
return $this->_stockFreezeObj->db->exec($sql);
|
||
}else{
|
||
$insertData = $filter;
|
||
$insertData['num'] = $num;
|
||
$insertData['obj_bn'] = (string)$obj_bn;
|
||
$insertData['sub_bill_type'] = (string)$sub_bill_type;
|
||
$insertData['create_time'] = time();
|
||
$insertData['last_modified'] = time();
|
||
|
||
if($insertExtData){
|
||
$insertData = array_merge($insertData, $insertExtData);
|
||
}
|
||
|
||
return $this->_stockFreezeObj->insert($insertData);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 订单预占
|
||
*
|
||
* redis库存高可用,废弃掉直接修改db库存、冻结的方法
|
||
* @param intval $product_id 基础物料ID
|
||
* @return true
|
||
*/
|
||
function order_freeze($product_id,$is_local = '')
|
||
{
|
||
if (empty($is_local) || $is_local != 'local') {
|
||
return false;
|
||
return false;
|
||
return false;
|
||
}
|
||
|
||
$orderSplitLib = kernel::single('ome_order_split');
|
||
|
||
$obj_type = material_basic_material_stock_freeze::__ORDER;
|
||
$bmsq_id = material_basic_material_stock_freeze::__SHARE_STORE;
|
||
$bill_type = 0;
|
||
$branch_id = 0;
|
||
|
||
//条件
|
||
$where = " AND i.product_id=". $product_id;
|
||
|
||
//订单
|
||
$sql = "SELECT o.order_id, o.order_bn, o.shop_id, o.order_type, o.process_status, o.ship_status, i.item_id, i.product_id, i.nums, i.sendnum, (i.nums-i.sendnum) AS freeze FROM sdb_ome_orders AS o
|
||
LEFT JOIN sdb_ome_order_items AS i ON o.order_id=i.order_id
|
||
WHERE o.ship_status IN('0','2','3') AND o.status='active' AND o.process_status in ('unconfirmed','confirmed','splitting','is_declare','splited','is_retrial')
|
||
AND i.delete='false' ". $where;
|
||
$order_list = $this->_stockFreezeObj->db->select($sql);
|
||
if($order_list)
|
||
{
|
||
foreach ($order_list as $key => $val)
|
||
{
|
||
$num = ($val['freeze']<0 ? 0 : $val['freeze']);
|
||
|
||
//brush特殊订单(刷单订单不预占冻结库存)
|
||
if($val['order_type'] == 'brush'){
|
||
continue;
|
||
}
|
||
|
||
//未生成发货单的数量
|
||
if($val['process_status']=='splitting' || $val['process_status']=='splited')
|
||
{
|
||
$dly_num = $orderSplitLib->get_item_product_num($val['order_id'], $val['item_id'], $val['product_id']);
|
||
$num = $val['nums'] - $dly_num;
|
||
}
|
||
|
||
$this->freeze($val['product_id'], $obj_type, $bill_type, $val['order_id'], $val['shop_id'], $branch_id, $bmsq_id, $num, $val['order_bn'], '',$is_local);
|
||
}
|
||
}
|
||
|
||
// //复审订单
|
||
// $sql = "SELECT o.order_id, o.order_bn, o.shop_id, o.order_type, o.process_status, o.ship_status, i.item_id, i.product_id, i.nums, i.sendnum, (i.nums-i.sendnum) AS freeze FROM sdb_ome_orders AS o
|
||
// LEFT JOIN sdb_ome_order_items AS i ON o.order_id=i.order_id
|
||
// WHERE o.ship_status IN('0','2') AND o.status='active' AND o.process_status='is_retrial' AND i.delete='false' ". $where;
|
||
// $retrial_list = $this->_stockFreezeObj->db->select($sql);
|
||
// if($retrial_list)
|
||
// {
|
||
// foreach ($retrial_list as $key => $val)
|
||
// {
|
||
// $num = ($val['freeze']<0 ? 0 : $val['freeze']);
|
||
//
|
||
// //brush特殊订单(刷单订单不预占冻结库存)
|
||
// if($val['order_type'] == 'brush'){
|
||
// continue;
|
||
// }
|
||
//
|
||
// //未发货的数量
|
||
// if($val['ship_status']=='2')
|
||
// {
|
||
// $dly_num = $orderSplitLib->get_item_product_num($val['order_id'], $val['item_id'], $val['product_id']);
|
||
// $num = $val['nums'] - $dly_num;
|
||
// }
|
||
//
|
||
// $this->freeze($val['product_id'], $obj_type, $bill_type, $val['order_id'], $val['shop_id'], $branch_id, $bmsq_id, $num, $val['order_bn'], '');
|
||
// }
|
||
// }
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 仓库预占
|
||
*
|
||
* @param intval $product_id 基础物料ID
|
||
* @return true
|
||
* redis库存高可用,废弃掉直接修改db库存、冻结的方法
|
||
*/
|
||
function branch_freeze($product_id,$is_local = '')
|
||
{
|
||
if (empty($is_local) || $is_local != 'local') {
|
||
return false;
|
||
return false;
|
||
return false;
|
||
}
|
||
|
||
$branchLib = kernel::single('ome_branch');
|
||
$branchPrdLib = kernel::single('o2o_branch_product');
|
||
|
||
$obj_type = material_basic_material_stock_freeze::__BRANCH;
|
||
$bmsq_id = material_basic_material_stock_freeze::__SHARE_STORE;
|
||
|
||
//条件
|
||
$where = ' AND b.product_id='. $product_id;
|
||
|
||
//发货单
|
||
$sql = 'SELECT a.delivery_id, a.delivery_bn, a.branch_id, b.item_id, b.product_id, b.number FROM sdb_ome_delivery AS a
|
||
LEFT JOIN sdb_ome_delivery_items as b ON a.delivery_id=b.delivery_id
|
||
WHERE a.status IN ("progress", "ready", "stop") and a.process="false" and type="normal" and a.is_bind="false" '. $where;
|
||
$dly_list = $this->_stockFreezeObj->db->select($sql);
|
||
if($dly_list)
|
||
{
|
||
//业务类型
|
||
$bill_type = material_basic_material_stock_freeze::__DELIVERY;
|
||
|
||
foreach ($dly_list as $key => $val)
|
||
{
|
||
//所属店铺
|
||
$order_sql = "SELECT b.shop_id FROM sdb_ome_delivery_order AS a LEFT JOIN sdb_ome_orders AS b ON a.order_id=b.order_id WHERE a.delivery_id=". $val['delivery_id'];
|
||
$tempInfo = $this->_stockFreezeObj->db->selectrow($order_sql);
|
||
$shop_id = $tempInfo['shop_id'];
|
||
|
||
//根据仓库识别是否门店仓还是电商仓
|
||
$store_id = $branchLib->isStoreBranch($val['branch_id']);
|
||
if($store_id)
|
||
{
|
||
//识别门店货品是否管控库存,不管控直接跳过
|
||
$is_bm_ctrl_store = $branchPrdLib->isCtrlBmStore($val['branch_id'], $val['product_id']);
|
||
if($is_bm_ctrl_store)
|
||
{
|
||
//门店仓
|
||
$this->freeze($val['product_id'], $obj_type, $bill_type, $val['delivery_id'], $shop_id, $val['branch_id'], material_basic_material_stock_freeze::__STORE_CONFIRM, $val['number'], $val['delivery_bn'],'',$is_local);
|
||
}
|
||
else
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//电商仓
|
||
$this->freeze($val['product_id'], $obj_type, $bill_type, $val['delivery_id'], $shop_id, $val['branch_id'], $bmsq_id, $val['number'], $val['delivery_bn'],'',$is_local);
|
||
}
|
||
}
|
||
}
|
||
|
||
//售后换货
|
||
$sql = "SELECT r.reship_id, r.reship_bn, r.shop_id, r.changebranch_id AS branch_id, b.product_id, b.num FROM sdb_ome_reship AS r
|
||
LEFT JOIN sdb_ome_reship_items AS b ON r.reship_id=b.reship_id
|
||
WHERE r.return_type='change' AND b.return_type='change' AND r.change_status='0' AND r.is_check in('1','11') ". $where;
|
||
|
||
$reship_list = $this->_stockFreezeObj->db->select($sql);
|
||
if($reship_list)
|
||
{
|
||
//业务类型
|
||
$bill_type = material_basic_material_stock_freeze::__RESHIP;
|
||
|
||
// 查库存,是否足够预占,如果不足,则不冻到仓,冻结到商品上。
|
||
$bpList = app::get('ome')->model('branch_product')->getList('product_id,store,store_freeze,branch_id', ['branch_id'=>array_unique(array_column($reship_list,'branch_id')),'product_id'=>$product_id]);
|
||
$bpList = array_column($bpList,null,'branch_id');
|
||
|
||
foreach ($reship_list as $key => $val)
|
||
{
|
||
$bpInfo = $bpList[$val['branch_id']] ?? [];
|
||
if ($bpInfo && $bpInfo['store'] - $bpInfo['store_freeze'] < $val['num']) {
|
||
// 可用库存不够,冻结到商品
|
||
$obj_type = material_basic_material_stock_freeze::__AFTERSALE;
|
||
$val['branch_id'] = 0;
|
||
}
|
||
|
||
//根据仓库识别是否门店仓还是电商仓
|
||
$store_id = $branchLib->isStoreBranch($val['branch_id']);
|
||
if($store_id)
|
||
{
|
||
//门店仓
|
||
$this->freeze($val['product_id'], $obj_type, $bill_type, $val['reship_id'], $val['shop_id'], $val['branch_id'], material_basic_material_stock_freeze::__STORE_CONFIRM, $val['num'],$val['reship_bn'],'',$is_local);
|
||
}
|
||
else
|
||
{
|
||
//电商仓
|
||
$this->freeze($val['product_id'], $obj_type, $bill_type, $val['reship_id'], $val['shop_id'], $val['branch_id'], $bmsq_id, $val['num'],$val['reship_bn'],'',$is_local);
|
||
}
|
||
}
|
||
}
|
||
|
||
//采购退货
|
||
$sql = "SELECT a.rp_id, a.rp_bn, a.branch_id, b.product_id, b.num FROM sdb_purchase_returned_purchase AS a
|
||
LEFT JOIN sdb_purchase_returned_purchase_items AS b ON a.rp_id=b.rp_id
|
||
WHERE a.rp_type IN ('eo') AND a.return_status IN ('1','4') AND a.check_status IN ('2') ". $where;
|
||
$purchase_list = $this->_stockFreezeObj->db->select($sql);
|
||
if($purchase_list)
|
||
{
|
||
//业务类型
|
||
$bill_type = material_basic_material_stock_freeze::__RETURNED;
|
||
|
||
foreach ($purchase_list as $key => $val)
|
||
{
|
||
$this->freeze($val['product_id'], $obj_type, $bill_type, $val['rp_id'], '', $val['branch_id'], $bmsq_id, $val['num'], $val['rp_bn'], '',$is_local);
|
||
}
|
||
}
|
||
|
||
//调拨出库
|
||
$sql = "SELECT a.iso_id, a.iso_bn, a.branch_id, b.product_id, b.nums FROM sdb_taoguaniostockorder_iso AS a
|
||
LEFT JOIN sdb_taoguaniostockorder_iso_items AS b ON a.iso_id=b.iso_id
|
||
WHERE a.iso_status IN ('1','2') AND a.check_status IN ('2') AND a.type_id in('5','7','100','300','40') ". $where;
|
||
$iso_list = $this->_stockFreezeObj->db->select($sql);
|
||
if($iso_list)
|
||
{
|
||
//业务类型
|
||
$bill_type = material_basic_material_stock_freeze::__STOCKOUT;
|
||
|
||
foreach ($iso_list as $key => $val)
|
||
{
|
||
$this->freeze($val['product_id'], $obj_type, $bill_type, $val['iso_id'], '', $val['branch_id'], $bmsq_id, $val['nums'], $val['iso_bn'], '',$is_local);
|
||
}
|
||
}
|
||
|
||
//库内转储
|
||
$sql = "SELECT d.stockdump_id, d.stockdump_bn, d.from_branch_id AS branch_id, b.product_id, b.num FROM sdb_console_stockdump AS d
|
||
LEFT JOIN sdb_console_stockdump_items AS b ON d.stockdump_id=b.stockdump_id
|
||
WHERE d.confirm_type='1' AND d.self_status='1' AND d.in_status='0' ". $where;
|
||
$stockdump_list = $this->_stockFreezeObj->db->select($sql);
|
||
if($stockdump_list)
|
||
{
|
||
//业务类型
|
||
$bill_type = material_basic_material_stock_freeze::__STOCKDUMP;
|
||
|
||
foreach ($stockdump_list as $key => $val)
|
||
{
|
||
$this->freeze($val['product_id'], $obj_type, $bill_type, $val['stockdump_id'], '', $val['branch_id'], $bmsq_id, $val['num'],$val['stockdump_bn'], '',$is_local);
|
||
}
|
||
}
|
||
|
||
//唯品会出库
|
||
$product_bns = array();
|
||
$sql = "SELECT material_bn FROM sdb_material_basic_material WHERE bm_id=". $product_id;
|
||
$productInfo = $this->_stockFreezeObj->db->select($sql);
|
||
if($productInfo)
|
||
{
|
||
foreach ($productInfo as $key => $val)
|
||
{
|
||
$product_bns[] = $val['material_bn'];
|
||
}
|
||
|
||
$where = " AND b.bn in ('". implode("','", $product_bns) ."')";
|
||
$sql = "SELECT a.stockout_id, a.stockout_no, a.branch_id, b.bn, b.num FROM sdb_purchase_pick_stockout_bills AS a
|
||
LEFT JOIN sdb_purchase_pick_stockout_bill_items AS b ON a.stockout_id=b.stockout_id
|
||
WHERE a.status=1 AND a.confirm_status=2 ". $where;
|
||
$stockout_list = $this->_stockFreezeObj->db->select($sql);
|
||
if($stockout_list)
|
||
{
|
||
//业务类型
|
||
$bill_type = material_basic_material_stock_freeze::__VOPSTOCKOUT;
|
||
|
||
foreach ($stockout_list as $key => $val)
|
||
{
|
||
//bm_id
|
||
$pro_sql = "SELECT bm_id FROM sdb_material_basic_material WHERE material_bn='". $val['bn'] ."'";
|
||
$productInfo = $this->_stockFreezeObj->db->selectrow($pro_sql);
|
||
if(empty($productInfo))
|
||
{
|
||
continue;
|
||
}
|
||
$product_id = $productInfo['bm_id'];
|
||
|
||
$this->freeze($product_id, $obj_type, $bill_type, $val['stockout_id'], '', $val['branch_id'], $bmsq_id, $val['num'], $val['stockout_no'], '',$is_local);
|
||
}
|
||
}
|
||
}
|
||
|
||
//人工库存预占记录(状态:预占中)
|
||
$bill_type = material_basic_material_stock_freeze::__ARTIFICIALFREEZE;
|
||
$sql_af = "select bmsaf_id,branch_id,bm_id,freeze_num,original_bn from sdb_material_basic_material_stock_artificial_freeze where status=1 and bm_id = ".$product_id;
|
||
$af_list = $this->_stockFreezeObj->db->select($sql_af);
|
||
if(!empty($af_list)){
|
||
foreach ($af_list as $val_af){
|
||
$this->freeze($val_af['bm_id'], $obj_type, $bill_type, $val_af['bmsaf_id'], '', $val_af['branch_id'], $bmsq_id, $val_af['freeze_num'], $val_af['original_bn'], '',$is_local);
|
||
}
|
||
}
|
||
//盘点差异单预占
|
||
$bill_type = material_basic_material_stock_freeze::__DIFFERENCEOUT;
|
||
$sql_af = "select i.diff_id, m.diff_bn, i.branch_id,i.bm_id,i.freeze_num as number from sdb_console_difference m
|
||
left join sdb_console_difference_items_freeze i on(m.id=i.diff_id)
|
||
where m.status in('4','2') and bm_id = ".$product_id;;
|
||
$af_list = $this->_stockFreezeObj->db->select($sql_af);
|
||
if(!empty($af_list)){
|
||
$adjustMdl = app::get('console')->model('adjust');
|
||
foreach($af_list as $val_af){
|
||
$this->freeze($val_af['bm_id'], $obj_type, $bill_type, $val_af['diff_id'], '', $val_af['branch_id'], $bmsq_id, abs($val_af['number']), $val_af['diff_bn'], '',$is_local);
|
||
}
|
||
}
|
||
//加工单预占
|
||
$bill_type = material_basic_material_stock_freeze::__MATERIALPACKAGEOUT;
|
||
$sql_af = "select i.mp_id, m.mp_bn, m.branch_id,i.bm_id,i.number from sdb_console_material_package m
|
||
left join sdb_console_material_package_items_detail i on(m.id=i.mp_id)
|
||
where m.status in('2') and bm_id = ".$product_id;;
|
||
$af_list = $this->_stockFreezeObj->db->select($sql_af);
|
||
if(!empty($af_list)){
|
||
$adjustMdl = app::get('console')->model('adjust');
|
||
foreach($af_list as $val_af){
|
||
$this->freeze($val_af['bm_id'], $obj_type, $bill_type, $val_af['mp_id'], '', $val_af['branch_id'], $bmsq_id, abs($val_af['number']), $val_af['mp_bn'], '',$is_local);
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 经销一件代发订单预占流水
|
||
*
|
||
* @param intval $product_id 基础物料ID
|
||
* @return true
|
||
*/
|
||
public function dealer_order_freeze($product_id)
|
||
{
|
||
//库存预占类型
|
||
$obj_type = material_basic_material_stock_freeze::__ORDER;
|
||
$bmsq_id = material_basic_material_stock_freeze::__SHARE_STORE;
|
||
$bill_type = material_basic_material_stock_freeze::__DEALER_ORDER;
|
||
$branch_id = 0;
|
||
|
||
//检查是否安装dealer应用
|
||
if(!app::get('dealer')->is_installed()){
|
||
return false;
|
||
}
|
||
|
||
//经销一件代发订单库存预占
|
||
$sql = "SELECT a.plat_item_id,a.product_id,a.bn,a.nums, b.plat_order_id,b.plat_order_bn,b.shop_id FROM sdb_dealer_platform_order_items AS a LEFT JOIN sdb_dealer_platform_orders AS b ON a.plat_order_id=b.plat_order_id ";
|
||
$sql .= " WHERE a.product_id=". $product_id ." AND is_shopyjdf_type='2' AND a.process_status='unconfirmed' AND a.is_delete='false'";
|
||
$sql .= " AND b.process_status IN('unconfirmed', 'fail')";
|
||
$tempList = kernel::database()->select($sql);
|
||
if(empty($tempList)){
|
||
return true;
|
||
}
|
||
|
||
foreach ($tempList as $itemKey => $itemVal)
|
||
{
|
||
$plat_order_id = $itemVal['plat_order_id'];
|
||
$product_id = $itemVal['product_id'];
|
||
$nums = $itemVal['nums'];
|
||
|
||
//freeze
|
||
$this->freeze($product_id, $obj_type, $bill_type, $plat_order_id, $itemVal['shop_id'], $branch_id, $bmsq_id, $nums, $itemVal['plat_order_bn'], '');
|
||
}
|
||
|
||
return true;
|
||
}
|
||
}
|