89 lines
2.7 KiB
Python
89 lines
2.7 KiB
Python
"""市场物料库存变动记录 CRUD"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List, Optional, Tuple
|
|
|
|
from sqlalchemy import func, or_
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.material import BizMaterialStockLog
|
|
|
|
|
|
def _dec(v: Any) -> float:
|
|
if v is None:
|
|
return 0.0
|
|
return float(v)
|
|
|
|
|
|
def _fmt_dt(t: Optional[datetime]) -> str:
|
|
return t.strftime("%Y-%m-%d %H:%M:%S") if t else ""
|
|
|
|
|
|
def _row_to_dict(r: BizMaterialStockLog) -> Dict[str, Any]:
|
|
return {
|
|
"id": r.id,
|
|
"materialId": r.material_id,
|
|
"materialCode": r.material_code or "",
|
|
"materialName": r.material_name or "",
|
|
"changeType": r.change_type,
|
|
"changeQty": _dec(r.change_qty),
|
|
"stockBefore": _dec(r.stock_before),
|
|
"stockAfter": _dec(r.stock_after),
|
|
"receiver": r.receiver or "",
|
|
"purpose": r.purpose or "",
|
|
"remark": r.remark or "",
|
|
"createBy": r.create_by or "",
|
|
"createTime": _fmt_dt(r.create_time),
|
|
"updateTime": _fmt_dt(r.update_time),
|
|
}
|
|
|
|
|
|
def list_stock_logs(
|
|
db: Session,
|
|
tenant_no: str,
|
|
*,
|
|
page: int = 1,
|
|
page_size: int = 10,
|
|
material_id: Optional[str] = None,
|
|
change_type: Optional[str] = None,
|
|
start_time: Optional[str] = None,
|
|
end_time: Optional[str] = None,
|
|
keyword: Optional[str] = None,
|
|
) -> Tuple[List[Dict[str, Any]], int]:
|
|
def _filtered():
|
|
q0 = db.query(BizMaterialStockLog).filter(
|
|
BizMaterialStockLog.tenant_no == tenant_no,
|
|
BizMaterialStockLog.del_flag == 0,
|
|
)
|
|
if material_id:
|
|
q0 = q0.filter(BizMaterialStockLog.material_id == material_id)
|
|
if change_type:
|
|
q0 = q0.filter(BizMaterialStockLog.change_type == change_type)
|
|
if start_time:
|
|
q0 = q0.filter(BizMaterialStockLog.create_time >= start_time)
|
|
if end_time:
|
|
q0 = q0.filter(BizMaterialStockLog.create_time <= end_time + " 23:59:59")
|
|
kw = (keyword or "").strip()
|
|
if kw:
|
|
like = f"%{kw}%"
|
|
q0 = q0.filter(
|
|
or_(
|
|
BizMaterialStockLog.material_code.ilike(like),
|
|
BizMaterialStockLog.material_name.ilike(like),
|
|
)
|
|
)
|
|
return q0
|
|
|
|
total = _filtered().order_by(None).with_entities(func.count(BizMaterialStockLog.id)).scalar() or 0
|
|
page = max(1, page)
|
|
page_size = min(max(1, page_size), 100)
|
|
rows = (
|
|
_filtered()
|
|
.order_by(BizMaterialStockLog.create_time.desc())
|
|
.offset((page - 1) * page_size)
|
|
.limit(page_size)
|
|
.all()
|
|
)
|
|
return [_row_to_dict(x) for x in rows], int(total)
|