|
|
e93107458a
|
feat(purchase): 采购列表支持关键词搜索与日期范围
背景
----
采购管理此前只有状态筛选,无法按单号/物料/申请人检索,也无法按采购
日期收窄范围。现对齐出库/报废记录的搜索语义,便于用户迁移使用习惯。
后端
----
PurchaseService.get_purchase_list 新增参数:
keyword / search_type / start_date / end_date
search_type 取值(与出库、报废一致):
all 单号 | 物料名称 | 规格型号 | 备注 | 申请人
no 单号
name 物料名称
spec_model 规格型号
requester 申请人
实现要点
--------
· 申请人姓名存在 SysUser.username,格式「姓名/账号」(如 韩善龙/hanshanlong),
ilike 直接匹配整串即可命中;
· 该类字段只在 SysUser 上,故**按需 join** —— 单号/名称/规格分支不联表,
避免无谓开销;
· 公司隔离分支也需 join SysUser,与关键词分支可能重复 join 同一目标,
会产生笛卡尔积导致结果翻倍,故按需补 join 并用 distinct 兜底;
· 日期范围按 purchase_date 过滤(该列是 Date,无需补时分秒)。
实测:名称'充电器'→1 单,申请人'韩善龙'→21 单,日期 05-13→2 单,
关键词不存在→0 单,状态+搜索组合→14 单。
|
2026-09-10 17:41:22 +08:00 |
|
|
|
8755837fe8
|
fix(timezone): 审批单据时间统一为 naive 北京时间,消除 8 小时偏差
成因:approved_at / executed_at 列是 timestamp without time zone,而赋值用了
带时区的 datetime.now(timezone(timedelta(hours=8)))。psycopg2 对 naive 列不会
剥掉 tzinfo,而是转成 naive UTC 再写入,结果比同为北京时间的 created_at 早 8 小时。
(代码里并无 datetime.utcnow(),真实成因是 aware 值被驱动的隐式 UTC 转换。)
改动:
· outbound_service / borrow_service 的审批分支
datetime.now(beijing_tz).replace(tzinfo=None) → beijing_time()
(免审批分支已在上一轮改为 beijing_time,此处补齐审批分支);
· purchase_service 审批/完结分支同源缺陷一并修复;
· scrap_approval / scrap_approval_service 的 _beijing()、_beijing_now() 由
tz-aware 改为 naive —— 配合上述迁移把列类型改为 naive,
若仍返回 aware 值,timestamptz→timestamp 后会反向早 8 小时。
实测四表(scrap/outbound/borrow/purchase)created_at 与 approved_at 差值
均在同一秒内(-1ms ~ -12ms)。
|
2026-09-10 10:14:31 +08:00 |
|
|
|
fbb4160787
|
feat: 采购申请新增库管'完结'功能(仿出库审批)
- 后端:approve 接口支持 action=close(已通过→已完结 status 1→4),模型 status_text 支持已完结
- 前端:采购申请状态tab加'已完结',已通过单显示'完结'按钮(库管)
|
2026-09-01 16:15:48 +08:00 |
|
|
|
1000deda2f
|
feat(purchase): 采购单号改为 批次-批内序号 格式,显式体现同批
按用户原始逻辑还原并扩展:
- 单号格式: PUR-日期-时间-批次-批内序号
例: PUR-20260831-1021-0001-0001(今日第1次采购的第1条)
- generate_request_no 支持 batch_seq 参数生成批次+批内序号
- 新增 GET /purchase/next-batch-seq 返回今日下一个批次号
- 前端提交时获取批次号,同批所有行共享,循环提交生成连续批内序号
- 批次识别: 单号去掉末尾 -批内序号 即为批次前缀
- 保留旧格式兼容(无 batch_seq 时回退 PUR-日期-时间-流水)
|
2026-08-31 13:54:03 +08:00 |
|
|
|
f499346f74
|
refactor(purchase): 批次概念改为基于 request_no 前缀推导,撤销数据库字段
按用户反馈:不需要新增数据库字段,现有 request_no (PUR-20260831-1021-0001)
本身就能推导批次——去掉末尾4位流水号即为批次前缀。
- 撤销 purchase_request.batch_no 字段(模型/数据库)
- 撤销 create 接口的 batch_no 参数与 generate_batch_no
- 批次标识 = request_no 去掉末尾 -XXXX 段
getBatchKey('PUR-20260831-1021-0001') = 'PUR-20260831-1021'
- 按批次查询/批量审批接口改用 batch_key (request_no LIKE 前缀)
- 前端列表批次号列、整批弹窗、一键审批本批均基于前缀推导
- 零数据库迁移,历史数据立即可用
|
2026-08-31 13:49:11 +08:00 |
|
|
|
664127ee30
|
feat(purchase): 采购批次号支持,同一批提交的记录可分组查看/统计
背景: 循环提交把一批物品生成多条独立申请,无法识别'哪些是同一批采购'
后端:
- purchase_request 模型新增 batch_no 字段(同一批提交共享)
- create 接口接收 batch_no,无则自动生成 BATCH-yyyyMMdd-HHmm-随机
- 新增 GET /purchase/batch/<batch_no> 按批次查询所有记录
- 批量审批接口支持按 batch_no 一键审批整批
前端:
- 提交时生成 batch_no 共享给所有行
- 列表新增批次号列(可点击)
- 新增'整批查看'弹窗:显示同批次所有记录 + 一键批量通过本批
- 操作列新增'整批'按钮
数据库需执行: ALTER TABLE purchase_request ADD COLUMN batch_no VARCHAR(100);
|
2026-08-31 13:46:46 +08:00 |
|
|
|
3290f206c6
|
perf: 导出OOM修复(yield_per流式) + 采购模糊匹配安全防护
## base_service.py export_excel
- query.all()全量→yield_per(2000)分块流式读取
- all_rows[]内存收集→write_only=True直写Excel
- all_rows.sort()→ORDER BY数据库排序
- 删除~160行旧Excel样式/脱敏死代码
- 内存: 全量→2000行分块+输出流
## purchase_service.py
- 模糊匹配安全防护:
len(n.strip())>=2 过滤空格/单字符
.limit(500) 防全表返回
|
2026-07-16 13:08:45 +08:00 |
|
|
|
128985af17
|
feat: 采购模块重构 — 权限驱动的可见性 + 严格操作权限
## purchase.py
- GET /purchase (列表): @jwt_required, 有权限看同公司全部/无权限只看自己
- POST /purchase (创建): @jwt_required, 任何登录用户可提交
- GET /purchase/<id> (详情): @jwt_required, 自己的或有权者可见
- PATCH /purchase/<id>/approve (审批): @permission_required('inbound_purchase:operation')
不再硬编码 SUPERVISOR 角色, 有操作权限即可审批
- GET /purchase/approvers, /auto-fill, /search-material: @jwt_required (开放给创建流程)
- 新增 _user_has_purchase_perm() 统一权限检查
- 移除所有硬编码 role in ('SUPERVISOR','SUPER_ADMIN')
## purchase_service.py
- send_email → send_email_async (采购审批邮件异步发送)
## purchase/index.vue
- canApprove: 仅检查 inbound_purchase:operation (菜单权限≠审批权限)
- customUpload: 修复 v-model:file-list 重复推入导致图片双份显示
- auth.py → purchase.py 权限前缀统一
|
2026-07-16 11:25:53 +08:00 |
|
|
|
4934cd4d8f
|
feat: 采购管理税率+分开单价总价列 + 按单出/借库锁定扫描 + 含税法计算
- purchase: 新增tax_rate字段(model+service+frontend), 表格拆分为不含税单价/总价/税率三列
- buy.vue: 含税法计算(含税总价=数量×含税单价), 含税总价自动计算可手动覆盖
- create.vue: 按单出库模式下未选审批单时锁定摄像头和SKU输入
- borrow.vue: 未选审批单时锁定摄像头和SKU输入
- deploy_production.sql: 整合全部数据库变更(表结构+权限码+角色分配)
|
2026-07-15 16:07:59 +08:00 |
|
|
|
9988d1b7eb
|
fix: 补全审计/出库审批/采购管理/借库审批的权限保护+公司隔离
- audit.py: 补@permission_required(system_audit)+import, 审计日志通过split_part关联用户表过滤公司
- outbound.py: 出库审批5个端点全补@permission_required(outbound_list)
- purchase.py: 采购管理7个端点全补@permission_required(inbound_buy)
- borrow_service: 借库审批列表通过applicant_id关联用户表过滤公司
- outbound_service: 出库审批列表通过applicant_id关联用户表过滤公司
- purchase_service: 采购列表通过base_id+requester_id双路过滤公司
- base_service/search_material: 去除debug日志
- decorators: 去除debug日志
|
2026-07-15 11:49:53 +08:00 |
|
|
|
a11b7972c3
|
feat: 打通采购申请与入库的按单入库链路
后端变更:
- PurchaseRequest 新增 base_id 硬关联 MaterialBase,StockBuy 新增 request_id 关联采购单
- handle_inbound 支持 request_id 入参,入库后自动反写采购单状态为已完成
- 新增 get_approved_requests 接口,返回已审批未入库采购单列表(含物料信息+历史数据回退匹配)
- create_purchase_request 新增 name+spec_model 自动匹配 MaterialBase
- 新增 SQL 和 Alembic 数据库迁移脚本
前端变更:
- 入库表单新增"从采购单导入"弹窗,支持搜索/选中已审批采购单并一键填充物料和商务信息
- 单价/总价交叉推算,缺项自动补全
- 选中行蓝色高亮+点击整行选中,行级交互优化
|
2026-07-14 15:25:00 +08:00 |
|
|
|
1a76c4853e
|
feat(purchase): 物料搜索分页+价格半联动+图片必填校验
|
2026-05-12 17:48:29 +08:00 |
|
|
|
9dfcb93146
|
feat(purchase): 新增采购申请模块后端(模型+Service+API路由)
|
2026-05-12 16:33:18 +08:00 |
|