feat: expand search fields and remove result limits in buy inbound service
This commit is contained in:
@ -41,21 +41,36 @@ class BuyInboundService:
|
||||
raise ValueError(f"该物料已存在批号【{batch_number}】,请勿重复录入,可直接在该批次下追加库存。")
|
||||
|
||||
# ============================================================
|
||||
# 1. 基础物料搜索
|
||||
# 1. 基础物料搜索 (参照 Base 模块:全量模糊匹配)
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def search_base_material(keyword):
|
||||
try:
|
||||
query = MaterialBase.query.filter(MaterialBase.is_enabled == True)
|
||||
|
||||
if keyword:
|
||||
query = query.filter(
|
||||
or_(
|
||||
MaterialBase.name.ilike(f'%{keyword}%'),
|
||||
MaterialBase.spec_model.ilike(f'%{keyword}%'),
|
||||
MaterialBase.pinyin.ilike(f'%{keyword}%')
|
||||
)
|
||||
)
|
||||
query = query.order_by(MaterialBase.id.desc()).limit(20)
|
||||
# [参照 Base 逻辑] 简单直接的模糊匹配:LIKE %keyword%
|
||||
k_str = f'%{keyword.strip()}%'
|
||||
|
||||
conditions = [
|
||||
MaterialBase.name.ilike(k_str), # 名称
|
||||
MaterialBase.spec_model.ilike(k_str), # 规格
|
||||
MaterialBase.pinyin.ilike(k_str), # 拼音
|
||||
MaterialBase.category.ilike(k_str), # 类别
|
||||
MaterialBase.material_type.ilike(k_str) # 类型
|
||||
]
|
||||
|
||||
# 安全地添加可能存在的扩展字段 (品牌/厂家)
|
||||
if hasattr(MaterialBase, 'brand'):
|
||||
conditions.append(MaterialBase.brand.ilike(k_str))
|
||||
if hasattr(MaterialBase, 'manufacturer'):
|
||||
conditions.append(MaterialBase.manufacturer.ilike(k_str))
|
||||
|
||||
query = query.filter(or_(*conditions))
|
||||
|
||||
# [参照 Base 逻辑] 移除 limit,返回所有结果
|
||||
query = query.order_by(MaterialBase.id.desc())
|
||||
|
||||
results = []
|
||||
for item in query.all():
|
||||
results.append({
|
||||
@ -65,6 +80,10 @@ class BuyInboundService:
|
||||
'category': item.category,
|
||||
'unit': item.unit,
|
||||
'type': item.material_type,
|
||||
# 使用 getattr 防止字段不存在报错
|
||||
'brand': getattr(item, 'brand', ''),
|
||||
'manufacturer': getattr(item, 'manufacturer', ''),
|
||||
'pinyin': getattr(item, 'pinyin', ''),
|
||||
'status': '启用'
|
||||
})
|
||||
return results
|
||||
@ -242,7 +261,7 @@ class BuyInboundService:
|
||||
raise e
|
||||
|
||||
# ============================================================
|
||||
# 5. 获取列表
|
||||
# 5. 获取列表 (参照 Base 逻辑:全量模糊匹配)
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def get_list(page, limit, keyword=None, statuses=None):
|
||||
@ -250,17 +269,30 @@ class BuyInboundService:
|
||||
query = db.session.query(StockBuy).outerjoin(MaterialBase, StockBuy.base_id == MaterialBase.id)
|
||||
|
||||
if keyword:
|
||||
kw = f'%{keyword}%'
|
||||
query = query.filter(
|
||||
or_(
|
||||
MaterialBase.name.ilike(kw),
|
||||
MaterialBase.spec_model.ilike(kw),
|
||||
StockBuy.batch_number.ilike(kw),
|
||||
StockBuy.serial_number.ilike(kw),
|
||||
StockBuy.sku.ilike(kw),
|
||||
StockBuy.supplier_name.ilike(kw)
|
||||
)
|
||||
)
|
||||
# [简单匹配] 只要任一字段包含该字符串,即匹配
|
||||
k_str = f'%{keyword.strip()}%'
|
||||
|
||||
conditions = [
|
||||
# 库存业务字段
|
||||
StockBuy.sku.ilike(k_str),
|
||||
StockBuy.barcode.ilike(k_str),
|
||||
StockBuy.batch_number.ilike(k_str),
|
||||
StockBuy.serial_number.ilike(k_str),
|
||||
StockBuy.supplier_name.ilike(k_str),
|
||||
StockBuy.buyer_name.ilike(k_str),
|
||||
# 基础物料关联字段
|
||||
MaterialBase.name.ilike(k_str),
|
||||
MaterialBase.spec_model.ilike(k_str),
|
||||
MaterialBase.pinyin.ilike(k_str),
|
||||
MaterialBase.category.ilike(k_str)
|
||||
]
|
||||
|
||||
if hasattr(MaterialBase, 'brand'):
|
||||
conditions.append(MaterialBase.brand.ilike(k_str))
|
||||
if hasattr(MaterialBase, 'manufacturer'):
|
||||
conditions.append(MaterialBase.manufacturer.ilike(k_str))
|
||||
|
||||
query = query.filter(or_(*conditions))
|
||||
|
||||
if not statuses:
|
||||
statuses = ['在库', '借库']
|
||||
@ -300,6 +332,9 @@ class BuyInboundService:
|
||||
'category': item.base.category if item.base else '',
|
||||
'unit': item.base.unit if item.base else '',
|
||||
'material_type': item.base.material_type if item.base else '',
|
||||
'brand': getattr(item.base, 'brand', '') if item.base else '',
|
||||
'manufacturer': getattr(item.base, 'manufacturer', '') if item.base else '',
|
||||
'pinyin': getattr(item.base, 'pinyin', '') if item.base else '',
|
||||
|
||||
'sku': item.sku,
|
||||
'inbound_date': date_display,
|
||||
@ -333,33 +368,28 @@ class BuyInboundService:
|
||||
return {"total": 0, "items": []}
|
||||
|
||||
# ============================================================
|
||||
# 6. 供应商历史查询 (基于 base_id)
|
||||
# 6. 供应商历史查询 (移除限制)
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def get_history_suppliers(base_id):
|
||||
"""返回该物料关联的供应商列表(去重)"""
|
||||
try:
|
||||
query = db.session.query(StockBuy.supplier_name).filter(
|
||||
StockBuy.base_id == base_id,
|
||||
StockBuy.supplier_name.isnot(None),
|
||||
StockBuy.supplier_name != ''
|
||||
).distinct().order_by(StockBuy.supplier_name)
|
||||
# [修改] 移除 limit
|
||||
suppliers = [row[0] for row in query.all()]
|
||||
return suppliers
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
# ============================================================
|
||||
# 7. 采购人建议 (全局,基于 stock_buy 表)
|
||||
# 7. 采购人建议 (移除限制)
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def get_history_purchasers(keyword):
|
||||
"""
|
||||
从 stock_buy 表中提取历史采购人和邮箱。
|
||||
不绑定 base_id,因为采购人通常是全局的。
|
||||
"""
|
||||
try:
|
||||
# 查询 buyer_name 和 buyer_email,并去重
|
||||
query = db.session.query(StockBuy.buyer_name, StockBuy.buyer_email) \
|
||||
.filter(StockBuy.buyer_name.isnot(None), StockBuy.buyer_name != '')
|
||||
|
||||
@ -370,13 +400,13 @@ class BuyInboundService:
|
||||
StockBuy.buyer_email.ilike(kw)
|
||||
))
|
||||
|
||||
# 按名字去重,取最新的记录(这里简单做 distinct)
|
||||
results = query.distinct().limit(20).all()
|
||||
# [修改] 移除 limit
|
||||
results = query.distinct().all()
|
||||
|
||||
users = []
|
||||
for row in results:
|
||||
users.append({
|
||||
'value': row.buyer_name, # 前端 autocomplete 显示的值
|
||||
'value': row.buyer_name,
|
||||
'email': row.buyer_email or ''
|
||||
})
|
||||
return users
|
||||
@ -385,38 +415,35 @@ class BuyInboundService:
|
||||
return []
|
||||
|
||||
# ============================================================
|
||||
# 8. 链接建议 (基于 base_id)
|
||||
# 8. 链接建议 (移除限制)
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def get_history_links(base_id, link_type='original'):
|
||||
"""查询该物料的历史链接,方便复用"""
|
||||
try:
|
||||
target_col = StockBuy.original_link if link_type == 'original' else StockBuy.detail_link
|
||||
query = db.session.query(target_col).filter(
|
||||
StockBuy.base_id == base_id,
|
||||
target_col.isnot(None),
|
||||
target_col != ''
|
||||
).distinct().limit(10)
|
||||
|
||||
).distinct()
|
||||
# [修改] 移除 limit
|
||||
links = [row[0] for row in query.all()]
|
||||
return links
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
# ============================================================
|
||||
# 9. [新增] 库位建议 (基于 base_id)
|
||||
# 9. 库位建议 (移除限制)
|
||||
# ============================================================
|
||||
@staticmethod
|
||||
def get_history_locations(base_id):
|
||||
"""查询该物料的历史存放库位,方便复用"""
|
||||
try:
|
||||
query = db.session.query(StockBuy.warehouse_location).filter(
|
||||
StockBuy.base_id == base_id,
|
||||
StockBuy.warehouse_location.isnot(None),
|
||||
StockBuy.warehouse_location != ''
|
||||
).distinct().limit(10)
|
||||
|
||||
# 简单去重列表
|
||||
).distinct()
|
||||
# [修改] 移除 limit
|
||||
locs = [row[0] for row in query.all()]
|
||||
return locs
|
||||
except Exception:
|
||||
|
||||
Reference in New Issue
Block a user