-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtransaction_log_api.py
More file actions
186 lines (153 loc) · 6.41 KB
/
Copy pathtransaction_log_api.py
File metadata and controls
186 lines (153 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
"""
transaction_log_api.py
======================
交易記錄查詢 API 模組
使用方式:
在 app9.py 中加入以下程式碼:
from transaction_log_api import register_transaction_log_api
register_transaction_log_api(app, LOG_FILE)
"""
import pandas as pd
from flask import request, jsonify
def register_transaction_log_api(app, log_file):
"""
註冊交易記錄相關的 API 端點到 Flask app
Args:
app: Flask 應用程式實例
log_file: 交易記錄檔案路徑 (Path 物件)
"""
@app.route("/api/transaction-log", methods=["GET"])
def api_transaction_log():
"""
查詢交易記錄
Query Parameters:
- barcode: 貨品編號(模糊搜尋)
- batch_no: 批號(模糊搜尋)
- trans_type: 操作類型(精確匹配:入庫/出庫/調撥/盤點/庫存清空)
- operator: 操作人員(模糊搜尋)
- date_from: 起始日期 (YYYY-MM-DD)
- date_to: 結束日期 (YYYY-MM-DD)
- limit: 回傳筆數限制(預設 200,最大 1000)
- offset: 分頁偏移量(預設 0)
"""
try:
# 檢查交易記錄檔案是否存在
if not log_file.exists():
return jsonify({
"status": "ok",
"records": [],
"total": 0,
"limit": 0,
"offset": 0
})
# 讀取交易記錄
log_df = pd.read_excel(log_file, dtype=str)
log_df = log_df.fillna('')
# 取得查詢參數
barcode = request.args.get('barcode', '').strip()
batch_no = request.args.get('batch_no', '').strip()
trans_type = request.args.get('trans_type', '').strip()
operator = request.args.get('operator', '').strip()
date_from = request.args.get('date_from', '').strip()
date_to = request.args.get('date_to', '').strip()
try:
limit = min(int(request.args.get('limit', 200)), 1000)
except ValueError:
limit = 200
try:
offset = max(int(request.args.get('offset', 0)), 0)
except ValueError:
offset = 0
# 篩選條件
mask = pd.Series([True] * len(log_df))
if barcode:
mask &= log_df['貨品編號'].str.contains(barcode, case=False, na=False)
if batch_no:
mask &= log_df['批號'].str.contains(batch_no, case=False, na=False)
if trans_type:
mask &= log_df['操作類型'] == trans_type
if operator:
mask &= log_df['操作人員'].str.contains(operator, case=False, na=False)
if date_from:
try:
mask &= log_df['時間'].apply(
lambda x: x[:10] >= date_from if x and len(x) >= 10 else False
)
except Exception:
pass
if date_to:
try:
mask &= log_df['時間'].apply(
lambda x: x[:10] <= date_to if x and len(x) >= 10 else False
)
except Exception:
pass
# 套用篩選
filtered_df = log_df[mask].copy()
# 計算總筆數(篩選後)
total = len(filtered_df)
# 按時間倒序排列(最新的在前)
filtered_df = filtered_df.sort_values(by='時間', ascending=False)
# 分頁
paginated_df = filtered_df.iloc[offset:offset + limit]
# 轉換為記錄列表
records = []
for _, row in paginated_df.iterrows():
records.append({
'time': row.get('時間', ''),
'trans_type': row.get('操作類型', ''),
'barcode': row.get('貨品編號', ''),
'batch_no': row.get('批號', ''),
'product_name': row.get('品名', ''),
'qty': row.get('數量', ''),
'from_location': row.get('來源位置', ''),
'to_location': row.get('目標位置', ''),
'operator': row.get('操作人員', ''),
'note': row.get('備註', '')
})
return jsonify({
"status": "ok",
"records": records,
"total": total,
"limit": limit,
"offset": offset
})
except Exception as e:
print(f"[api_transaction_log] 錯誤: {e}")
return jsonify({
"status": "error",
"msg": str(e)
}), 500
@app.route("/api/transaction-log/types", methods=["GET"])
def api_transaction_types():
"""取得所有操作類型(供前端下拉選單使用)"""
types = ['入庫', '出庫', '調撥', '盤點', '庫存清空']
return jsonify({
"status": "ok",
"types": types
})
@app.route("/api/transaction-log/operators", methods=["GET"])
def api_transaction_operators():
"""取得所有操作人員(供前端下拉選單使用)"""
try:
if not log_file.exists():
return jsonify({
"status": "ok",
"operators": []
})
log_df = pd.read_excel(log_file, dtype=str)
# 取得不重複的操作人員
operators = log_df['操作人員'].dropna().unique().tolist()
operators = [op for op in operators if op.strip()]
operators.sort()
return jsonify({
"status": "ok",
"operators": operators
})
except Exception as e:
print(f"[api_transaction_operators] 錯誤: {e}")
return jsonify({
"status": "error",
"msg": str(e)
}), 500
print("[transaction_log_api] API 端點已註冊")