初始上传
This commit is contained in:
39
addon/stock/model/Store.php
Executable file
39
addon/stock/model/Store.php
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 上海牛之云网络科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\stock\model;
|
||||
|
||||
|
||||
use app\model\store\Store as StoreCommonModel;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 库存model
|
||||
*
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
class Store extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 库存用门店列表
|
||||
* @param $site_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function getStoreList($site_id)
|
||||
{
|
||||
$condition = [
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'stock_type', '=', 'store' ]
|
||||
];
|
||||
$store_model = new StoreCommonModel();
|
||||
return $store_model->getStoreList($condition);
|
||||
}
|
||||
}
|
||||
621
addon/stock/model/stock/Allot.php
Executable file
621
addon/stock/model/stock/Allot.php
Executable file
@@ -0,0 +1,621 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 上海牛之云网络科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\stock\model\stock;
|
||||
|
||||
|
||||
use addon\stock\dict\StockDict;
|
||||
use addon\stock\model\stock\Stock as StockModel;
|
||||
use app\model\store\Store;
|
||||
use app\model\BaseModel;
|
||||
use app\model\system\User;
|
||||
use app\dict\goods\GoodsDict;
|
||||
|
||||
/**
|
||||
* 调拨
|
||||
* Class Allot
|
||||
* @package addon\stock\model\stock
|
||||
*/
|
||||
class Allot extends BaseModel
|
||||
{
|
||||
|
||||
public function getAllotNo()
|
||||
{
|
||||
return 'ALLOT' . date('ymdhis', time()) . rand(1111, 9999);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增库存调拨
|
||||
* @param $params
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function addAllot($params)
|
||||
{
|
||||
model('stock_allot')->startTrans();
|
||||
try {
|
||||
$output_store_id = $params[ 'output_store_id' ];//出库门店
|
||||
$input_store_id = $params[ 'input_store_id' ];//入库门店
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$allot_time = $params[ 'allot_time' ] ?? time();
|
||||
$remark = $params[ 'remark' ] ?? '';
|
||||
$goods_sku_list = $params[ 'goods_sku_list' ];
|
||||
|
||||
//查询门店名称信息
|
||||
$store_model = new Store();
|
||||
$output_store_condition = [
|
||||
[ 'store_id', '=', $output_store_id ]
|
||||
];
|
||||
$output_store_info = $store_model->getStoreInfo($output_store_condition)[ 'data' ] ?? [];
|
||||
if (empty($output_store_info))
|
||||
return $this->success([], '找不到所选的门店');
|
||||
|
||||
$output_store_name = $output_store_info[ 'store_name' ] ?? '';
|
||||
$input_store_condition = [
|
||||
[ 'store_id', '=', $input_store_id ]
|
||||
];
|
||||
$input_store_info = $store_model->getStoreInfo($input_store_condition)[ 'data' ] ?? [];
|
||||
if (empty($input_store_info))
|
||||
return $this->success([], '找不到所选的门店');
|
||||
|
||||
$operater = $params[ 'operater' ];
|
||||
|
||||
$goods_sku_list_array_result = $this->getSkuArray($goods_sku_list, $output_store_id);
|
||||
|
||||
if ($goods_sku_list_array_result[ 'code' ] < 0) {
|
||||
model('stock_allot')->rollback();
|
||||
return $goods_sku_list_array_result;
|
||||
}
|
||||
$goods_sku_list_array = $goods_sku_list_array_result[ 'data' ];
|
||||
$input_store_name = $input_store_info[ 'store_name' ] ?? '';
|
||||
$allot_no = isset($params['allot_no']) && $params['allot_no'] ? $params['allot_no'] : $this->getAllotNo();
|
||||
|
||||
$count = model('stock_allot')->getCount([ ['allot_no', '=', $allot_no] ]);
|
||||
if($count > 0) return $this->error([], '录入失败,单号重复');
|
||||
|
||||
$user_model = new User();
|
||||
$user_info = $user_model->getUserInfo([ [ 'uid', '=', $operater ] ])[ 'data' ] ?? [];
|
||||
$goods_money = getArraySum($goods_sku_list, 'cost_price', 'goods_num');
|
||||
$data = [
|
||||
'site_id' => $site_id,
|
||||
'output_store_id' => $output_store_id,
|
||||
'output_store_name' => $output_store_name,
|
||||
'input_store_id' => $input_store_id,
|
||||
'input_store_name' => $input_store_name,
|
||||
'allot_time' => $allot_time,
|
||||
'goods_money' => $goods_money,
|
||||
'allot_no' => $allot_no,
|
||||
'remark' => $remark,
|
||||
'status' => 1,
|
||||
'create_time' => time(),
|
||||
'operater' => $operater,
|
||||
'operater_name' => $user_info[ 'username' ] ?? ''
|
||||
];
|
||||
$allot_id = model('stock_allot')->add($data);
|
||||
$common_data = [
|
||||
'site_id' => $site_id,
|
||||
'allot_id' => $allot_id,
|
||||
'create_time' => time()
|
||||
];
|
||||
foreach ($goods_sku_list_array as $k => $v) {
|
||||
$item_data = array_merge($common_data, $v);
|
||||
model('stock_allot_goods')->add($item_data);
|
||||
}
|
||||
|
||||
$is_auto_audit = $params[ 'is_auto_audit' ] ?? true;
|
||||
if ($is_auto_audit) {
|
||||
//主动调用审核
|
||||
$result = $this->audit([
|
||||
'allot_id' => $allot_id,
|
||||
'site_id' => $site_id
|
||||
]);
|
||||
if ($result[ 'code' ] < 0) {
|
||||
model('stock_allot')->rollback();
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
$stock_model = new Stock();
|
||||
$stock_config = $stock_model->getStockConfig($site_id)[ 'data' ][ 'value' ];
|
||||
$is_audit = $stock_config[ 'is_audit' ];
|
||||
if (!$is_audit) {
|
||||
$result = $this->audit([
|
||||
'allot_id' => $allot_id,
|
||||
'site_id' => $site_id
|
||||
]);
|
||||
if ($result[ 'code' ] < 0) {
|
||||
model('stock_allot')->rollback();
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model('stock_allot')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('stock_allot')->rollback();
|
||||
return $this->error([$e->getFile(),$e->getLine(),$e->getMessage()], $e->getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 修改库存调拨
|
||||
* @param $params
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function editAllot($params)
|
||||
{
|
||||
model('stock_allot')->startTrans();
|
||||
try {
|
||||
$output_store_id = $params[ 'output_store_id' ];//出库门店
|
||||
$input_store_id = $params[ 'input_store_id' ];//入库门店
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$allot_time = $params[ 'allot_time' ] ?? time();
|
||||
$remark = $params[ 'remark' ] ?? '';
|
||||
$goods_sku_list = $params[ 'goods_sku_list' ];
|
||||
$allot_id = $params['allot_id'];
|
||||
$user_info = $params['user_info'];
|
||||
|
||||
$condition = [
|
||||
[ 'allot_id', '=', $allot_id ],
|
||||
[ 'site_id', '=', $site_id ],
|
||||
];
|
||||
$allot_info = model('stock_allot')->getInfo($condition);
|
||||
|
||||
if ($allot_info[ 'status' ] == 2) {
|
||||
model('stock_allot')->rollback();
|
||||
return $this->error([], '已审核的单据不能编辑');
|
||||
}
|
||||
if ($allot_info[ 'operater' ] != $user_info[ 'uid' ]) {
|
||||
model('stock_allot')->rollback();
|
||||
return $this->error([], '只有单据创建者可以编辑单据');
|
||||
}
|
||||
|
||||
//查询门店名称信息
|
||||
$store_model = new Store();
|
||||
$output_store_condition = [
|
||||
[ 'store_id', '=', $output_store_id ]
|
||||
];
|
||||
$output_store_info = $store_model->getStoreInfo($output_store_condition)[ 'data' ] ?? [];
|
||||
if (empty($output_store_info))
|
||||
return $this->success([], '找不到所选的门店');
|
||||
|
||||
$output_store_name = $output_store_info[ 'store_name' ] ?? '';
|
||||
$input_store_condition = [
|
||||
[ 'store_id', '=', $input_store_id ]
|
||||
];
|
||||
$input_store_info = $store_model->getStoreInfo($input_store_condition)[ 'data' ] ?? [];
|
||||
if (empty($input_store_info))
|
||||
return $this->success([], '找不到所选的门店');
|
||||
|
||||
$goods_sku_list_array_result = $this->getSkuArray($goods_sku_list, $output_store_id);
|
||||
|
||||
if ($goods_sku_list_array_result[ 'code' ] < 0) {
|
||||
model('stock_allot')->rollback();
|
||||
return $goods_sku_list_array_result;
|
||||
}
|
||||
$goods_sku_list_array = $goods_sku_list_array_result[ 'data' ];
|
||||
$input_store_name = $input_store_info[ 'store_name' ] ?? '';
|
||||
$allot_no = isset($params['allot_no']) && $params['allot_no'] ? $params['allot_no'] : $this->getAllotNo();
|
||||
|
||||
$count = model('stock_allot')->getCount([ ['allot_no', '=', $allot_no], ['allot_id', '<>', $allot_id] ]);
|
||||
if($count > 0) return $this->error([], '录入失败,单号重复');
|
||||
$goods_money = getArraySum($goods_sku_list, 'cost_price', 'goods_num');
|
||||
|
||||
$data = [
|
||||
'output_store_id' => $output_store_id,
|
||||
'output_store_name' => $output_store_name,
|
||||
'input_store_id' => $input_store_id,
|
||||
'input_store_name' => $input_store_name,
|
||||
'allot_time' => $allot_time,
|
||||
'allot_no' => $allot_no,
|
||||
'remark' => $remark,
|
||||
'status' => 1,
|
||||
'goods_money' => $goods_money
|
||||
];
|
||||
model('stock_allot')->update($data, [ ['site_id', '=', $site_id], ['allot_id', '=', $allot_id] ]);
|
||||
//删除原有的单据商品
|
||||
model('stock_allot_goods')->delete([ 'allot_id' => $allot_id ]);
|
||||
$common_data = [
|
||||
'site_id' => $site_id,
|
||||
'allot_id' => $allot_id,
|
||||
'create_time' => time()
|
||||
];
|
||||
foreach ($goods_sku_list_array as $k => $v) {
|
||||
$item_data = array_merge($common_data, $v);
|
||||
model('stock_allot_goods')->add($item_data);
|
||||
}
|
||||
|
||||
$is_auto_audit = $params[ 'is_auto_audit' ] ?? true;
|
||||
|
||||
if ($is_auto_audit) {
|
||||
//主动调用审核
|
||||
$result = $this->audit([
|
||||
'allot_id' => $allot_id,
|
||||
'site_id' => $site_id
|
||||
]);
|
||||
if ($result[ 'code' ] < 0) {
|
||||
model('stock_allot')->rollback();
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
$stock_model = new Stock();
|
||||
$stock_config = $stock_model->getStockConfig($site_id)[ 'data' ][ 'value' ];
|
||||
$is_audit = $stock_config[ 'is_audit' ];
|
||||
if (!$is_audit) {
|
||||
$result = $this->audit([
|
||||
'allot_id' => $allot_id,
|
||||
'site_id' => $site_id
|
||||
]);
|
||||
if ($result[ 'code' ] < 0) {
|
||||
model('stock_allot')->rollback();
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model('stock_allot')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('stock_allot')->rollback();
|
||||
return $this->error('', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function getSkuArray($goods_sku_list, $store_id)
|
||||
{
|
||||
$sku_ids = array_column($goods_sku_list, 'goods_sku_id');
|
||||
$goods_nums = array_column($goods_sku_list, 'goods_num', 'goods_sku_id');
|
||||
$stock_model = new StockModel();
|
||||
$condition = [
|
||||
['gs.sku_id', 'in', $sku_ids],
|
||||
];
|
||||
$field = 'g.goods_class,gs.sku_id,gs.goods_id,gs.sku_image,gs.sku_name,gs.unit,gs.sku_no,gs.spec_name,sgs.stock,sgs.real_stock,sgs.price,gs.cost_price';
|
||||
$goods_sku_list = $stock_model->getStoreGoodsSkuPage($condition, $field, 'gs.create_time desc, gs.sku_id desc', $store_id, 1, 0)['data']['list'];
|
||||
|
||||
$goods_sku_list_array = [];
|
||||
foreach ($goods_sku_list as $goods_sku_info) {
|
||||
$goods_sku_id = $goods_sku_info[ 'sku_id' ];
|
||||
$goods_num = $goods_nums[$goods_sku_id] ?? 0;
|
||||
$goods_class = $goods_sku_info['goods_class'];
|
||||
if($goods_class == GoodsDict::weigh && !preg_match(config('regexp.>0float3'), $goods_num)){
|
||||
return $this->error(null, '[' . $goods_sku_info[ 'sku_name' ] . ']调拨数量必须为正数且最多保留三位小数!');
|
||||
}else if($goods_class != GoodsDict::weigh && !preg_match(config('regexp.>0num'), $goods_num)){
|
||||
return $this->error(null, '[' . $goods_sku_info[ 'sku_name' ] . ']调拨数量必须为正整数!');
|
||||
}else if($goods_num > $goods_sku_info['real_stock']){
|
||||
return $this->error(null, '[' . $goods_sku_info[ 'sku_name' ] . ']可调拨数量不足!');
|
||||
}
|
||||
|
||||
$goods_sku_list_array[] = [
|
||||
'goods_id' => $goods_sku_info[ 'goods_id' ],
|
||||
'goods_sku_id' => $goods_sku_info[ 'sku_id' ],
|
||||
'goods_sku_name' => $goods_sku_info[ 'sku_name' ],
|
||||
'goods_sku_no' => $goods_sku_info[ 'sku_no' ],
|
||||
'goods_sku_img' => $goods_sku_info[ 'sku_image' ],
|
||||
'goods_sku_spec' => $goods_sku_info[ 'spec_name' ],
|
||||
'goods_unit' => $goods_sku_info[ 'unit' ] ? $goods_sku_info[ 'unit' ] : '件',
|
||||
'goods_num' => $goods_num,
|
||||
'goods_price' => $goods_sku_info[ 'cost_price' ],
|
||||
'goods_remark' => '',
|
||||
];
|
||||
}
|
||||
|
||||
return $this->success($goods_sku_list_array);
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核
|
||||
* @param $params
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function audit($params)
|
||||
{
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$allot_id = $params[ 'allot_id' ];
|
||||
$condition = [
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'allot_id', '=', $allot_id ]
|
||||
];
|
||||
$info = model('stock_allot')->getInfo($condition);
|
||||
if (empty($info)) {
|
||||
return $this->error([], '调拨单据不存在');
|
||||
}
|
||||
|
||||
$allot_data = [
|
||||
'verify_time' => time(),
|
||||
'status' => 2
|
||||
];
|
||||
|
||||
model('stock_allot')->update($allot_data, $condition);
|
||||
$result = $this->complete($params);
|
||||
if ($result[ 'code' ] < 0)
|
||||
return $result;
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 拒绝审核
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
public function refuse($params)
|
||||
{
|
||||
$allot_id = $params[ 'allot_id' ];
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$user_info = $params[ 'user_info' ];
|
||||
$condition = [
|
||||
[ 'allot_id', '=', $allot_id ],
|
||||
[ 'site_id', '=', $site_id ]
|
||||
];
|
||||
$info = model('stock_allot')->getInfo($condition);
|
||||
if (empty($info))
|
||||
return $this->error([], '找不到可审核的单据');
|
||||
|
||||
if ($info[ 'status' ] == 2)
|
||||
return $this->error([], '当前单据已审核');
|
||||
|
||||
$data = [
|
||||
'status' => -1,
|
||||
'verify_time' => time(),
|
||||
'refuse_reason' => $params[ 'refuse_reason' ],
|
||||
'verifier' => $user_info[ 'uid' ] ?? 0,//审核人
|
||||
'verifier_name' => $user_info[ 'username' ] ?? '系统'
|
||||
];
|
||||
model('stock_allot')->update($data, $condition);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
public function delete($params)
|
||||
{
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$allot_id = $params[ 'allot_id' ];
|
||||
$user_info = $params[ 'user_info' ];
|
||||
$store_id = $params[ 'store_id' ] ?? 0;
|
||||
//查询单据
|
||||
$condition = [
|
||||
[ 'allot_id', '=', $allot_id ],
|
||||
[ 'site_id', '=', $site_id ],
|
||||
];
|
||||
if ($store_id > 0) {
|
||||
$condition[] = [ 'store_id', '=', $store_id ];
|
||||
}
|
||||
$allot_info = model('stock_allot')->getInfo($condition);
|
||||
//被拒绝也可以删除
|
||||
if ($allot_info[ 'status' ] == 2) {
|
||||
return $this->error('已审核的单据不能删除');
|
||||
}
|
||||
if ($allot_info[ 'operater' ] != $user_info[ 'uid' ]) {
|
||||
return $this->error('只有单据创建者可以删除单据');
|
||||
}
|
||||
model('stock_allot')->delete($condition);
|
||||
model('stock_allot_goods')->delete($condition);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
public function complete($params)
|
||||
{
|
||||
$allot_id = $params[ 'allot_id' ];
|
||||
$condition = [
|
||||
[ 'allot_id', '=', $allot_id ]
|
||||
];
|
||||
$info = model('stock_allot')->getInfo($condition);
|
||||
if (empty($info)) {
|
||||
return $this->error([], '调拨单据不存在');
|
||||
}
|
||||
$result = $this->setStock($info);
|
||||
if ($result[ 'code' ] < 0)
|
||||
return $result;
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 整理调拨单据
|
||||
* @param $params
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function setStock($params)
|
||||
{
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$allot_id = $params[ 'allot_id' ];
|
||||
$allot_goods_condition = [
|
||||
[ 'allot_id', '=', $allot_id ]
|
||||
];
|
||||
$allot_goods_list = model('stock_allot_goods')->getList($allot_goods_condition);
|
||||
$output_store_id = $params[ 'output_store_id' ];
|
||||
$input_store_id = $params[ 'input_store_id' ];
|
||||
$remark = $params[ 'remark' ];
|
||||
$allot_time = $params[ 'allot_time' ];
|
||||
$operater = $params[ 'operater' ];
|
||||
$operater_name = $params[ 'operater_name' ];
|
||||
foreach ($allot_goods_list as $k => $goods_sku_item) {
|
||||
$allot_goods_id = $goods_sku_item[ 'allot_goods_id' ];
|
||||
$item_sku_id = $goods_sku_item[ 'goods_sku_id' ];
|
||||
$item_goods_id = $goods_sku_item[ 'goods_id' ];
|
||||
|
||||
$goods_num = numberFormat($goods_sku_item[ 'goods_num' ]);
|
||||
|
||||
$sku_condition = [
|
||||
[ 'sku_id', '=', $item_sku_id ]
|
||||
];
|
||||
$goods_sku_info = model('goods_sku')->getInfo($sku_condition);
|
||||
|
||||
$goods_price = $goods_sku_info[ 'cost_price' ];
|
||||
$output_store_sku_condition = [
|
||||
[ 'store_id', '=', $output_store_id ],
|
||||
[ 'goods_id', '=', $item_goods_id ],
|
||||
[ 'sku_id', '=', $item_sku_id ]
|
||||
];
|
||||
$output_store_sku_info = model('store_goods_sku')->getInfo($output_store_sku_condition);
|
||||
|
||||
$output_store_stock = $output_store_sku_info[ 'real_stock' ] ?? 0;
|
||||
$input_store_sku_condition = [
|
||||
[ 'store_id', '=', $input_store_id ],
|
||||
[ 'goods_id', '=', $item_goods_id ],
|
||||
[ 'sku_id', '=', $item_sku_id ]
|
||||
];
|
||||
$input_store_sku_info = model('store_goods_sku')->getInfo($input_store_sku_condition);
|
||||
|
||||
$input_store_stock = $input_store_sku_info[ 'real_stock' ] ?? 0;
|
||||
$total_goods_money = $goods_num * $goods_price;
|
||||
$update_data = [
|
||||
'output_store_stock' => numberFormat($output_store_stock),
|
||||
'input_store_stock' => numberFormat($input_store_stock),
|
||||
'goods_price' => $goods_price,
|
||||
'total_goods_money' => $total_goods_money,
|
||||
];
|
||||
$update_condition = [
|
||||
[ 'allot_goods_id', '=', $allot_goods_id ]
|
||||
];
|
||||
model('stock_allot_goods')->update($update_data, $update_condition);
|
||||
|
||||
$goods_money = model('stock_allot_goods')->getSum([ [ 'site_id', '=', $site_id ], [ 'allot_id', '=', $allot_id ] ], 'total_goods_money');
|
||||
|
||||
model('stock_allot')->update([ 'goods_money' => $goods_money ], [
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'allot_id', '=', $allot_id ]
|
||||
]);
|
||||
|
||||
//新增门店出库
|
||||
$goods_sku_list = [
|
||||
[
|
||||
'goods_sku_id' => $item_sku_id,
|
||||
'goods_id' => $item_goods_id,
|
||||
'goods_num' => $goods_num,
|
||||
'goods_price' => $goods_price
|
||||
]
|
||||
];
|
||||
|
||||
$user_info = [
|
||||
'uid' => $operater,
|
||||
'username' => $operater_name,
|
||||
];
|
||||
$document_model = new Document();
|
||||
$document_params = [
|
||||
'allot_id' => $allot_id,
|
||||
'store_id' => $output_store_id,
|
||||
'user_info' => $user_info,
|
||||
'site_id' => $site_id,
|
||||
'is_auto_audit' => false,//调拨的单据如果开始审核开关的话就需要审核
|
||||
];
|
||||
$document_params[ 'document_type' ] = 'ALLOTPUT';
|
||||
$document_params[ 'goods_sku_list' ] = $goods_sku_list;
|
||||
$document_params[ 'is_auto_audit' ] = 1;
|
||||
|
||||
$out_result = $document_model->addDocument(array_merge($document_params, [ 'is_out_stock' => 1 ]));
|
||||
if ($out_result[ 'code' ] < 0) {
|
||||
return $out_result;
|
||||
}
|
||||
|
||||
$document_params[ 'store_id' ] = $input_store_id;
|
||||
$document_params[ 'document_type' ] = 'ALLOTIN';
|
||||
$out_result = $document_model->addDocument($document_params);
|
||||
if ($out_result[ 'code' ] < 0) {
|
||||
return $out_result;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取调拨单分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getStockAllotPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*', $alias = '', $join = '')
|
||||
{
|
||||
$document_list = model('stock_allot')->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
|
||||
return $this->success($document_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单据详情
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getAllotInfo($condition = [], $field = '*')
|
||||
{
|
||||
$info = model('stock_allot')->getInfo($condition, $field);
|
||||
if (!empty($info)) {
|
||||
|
||||
$document_model = new Document();
|
||||
|
||||
// 查询入库单
|
||||
$info[ 'input_info' ] = $document_model->getDocumentInfo([ [ 'site_id', '=', $info[ 'site_id' ] ], [ 'allot_id', '=', $info[ 'allot_id' ] ], [ 'type', '=', StockDict::input ], [ 'store_id', '=', $info[ 'input_store_id' ] ] ], 'operater_name,verifier_name,status,refuse_reason,create_time,audit_time')[ 'data' ];
|
||||
|
||||
// 查询出库单
|
||||
$info[ 'out_info' ] = $document_model->getDocumentInfo([ [ 'site_id', '=', $info[ 'site_id' ] ], [ 'allot_id', '=', $info[ 'allot_id' ] ], [ 'type', '=', StockDict::output ], [ 'store_id', '=', $info[ 'output_store_id' ] ] ], 'operater_name,verifier_name,status,refuse_reason,create_time,audit_time')[ 'data' ];
|
||||
|
||||
//单据产品项
|
||||
$goods_list = model('stock_allot_goods')->getList([
|
||||
'allot_id' => $info[ 'allot_id' ]
|
||||
]);
|
||||
foreach ($goods_list as $k => $v) {
|
||||
$goods_list[ $k ][ 'goods_num' ] = numberFormat($v[ 'goods_num' ]);
|
||||
$goods_list[ $k ][ 'output_store_stock' ] = numberFormat($goods_list[ $k ][ 'output_store_stock' ]);
|
||||
$goods_list[ $k ][ 'input_store_stock' ] = numberFormat($goods_list[ $k ][ 'input_store_stock' ]);
|
||||
$info[ 'goods_unit' ] = $v[ 'goods_unit' ];
|
||||
}
|
||||
$info[ 'goods_sku_list_array' ] = $goods_list;
|
||||
$info[ 'goods_price' ] = 0;
|
||||
$info[ 'goods_total_price' ] = 0.00;
|
||||
foreach ($goods_list as $key => $value) {
|
||||
$info[ 'goods_sku_list_array' ][ $key ][ 'goods_sum' ] = floatval($value[ 'goods_num' ] * $value[ 'goods_price' ]);
|
||||
$info[ 'goods_price' ] += numberFormat($value[ 'goods_num' ]);
|
||||
$info[ 'goods_total_price' ] += $info[ 'goods_sku_list_array' ][ $key ][ 'goods_sum' ];
|
||||
}
|
||||
$info[ 'goods_count' ] = count($info[ 'goods_sku_list_array' ]);
|
||||
}
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取编辑单据数据
|
||||
* @param array $condition
|
||||
* @return array
|
||||
*/
|
||||
public function getAllotEditData($condition = [])
|
||||
{
|
||||
$field = 'site_id,allot_id,output_store_id,input_store_id,allot_no,remark,allot_time';
|
||||
$allot_info = $this->getAllotInfo($condition, $field)[ 'data' ];
|
||||
if (!empty($allot_info)) {
|
||||
$goods_field = 'gs.sku_id,gs.sku_image,gs.sku_name,gs.unit,gs.sku_no,
|
||||
sgs.stock,sgs.real_stock,sgs.price,sgs.cost_price,
|
||||
ig.goods_num,ig.goods_sku_id';
|
||||
|
||||
$join = [
|
||||
[ 'goods_sku gs', 'ig.goods_sku_id = gs.sku_id', 'left' ],
|
||||
[
|
||||
'store_goods_sku sgs',
|
||||
'sgs.sku_id = gs.sku_id and (sgs.store_id is null or sgs.store_id = ' . $allot_info[ 'output_store_id' ] . ')',
|
||||
'left'
|
||||
]
|
||||
];
|
||||
|
||||
$allot_goods_list = model('stock_allot_goods')->getList([
|
||||
[ 'allot_id', '=', $allot_info[ 'allot_id' ] ]
|
||||
], $goods_field, '', 'ig', $join);
|
||||
foreach ($allot_goods_list as $k => $v) {
|
||||
$allot_goods_list[ $k ][ 'stock' ] = numberFormat($v[ 'stock' ]);
|
||||
$allot_goods_list[ $k ][ 'goods_num' ] = numberFormat($allot_goods_list[ $k ][ 'goods_num' ]);
|
||||
}
|
||||
$allot_info[ 'goods_list' ] = array_column($allot_goods_list, null, 'goods_sku_id');
|
||||
}
|
||||
return $this->success($allot_info);
|
||||
}
|
||||
|
||||
}
|
||||
1057
addon/stock/model/stock/Document.php
Executable file
1057
addon/stock/model/stock/Document.php
Executable file
File diff suppressed because it is too large
Load Diff
307
addon/stock/model/stock/Export.php
Executable file
307
addon/stock/model/stock/Export.php
Executable file
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\stock\model\stock;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 导出
|
||||
* @author Administrator
|
||||
*/
|
||||
class Export extends BaseModel
|
||||
{
|
||||
|
||||
public $field = [
|
||||
'store_name' => '门店名称',
|
||||
'sku_no' => '商品编码',
|
||||
'sku_name' => '商品名称',
|
||||
'stock' => '销售库存',
|
||||
'real_stock' => '实物库存',
|
||||
'price' => '销售价',
|
||||
'cost_price' => '成本价',
|
||||
'sale_num' => '销量',
|
||||
'goods_state' => '商品状态'
|
||||
];
|
||||
|
||||
public $store_name = '';
|
||||
|
||||
|
||||
/**
|
||||
* 查询商品项数据并导出
|
||||
* @param $condition
|
||||
* @param $condition_desc
|
||||
* @param $site_id
|
||||
* @param $store_id
|
||||
* @param $store_name
|
||||
* @return array
|
||||
*/
|
||||
public function export($condition, $condition_desc, $site_id, $store_id, $store_name)
|
||||
{
|
||||
try {
|
||||
// 预先创建导出的记录
|
||||
$data = [
|
||||
'condition' => json_encode($condition_desc),
|
||||
'create_time' => time(),
|
||||
'status' => 0,
|
||||
'site_id' => $site_id
|
||||
];
|
||||
$records_result = $this->addExport($data);
|
||||
|
||||
$export_id = $records_result[ 'data' ] ?? 0;
|
||||
if ($export_id <= 0) {
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
$alias = 'gs';
|
||||
|
||||
$field = $this->field;
|
||||
|
||||
if ($store_id > 0) {
|
||||
$this->store_name = $store_name;
|
||||
} else {
|
||||
unset($field[ 'store_name' ]);
|
||||
}
|
||||
|
||||
// 通过分批次执行数据导出(防止内存超出配置设置的)
|
||||
|
||||
set_time_limit(0);
|
||||
$file_name = date('YmdHis');// csv文件名
|
||||
$file_path = 'upload/goods_csv/';
|
||||
if (dir_mkdir($file_path)) {
|
||||
$file_path = $file_path . $file_name . '.csv';
|
||||
//创建一个临时csv文件
|
||||
$fp = fopen($file_path, 'w'); // 生成临时文件
|
||||
fwrite($fp, chr(0xEF) . chr(0xBB) . chr(0xBF)); // 添加 BOM
|
||||
$field_value = [];
|
||||
$field_key = [];
|
||||
$field_key_array = [];
|
||||
// 为了防止部分代码被筛选中替换, 给变量前后两边增加字符串
|
||||
foreach ($field as $k => $v) {
|
||||
$field_value[] = $v;
|
||||
$field_key[] = "{\$$k}";
|
||||
$field_key_array[] = $k;
|
||||
}
|
||||
|
||||
$table_field = 'gs.sku_id, gs.sku_no, gs.sku_name, gs.goods_state';
|
||||
$join = [
|
||||
[ 'goods g', 'g.goods_id = gs.goods_id', 'left' ]
|
||||
];
|
||||
|
||||
$group = '';
|
||||
if ($store_id > 0) {
|
||||
$table_field .= ',sgs.price, sgs.sale_num,sgs.cost_price,ifnull(sgs.stock,0) as stock, ifnull(sgs.real_stock, 0) as real_stock,s.store_name';
|
||||
$join[] = [ 'store_goods_sku sgs', 'sgs.sku_id = gs.sku_id and (sgs.store_id is null or sgs.store_id = ' . $store_id . ')', 'left' ];
|
||||
$join[] = [ 'store s', 's.store_id = sgs.store_id', 'left' ];
|
||||
} else {
|
||||
$join[] = [ 'store_goods_sku sgs', 'sgs.sku_id = gs.sku_id or sgs.sku_id is null', 'left' ];
|
||||
$table_field .= ',gs.price, gs.sale_num,gs.cost_price,gs.stock, ifnull(sum(sgs.real_stock),0) as real_stock';
|
||||
$group = 'gs.sku_id';
|
||||
}
|
||||
|
||||
$table = Db::name('goods_sku')->where($condition)->alias($alias)->group($group)->order('g.create_time desc');
|
||||
|
||||
$table = $this->parseJoin($table, $join);
|
||||
|
||||
$first_line = implode(',', $field_value);
|
||||
// 写入第一行表头
|
||||
fwrite($fp, $first_line . "\n");
|
||||
|
||||
$temp_line = implode(',', $field_key) . "\n";
|
||||
|
||||
$table->field($table_field)->chunk(5000, function($item_list) use ($fp, $temp_line, $field_key_array) {
|
||||
// 写入导出信息
|
||||
$this->itemExport($item_list, $field_key_array, $temp_line, $fp);
|
||||
unset($item_list);
|
||||
}, 'gs.sku_id');
|
||||
|
||||
$table->removeOption();
|
||||
fclose($fp); // 每生成一个文件关闭
|
||||
unset($table);
|
||||
|
||||
// 将同步导出记录状态
|
||||
$records_data = [
|
||||
'path' => $file_path,
|
||||
'status' => 1
|
||||
];
|
||||
$records_condition = [
|
||||
[ 'export_id', '=', $export_id ]
|
||||
];
|
||||
$this->editExport($records_data, $records_condition);
|
||||
return $this->success();
|
||||
} else {
|
||||
return $this->error();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->error([], $e->getMessage() . $e->getFile() . $e->getLine());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $db_obj
|
||||
* @param $join
|
||||
* @return mixed
|
||||
*/
|
||||
public function parseJoin($db_obj, $join)
|
||||
{
|
||||
foreach ($join as $item) {
|
||||
list($table, $on, $type) = $item;
|
||||
$type = strtolower($type);
|
||||
switch ( $type ) {
|
||||
case 'left':
|
||||
$db_obj = $db_obj->leftJoin($table, $on);
|
||||
break;
|
||||
case 'inner':
|
||||
$db_obj = $db_obj->join($table, $on);
|
||||
break;
|
||||
case 'right':
|
||||
$db_obj = $db_obj->rightjoin($table, $on);
|
||||
break;
|
||||
case 'full':
|
||||
$db_obj = $db_obj->fulljoin($table, $on);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $db_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给csv写入新的数据
|
||||
* @param $item_list
|
||||
* @param $field_key
|
||||
* @param $temp_line
|
||||
* @param $fp
|
||||
*/
|
||||
public function itemExport($item_list, $field_key, $temp_line, $fp)
|
||||
{
|
||||
$item_list = $item_list->toArray();
|
||||
foreach ($item_list as $k => $item_v) {
|
||||
$new_line_value = $temp_line;
|
||||
|
||||
if (!empty($this->store_name)) {
|
||||
$item_v[ 'store_name' ] = $this->store_name;
|
||||
}
|
||||
|
||||
if (isset($item_v[ 'num' ])) {
|
||||
$item_v[ 'num' ] = numberFormat($item_v[ 'num' ]);
|
||||
}
|
||||
|
||||
if (isset($item_v[ 'stock' ])) {
|
||||
$item_v[ 'stock' ] = numberFormat($item_v[ 'stock' ]);
|
||||
}
|
||||
|
||||
if (isset($item_v[ 'sale_num' ])) {
|
||||
$item_v[ 'sale_num' ] = numberFormat($item_v[ 'sale_num' ]);
|
||||
}
|
||||
if (isset($item_v[ 'real_stock' ])) {
|
||||
$item_v[ 'real_stock' ] = numberFormat($item_v[ 'real_stock' ]);
|
||||
}
|
||||
|
||||
$item_v[ 'goods_state' ] = $item_v[ 'goods_state' ] == 1 ? '销售中' : '仓库中';
|
||||
|
||||
foreach ($item_v as $key => $value) {
|
||||
$value = trim($value);
|
||||
|
||||
//CSV比较简单,记得转义 逗号就好
|
||||
$values = str_replace(',', '\\', $value . "\t");
|
||||
$values = str_replace("\n", '', $values);
|
||||
$values = str_replace("\r", '', $values);
|
||||
$new_line_value = str_replace("{\$$key}", $values, $new_line_value);
|
||||
}
|
||||
|
||||
// 写入第一行表头
|
||||
fwrite($fp, $new_line_value);
|
||||
|
||||
// 销毁变量, 防止内存溢出
|
||||
unset($new_line_value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加导出记录
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addExport($data)
|
||||
{
|
||||
$res = model('stock_goods_export')->add($data);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新导出记录
|
||||
* @param $data
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function editExport($data, $condition)
|
||||
{
|
||||
$res = model('stock_goods_export')->update($data, $condition);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除导出记录
|
||||
* @param $condition
|
||||
* @return array
|
||||
*/
|
||||
public function deleteExport($condition)
|
||||
{
|
||||
// 先查询数据
|
||||
$list = model('stock_goods_export')->getList($condition, '*');
|
||||
if (!empty($list)) {
|
||||
foreach ($list as $k => $v) {
|
||||
if (file_exists($v[ 'path' ])) {
|
||||
// 删除物理文件路径
|
||||
if (!unlink($v[ 'path' ])) {
|
||||
// 失败
|
||||
} else {
|
||||
// 成功
|
||||
}
|
||||
}
|
||||
}
|
||||
$res = model('stock_goods_export')->delete($condition);
|
||||
}
|
||||
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导出记录
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @return array
|
||||
*/
|
||||
public function getExport($condition, $field = '*', $order = '')
|
||||
{
|
||||
$list = model('stock_goods_export')->getList($condition, $field, $order);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出记录
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getExportPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
|
||||
{
|
||||
$list = model('stock_goods_export')->pageList($condition, $field, $order, $page, $page_size);
|
||||
return $this->success($list);
|
||||
}
|
||||
}
|
||||
67
addon/stock/model/stock/Import.php
Executable file
67
addon/stock/model/stock/Import.php
Executable file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\stock\model\stock;
|
||||
|
||||
use app\model\BaseModel;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 导入
|
||||
* @author Administrator
|
||||
*/
|
||||
class Import extends BaseModel
|
||||
{
|
||||
|
||||
/**
|
||||
* 单据导入
|
||||
* @param $path
|
||||
* @param $type
|
||||
*/
|
||||
public function import($path, $type)
|
||||
{
|
||||
|
||||
$PHPReader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
|
||||
|
||||
//载入文件
|
||||
$PHPExcel = $PHPReader->load($path);
|
||||
|
||||
//获取表中的第一个工作表,如果要获取第二个,把0改为1,依次类推
|
||||
$currentSheet = $PHPExcel->getSheet(0);
|
||||
|
||||
//获取总行数
|
||||
$allRow = $currentSheet->getHighestRow();
|
||||
|
||||
$time = $PHPExcel->getActiveSheet()->getCell('A2')->getValue();
|
||||
$time = trim(str_replace('入库时间:', '', $time));
|
||||
$time = $time ? date_to_time($time) : time();
|
||||
|
||||
$document_no = $PHPExcel->getActiveSheet()->getCell('C2')->getValue();
|
||||
$document_no = trim(str_replace('编号:', '', $document_no));
|
||||
|
||||
$remark = $PHPExcel->getActiveSheet()->getCell('A3')->getValue();
|
||||
$remark = trim(str_replace('备注:', '', $remark));
|
||||
|
||||
dump($time, $document_no, $remark);
|
||||
|
||||
dd($allRow);
|
||||
|
||||
|
||||
// switch ($type){
|
||||
// case 'PURCHASE'://采购入库单
|
||||
//
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
798
addon/stock/model/stock/Inventory.php
Executable file
798
addon/stock/model/stock/Inventory.php
Executable file
@@ -0,0 +1,798 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 上海牛之云网络科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\stock\model\stock;
|
||||
|
||||
|
||||
use app\model\store\Store;
|
||||
use app\model\BaseModel;
|
||||
use app\model\storegoods\StoreGoods;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 盘点
|
||||
* Class Inventory
|
||||
* @package addon\stock\model\stock
|
||||
*/
|
||||
class Inventory extends BaseModel
|
||||
{
|
||||
|
||||
const AUDIT = 1; // 待审核
|
||||
|
||||
const REFUSE = -1;// 审核被拒绝
|
||||
|
||||
const AUDITED = 2; // 审核通过
|
||||
|
||||
public $status = [
|
||||
|
||||
self::AUDIT => [
|
||||
'status' => self::AUDIT,
|
||||
'name' => '待审核'
|
||||
],
|
||||
self::AUDITED => [
|
||||
'status' => self::AUDITED,
|
||||
'name' => '已审核'
|
||||
],
|
||||
self::REFUSE => [
|
||||
'status' => self::REFUSE,
|
||||
'name' => '已拒绝'
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* 获取审核状态
|
||||
* @return array
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function inventoryNo()
|
||||
{
|
||||
return 'PD' . date('ymdhis', time()) . rand(1111, 9999);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加盘点单
|
||||
* @param $params
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function addInventory($params)
|
||||
{
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$store_id = $params[ 'store_id' ];
|
||||
//是否限制只能有一个盘点单据
|
||||
$is_limit = $params['is_limit'] ?? true;
|
||||
if($is_limit){
|
||||
//同商品同时只能存在一个盘点单据
|
||||
$count = model('stock_inventory')->getCount([
|
||||
[ 'store_id', '=', $store_id ],
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'status', '=', self::AUDIT ]
|
||||
]);
|
||||
if ($count > 0) {
|
||||
return $this->error([], '一段时间内只能存在一个待审核的盘点单据');
|
||||
}
|
||||
}
|
||||
|
||||
model('stock_inventory')->startTrans();
|
||||
try {
|
||||
$sku_list = $params[ 'sku_list' ];
|
||||
$user_info = $params[ 'user_info' ];
|
||||
$inventory_no = isset($params['inventory_no']) && $params['inventory_no'] ? $params['inventory_no'] : $this->inventoryNo();
|
||||
|
||||
$count = model('stock_inventory')->getCount([ ['inventory_no', '=', $inventory_no] ]);
|
||||
if($count > 0) return $this->error([], '录入失败,单号重复');
|
||||
|
||||
//查询门店名称信息
|
||||
$store_model = new Store();
|
||||
$store_condition = [
|
||||
[ 'store_id', '=', $store_id ]
|
||||
];
|
||||
$store_info = $store_model->getStoreInfo($store_condition, 'store_name')[ 'data' ] ?? [];
|
||||
if (empty($store_info)) {
|
||||
model('stock_inventory')->rollback();
|
||||
return $this->success([], '找不到所选的门店');
|
||||
}
|
||||
$store_name = $store_info[ 'store_name' ];
|
||||
$common_data = [
|
||||
'site_id' => $site_id,
|
||||
'create_time' => time(),
|
||||
'store_id' => $store_id
|
||||
];
|
||||
$data = [
|
||||
'operater' => $user_info[ 'uid' ] ?? 0,
|
||||
'operater_name' => $user_info[ 'username' ] ?? '系统',
|
||||
'create_time' => time(),
|
||||
'inventory_no' => $inventory_no,
|
||||
'store_name' => $store_name,
|
||||
'remark' => $params[ 'remark' ] ?? '',
|
||||
'action_time' => $params[ 'action_time' ] ?? time(),
|
||||
'status' => self::AUDIT
|
||||
];
|
||||
//盘点单据
|
||||
$inventory_data = array_merge($data, $common_data);
|
||||
$inventory_id = model('stock_inventory')->add($inventory_data);
|
||||
$common_data[ 'inventory_id' ] = $inventory_id;
|
||||
$temp_goods_list = model('goods_sku')->getList(
|
||||
[
|
||||
['gs.sku_id', 'in', array_column($sku_list, 'goods_sku_id')]
|
||||
],
|
||||
'gs.sku_id,gs.goods_id,gs.sku_name,gs.sku_no,gs.sku_image,gs.spec_name,
|
||||
sgs.real_stock',
|
||||
'',
|
||||
'gs',
|
||||
[
|
||||
[
|
||||
'store_goods_sku sgs',
|
||||
'gs.sku_id = sgs.sku_id and sgs.store_id = '.$store_id,
|
||||
'left'
|
||||
]
|
||||
]
|
||||
);
|
||||
$temp_goods_list = array_column($temp_goods_list, null, 'sku_id');
|
||||
$insert_data = [];
|
||||
foreach ($sku_list as $k => $goods_sku) {
|
||||
$goods_sku_id = $goods_sku[ 'goods_sku_id' ];
|
||||
$goods_num = numberFormat($goods_sku[ 'goods_num' ]);
|
||||
$item_temp_item = $temp_goods_list[$goods_sku_id] ?? [];
|
||||
$goods_remark = '';
|
||||
//具体业务尚未调试,表结构不一致
|
||||
// $goods_sku_info = model('goods_sku')->getInfo([ [ 'sku_id', '=', $goods_sku_id ] ], 'sku_id,goods_id,sku_name,sku_no,sku_image,spec_name');
|
||||
// $goods_sku_data_info = model('store_goods_sku')->getInfo([ [ 'sku_id', '=', $goods_sku_id ], [ 'store_id', '=', $store_id ] ], '*');
|
||||
$goods_stock = $item_temp_item[ 'real_stock' ] ?? 0;
|
||||
$goods_sku_data = [];
|
||||
$goods_sku_data[ 'inventory_num' ] = $goods_num;
|
||||
$goods_sku_data[ 'inventory_remark' ] = $goods_remark;
|
||||
$goods_sku_data[ 'goods_id' ] = $item_temp_item[ 'goods_id' ];
|
||||
$goods_sku_data[ 'goods_sku_id' ] = $goods_sku_id;
|
||||
$goods_sku_data[ 'goods_sku_name' ] = $item_temp_item[ 'sku_name' ];
|
||||
$goods_sku_data[ 'goods_sku_no' ] = $item_temp_item[ 'sku_no' ];
|
||||
$goods_sku_data[ 'goods_sku_spec' ] = $item_temp_item[ 'spec_name' ];
|
||||
$goods_sku_data[ 'goods_img' ] = $item_temp_item[ 'sku_image' ];
|
||||
$goods_sku_data[ 'stock' ] = numberFormat($goods_stock);
|
||||
$insert_data[] = array_merge($goods_sku_data, $common_data);
|
||||
}
|
||||
model('stock_inventory_goods')->addList($insert_data);
|
||||
$is_auto_audit = $params[ 'is_auto_audit' ] ?? true;
|
||||
if ($is_auto_audit) {
|
||||
//主动调用审核
|
||||
$inventory_params = [
|
||||
'inventory_id' => $inventory_id,
|
||||
'site_id' => $site_id,
|
||||
'user_info' => $user_info
|
||||
];
|
||||
$audit_result = $this->audit($inventory_params);
|
||||
if ($audit_result[ 'code' ] < 0) {
|
||||
model('stock_inventory')->rollback();
|
||||
return $audit_result;
|
||||
}
|
||||
} else {
|
||||
$stock_model = new Stock();
|
||||
$stock_config = $stock_model->getStockConfig($site_id)[ 'data' ][ 'value' ];
|
||||
$is_audit = $stock_config[ 'is_audit' ];
|
||||
if (!$is_audit) {
|
||||
//主动调用审核
|
||||
$inventory_params = [
|
||||
'inventory_id' => $inventory_id,
|
||||
'site_id' => $site_id,
|
||||
'user_info' => $user_info
|
||||
];
|
||||
$audit_result = $this->audit($inventory_params);
|
||||
if ($audit_result[ 'code' ] < 0) {
|
||||
model('stock_inventory')->rollback();
|
||||
return $audit_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model('stock_inventory')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('stock_inventory')->rollback();
|
||||
return $this->error($e->getMessage() . $e->getFile() . $e->getLine());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过审核
|
||||
* @param $params
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function audit($params)
|
||||
{
|
||||
$inventory_id = $params[ 'inventory_id' ];
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$user_info = $params[ 'user_info' ];
|
||||
$condition = [
|
||||
[ 'inventory_id', '=', $inventory_id ],
|
||||
[ 'site_id', '=', $site_id ]
|
||||
];
|
||||
$info = model('stock_inventory')->getInfo($condition);
|
||||
if (empty($info))
|
||||
return $this->error([], '找不到可审核的单据');
|
||||
|
||||
if ($info[ 'status' ] == self::AUDITED)
|
||||
return $this->error([], '当前单据已审核');
|
||||
$data = [
|
||||
'status' => self::AUDITED,
|
||||
'audit_time' => time(),
|
||||
'verifier' => $user_info[ 'uid' ] ?? 0,//审核人
|
||||
'verifier_name' => $user_info[ 'username' ] ?? '系统'
|
||||
];
|
||||
model('stock_inventory')->update($data, $condition);
|
||||
$store_id = $info[ 'store_id' ];
|
||||
return $this->complete([ 'inventory_id' => $inventory_id, 'site_id' => $site_id, 'store_id' => $store_id, 'user_info' => $user_info ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单据通过审核
|
||||
* @param $params
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function complete($params)
|
||||
{
|
||||
$inventory_id = $params[ 'inventory_id' ];
|
||||
$user_info = $params[ 'user_info' ] ?? [];
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$condition = [
|
||||
[ 'inventory_id', '=', $inventory_id ],
|
||||
[ 'site_id', '=', $site_id ]
|
||||
];
|
||||
$info = model('stock_inventory')->getInfo($condition);
|
||||
if (empty($info))
|
||||
return $this->error([], '找不到可审核的单据');
|
||||
|
||||
$stock_inventory_goods_list = model('stock_inventory_goods')->getList($condition, '*');
|
||||
if (empty($stock_inventory_goods_list))
|
||||
return $this->error([], '找不到可审核的单据');
|
||||
|
||||
$store_id = $info[ 'store_id' ];
|
||||
$stat_data = $this->stat([ 'inventory_id' => $inventory_id, 'store_id' => $store_id ])[ 'data' ] ?? [];
|
||||
|
||||
$data = [
|
||||
'kinds_num' => $stat_data[ 'kinds_num' ],
|
||||
'kinds_profit_num' => $stat_data[ 'kinds_profit_num' ],
|
||||
'kinds_loss_num' => $stat_data[ 'kinds_loss_num' ],
|
||||
'kinds_even_num' => $stat_data[ 'kinds_even_num' ],
|
||||
'num' => $stat_data[ 'num' ],
|
||||
'profit_num' => $stat_data[ 'profit_num' ],
|
||||
'loss_num' => $stat_data[ 'loss_num' ],
|
||||
'even_num' => $stat_data[ 'even_num' ],
|
||||
'profitloss_num' => $stat_data[ 'profitloss_num' ],
|
||||
'inventory_cost_money' => $stat_data[ 'inventory_cost_money' ],
|
||||
'profitloss_sale_money' => $stat_data[ 'profitloss_sale_money' ],
|
||||
];
|
||||
model('stock_inventory')->update($data, $condition);
|
||||
$inventory_goods_list = $stat_data[ 'inventory_goods_list' ] ?? [];
|
||||
|
||||
$store_goods_model = new StoreGoods();
|
||||
$store_goods_sku_list_condition = [
|
||||
[ 'sgs.sku_id', 'in', array_column($inventory_goods_list, 'goods_sku_id') ],
|
||||
[ 'sgs.store_id', '=', $store_id ]
|
||||
];
|
||||
$store_sku_list = $store_goods_model->getStoreGoodsSkuList($store_goods_sku_list_condition, 'sgs.*, gs.sku_name, gs.unit', '', 'sgs',
|
||||
[
|
||||
[
|
||||
'goods_sku gs',
|
||||
'gs.sku_id = sgs.sku_id',
|
||||
'left'
|
||||
]
|
||||
]
|
||||
)['data'] ?? [];
|
||||
$store_sku_list_column = array_column($store_sku_list, null, 'sku_id');
|
||||
$document = new Document();
|
||||
$input_array = [];
|
||||
$output_array = [];
|
||||
foreach ($inventory_goods_list as $v) {
|
||||
$item_sku_id = $v[ 'goods_sku_id' ];
|
||||
$item_goods_id = $v[ 'goods_id' ];
|
||||
$item_condition = [
|
||||
[ 'inventory_id', '=', $inventory_id ],
|
||||
[ 'goods_sku_id', '=', $item_sku_id ]
|
||||
];
|
||||
$item_data = [
|
||||
'inventory_id' => $inventory_id,
|
||||
'goods_id' => $v[ 'goods_id' ],
|
||||
'goods_sku_id' => $v[ 'goods_sku_id' ],
|
||||
'stock' => $v[ 'stock' ],
|
||||
'inventory_num' => $v[ 'inventory_num' ],
|
||||
'inventory_remark' => $v[ 'inventory_remark' ] ?? '',
|
||||
'profitloss_num' => $v[ 'profitloss_num' ],
|
||||
'inventory_cost_money' => $v[ 'inventory_cost_money' ],
|
||||
'profitloss_sale_money' => $v[ 'profitloss_sale_money' ],
|
||||
];
|
||||
model('stock_inventory_goods')->update($item_data, $item_condition);
|
||||
|
||||
$store_sku_info = $store_sku_list_column[$item_sku_id] ?? [];
|
||||
$store_sku_stock = $store_sku_info[ 'real_stock' ] ?? 0;
|
||||
$inventory_num = $v[ 'inventory_num' ];
|
||||
$item_price = $store_sku_info[ 'cost_price' ] ?? 0;
|
||||
$item_unit = $store_sku_info[ 'unit' ] ?? '件';
|
||||
$diff = abs($inventory_num - $store_sku_stock);
|
||||
if ($diff != 0) {
|
||||
if ($inventory_num > $store_sku_stock) {
|
||||
$input_array[] = [
|
||||
'goods_id' => $item_goods_id,
|
||||
'goods_sku_id' => $item_sku_id,
|
||||
'goods_sku_name' => $store_sku_info[ 'sku_name' ],
|
||||
'goods_unit' => $item_unit,
|
||||
'goods_num' => $diff,
|
||||
'goods_price' => $item_price,
|
||||
];
|
||||
} else if ($inventory_num < $store_sku_stock) {
|
||||
$output_array[] = [
|
||||
'goods_id' => $item_goods_id,
|
||||
'goods_sku_id' => $item_sku_id,
|
||||
'goods_sku_name' => $store_sku_info[ 'sku_name' ],
|
||||
'goods_unit' => $item_unit,
|
||||
'goods_num' => $diff,
|
||||
'goods_price' => $item_price,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
$document_params = [
|
||||
'inventory_id' => $inventory_id,
|
||||
'store_id' => $store_id,
|
||||
'user_info' => $user_info,
|
||||
'site_id' => $site_id,
|
||||
'remark' => $info['remark'],
|
||||
];
|
||||
|
||||
if (!empty($input_array)) {
|
||||
$document_params[ 'document_type' ] = 'PANYING';
|
||||
$document_params[ 'goods_sku_list' ] = $input_array;
|
||||
$result = $document->addDocument($document_params);
|
||||
}
|
||||
if (!empty($output_array)) {
|
||||
$document_params[ 'document_type' ] = 'PANKUI';
|
||||
$document_params[ 'goods_sku_list' ] = $output_array;
|
||||
$document_params[ 'is_out_stock' ] = 1;
|
||||
$result = $document->addDocument($document_params);
|
||||
}
|
||||
|
||||
if (isset($result) && $result[ 'code' ] < 0) {
|
||||
return $result;
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据统计以及整理
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
public function stat($params)
|
||||
{
|
||||
$inventory_id = $params[ 'inventory_id' ];
|
||||
$condition = [
|
||||
[ 'inventory_id', '=', $inventory_id ]
|
||||
];
|
||||
$info = model('stock_inventory')->getInfo($condition);
|
||||
$store_id = $info[ 'store_id' ];
|
||||
$kinds_num = $kinds_profit_num = $kinds_loss_num = $kinds_even_num = $num = $profit_num = $loss_num = $even_num = $profitloss_num = $inventory_cost_money = $profitloss_sale_money = 0;
|
||||
|
||||
$stock_inventory_goods_list = model('stock_inventory_goods')->getList($condition, '*');
|
||||
|
||||
$temp_goods_sku_list = model('goods_sku')->getList(
|
||||
[
|
||||
['gs.sku_id', 'in', array_column($stock_inventory_goods_list, 'goods_sku_id')]
|
||||
],
|
||||
'gs.sku_id, gs.sku_name, gs.sku_no, gs.unit, sgs.price, sgs.cost_price, sgs.real_stock',
|
||||
'',
|
||||
'gs',
|
||||
[
|
||||
[
|
||||
'store_goods_sku sgs',
|
||||
'gs.sku_id = sgs.sku_id and sgs.store_id = '.$store_id,
|
||||
'left'
|
||||
]
|
||||
]
|
||||
);
|
||||
$goods_list_column = array_column($temp_goods_sku_list, null, 'sku_id');
|
||||
$store_goods_model = new StoreGoods();
|
||||
$inventory_goods_list = [];
|
||||
foreach ($stock_inventory_goods_list as $k => $v) {
|
||||
$kinds_num++;
|
||||
$sku_id = $v[ 'goods_sku_id' ];
|
||||
$goods_id = $v[ 'goods_id' ];
|
||||
$store_sku_condition = [
|
||||
[ 'store_id', '=', $store_id ],
|
||||
[ 'sku_id', '=', $sku_id ]
|
||||
];
|
||||
|
||||
$v[ 'stock' ] = numberFormat($v[ 'stock' ]);
|
||||
$v[ 'inventory_num' ] = numberFormat($v[ 'inventory_num' ]);
|
||||
$v[ 'profitloss_num' ] = numberFormat($v[ 'profitloss_num' ]);
|
||||
$item_info = $goods_list_column[$sku_id] ?? [];
|
||||
$item_price = $item_info[ 'price' ] ?? 0;//销售价
|
||||
$item_cost_price = $item_info[ 'cost_price' ] ?? 0;// 成本价
|
||||
$item_stock = $item_info[ 'real_stock' ] ?? 0;//实物库存
|
||||
$item_total_sale_money = $item_price * $item_stock;//总销售价
|
||||
|
||||
$inventory_num = $v[ 'inventory_num' ];//盘点数量
|
||||
$item_inventory_cost_money = $inventory_num * $item_cost_price;
|
||||
$inventory_cost_money += $item_inventory_cost_money;//盘点总成本价
|
||||
$ing_total_sale_money = $inventory_num * $item_price;//盘点总销售价
|
||||
$num += $inventory_num;//盘点总数
|
||||
$item_profitloss_num = $inventory_num - $item_stock;
|
||||
$item_profitloss_sale_money = 0;
|
||||
if ($item_profitloss_num == 0) {//持平
|
||||
$kinds_even_num++;
|
||||
$even_num += abs($item_profitloss_num);
|
||||
} else if ($item_profitloss_num > 0) {//盘盈数
|
||||
$kinds_profit_num++;
|
||||
$profit_num += abs($item_profitloss_num);
|
||||
$item_profitloss_sale_money = $ing_total_sale_money - $item_total_sale_money;
|
||||
} else {//盘亏数
|
||||
$kinds_loss_num++;
|
||||
$loss_num += abs($item_profitloss_num);
|
||||
}
|
||||
$profitloss_num += $item_profitloss_num;
|
||||
$profitloss_sale_money += $item_profitloss_sale_money;
|
||||
|
||||
$inventory_goods_list[ $sku_id ] = [
|
||||
'goods_id' => $goods_id,
|
||||
'goods_sku_id' => $sku_id,
|
||||
'goods_sku_name' => $item_info[ 'sku_name' ],
|
||||
'goods_sku_no' => $item_info[ 'sku_no' ],
|
||||
'goods_unit' => $item_info[ 'unit' ],
|
||||
'stock' => numberFormat($item_stock),
|
||||
'inventory_num' => numberFormat($inventory_num),
|
||||
'profitloss_num' => numberFormat($item_profitloss_num),
|
||||
'inventory_cost_money' => $item_inventory_cost_money,
|
||||
'profitloss_sale_money' => $item_profitloss_sale_money,
|
||||
];
|
||||
}
|
||||
$data = [
|
||||
'kinds_num' => $kinds_num,
|
||||
'kinds_profit_num' => $kinds_profit_num,
|
||||
'kinds_loss_num' => $kinds_loss_num,
|
||||
'kinds_even_num' => $kinds_even_num,
|
||||
'num' => $num,
|
||||
'profit_num' => $profit_num,
|
||||
'loss_num' => $loss_num,
|
||||
'even_num' => $even_num,
|
||||
'profitloss_num' => $profitloss_num,
|
||||
'inventory_cost_money' => $inventory_cost_money,
|
||||
'profitloss_sale_money' => $profitloss_sale_money,
|
||||
'inventory_goods_list' => $inventory_goods_list
|
||||
];
|
||||
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 库存盘点单列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getInventoryPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
|
||||
{
|
||||
$res = model('stock_inventory')->pageList($condition, $field, $order, $page, $page_size);
|
||||
foreach ($res[ 'list' ] as $k => $v) {
|
||||
if (isset($v[ 'num' ])) {
|
||||
$res[ 'list' ][ $k ][ 'num' ] = numberFormat($res[ 'list' ][ $k ][ 'num' ]);
|
||||
}
|
||||
if (isset($v[ 'profit_num' ])) {
|
||||
$res[ 'list' ][ $k ][ 'profit_num' ] = numberFormat($res[ 'list' ][ $k ][ 'profit_num' ]);
|
||||
}
|
||||
if (isset($v[ 'loss_num' ])) {
|
||||
$res[ 'list' ][ $k ][ 'loss_num' ] = numberFormat($res[ 'list' ][ $k ][ 'loss_num' ]);
|
||||
}
|
||||
if (isset($v[ 'even_num' ])) {
|
||||
$res[ 'list' ][ $k ][ 'even_num' ] = numberFormat($res[ 'list' ][ $k ][ 'even_num' ]);
|
||||
}
|
||||
if (isset($v[ 'profitloss_num' ])) {
|
||||
$res[ 'list' ][ $k ][ 'profitloss_num' ] = numberFormat($res[ 'list' ][ $k ][ 'profitloss_num' ]);
|
||||
}
|
||||
if (isset($v[ 'status' ])) {
|
||||
$res[ 'list' ][ $k ][ 'status_name' ] = $this->status[ $v[ 'status' ] ][ 'name' ];
|
||||
}
|
||||
}
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单据详情
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getInventoryInfo($condition = [], $field = '*')
|
||||
{
|
||||
$inventory_info = model('stock_inventory')->getInfo($condition, $field);
|
||||
if (!empty($inventory_info)) {
|
||||
|
||||
if (isset($inventory_info[ 'status' ])) {
|
||||
$inventory_info[ 'status_name' ] = $this->status[ $inventory_info[ 'status' ] ][ 'name' ];
|
||||
}
|
||||
|
||||
if (isset($inventory_info[ 'num' ])) {
|
||||
$inventory_info[ 'num' ] = numberFormat($inventory_info[ 'num' ]);
|
||||
}
|
||||
if (isset($inventory_info[ 'profit_num' ])) {
|
||||
$inventory_info[ 'profit_num' ] = numberFormat($inventory_info[ 'profit_num' ]);
|
||||
}
|
||||
if (isset($inventory_info[ 'loss_num' ])) {
|
||||
$inventory_info[ 'loss_num' ] = numberFormat($inventory_info[ 'loss_num' ]);
|
||||
}
|
||||
if (isset($inventory_info[ 'even_num' ])) {
|
||||
$inventory_info[ 'even_num' ] = numberFormat($inventory_info[ 'even_num' ]);
|
||||
}
|
||||
if (isset($inventory_info[ 'profitloss_num' ])) {
|
||||
$inventory_info[ 'profitloss_num' ] = numberFormat($inventory_info[ 'profitloss_num' ]);
|
||||
}
|
||||
|
||||
//单据产品项
|
||||
$inventory_goods_list = model('stock_inventory_goods')->getList([
|
||||
[ 'inventory_id', '=', $inventory_info[ 'inventory_id' ] ]
|
||||
]);
|
||||
foreach ($inventory_goods_list as $k => $v) {
|
||||
$inventory_goods_list[ $k ][ 'stock' ] = numberFormat($v[ 'stock' ]);
|
||||
$inventory_goods_list[ $k ][ 'inventory_num' ] = numberFormat($inventory_goods_list[ $k ][ 'inventory_num' ]);
|
||||
$inventory_goods_list[ $k ][ 'profitloss_num' ] = numberFormat($inventory_goods_list[ $k ][ 'profitloss_num' ]);
|
||||
}
|
||||
$inventory_info[ 'goods_sku_list_array' ] = $inventory_goods_list;
|
||||
$inventory_info[ 'goods_count' ] = count($inventory_info[ 'goods_sku_list_array' ]);
|
||||
$inventory_info[ 'create_time' ] = date('Y-m-d H:i:s', $inventory_info[ 'create_time' ]);
|
||||
if ($inventory_info[ 'audit_time' ]) $inventory_info[ 'audit_time' ] = date('Y-m-d H:i:s', $inventory_info[ 'audit_time' ]);
|
||||
if ($inventory_info[ 'action_time' ]) $inventory_info[ 'action_time' ] = date('Y-m-d H:i:s', $inventory_info[ 'action_time' ]);
|
||||
}
|
||||
return $this->success($inventory_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取编辑单据数据
|
||||
* @param array $condition
|
||||
* @return array
|
||||
*/
|
||||
public function getInventoryEditData($condition = [])
|
||||
{
|
||||
$field = 'inventory_id, store_id,inventory_no,action_time,remark';
|
||||
$inventory_info = model('stock_inventory')->getInfo($condition, $field);
|
||||
if (!empty($inventory_info)) {
|
||||
$goods_field = 'gs.sku_id,gs.sku_image,gs.sku_name,gs.unit,gs.sku_no,
|
||||
sgs.stock,sgs.real_stock,sgs.price,sgs.cost_price,
|
||||
ig.inventory_num as goods_num,ig.goods_sku_id';
|
||||
|
||||
$join = [
|
||||
[ 'goods_sku gs', 'ig.goods_sku_id = gs.sku_id', 'left' ],
|
||||
[
|
||||
'store_goods_sku sgs',
|
||||
'sgs.sku_id = gs.sku_id and (sgs.store_id is null or sgs.store_id = ' . $inventory_info[ 'store_id' ] . ')',
|
||||
'left'
|
||||
]
|
||||
];
|
||||
|
||||
$inventory_goods_list = model('stock_inventory_goods')->getList([
|
||||
[ 'inventory_id', '=', $inventory_info[ 'inventory_id' ] ]
|
||||
], $goods_field, '', 'ig', $join);
|
||||
foreach ($inventory_goods_list as $k => $v) {
|
||||
$inventory_goods_list[ $k ][ 'stock' ] = numberFormat($v[ 'stock' ]);
|
||||
$inventory_goods_list[ $k ][ 'goods_num' ] = numberFormat($inventory_goods_list[ $k ][ 'goods_num' ]);
|
||||
}
|
||||
$inventory_info[ 'goods_list' ] = array_column($inventory_goods_list, null, 'goods_sku_id');
|
||||
}
|
||||
return $this->success($inventory_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拒绝审核
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
public function refuse($params)
|
||||
{
|
||||
$inventory_id = $params[ 'inventory_id' ];
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$user_info = $params[ 'user_info' ];
|
||||
$condition = [
|
||||
[ 'inventory_id', '=', $inventory_id ],
|
||||
[ 'site_id', '=', $site_id ]
|
||||
];
|
||||
$info = model('stock_inventory')->getInfo($condition);
|
||||
if (empty($info))
|
||||
return $this->error([], '找不到可审核的单据');
|
||||
|
||||
if ($info[ 'status' ] == self::AUDITED)
|
||||
return $this->error([], '当前单据已审核');
|
||||
$data = [
|
||||
'status' => self::REFUSE,
|
||||
'audit_time' => time(),
|
||||
'refuse_reason' => $params[ 'refuse_reason' ],
|
||||
'verifier' => $user_info[ 'uid' ] ?? 0,//审核人
|
||||
'verifier_name' => $user_info[ 'username' ] ?? '系统'
|
||||
];
|
||||
model('stock_inventory')->update($data, $condition);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
public function delete($params)
|
||||
{
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$inventory_id = $params[ 'inventory_id' ];
|
||||
$user_info = $params[ 'user_info' ];
|
||||
$store_id = $params[ 'store_id' ] ?? 0;
|
||||
//查询单据
|
||||
$condition = [
|
||||
[ 'inventory_id', '=', $inventory_id ],
|
||||
[ 'site_id', '=', $site_id ]
|
||||
];
|
||||
if ($store_id > 0) {
|
||||
$condition[] = [ 'store_id', '=', $store_id ];
|
||||
}
|
||||
$info = model('stock_inventory')->getInfo($condition);
|
||||
if (empty($info)) {
|
||||
return $this->error([], '找不到盘点单据');
|
||||
}
|
||||
//被拒绝也可以删除
|
||||
if ($info[ 'status' ] == self::AUDITED) {
|
||||
return $this->error('已审核的单据不能删除');
|
||||
}
|
||||
if ($info[ 'operater' ] != $user_info[ 'uid' ]) {
|
||||
return $this->error('只有单据创建者可以删除单据');
|
||||
}
|
||||
model('stock_inventory')->delete($condition);
|
||||
model('stock_inventory_goods')->delete($condition);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑盘点单
|
||||
* @param $params
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function editInventory($params)
|
||||
{
|
||||
$inventory_id = $params[ 'inventory_id' ];
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$store_id = $params[ 'store_id' ];
|
||||
$user_info = $params[ 'user_info' ];
|
||||
//同商品同时只能存在一个盘点单据
|
||||
$info = model('stock_inventory')->getInfo([
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'inventory_id', '=', $inventory_id ],
|
||||
]);
|
||||
|
||||
if (empty($info)) {
|
||||
return $this->error([], '找不到盘点单据');
|
||||
}
|
||||
|
||||
if ($info[ 'status' ] == self::AUDITED) {
|
||||
return $this->error('已审核的单据不能编辑');
|
||||
}
|
||||
if ($info[ 'operater' ] != $user_info[ 'uid' ]) {
|
||||
return $this->error('只有单据创建者可以编辑单据');
|
||||
}
|
||||
|
||||
$inventory_no = isset($params['inventory_no']) && $params['inventory_no'] ? $params['inventory_no'] : $this->inventoryNo();
|
||||
|
||||
$count = model('stock_inventory')->getCount([ ['inventory_no', '=', $inventory_no], ['inventory_id', '<>', $inventory_id] ]);
|
||||
if($count > 0) return $this->error([], '录入失败,单号重复');
|
||||
|
||||
model('stock_inventory')->startTrans();
|
||||
try {
|
||||
$sku_list = $params[ 'sku_list' ];
|
||||
|
||||
//查询门店名称信息
|
||||
$store_model = new Store();
|
||||
$store_condition = [
|
||||
[ 'store_id', '=', $store_id ]
|
||||
];
|
||||
$store_info = $store_model->getStoreInfo($store_condition, 'store_name')[ 'data' ] ?? [];
|
||||
if (empty($store_info)) {
|
||||
model('stock_inventory')->rollback();
|
||||
return $this->success([], '找不到所选的门店');
|
||||
}
|
||||
$store_name = $store_info[ 'store_name' ];
|
||||
|
||||
$common_data = [
|
||||
'site_id' => $info[ 'site_id' ],
|
||||
'create_time' => $info[ 'create_time' ],
|
||||
'store_id' => $store_id
|
||||
];
|
||||
$data = [
|
||||
'remark' => $params[ 'remark' ] ?? '',
|
||||
'status' => self::AUDIT,
|
||||
'action_time' => $params[ 'action_time' ] ?? time(),
|
||||
'inventory_no' => $inventory_no,
|
||||
'store_name' => $store_name
|
||||
];
|
||||
//盘点单据
|
||||
$inventory_data = array_merge($data, $common_data);
|
||||
|
||||
$inventory_goods_condition = [
|
||||
[ 'site_id', '=', $site_id ],
|
||||
[ 'inventory_id', '=', $inventory_id ]
|
||||
];
|
||||
//编辑盘点单据
|
||||
model('stock_inventory')->update($inventory_data, $inventory_goods_condition);
|
||||
|
||||
$common_data[ 'inventory_id' ] = $inventory_id;
|
||||
|
||||
//删除原来的盘点商品单据
|
||||
model('stock_inventory_goods')->delete($inventory_goods_condition);
|
||||
foreach ($sku_list as $k => $goods_sku) {
|
||||
$goods_sku_id = $goods_sku[ 'goods_sku_id' ];
|
||||
$goods_num = numberFormat($goods_sku[ 'goods_num' ]);
|
||||
$goods_remark = '';
|
||||
//具体业务尚未调试,表结构不一致
|
||||
$goods_sku_info = model('goods_sku')->getInfo([ [ 'sku_id', '=', $goods_sku_id ] ], 'sku_id,goods_id,sku_name,sku_no,sku_image,spec_name');
|
||||
$goods_sku_data_info = model('store_goods_sku')->getInfo([ [ 'sku_id', '=', $goods_sku_id ], [ 'store_id', '=', $store_id ] ], '*');
|
||||
$goods_stock = $goods_sku_data_info[ 'real_stock' ] ?? 0;
|
||||
$goods_sku_data = [];
|
||||
$goods_sku_data[ 'inventory_num' ] = $goods_num;
|
||||
$goods_sku_data[ 'inventory_remark' ] = $goods_remark;
|
||||
$goods_sku_data[ 'goods_id' ] = $goods_sku_info[ 'goods_id' ];
|
||||
$goods_sku_data[ 'goods_sku_id' ] = $goods_sku_id;
|
||||
$goods_sku_data[ 'goods_sku_name' ] = $goods_sku_info[ 'sku_name' ];
|
||||
$goods_sku_data[ 'goods_sku_no' ] = $goods_sku_info[ 'sku_no' ];
|
||||
$goods_sku_data[ 'goods_sku_spec' ] = $goods_sku_info[ 'spec_name' ];
|
||||
$goods_sku_data[ 'goods_img' ] = $goods_sku_info[ 'sku_image' ];
|
||||
$goods_sku_data[ 'stock' ] = numberFormat($goods_stock);
|
||||
model('stock_inventory_goods')->add(array_merge($goods_sku_data, $common_data));
|
||||
}
|
||||
|
||||
$stock_model = new Stock();
|
||||
$stock_config = $stock_model->getStockConfig($site_id)[ 'data' ][ 'value' ];
|
||||
$is_audit = $stock_config[ 'is_audit' ];
|
||||
if (!$is_audit) {
|
||||
//主动调用审核
|
||||
$inventory_params = [
|
||||
'inventory_id' => $inventory_id,
|
||||
'site_id' => $site_id,
|
||||
'user_info' => $user_info
|
||||
];
|
||||
$audit_result = $this->audit($inventory_params);
|
||||
if ($audit_result[ 'code' ] < 0) {
|
||||
model('stock_inventory')->rollback();
|
||||
return $audit_result;
|
||||
}
|
||||
}
|
||||
model('stock_inventory')->commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
model('stock_inventory')->rollback();
|
||||
return $this->error($e->getMessage() . $e->getFile() . $e->getLine());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询商品盘点单据
|
||||
* @param $condition
|
||||
* @param string $field
|
||||
* @return array
|
||||
*/
|
||||
public function getInventoryGoodsInfo($condition, $field = '*')
|
||||
{
|
||||
//关联单据主表
|
||||
$join = [
|
||||
[ 'stock_inventory si', 'si.inventory_id = sig.inventory_id', 'inner' ],
|
||||
];
|
||||
$info = model('stock_inventory_goods')->getInfo($condition, $field, 'sig', $join);
|
||||
|
||||
return $this->success($info);
|
||||
|
||||
}
|
||||
}
|
||||
402
addon/stock/model/stock/Stock.php
Executable file
402
addon/stock/model/stock/Stock.php
Executable file
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 上海牛之云网络科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\stock\model\stock;
|
||||
|
||||
|
||||
use addon\stock\dict\StockDict;
|
||||
use app\model\BaseModel;
|
||||
use app\model\store\Store;
|
||||
use app\model\system\Config as ConfigModel;
|
||||
|
||||
/**
|
||||
* 库存model
|
||||
*
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
class Stock extends BaseModel
|
||||
{
|
||||
public $document_type_list = [
|
||||
'PURCHASE' => [
|
||||
'name' => '采购入库单',
|
||||
'type' => StockDict::input,
|
||||
'prefix' => 'CGRK',
|
||||
'key' => 'PURCHASE',
|
||||
],
|
||||
'REFUND' => [
|
||||
'name' => '退货入库单',
|
||||
'type' => StockDict::input,
|
||||
'prefix' => 'THRK',
|
||||
'key' => 'REFUND',
|
||||
],
|
||||
'OTHERRK' => [
|
||||
'name' => '其他入库单',
|
||||
'type' => StockDict::input,
|
||||
'prefix' => 'QTRK',
|
||||
'key' => 'OTHERRK',
|
||||
],
|
||||
'TRANSFORMRK' => [
|
||||
'name' => '其他入库单',
|
||||
'type' => StockDict::input,
|
||||
'prefix' => 'ZHRK',
|
||||
'key' => 'TRANSFORMRK',
|
||||
],
|
||||
'SEAILCK' => [
|
||||
'name' => '销售出库单',
|
||||
'type' => StockDict::output,
|
||||
'prefix' => 'XSCK',
|
||||
'key' => 'SEAILCK',
|
||||
],
|
||||
'OTHERCK' => [
|
||||
'name' => '其他出库单',
|
||||
'type' => StockDict::output,
|
||||
'prefix' => 'QTCK',
|
||||
'key' => 'OTHERCK',
|
||||
],
|
||||
'TRANSFORMCK' => [
|
||||
'name' => '转换出库单',
|
||||
'type' => StockDict::output,
|
||||
'prefix' => 'ZHCK',
|
||||
'key' => 'TRANSFORMCK',
|
||||
],
|
||||
'PDD' => [
|
||||
'name' => '盘点单',
|
||||
'type' => 'pandian',
|
||||
'prefix' => 'PDD',
|
||||
'key' => 'PDD',
|
||||
],
|
||||
'PANYING' => [
|
||||
'name' => '盘盈入库单',
|
||||
'type' => StockDict::input,
|
||||
'prefix' => 'PYRK',
|
||||
'key' => 'PANYING',
|
||||
],
|
||||
'PANKUI' => [
|
||||
'name' => '盘亏出库单',
|
||||
'type' => StockDict::output,
|
||||
'prefix' => 'PKCK',
|
||||
'key' => 'PANKUI',
|
||||
],
|
||||
'ALLOTIN' => [
|
||||
'name' => '调拨入库单',
|
||||
'type' => StockDict::input,
|
||||
'prefix' => 'DBRK',
|
||||
'key' => 'ALLOTIN',
|
||||
],
|
||||
'ALLOTPUT' => [
|
||||
'name' => '调拨出库单',
|
||||
'type' => StockDict::output,
|
||||
'prefix' => 'DBCK',
|
||||
'key' => 'ALLOTPUT',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* 设置库存
|
||||
* @param $params
|
||||
*/
|
||||
public function changeStock($params)
|
||||
{
|
||||
$user_info = $params[ 'user_info' ] ?? [];
|
||||
$site_id = $params[ 'site_id' ] ?? 1;
|
||||
|
||||
$store_id = $params[ 'store_id' ] ?? 0;
|
||||
if ($store_id == 0) {
|
||||
$store_model = new Store();
|
||||
$store_info = $store_model->getDefaultStore()[ 'data' ] ?? [];
|
||||
$store_id = $store_info[ 'store_id' ];
|
||||
}
|
||||
$key = $params[ 'key' ];
|
||||
$remark = $params[ 'remark' ] ?? '';
|
||||
$is_out_stock = $params[ 'is_out_stock' ] ?? 0;
|
||||
$time = $params[ 'time' ] ?? time();
|
||||
$document_model = new Document();
|
||||
if (!empty($params[ 'goods_sku_list' ])) {
|
||||
foreach ($params[ 'goods_sku_list' ] as $k => $v) {
|
||||
$params[ 'goods_sku_list' ][ $k ] = [
|
||||
'goods_sku_id' => $v[ 'sku_id' ],
|
||||
'goods_id' => $v[ 'goods_id' ] ?? 0,
|
||||
'goods_num' => $v[ 'num' ] ?? $v[ 'stock' ],
|
||||
'goods_price' => $v[ 'price' ] ?? 0
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$sku_id = $params[ 'sku_id' ] ?? 0;
|
||||
$goods_id = $params[ 'goods_id' ] ?? 0;
|
||||
$goods_num = $params[ 'num' ] ?? $params[ 'stock' ];
|
||||
$goods_price = $params[ 'price' ] ?? 0;
|
||||
}
|
||||
$goods_sku_list = $params[ 'goods_sku_list' ] ?? [
|
||||
[
|
||||
'goods_sku_id' => $sku_id,
|
||||
'goods_id' => $goods_id,
|
||||
'goods_num' => $goods_num,
|
||||
'goods_price' => $goods_price
|
||||
]
|
||||
];
|
||||
|
||||
$document_params = [
|
||||
'store_id' => $store_id,
|
||||
'site_id' => $site_id,
|
||||
'remark' => $remark,
|
||||
'goods_sku_list' => $goods_sku_list,
|
||||
'user_info' => $user_info,
|
||||
'time' => $time,
|
||||
'is_out_stock' => $is_out_stock
|
||||
];
|
||||
switch ( $key ) {
|
||||
case 'PURCHASE'://采购入库单
|
||||
$result = $document_model->addPurchase($document_params);
|
||||
break;
|
||||
case 'REFUND'://退货入库单
|
||||
$result = $document_model->addRefundInput($document_params);
|
||||
break;
|
||||
case 'OTHERRK'://其他入库单
|
||||
$result = $document_model->addOtherInput($document_params);
|
||||
break;
|
||||
case 'TRANSFORMRK'://转换入库单
|
||||
$result = $document_model->addTransformInput($document_params);
|
||||
break;
|
||||
case 'SEAILCK'://销售出库单
|
||||
$result = $document_model->addSell($document_params);
|
||||
break;
|
||||
case 'OTHERCK'://其他出库单
|
||||
$result = $document_model->addOtherOutput($document_params);
|
||||
break;
|
||||
case 'TRANSFORMCK'://转换出库单
|
||||
$result = $document_model->addTransformput($document_params);
|
||||
break;
|
||||
case 'PANYING'://盘盈入库单
|
||||
$result = $document_model->addDocument($document_params);
|
||||
break;
|
||||
case 'PANKUI'://盘亏出库单
|
||||
$result = $document_model->addDocument($document_params);
|
||||
break;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置商品库存(比对差值,得出)
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
public function setGoodsStock($params)
|
||||
{
|
||||
|
||||
$site_id = $params[ 'site_id' ];
|
||||
$remark = $params[ 'remark' ] ?? '';
|
||||
$store_id = $params[ 'store_id' ];
|
||||
|
||||
$goods_sku_list = $params[ 'goods_sku_list' ] ?? [];
|
||||
|
||||
//todo 这儿可以查询商品信息类型 来定义可能只有实物商品才需要出入库记录
|
||||
if (!empty($goods_sku_list)) {
|
||||
foreach ($goods_sku_list as $k => $v) {
|
||||
$sku_list[] = [
|
||||
'goods_sku_id' => $v[ 'sku_id' ],
|
||||
'goods_num' => $v[ 'stock' ],
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$goods_id = $params[ 'goods_id' ] ?? 0;//只要传递就必然是与sku_id匹配的
|
||||
$sku_id = $params[ 'sku_id' ];
|
||||
$stock = $params[ 'stock' ];//设置的新库存
|
||||
$sku_list = [
|
||||
[
|
||||
'goods_sku_id' => $sku_id,
|
||||
'goods_num' => $stock,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
//同步整理, 将要设置的销售库存转化为实际库存
|
||||
$sku_ids = array_column($sku_list, 'goods_sku_id');
|
||||
// $sku_key_list = array_column($sku_list, null, 'goods_sku_id');
|
||||
$sku_info_list = model('store_goods_sku')->getList([ [ 'sku_id', 'in', $sku_ids ], [ 'store_id', '=', $store_id ] ]);
|
||||
foreach ($sku_info_list as $k => $v) {
|
||||
$sku_info_list[ $k ][ 'stock' ] = numberFormat($v[ 'stock' ]);
|
||||
$sku_info_list[ $k ][ 'sale_num' ] = numberFormat($sku_info_list[ $k ][ 'sale_num' ]);
|
||||
$sku_info_list[ $k ][ 'real_stock' ] = numberFormat($sku_info_list[ $k ][ 'real_stock' ]);
|
||||
}
|
||||
$sku_info_column_list = array_column($sku_info_list, null, 'sku_id');
|
||||
$stock_sku_list = [];
|
||||
|
||||
foreach ($sku_list as $k => $item) {
|
||||
$item_sku_id = $item[ 'goods_sku_id' ];
|
||||
$temp_item = $sku_info_column_list[ $item_sku_id ] ?? [];
|
||||
$item_stock = $temp_item[ 'stock' ] ?? 0;
|
||||
$item_real_stock = $temp_item[ 'real_stock' ] ?? 0;
|
||||
if($item_stock > $item_real_stock){
|
||||
$item_stock = $item_real_stock;
|
||||
}
|
||||
if ($item_stock != $item_real_stock) {
|
||||
$item[ 'goods_num' ] = $item[ 'goods_num' ] + ( $item_real_stock - $item_stock );
|
||||
}
|
||||
$stock_sku_list[] = $item;
|
||||
}
|
||||
|
||||
$inventory_params = [
|
||||
'site_id' => $site_id,
|
||||
'store_id' => $store_id,
|
||||
'sku_list' => $stock_sku_list,
|
||||
'user_info' => $params[ 'user_info' ] ?? [],
|
||||
'remark' => $remark,
|
||||
'is_limit' => false
|
||||
];
|
||||
$inventory_model = new Inventory();
|
||||
return $inventory_model->addInventory($inventory_params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品sku列表
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param int $store_id
|
||||
* @return array
|
||||
*/
|
||||
public function getStoreGoodsSkuList($condition = [], $field = '*', $order = 'gs.create_time desc', $store_id = 0)
|
||||
{
|
||||
$alias = 'gs';
|
||||
$join = [
|
||||
[ 'goods g', 'g.goods_id = gs.goods_id', 'left' ],
|
||||
[
|
||||
'store_goods_sku sgs',
|
||||
'sgs.sku_id = gs.sku_id and (sgs.store_id is null or sgs.store_id = ' . $store_id . ')',
|
||||
'left'
|
||||
]
|
||||
];
|
||||
$list = model('goods_sku')->getList($condition, $field, $order, $alias, $join, '', 15);
|
||||
foreach ($list as $k => $v) {
|
||||
if (isset($v[ 'goods_stock' ])) {
|
||||
$list[ $k ][ 'goods_stock' ] = numberFormat($v[ 'goods_stock' ]);
|
||||
}
|
||||
if (isset($v[ 'stock' ])) {
|
||||
$list[ $k ][ 'stock' ] = numberFormat($list[ $k ][ 'stock' ]);
|
||||
}
|
||||
if (isset($v[ 'sale_num' ])) {
|
||||
$list[ $k ][ 'sale_num' ] = numberFormat($list[ $k ][ 'sale_num' ]);
|
||||
}
|
||||
if (isset($v[ 'virtual_sale' ])) {
|
||||
$list[ $k ][ 'virtual_sale' ] = numberFormat($list[ $k ][ 'virtual_sale' ]);
|
||||
}
|
||||
|
||||
if (isset($v[ 'real_stock' ])) {
|
||||
$list[ $k ][ 'real_stock' ] = numberFormat($list[ $k ][ 'real_stock' ]);
|
||||
}
|
||||
}
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置库存配置
|
||||
* @param $data
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function setStockConfig($data, $site_id)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
return $config->setConfig($data, '库存配置', 1, [ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'STOCK_CONFIG' ] ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取库存配置
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getStockConfig($site_id)
|
||||
{
|
||||
$config = new ConfigModel();
|
||||
$res = $config->getConfig([ [ 'site_id', '=', $site_id ], [ 'app_module', '=', 'shop' ], [ 'config_key', '=', 'STOCK_CONFIG' ] ]);
|
||||
|
||||
if (empty($res[ 'data' ][ 'value' ])) {
|
||||
$res[ 'data' ][ 'value' ] = [
|
||||
'is_audit' => 0
|
||||
];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询商品是否存在盘点单据
|
||||
* @param $goods_id
|
||||
* @param $site_id
|
||||
* @return array
|
||||
*/
|
||||
public function getGoodsIsHasStockRecords($goods_id, $site_id){
|
||||
$stock_model = new Stock();
|
||||
$stock_config = $stock_model->getStockConfig($site_id)[ 'data' ][ 'value' ];
|
||||
$is_audit = $stock_config[ 'is_audit' ];
|
||||
if ($is_audit) {
|
||||
//查询商品是否存在盘点单据
|
||||
$inventory_model = new Inventory();
|
||||
$info = $inventory_model->getInventoryGoodsInfo([
|
||||
['sig.site_id', '=', $site_id],
|
||||
['sig.goods_id', '=', $goods_id],
|
||||
['si.status', '=', Inventory::AUDIT],
|
||||
])['data'] ?? [];
|
||||
if (empty($info)) {
|
||||
return $this->success();
|
||||
} else {
|
||||
return $this->error();
|
||||
}
|
||||
}else{
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品sku列表
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param int $store_id
|
||||
* @return array
|
||||
*/
|
||||
public function getStoreGoodsSkuPage($condition = [], $field = '*', $order = 'gs.create_time desc', $store_id = 0, $page = 1, $page_size = 10)
|
||||
{
|
||||
$alias = 'gs';
|
||||
$join = [
|
||||
[ 'goods g', 'g.goods_id = gs.goods_id', 'left' ],
|
||||
[
|
||||
'store_goods_sku sgs',
|
||||
'sgs.sku_id = gs.sku_id and (sgs.store_id is null or sgs.store_id = ' . $store_id . ')',
|
||||
'left'
|
||||
]
|
||||
];
|
||||
$list = model('goods_sku')->pageList($condition, $field, $order, $page, $page_size, $alias, $join, '');
|
||||
// $list = model('goods_sku')->getList($condition, $field, $order, $alias, $join, '', 15);
|
||||
|
||||
foreach ($list['list'] as $k => $v) {
|
||||
if (isset($v[ 'goods_stock' ])) {
|
||||
$list['list'][ $k ][ 'goods_stock' ] = numberFormat($list['list'][ $k ][ 'goods_stock' ]);
|
||||
}
|
||||
if (isset($v[ 'stock' ])) {
|
||||
$list['list'][ $k ][ 'stock' ] = numberFormat($list['list'][ $k ][ 'stock' ]);
|
||||
}
|
||||
if (isset($v[ 'sale_num' ])) {
|
||||
$list['list'][ $k ][ 'sale_num' ] = numberFormat($list['list'][ $k ][ 'sale_num' ]);
|
||||
}
|
||||
if (isset($v[ 'virtual_sale' ])) {
|
||||
$list['list'][ $k ][ 'virtual_sale' ] = numberFormat($list['list'][ $k ][ 'virtual_sale' ]);
|
||||
}
|
||||
|
||||
if (isset($v[ 'real_stock' ])) {
|
||||
$list['list'][ $k ][ 'real_stock' ] = numberFormat($list['list'][ $k ][ 'real_stock' ]);
|
||||
}
|
||||
}
|
||||
// $data = [];
|
||||
// $data['list'] = $list['list'];
|
||||
return $this->success($list);
|
||||
}
|
||||
}
|
||||
391
addon/stock/model/stock/Transform.php
Executable file
391
addon/stock/model/stock/Transform.php
Executable file
@@ -0,0 +1,391 @@
|
||||
<?php
|
||||
/**
|
||||
* Niushop商城系统 - 团队十年电商经验汇集巨献!
|
||||
* =========================================================
|
||||
* Copy right 2019-2029 上海牛之云网络科技有限公司, 保留所有权利。
|
||||
* ----------------------------------------------
|
||||
* 官方网址: https://www.niushop.com
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
namespace addon\stock\model\stock;
|
||||
|
||||
use app\dict\goods\GoodsDict;
|
||||
use app\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 库存转换
|
||||
* Class Transform
|
||||
* @package addon\stock\model\stock
|
||||
*/
|
||||
class Transform extends BaseModel
|
||||
{
|
||||
/**
|
||||
* 添加库存转换
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function addTransform($data)
|
||||
{
|
||||
try{
|
||||
//数据检测
|
||||
if(count($data['goods_list']) < 2){
|
||||
return $this->error(null, '转换商品至少要有两种');
|
||||
}
|
||||
$sku_ids = array_column($data['goods_list'], 'sku_id');
|
||||
$sku_count = model('stock_transform_goods')->getCount([['sku_id', 'in', $sku_ids]]);
|
||||
if($sku_count > 0){
|
||||
return $this->error(null, '转换商品在其他转换组已存在');
|
||||
}
|
||||
$transform_id = 0;
|
||||
|
||||
//转换组和转换商品数据
|
||||
$transform_data = [
|
||||
'name' => $data['name'],
|
||||
'create_time' => time(),
|
||||
];
|
||||
$transform_goods_data = [];
|
||||
foreach($data['goods_list'] as $goods_info){
|
||||
$transform_goods_data[] = [
|
||||
'transform_id' => &$transform_id,
|
||||
'sku_id' => $goods_info['sku_id'],
|
||||
'num' => $goods_info['num'],
|
||||
];
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
return $this->error(exceptionData($e), '添加库存转换错误');
|
||||
}
|
||||
|
||||
|
||||
model('stock_transform')->startTrans();
|
||||
try{
|
||||
$transform_id = model('stock_transform')->add($transform_data);
|
||||
model('stock_transform_goods')->addList($transform_goods_data);
|
||||
|
||||
model('stock_transform')->commit();
|
||||
return $this->success();
|
||||
}catch(\Exception $e){
|
||||
model('stock_transform')->rollback();
|
||||
return $this->error(exceptionData($e), '添加库存转换错误');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改库存转换
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function editTransform($data)
|
||||
{
|
||||
try{
|
||||
//数据检测
|
||||
if(count($data['goods_list']) < 2){
|
||||
return $this->error(null, '转换商品至少要有两种');
|
||||
}
|
||||
$transform_id = $data['transform_id'];
|
||||
$sku_ids = array_column($data['goods_list'], 'sku_id');
|
||||
$sku_count = model('stock_transform_goods')->getCount([['sku_id', 'in', $sku_ids], ['transform_id', '<>', $transform_id]]);
|
||||
if($sku_count > 0){
|
||||
return $this->error(null, '转换商品在其他转换组已存在');
|
||||
}
|
||||
|
||||
//转换组和转换商品数据
|
||||
$transform_data = [
|
||||
'name' => $data['name'],
|
||||
'update_time' => time(),
|
||||
];
|
||||
$transform_goods_data = [];
|
||||
foreach($data['goods_list'] as $goods_info){
|
||||
$transform_goods_data[] = [
|
||||
'transform_id' => $transform_id,
|
||||
'sku_id' => $goods_info['sku_id'],
|
||||
'num' => $goods_info['num'],
|
||||
];
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
return $this->error(exceptionData($e), '修改库存转换错误');
|
||||
}
|
||||
|
||||
model('stock_transform')->startTrans();
|
||||
try{
|
||||
model('stock_transform')->update($transform_data, [['transform_id', '=', $transform_id]]);
|
||||
model('stock_transform_goods')->delete([['transform_id', '=', $transform_id]]);
|
||||
model('stock_transform_goods')->addList($transform_goods_data);
|
||||
|
||||
model('stock_transform')->commit();
|
||||
return $this->success();
|
||||
}catch(\Exception $e){
|
||||
model('stock_transform')->rollback();
|
||||
return $this->error(exceptionData($e), '修改库存转换错误');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除库存转换
|
||||
* @param $transform_ids
|
||||
* @return array
|
||||
*/
|
||||
public function deleteTransform($transform_ids)
|
||||
{
|
||||
model('stock_transform')->startTrans();
|
||||
try{
|
||||
model('stock_transform')->delete([['transform_id', 'in', $transform_ids]]);
|
||||
model('stock_transform_goods')->delete([['transform_id', 'in', $transform_ids]]);
|
||||
|
||||
model('stock_transform')->commit();
|
||||
return $this->success();
|
||||
}catch(\Exception $e){
|
||||
model('stock_transform')->rollback();
|
||||
return $this->error(exceptionData($e), '删除库存转换错误');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取库存转换分页列表
|
||||
* @param array $condition
|
||||
* @param int $page
|
||||
* @param int $page_size
|
||||
* @param string $order
|
||||
* @param string $field
|
||||
* @param string $alias
|
||||
* @param array $join
|
||||
* @param null $group
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getTransformPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*', $alias = 'a', $join = [], $group = null)
|
||||
{
|
||||
$res = model('stock_transform')->pageList($condition, $field, $order, $page, $page_size, $alias, $join, $group);
|
||||
return $this->success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取库存转换列表
|
||||
* @param array $condition
|
||||
* @param string $field
|
||||
* @param string $order
|
||||
* @param string $alias
|
||||
* @param array $join
|
||||
* @param null $group
|
||||
* @param null $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformList($condition = [], $field = '', $order = '', $alias = '', $join = [], $group = null, $limit = null)
|
||||
{
|
||||
$list = model('stock_transform')->getList($condition, $field, $order, $alias, $join, $group, $limit);
|
||||
return $this->success($list);
|
||||
}
|
||||
|
||||
public function getTransformInfo($condition, $field = '*')
|
||||
{
|
||||
$info = model('stock_transform')->getInfo($condition, $field);
|
||||
return $this->success($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取库存转换商品数据
|
||||
* @param $list
|
||||
* @return array
|
||||
*/
|
||||
public function getTransformGoodsData(Array $list)
|
||||
{
|
||||
$list = array_column($list, null, 'transform_id');
|
||||
$transform_ids = array_column($list, 'transform_id');
|
||||
$alias = 'stg';
|
||||
$join = [['goods_sku gs', 'gs.sku_id = stg.sku_id', 'inner']];
|
||||
$condition = [['stg.transform_id', 'in', $transform_ids]];
|
||||
$field = 'stg.*,gs.sku_name,gs.sku_image,gs.sku_no,gs.stock,gs.goods_class';
|
||||
$order = 'stg.transform_id asc,stg.num asc';
|
||||
$goods_list = model('stock_transform_goods')->getList($condition, $field, $order, $alias, $join);
|
||||
foreach($goods_list as $goods_info){
|
||||
$transform_id = $goods_info['transform_id'];
|
||||
if(!isset($list[$transform_id])){
|
||||
$list[$transform_id]['goods_list'] = [];
|
||||
}
|
||||
$goods_info['stock'] = numberFormat($goods_info['stock']);
|
||||
$goods_info['transform_stock'] = $goods_info['stock'] * $goods_info['num'];
|
||||
$list[$transform_id]['goods_list'][] = $goods_info;
|
||||
}
|
||||
|
||||
foreach($list as &$info){
|
||||
$info['transform_stock'] = array_sum(array_column($info['goods_list'], 'transform_stock'));
|
||||
foreach($info['goods_list'] as &$goods_info){
|
||||
$transform_stock = $info['transform_stock'] / $goods_info['num'];
|
||||
if($goods_info['goods_class'] == GoodsDict::weigh){
|
||||
$transform_stock = numberFormat($transform_stock);
|
||||
}else{
|
||||
$transform_stock = floor($transform_stock);
|
||||
}
|
||||
$goods_info['transform_stock'] = $transform_stock;
|
||||
}
|
||||
}
|
||||
return array_values($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品转换后库存数据
|
||||
* @param $param
|
||||
* @return array
|
||||
*/
|
||||
public function getGoodsStockTransformData($param)
|
||||
{
|
||||
$sku_ids = $param['sku_ids'];
|
||||
$store_id = $param['store_id'];
|
||||
$store_business = $param['store_business'];
|
||||
|
||||
//获取库存转换设置和商品类型数据
|
||||
$alias = 'stg';
|
||||
$join = [
|
||||
['goods_sku gs', 'gs.sku_id = stg.sku_id', 'inner'],
|
||||
];
|
||||
$condition = [
|
||||
['stg.sku_id', 'in', $sku_ids],
|
||||
];
|
||||
$field = 'stg.*,gs.goods_class';
|
||||
$goods_list = model('stock_transform_goods')->getList($condition, $field, '', $alias, $join);
|
||||
$transform_ids = array_unique(array_column($goods_list, 'transform_id'));
|
||||
|
||||
$transform_stock_data = [];
|
||||
if(!empty($transform_ids)){
|
||||
//所有涉及的库存转换商品
|
||||
$alias = 'stg';
|
||||
$join = [
|
||||
['goods_sku gs', 'gs.sku_id = stg.sku_id', 'inner'],
|
||||
['goods g', 'g.goods_id = gs.goods_id', 'inner'],
|
||||
];
|
||||
$condition = [
|
||||
['stg.transform_id', 'in', $transform_ids],
|
||||
];
|
||||
$field = 'stg.transform_id,stg.sku_id,stg.num,gs.stock,gs.unit,gs.sku_name,gs.cost_price';
|
||||
$order = 'stg.transform_id asc,stg.num asc';
|
||||
if($store_business == 'store'){
|
||||
$join[] = [ 'store_goods_sku sgs', 'gs.sku_id = sgs.sku_id and sgs.store_id=' . $store_id, 'left' ];
|
||||
//TODO 这里不需要加可售门店的条件,但是还需要进一步的思考
|
||||
//$condition[] = [ 'g.sale_store', 'like', [ '%all%', '%,' . $store_id . ',%' ], 'or' ];
|
||||
$store_info = model('store')->getInfo([['store_id', '=', $store_id]], 'stock_type');
|
||||
if ($store_info[ 'stock_type' ] == 'store') {
|
||||
$field = str_replace('gs.stock', 'IFNULL(sgs.stock, 0) as stock', $field);
|
||||
$field = str_replace('gs.cost_price', 'IFNULL(sgs.cost_price, gs.cost_price) as cost_price', $field);
|
||||
}
|
||||
}
|
||||
$all_goods_list = model('stock_transform_goods')->getList($condition, $field, $order, $alias, $join);
|
||||
//库存按照转换设置汇总
|
||||
$transform_list = [];
|
||||
foreach($all_goods_list as $goods_info){
|
||||
if(!isset($transform_list[$goods_info['transform_id']])){
|
||||
$transform_list[$goods_info['transform_id']] = [
|
||||
'total_transform_stock' => 0,
|
||||
'goods_list' => [],
|
||||
];
|
||||
}
|
||||
$transform_list[$goods_info['transform_id']]['total_transform_stock'] += $goods_info['num']*$goods_info['stock'];
|
||||
$transform_list[$goods_info['transform_id']]['goods_list'][] = $goods_info;
|
||||
}
|
||||
//组装数据
|
||||
foreach($goods_list as $goods_info){
|
||||
$total_transform_stock = $transform_list[$goods_info['transform_id']]['total_transform_stock'] ?? null;
|
||||
if(!is_null($total_transform_stock)){
|
||||
$transform_stock = $total_transform_stock / $goods_info['num'];
|
||||
if($goods_info['goods_class'] == GoodsDict::weigh){
|
||||
$transform_stock = numberFormat($transform_stock);
|
||||
}else{
|
||||
$transform_stock = floor($transform_stock);
|
||||
}
|
||||
$goods_info['transform_stock'] = $transform_stock;
|
||||
$goods_info['transform_info'] = $transform_list[$goods_info['transform_id']];
|
||||
$transform_stock_data[$goods_info['sku_id']] = $goods_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $transform_stock_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动库存转换
|
||||
* @param $param
|
||||
* @return array|int
|
||||
*/
|
||||
public function autoGoodsStockTransform($param)
|
||||
{
|
||||
$transform_data = $param['transform_data'];
|
||||
$buy_num = $param['buy_num'];
|
||||
$site_id = $param['site_id'];
|
||||
$store_id = $param['store_id'];
|
||||
$sku_id = $transform_data['sku_id'];
|
||||
|
||||
$goods_list = $transform_data['transform_info']['goods_list'];
|
||||
$goods_list = array_column($goods_list, null, 'sku_id');
|
||||
$curr_goods_info = $goods_list[$sku_id] ?? null;
|
||||
unset($goods_list[$sku_id]);
|
||||
if(is_null($curr_goods_info)){
|
||||
return $this->error(null, '库存转换商品查找失败');
|
||||
}
|
||||
|
||||
//如果是门店独立库存,是当前门店转换库存;否则就是总部转换库存。
|
||||
$default_store_info = model('store')->getInfo([['is_default', '=', 1]], 'store_id');
|
||||
$store_info = model('store')->getInfo([['store_id', '=', $store_id]], 'stock_type');
|
||||
$stock_store_id = $store_info['stock_type'] == 'store' ? $store_id : $default_store_info['store_id'];
|
||||
|
||||
$need_transform_num = $buy_num - $curr_goods_info['stock'];
|
||||
if($need_transform_num > 0){
|
||||
$document_model = new Document();
|
||||
foreach($goods_list as $goods_info){
|
||||
if($goods_info['stock'] > 0){
|
||||
$least_common_multiple = getLeastCommonMultiple($curr_goods_info['num'], $goods_info['num']);
|
||||
$least_input_num = $least_common_multiple / $curr_goods_info['num'];
|
||||
$least_output_num = $least_common_multiple / $goods_info['num'];
|
||||
if($need_transform_num/$least_input_num <= $goods_info['stock']/$least_output_num){
|
||||
$num_multiple = ceil($need_transform_num/$least_input_num);
|
||||
}else{
|
||||
$num_multiple = floor($goods_info['stock']/$least_output_num);
|
||||
}
|
||||
if($num_multiple > 0){
|
||||
$input_num = $num_multiple*$least_input_num;
|
||||
$output_num = $num_multiple*$least_output_num;
|
||||
$input_unit = $curr_goods_info['unit'] ?: '件';
|
||||
$output_unit = $goods_info['unit'] ?: '件';
|
||||
//转换入库
|
||||
$document_params = [
|
||||
'site_id' => $site_id,
|
||||
'store_id' => $stock_store_id,
|
||||
'user_info' => [],
|
||||
'goods_sku_list' => [
|
||||
['goods_sku_id' => $curr_goods_info['sku_id'], 'goods_num' => $input_num, 'goods_price' => $curr_goods_info['cost_price']],
|
||||
],
|
||||
'remark' => "用{$output_num}{$output_unit}[{$goods_info['sku_name']}]自动转换",
|
||||
'time' => time(),
|
||||
];
|
||||
$document_params[ 'is_auto_audit' ] = true;
|
||||
$result = $document_model->addTransformInput($document_params);
|
||||
|
||||
if($result['code'] < 0) return $result;
|
||||
//转换出库
|
||||
$document_params = [
|
||||
'site_id' => $site_id,
|
||||
'store_id' => $stock_store_id,
|
||||
'user_info' => [],
|
||||
'goods_sku_list' => [
|
||||
['goods_sku_id' => $goods_info['sku_id'], 'goods_num' => $output_num, 'goods_price' => $goods_info['cost_price']],
|
||||
],
|
||||
'remark' => "自动转换为{$input_num}{$input_unit}[{$curr_goods_info['sku_name']}]",
|
||||
'time' => time(),
|
||||
'is_out_stock' => 1,
|
||||
];
|
||||
$document_params[ 'is_auto_audit' ] = true;
|
||||
$result = $document_model->addTransformOutput($document_params);
|
||||
if($result['code'] < 0) return $result;
|
||||
//判断是否继续转换
|
||||
$need_transform_num -= $input_num;
|
||||
if($need_transform_num <= 0) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($need_transform_num > 0){
|
||||
return $this->error(null, '库存转换失败');
|
||||
}
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user