调整商品溯源

This commit is contained in:
lewis 2025-03-14 17:18:17 +08:00
parent b2e51cbf5f
commit 4a8d90d1a6
9 changed files with 248 additions and 72 deletions

View File

@ -3,9 +3,11 @@
namespace app\admin\logic\inventory_transfer_order;
use app\admin\logic\product_source_link\ProductSourceLinkLogic;
use app\common\model\inventory_transfer_order\InventoryTransferOrder;
use app\common\logic\BaseLogic;
use app\common\model\inventory_transfer\InventoryTransfer;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_product\StoreProduct;
use app\common\model\system_store\SystemStore;
@ -129,6 +131,10 @@ class InventoryTransferOrderLogic extends BaseLogic
}
SqlChannelLog('WarehouseProductStorege', $find['id'], $v['nums'], 1, Request()->url(),$admin_id);
}
ProductSourceLinkLogic::transfer([
'oid' => $v['oid'],
'product_id' => $v['product_id'],
]);
}
Db::commit();
return true;

View File

@ -4,10 +4,14 @@ namespace app\admin\logic\product_source_link;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\common\model\inventory_transfer\InventoryTransfer;
use app\common\model\product_source_link\ProductSourceLink;
use app\common\logic\BaseLogic;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use support\exception\BusinessException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
@ -41,6 +45,7 @@ class ProductSourceLinkLogic extends BaseLogic
ProductSourceLinkInfoLogic::add([
'oid' => $model['id'],
'product_id' => $offer['product_id'],
'warehouse_id' => $info['warehouse_id'],
'nums' => $offer['buyer_nums'],
'current_nums' => $offer['buyer_nums'],
'types' => $info['types'],
@ -114,19 +119,21 @@ class ProductSourceLinkLogic extends BaseLogic
*/
public static function outbound(array $info)
{
$productSourceLinkInfo = ProductSourceLink::alias('t1')
->field('t2.id,t2.product_id,oid,price,current_nums')
->join('product_source_link_info t2', 't1.id = t2.oid')
->where('t1.product_id', $info['product']['product_id'])
->where('types', ProductSourceLinkInfo::TypeIn)
->where('current_nums', '>', 0)
->select()->toArray();
$query = ProductSourceLinkInfo::where('product_id', $info['product']['product_id'])->where('current_nums', '>', 0);
if (!empty($info['store_id'])) {
$query->where('store_id', $info['store_id'])->whereIn('types', [ProductSourceLinkInfo::TypeStoreIn, ProductSourceLinkInfo::TypeS2S]);
} else {
$query->whereIn('types', [ProductSourceLinkInfo::TypeIn, ProductSourceLinkInfo::TypeS2W, ProductSourceLinkInfo::TypeW2W]);
}
$productSourceLinkInfo = $query->select()->toArray();
$update = [];
$insert = [];
$needNum = $info['product']['nums'];
foreach ($productSourceLinkInfo as $item) {
$info['warehouse_id'] = empty($info['warehouse_id']) ? $item['warehouse_id'] : $info['warehouse_id'];
$info['store_id'] = empty($info['store_id']) ? $item['store_id'] : $info['store_id'];
$currentNum = max(bcsub($item['current_nums'], $needNum, 2), 0);
if ($needNum - $item['current_nums'] <= 0) {
if ($item['current_nums'] > $needNum) {
[$update, $insert] = self::getInsertAndUpdate($update, $insert, $currentNum, $item, $info, $needNum);
break;
} else {
@ -147,23 +154,28 @@ class ProductSourceLinkLogic extends BaseLogic
'current_nums' => $currentNum,
'update_time' => $time,
];
$exist = ProductSourceLinkInfo::field('id,from_id,nums')->where('link_id', $info['link_id'])->where('types', ProductSourceLinkInfo::TypeOut)->findOrEmpty()->toArray();
$exist = ProductSourceLinkInfo::field('id,from_id,nums,current_nums')->where('link_id', $info['link_id'])->where('types', ProductSourceLinkInfo::TypeOut)->findOrEmpty()->toArray();
if (!empty($exist) && $exist['from_id'] == $item['id']) {
$itemNums = bcadd($exist['nums'], $needNum, 2);
$itemCurrentNums = bcadd($exist['current_nums'], $needNum, 2);
$update[] = [
'id' => $exist['id'],
'nums' => $itemNums,
'current_nums' => $itemCurrentNums,
'total_price' => bcmul($item['price'], $itemNums, 2),
'update_time' => $time,
];
} else {
$insert[] = [
'product_id' => $item['product_id'],
'warehouse_id' => $info['warehouse_id'] ?? 0,
'store_id' => $info['store_id'] ?? 0,
'oid' => $item['oid'],
'types' => ProductSourceLinkInfo::TypeOut,
'types' => $info['types'] ?? ProductSourceLinkInfo::TypeOut,
'link_id' => $info['link_id'],
'from_id' => $item['id'],
'nums' => $needNum,
'current_nums' => $needNum,
'price' => $item['price'],
'total_price' => bcmul($item['price'], $needNum, 2),
'create_time' => $time,
@ -173,4 +185,112 @@ class ProductSourceLinkLogic extends BaseLogic
return [$update, $insert];
}
/**
* 门店入库
* @param array $info
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function storeInStorage(array $info)
{
$list = ProductSourceLinkInfo::where('link_id', $info['link_id'])
->where('product_id', $info['product_id'])
->where('types', ProductSourceLinkInfo::TypeOut)
->select()->toArray();
if (empty($list)) {
return;
}
foreach ($list as $item) {
ProductSourceLinkInfoLogic::add([
'oid' => $item['oid'],
'product_id' => $item['product_id'],
'warehouse_id' => $info['warehouse_id'] ?? 0,
'store_id' => $info['store_id'] ?? 0,
'nums' => $item['nums'],
'current_nums' => $item['nums'],
'types' => $info['types'],
'link_id' => $info['link_id'],
'from_id' => $item['id'],
'price' => $item['price'],
'total_price' => $item['total_price'],
]);
}
}
/**
* 门店退库
* @param array $info
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function storeRollback(array $info)
{
$list = ProductSourceLinkInfo::where('link_id', $info['link_id'])
->where('product_id', $info['product_id'])
->where('types', ProductSourceLinkInfo::TypeStoreIn)
->select()->toArray();
if (empty($list)) {
return;
}
ProductSourceLinkInfoLogic::updateByLinkId($info['link_id'], ProductSourceLinkInfo::TypeStoreIn, ['add_nums' => -$info['nums']]);
}
/**
* 商品调拨
* @param array $info
* @return void
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function transfer(array $info)
{
$inventoryTransfer = InventoryTransfer::field('id,nums,one_type,one_id,two_type,two_id')
->where('oid', $info['oid'])
->where('product_id', $info['product_id'])
->findOrEmpty()->toArray();
if (empty($inventoryTransfer)) {
return;
}
$info['link_id'] = $inventoryTransfer['id'];
$query = ProductSourceLinkInfo::where('product_id', $info['product_id']);
if ($inventoryTransfer['one_type'] == 1) {
$query->where('store_id', $inventoryTransfer['one_id'])->whereIn('types', [ProductSourceLinkInfo::TypeStoreIn, ProductSourceLinkInfo::TypeS2S]);
$info['types'] = $inventoryTransfer['two_type'] == 1 ? ProductSourceLinkInfo::TypeS2S : ProductSourceLinkInfo::TypeS2W;
} else {
$info['types'] = ProductSourceLinkInfo::TypeW2W;
$query->where('warehouse_id', $inventoryTransfer['one_id'])->whereIn('types', [ProductSourceLinkInfo::TypeIn, ProductSourceLinkInfo::TypeS2W, ProductSourceLinkInfo::TypeW2W]);
}
if ($inventoryTransfer['two_type'] == 1) {
$info['store_id'] = $inventoryTransfer['two_id'];
} else {
$info['warehouse_id'] = $inventoryTransfer['two_id'];
}
$list = $query->where('current_nums', '>', 0)
->field('id,oid,product_id,warehouse_id,store_id,nums,current_nums,link_id,from_id,price')
->select()->toArray();
if (empty($list)) {
return;
}
$update = [];
$insert = [];
$needNum = $inventoryTransfer['nums'];
foreach ($list as $item) {
$currentNum = max(bcsub($item['current_nums'], $needNum, 2), 0);
if ($item['current_nums'] > $needNum) {
[$update, $insert] = self::getInsertAndUpdate($update, $insert, $currentNum, $item, $info, $needNum);
break;
} else {
[$update, $insert] = self::getInsertAndUpdate($update, $insert, 0, $item, $info, $item['current_nums']);
}
$needNum = $needNum - $item['current_nums'];
}
(new ProductSourceLinkInfo())->saveAll($update);
(new ProductSourceLinkInfo())->insertAll($insert);
}
}

View File

@ -23,6 +23,7 @@ class ProductSourceLinkInfoLogic extends BaseLogic
/**
* @notes 添加商品溯源详细
* @param array $params
* @return ProductSourceLinkInfo
* @author admin
* @date 2025/03/12 10:08
*/
@ -97,9 +98,10 @@ class ProductSourceLinkInfoLogic extends BaseLogic
unset($params['add_nums']);
$params['total_price'] = bcmul($params['nums'], $data['price'], 2);
ProductSourceLinkInfo::where('id', $data['id'])->update($params);
} elseif ($types == ProductSourceLinkInfo::TypeOut && isset($params['add_nums'])) {
} elseif (isset($params['add_nums']) && in_array($types, [ProductSourceLinkInfo::TypeOut, ProductSourceLinkInfo::TypeStoreIn])) {
if ($params['add_nums'] < 0) {
$otherData = ProductSourceLinkInfo::where('id', '<>', $data['id'])->where('link_id', $linkId)->where('types', $types)->order('id desc')->select()->toArray();
$subQuery = ProductSourceLinkInfo::where('link_id', $linkId)->where('types', $types);
$otherData = $subQuery->order('id desc')->select()->toArray();
if (!empty($otherData)) {
$rollbackNum = abs($params['add_nums']);
$update = [];
@ -112,9 +114,6 @@ class ProductSourceLinkInfoLogic extends BaseLogic
}
$rollbackNum = bcsub($rollbackNum, $item['nums'], 2);
}
if ($rollbackNum > 0) {
$update = self::setUpdate($data, $rollbackNum, $update);
}
(new ProductSourceLinkInfo())->saveAll($update);
}
} else {
@ -131,6 +130,15 @@ class ProductSourceLinkInfoLogic extends BaseLogic
}
}
/**
* 根据linkId删除
* @param $linkId
* @param $types
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function deleteByLinkId($linkId, $types)
{
$list = ProductSourceLinkInfo::where('link_id', $linkId)->where('types', $types)->select()->toArray();
@ -159,9 +167,11 @@ class ProductSourceLinkInfoLogic extends BaseLogic
public static function setUpdate(array $data, float|int|string $rollbackNum, array $update): array
{
$dataNums = bcsub($data['nums'], $rollbackNum, 2);
$currentNums = max(bcsub($data['current_nums'], $rollbackNum, 2), 0);
$update[] = [
'id' => $data['id'],
'nums' => $dataNums,
'current_nums' => $currentNums,
'total_price' => bcmul($data['price'], $dataNums, 2),
'delete_time' => $dataNums > 0 ? null : time(),
];

View File

@ -2,7 +2,9 @@
namespace app\admin\logic\system_store_storage;
use app\admin\logic\product_source_link\ProductSourceLinkLogic;
use app\admin\logic\store_product\StoreProductLogic;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_branch_product_attr_value\StoreBranchProductAttrValue;
use app\common\model\system_store_storage\SystemStoreStorage;
@ -64,9 +66,7 @@ class SystemStoreStorageLogic extends BaseLogic
Db::startTrans();
try {
$find= WarehouseProduct::where(['id' => $params['id']])->find();
// $find=SystemStoreStorage::where(['id' => $params['id']])->find();
if($find){
// if($find['order_type']==1){
$find->save(['status'=>1,'staff_id'=>$params['staff_id']??0,'admin_id'=>$params['admin_id']??0,'mark'=>'入库时间:'.date('Y-m-d H:i:s',time())]);
$branch_product=StoreBranchProduct::where(['product_id'=>$find['product_id'],'store_id'=>$find['store_id']])->find();
if($branch_product){
@ -80,10 +80,13 @@ class SystemStoreStorageLogic extends BaseLogic
$storeBranchProduct->save();
SqlChannelLog('StoreBranchProduct', $storeBranchProduct['id'], $find['nums'], 1,Request()->url(),$admin_id);
}
// }else{
// $find->save(['status'=>1,'staff_id'=>$params['staff_id']??0,'admin_id'=>$params['admin_id']??0,'mark'=>'确认时间:'.date('Y-m-d H:i:s',time())]);
// }
ProductSourceLinkLogic::storeInStorage([
'link_id' => $find['id'],
'product_id' => $find['product_id'],
'warehouse_id' => $find['warehouse_id'],
'store_id' => $find['store_id'],
'types' => ProductSourceLinkInfo::TypeStoreIn,
]);
}
Db::commit();
return true;
@ -197,6 +200,12 @@ class SystemStoreStorageLogic extends BaseLogic
$warehouseStorage->save();
SqlChannelLog('WarehouseProductStorege', $warehouseStorage['id'], $params['num'], 1,Request()->url());
SqlChannelLog('StoreBranchProduct', $StoreProduct['id'], $params['num'], -1,Request()->url());
ProductSourceLinkLogic::storeRollback([
'link_id' => $warehouseProduct['id'],
'product_id' => $warehouseProduct['product_id'],
'nums' => $params['num'],
'types' => ProductSourceLinkInfo::TypeStoreOut,
]);
Db::commit();
return true;
} catch (\Exception $e) {

View File

@ -17,6 +17,9 @@ use app\common\model\system_store_storage\SystemStoreStorage;
use app\common\model\warehouse_order\WarehouseOrder;
use app\common\model\warehouse_product_storege\WarehouseProductStorege;
use support\Log;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use support\exception\BusinessException;
@ -200,6 +203,7 @@ class WarehouseProductLogic extends BaseLogic
ProductSourceLinkLogic::outbound([
'product' => $data,
'warehouse_id' => $params['warehouse_id'],
'store_id' => $data['store_id'],
'link_id' => $res['id'],
]);
@ -231,16 +235,7 @@ class WarehouseProductLogic extends BaseLogic
$productNum = $updateNums;
self::updateWarehouseProduct($res, $storageNum, $productNum);
$ProductSourceLinkInfoParams = ['nums' => $params['nums'], 'total_price' => $params['total_price']];
if ($find['financial_pm'] == 1) {
$ProductSourceLinkInfoParams['price'] = $params['purchase'];
$ProductSourceLinkInfoParams['add_nums'] = $updateNums;
ProductSourceLinkInfoLogic::updateByLinkId($res['id'], ProductSourceLinkInfo::TypeIn, $ProductSourceLinkInfoParams);
} else {
$ProductSourceLinkInfoParams['origin_nums'] = $res['nums'];
$ProductSourceLinkInfoParams['add_nums'] = bcsub($params['nums'], $res['nums'],2);
ProductSourceLinkInfoLogic::updateByLinkId($res['id'], ProductSourceLinkInfo::TypeOut, $ProductSourceLinkInfoParams);
}
self::updateProductSourceLink($res, $params, $updateNums);
}
$datas = [
'total_price' => $params['total_price'],
@ -328,28 +323,29 @@ class WarehouseProductLogic extends BaseLogic
{
Db::startTrans();
try {
$res = WarehouseProduct::where('id', $params['id'])->find();
if ($res) {
if($params['nums']>$res['nums']){
$nums=bcsub($params['nums'], $res['nums'],2);
self::incProductDecStorege($res, $nums,$admin_id);
}else{
$nums=bcsub($res['nums'],$params['nums'],2);
self::decProductIncStorege($res, $nums,$admin_id);
$warehouseProduct = WarehouseProduct::where('id', $params['id'])->find();
if ($warehouseProduct) {
$updateNums = bcsub($params['nums'], $warehouseProduct['nums'],2);
if ($updateNums != 0) {
$storageNum = $warehouseProduct['financial_pm'] == 0 ? -$updateNums : $updateNums;
$productNum = $updateNums;
self::updateWarehouseProduct($warehouseProduct, $storageNum, $productNum);
self::updateProductSourceLink($warehouseProduct, $params, $updateNums);
}
if($res['financial_pm']==1){
if($warehouseProduct['financial_pm']==1){
$datas = [
'nums' => $params['nums'],
'total_price' => bcmul($params['nums'], $res['purchase'], 2),
'total_price' => bcmul($params['nums'], $warehouseProduct['purchase'], 2),
];
}else{
$datas = [
'nums' => $params['nums'],
'total_price' => bcmul($params['nums'], $res['price'], 2),
'total_price' => bcmul($params['nums'], $warehouseProduct['price'], 2),
];
}
$res->save($datas);
$warehouseProduct->save($datas);
}
Db::commit();
} catch (\Throwable $th) {
@ -457,13 +453,14 @@ class WarehouseProductLogic extends BaseLogic
}
/**
* 增加商品入库数量
* 增加商品数量
* @param $warehouseProduct
* @param $nums
* @param $storageNum
* @param $productNum
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function updateWarehouseProduct($warehouseProduct, $storageNum, $productNum)
{
@ -520,4 +517,17 @@ class WarehouseProductLogic extends BaseLogic
}
}
public static function updateProductSourceLink($warehouseProduct, $params, $updateNums)
{
$ProductSourceLinkInfoParams = ['nums' => $params['nums'], 'total_price' => bcmul($warehouseProduct['price'], $params['nums'], 2)];
if ($warehouseProduct['financial_pm'] == 1) {
$ProductSourceLinkInfoParams['price'] = $params['purchase'];
$ProductSourceLinkInfoParams['add_nums'] = $updateNums;
ProductSourceLinkInfoLogic::updateByLinkId($warehouseProduct['id'], ProductSourceLinkInfo::TypeIn, $ProductSourceLinkInfoParams);
} else {
$ProductSourceLinkInfoParams['add_nums'] = bcsub($params['nums'], $warehouseProduct['nums'],2);
ProductSourceLinkInfoLogic::updateByLinkId($warehouseProduct['id'], ProductSourceLinkInfo::TypeOut, $ProductSourceLinkInfoParams);
}
}
}

View File

@ -3,6 +3,9 @@
namespace app\admin\logic\warehouse_product_return;
use app\admin\logic\product_source_link_info\ProductSourceLinkInfoLogic;
use app\admin\logic\warehouse_product\WarehouseProductLogic;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\warehouse_product_return\WarehouseProductReturn;
use app\common\logic\BaseLogic;
use app\common\model\beforehand_order\BeforehandOrder;
@ -76,10 +79,6 @@ class WarehouseProductReturnLogic extends BaseLogic
throw new BusinessException('该商品库存:'.$params['nums'].'小于仓库库存'.$proudct['nums']);
}
}
// $offer = PurchaseProductOffer::where('order_id', $params['bhoid'])->where('product_id', $find['product_id'])->find();
// if (!$offer) {
// throw new BusinessException('该商品没有采购信息');
// }
$datas = [
'source_id' => $params['id'],
'bhoid' => $params['bhoid'] ?? 0,
@ -93,14 +92,18 @@ class WarehouseProductReturnLogic extends BaseLogic
'nums' => $params['nums'],
'return_type' => $params['return_type'],
'mark' => $params['mark'],
// 'price' => $offer['price'],
// 'total_price' => bcmul($params['nums'], $offer['price'], 2),
'price' => 0,
'total_price' => 0,
];
}
WarehouseProductReturn::create($datas);
$updateNums = bcsub($params['nums'], $find['nums'],2);
if ($updateNums != 0) {
WarehouseProductLogic::updateProductSourceLink($find, $params, $updateNums);
}
if ($params['financial_pm'] == 1 && $params['return_type'] == 1) {
$nums = bcsub($find['nums'], $params['nums'], 2);
$total_price = 0;

View File

@ -546,6 +546,9 @@ class OrderLogic extends BaseLogic
if (empty($order)) {
throw new BusinessException('订单不存在');
}
if ($order['paid'] != 1) {
throw new BusinessException('订单未支付');
}
Db::startTrans();
try {
StoreOrder::update([

View File

@ -2,6 +2,7 @@
namespace app\common\logic;
use app\admin\logic\product_source_link\ProductSourceLinkLogic;
use app\admin\logic\store_product\StoreProductLogic;
use app\admin\logic\user_ship\UserShipLogic;
use app\api\logic\order\OrderLogic;
@ -16,6 +17,7 @@ use app\common\model\dict\DictType;
use app\common\model\finance\CapitalFlow;
use app\common\model\finance\PayNotifyLog;
use app\common\model\pay\PayNotify;
use app\common\model\product_source_link_info\ProductSourceLinkInfo;
use app\common\model\store_branch_product\StoreBranchProduct;
use app\common\model\store_cash_finance_flow\StoreCashFinanceFlow;
use app\common\model\store_finance_flow\StoreFinanceFlow;
@ -639,6 +641,15 @@ class PayNotifyLogic extends BaseLogic
'sales' => bcadd($branchProduct['sales'], $v['cart_num'], 2)
], ['id' => $branchProduct['id']]);
SqlChannelLog('StoreBranchProduct', $branchProduct['id'], $v['cart_num'], -1, Request()->url());
ProductSourceLinkLogic::outbound([
'product' => [
'product_id' => $v['product_id'],
'nums' => $v['cart_num'],
],
'store_id' => $v['store_id'],
'link_id' => $v['id'],
'types' => ProductSourceLinkInfo::TypeOrder,
]);
} else {
StoreProductLogic::ordinary(['id' => $v['product_id']], $v['store_id'], 0, $storeProduct);
StoreBranchProduct::update([

View File

@ -24,8 +24,10 @@ class ProductSourceLinkInfo extends BaseModel
const TypeStoreIn = 3;
const TypeOrder = 4;
const TypeOrderRefund = 5;
const TypeTransferToWarehouse = 6;
const TypeTransferToStore = 7;
const TypeS2W = 6;
const TypeS2S = 7;
const TypeW2W = 8;
const TypeStoreOut = 301;
public function getTypeName()
{
@ -33,10 +35,12 @@ class ProductSourceLinkInfo extends BaseModel
self::TypeIn => '仓库入库',
self::TypeOut => '仓库出库',
self::TypeStoreIn => '门店入库',
self::TypeStoreOut => '门店退库',
self::TypeOrder => '订单出库',
self::TypeOrderRefund => '订单退货入库',
self::TypeTransferToWarehouse => '门店调拨至仓库',
self::TypeTransferToStore => '门店调拨至门店',
self::TypeS2W => '门店调拨至仓库',
self::TypeS2S => '门店调拨至门店',
self::TypeW2W => '仓库调拨至仓库',
];
return $typeMap[$this->getAttr('types')];
}