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