Initial commit: queue workspace
Made-with: Cursor
This commit is contained in:
55
pro_v3.5.1/app/dao/product/stock/StockInventoryDao.php
Normal file
55
pro_v3.5.1/app/dao/product/stock/StockInventoryDao.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\dao\product\stock;
|
||||
|
||||
use app\dao\BaseDao;
|
||||
use app\model\product\stock\StockInventory;
|
||||
use app\model\product\stock\StockRecord;
|
||||
|
||||
/**
|
||||
* 出入库记录DAO
|
||||
* Class StockInventoryDao
|
||||
* @package app\dao\stock
|
||||
*/
|
||||
class StockInventoryDao extends BaseDao
|
||||
{
|
||||
/**
|
||||
* 设置模型
|
||||
* @return string
|
||||
*/
|
||||
protected function setModel(): string
|
||||
{
|
||||
return StockInventory::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取出入库记录列表
|
||||
* @param array $where
|
||||
* @param string $field
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @param array $with
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getList(array $where = [], string $field = '*', int $page = 0, int $limit = 0, array $with = []): array
|
||||
{
|
||||
return $this->search($where, false)->field($field)->when($with, function ($query) use ($with) {
|
||||
$query->with($with);
|
||||
})
|
||||
->when($page && $limit, function ($query) use ($page, $limit) {
|
||||
$query->page($page, $limit);
|
||||
})->order('id DESC')->select()->toArray();
|
||||
}
|
||||
}
|
||||
176
pro_v3.5.1/app/dao/product/stock/StockRecordDao.php
Normal file
176
pro_v3.5.1/app/dao/product/stock/StockRecordDao.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\dao\product\stock;
|
||||
|
||||
use app\dao\BaseDao;
|
||||
use app\model\product\stock\StockRecord;
|
||||
|
||||
/**
|
||||
* 出入库记录DAO
|
||||
* Class StockRecordDao
|
||||
* @package app\dao\stock
|
||||
*/
|
||||
class StockRecordDao extends BaseDao
|
||||
{
|
||||
/**
|
||||
* 设置模型
|
||||
* @return string
|
||||
*/
|
||||
protected function setModel(): string
|
||||
{
|
||||
return StockRecord::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取出入库记录列表
|
||||
* @param array $where
|
||||
* @param string $field
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @param array $with
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getList(array $where = [], string $field = '*', int $page = 0, int $limit = 0, array $with = []): array
|
||||
{
|
||||
return $this->search($where,false)->field($field)->when($with, function ($query) use ($with) {
|
||||
$query->with($with);
|
||||
})
|
||||
|
||||
->when($page && $limit, function ($query) use ($page, $limit) {
|
||||
$query->page($page, $limit);
|
||||
})->order('id DESC')->select()->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件获取出入库记录数量
|
||||
* @param array $where
|
||||
* @return int
|
||||
*/
|
||||
public function getCount(array $where = []): int
|
||||
{
|
||||
return $this->search($where)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成出入库单号
|
||||
* @param int $type
|
||||
* @return string
|
||||
*/
|
||||
public function generateRecordNo(int $type): string
|
||||
{
|
||||
if($type == 3){
|
||||
$prefix = 'IC';
|
||||
}else{
|
||||
$prefix = $type == StockRecord::TYPE_IN ? 'IN' : 'OUT';
|
||||
}
|
||||
$date = date('Ymd');
|
||||
$rand = mt_rand(1000, 9999);
|
||||
return $prefix . $date . $rand;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查单号是否存在
|
||||
* @param string $recordNo
|
||||
* @param int $excludeId
|
||||
* @return bool
|
||||
*/
|
||||
public function checkRecordNoExists(string $recordNo, int $excludeId = 0): bool
|
||||
{
|
||||
$query = $this->getModel()->where('record_no', $recordNo);
|
||||
if ($excludeId > 0) {
|
||||
$query->where('id', '<>', $excludeId);
|
||||
}
|
||||
return $query->count() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取统计数据
|
||||
* @param array $where
|
||||
* @return array
|
||||
*/
|
||||
public function getStatistics(array $where = []): array
|
||||
{
|
||||
$query = $this->search($where);
|
||||
|
||||
return [
|
||||
'total_count' => $query->count(),
|
||||
'in_count' => $query->where('type', StockRecord::TYPE_IN)->count(),
|
||||
'out_count' => $query->where('type', StockRecord::TYPE_OUT)->count(),
|
||||
'pending_count' => $query->count(),
|
||||
'approved_count' => $query->count(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据日期范围获取记录
|
||||
* @param int $startTime 开始时间戳
|
||||
* @param int $endTime 结束时间戳
|
||||
* @param array $where
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getRecordsByDateRange(int $startTime, int $endTime, array $where = []): array
|
||||
{
|
||||
return $this->search($where)
|
||||
->where('record_date', '>=', $startTime)
|
||||
->where('record_date', '<=', $endTime)
|
||||
->with(['items'])
|
||||
->order('record_date DESC, id DESC')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取待审核的记录
|
||||
* @param int $limit
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getPendingRecords(int $limit = 10): array
|
||||
{
|
||||
return $this->getModel()
|
||||
->with(['items'])
|
||||
->order('create_time ASC')
|
||||
->limit($limit)
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据出入库类型获取记录
|
||||
* @param int $type 出入库类型
|
||||
* @param int $subType 子类型
|
||||
* @param array $where 其他条件
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getRecordsByType(int $type, int $subType = 0, array $where = []): array
|
||||
{
|
||||
$query = $this->search($where)->where('type', $type);
|
||||
if ($subType > 0) {
|
||||
$query->where('sub_type', $subType);
|
||||
}
|
||||
return $query->with(['items'])
|
||||
->order('record_date DESC, id DESC')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
270
pro_v3.5.1/app/dao/product/stock/StockRecordItemDao.php
Normal file
270
pro_v3.5.1/app/dao/product/stock/StockRecordItemDao.php
Normal file
@@ -0,0 +1,270 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\dao\product\stock;
|
||||
|
||||
use app\dao\BaseDao;
|
||||
use app\model\product\stock\StockRecordItem;
|
||||
|
||||
/**
|
||||
* 出入库商品详情DAO
|
||||
* Class StockRecordItemDao
|
||||
* @package app\dao\stock
|
||||
*/
|
||||
class StockRecordItemDao extends BaseDao
|
||||
{
|
||||
/**
|
||||
* 设置模型
|
||||
* @return string
|
||||
*/
|
||||
protected function setModel(): string
|
||||
{
|
||||
return StockRecordItem::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据出入库记录ID获取商品详情
|
||||
* @param int $recordId
|
||||
* @param string $field
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function getItemsByRecordId(int $recordId, string $field = '*'): array
|
||||
{
|
||||
return $this->getModel()
|
||||
->where('record_id', $recordId)
|
||||
->where('type', 1)
|
||||
->field($field)
|
||||
->order('id ASC')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加出入库商品详情
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function saveAllItems(array $data): bool
|
||||
{
|
||||
return $this->getModel()->saveAll($data) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据记录ID删除商品详情
|
||||
* @param int $recordId
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteByRecordId(int $recordId): bool
|
||||
{
|
||||
return $this->getModel()->where('record_id', $recordId)->delete() !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品的出入库统计
|
||||
* @param int $productId
|
||||
* @param int $skuId
|
||||
* @param string $startDate
|
||||
* @param string $endDate
|
||||
* @return array
|
||||
*/
|
||||
public function getProductStockStatistics(int $productId, int $skuId = 0, string $startDate = '', string $endDate = ''): array
|
||||
{
|
||||
$query = $this->getModel()
|
||||
->alias('item')
|
||||
->leftJoin('stock_record record', 'item.record_id = record.id')
|
||||
->where('item.product_id', $productId)
|
||||
->where('record.status', 2); // 已审核状态
|
||||
|
||||
if ($skuId > 0) {
|
||||
$query->where('item.sku_id', $skuId);
|
||||
}
|
||||
|
||||
if ($startDate && $endDate) {
|
||||
$query->whereBetweenTime('record.record_date', $startDate, $endDate);
|
||||
}
|
||||
|
||||
// 入库统计
|
||||
$inStats = (clone $query)
|
||||
->where('record.type', 1)
|
||||
->field([
|
||||
'SUM(item.good_stock) as total_good_in',
|
||||
'SUM(item.defective_stock) as total_defective_in',
|
||||
'COUNT(*) as in_count'
|
||||
])
|
||||
->find();
|
||||
|
||||
// 出库统计
|
||||
$outStats = (clone $query)
|
||||
->where('record.type', 2)
|
||||
->field([
|
||||
'SUM(item.good_stock) as total_good_out',
|
||||
'SUM(item.defective_stock) as total_defective_out',
|
||||
'COUNT(*) as out_count'
|
||||
])
|
||||
->find();
|
||||
|
||||
return [
|
||||
'in_stats' => $inStats ? $inStats->toArray() : ['total_good_in' => 0, 'total_defective_in' => 0, 'in_count' => 0],
|
||||
'out_stats' => $outStats ? $outStats->toArray() : ['total_good_out' => 0, 'total_defective_out' => 0, 'out_count' => 0],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商品库存(这里实际不需要更新,因为库存通过出入库记录计算)
|
||||
* @param int $productId
|
||||
* @param int $skuId
|
||||
* @param int $quantity
|
||||
* @param string $operation
|
||||
* @return bool
|
||||
*/
|
||||
public function updateProductStock(int $productId, int $skuId, int $quantity, string $operation): bool
|
||||
{
|
||||
// 由于库存通过出入库记录实时计算,这里不需要实际更新操作
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品库存详情
|
||||
* @param array $where
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getProductStockDetails(array $where = [], int $page = 1, int $limit = 20): array
|
||||
{
|
||||
$query = $this->getModel()->alias('item')
|
||||
->leftJoin('stock_record record', 'item.record_id = record.id')
|
||||
->leftJoin('store_product p', 'item.product_id = p.id')
|
||||
->leftJoin('store_product_attr_value pav', 'item.sku_id = pav.unique')
|
||||
->field([
|
||||
'item.product_id',
|
||||
'item.sku_id',
|
||||
'p.store_name',
|
||||
'p.image',
|
||||
'pav.sku as sku_name',
|
||||
'SUM(CASE WHEN record.type = 1 AND record.status = 2 THEN item.quantity ELSE 0 END) as in_stock',
|
||||
'SUM(CASE WHEN record.type = 2 AND record.status = 2 THEN item.quantity ELSE 0 END) as out_stock',
|
||||
'SUM(CASE WHEN record.type = 1 AND record.status = 2 THEN item.quantity ELSE -item.quantity END) as current_stock'
|
||||
])
|
||||
->group('item.product_id, item.sku_id')
|
||||
->order('current_stock desc');
|
||||
|
||||
if (!empty($where['product_name'])) {
|
||||
$query->where('p.store_name', 'like', '%' . $where['product_name'] . '%');
|
||||
}
|
||||
|
||||
if (isset($where['low_stock']) && $where['low_stock']) {
|
||||
$query->having('current_stock', '<', 10);
|
||||
}
|
||||
|
||||
return $query->page($page, $limit)->select()->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品库存详情总数
|
||||
* @param array $where
|
||||
* @return int
|
||||
*/
|
||||
public function getProductStockDetailsCount(array $where = []): int
|
||||
{
|
||||
$query = $this->getModel()->alias('item')
|
||||
->leftJoin('eb_stock_record record', 'item.record_id = record.id')
|
||||
->leftJoin('store_product p', 'item.product_id = p.id')
|
||||
->group('item.product_id, item.sku_id');
|
||||
|
||||
if (!empty($where['product_name'])) {
|
||||
$query->where('p.store_name', 'like', '%' . $where['product_name'] . '%');
|
||||
}
|
||||
|
||||
return $query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查库存是否充足
|
||||
* @param int $productId
|
||||
* @param int $skuId
|
||||
* @param int $quantity
|
||||
* @return bool
|
||||
*/
|
||||
public function checkStockSufficient(int $productId, int $skuId, int $quantity): bool
|
||||
{
|
||||
$currentStock = $this->getCurrentStock($productId, $skuId);
|
||||
return $currentStock >= $quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前库存
|
||||
* @param int $productId
|
||||
* @param int $skuId
|
||||
* @return int
|
||||
*/
|
||||
public function getCurrentStock(int $productId, int $skuId): int
|
||||
{
|
||||
$inStock = $this->getModel()->alias('item')
|
||||
->leftJoin('eb_stock_record record', 'item.record_id = record.id')
|
||||
->where('item.product_id', $productId)
|
||||
->where('item.sku_id', $skuId)
|
||||
->where('record.type', 1)
|
||||
->where('record.status', 2)
|
||||
->sum('item.quantity');
|
||||
|
||||
$outStock = $this->getModel()->alias('item')
|
||||
->leftJoin('eb_stock_record record', 'item.record_id = record.id')
|
||||
->where('item.product_id', $productId)
|
||||
->where('item.sku_id', $skuId)
|
||||
->where('record.type', 2)
|
||||
->where('record.status', 2)
|
||||
->sum('item.quantity');
|
||||
|
||||
return ($inStock ?: 0) - ($outStock ?: 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取库存预警列表
|
||||
* @param int $warningStock
|
||||
* @param int $page
|
||||
* @param int $limit
|
||||
* @return array
|
||||
*/
|
||||
public function getWarningStockList(int $warningStock = 10, int $page = 1, int $limit = 20): array
|
||||
{
|
||||
$query = $this->getModel()->alias('item')
|
||||
->leftJoin('eb_stock_record record', 'item.record_id = record.id')
|
||||
->leftJoin('store_product p', 'item.product_id = p.id')
|
||||
->leftJoin('store_product_attr_value pav', 'item.sku_id = pav.unique')
|
||||
->field([
|
||||
'item.product_id',
|
||||
'item.sku_id',
|
||||
'p.store_name',
|
||||
'p.image',
|
||||
'pav.sku as sku_name',
|
||||
'SUM(CASE WHEN record.type = 1 AND record.status = 2 THEN item.quantity ELSE 0 END) as in_stock',
|
||||
'SUM(CASE WHEN record.type = 2 AND record.status = 2 THEN item.quantity ELSE 0 END) as out_stock',
|
||||
'SUM(CASE WHEN record.type = 1 AND record.status = 2 THEN item.quantity ELSE -item.quantity END) as current_stock'
|
||||
])
|
||||
->group('item.product_id, item.sku_id')
|
||||
->having('current_stock', '<', $warningStock)
|
||||
->order('current_stock ASC');
|
||||
|
||||
$total = $query->count();
|
||||
$list = $query->page($page, $limit)->select()->toArray();
|
||||
|
||||
return [
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user