|
|
@@ -63,6 +63,85 @@ def parse_ccb_flow(flow_file_path):
|
|
|
messagebox.showerror("错误", f"解析建行流水失败:{str(e)}")
|
|
|
return None
|
|
|
|
|
|
+def parse_boc_flow(flow_file_path):
|
|
|
+ """解析中国银行流水文件,返回标准化的流水数据"""
|
|
|
+ try:
|
|
|
+ # 读取中国银行流水(列名在第8行)
|
|
|
+ flow_df = pd.read_excel(flow_file_path, dtype=str, header=8)
|
|
|
+
|
|
|
+ # 去除列名中的空格
|
|
|
+ flow_df.columns = flow_df.columns.str.strip()
|
|
|
+
|
|
|
+ # 检查必要列是否存在
|
|
|
+ required_columns = [
|
|
|
+ "交易类型[ Transaction Type ]",
|
|
|
+ "交易日期[ Transaction Date ]",
|
|
|
+ "交易时间[ Transaction time ]",
|
|
|
+ "交易金额[ Trade Amount ]",
|
|
|
+ "交易后余额[ After-transaction balance ]",
|
|
|
+ "摘要[ Reference ]",
|
|
|
+ "收款人名称[ Payee's Name ]",
|
|
|
+ "收款人开户行名[ Beneficiary account bank ]",
|
|
|
+ "付款人名称[ Payer's Name ]",
|
|
|
+ "付款人开户行名[ Payer account bank ]"
|
|
|
+ ]
|
|
|
+
|
|
|
+ missing_fields = [k for k in required_columns if k not in flow_df.columns]
|
|
|
+ if missing_fields:
|
|
|
+ messagebox.showerror("错误", f"中国银行流水缺少必要列:{missing_fields}")
|
|
|
+ return None
|
|
|
+
|
|
|
+ # 构建标准化流水数据
|
|
|
+ standard_flow = []
|
|
|
+ for _, row in flow_df.iterrows():
|
|
|
+ transaction_type = str(row["交易类型[ Transaction Type ]"]).strip()
|
|
|
+ transaction_date = str(row["交易日期[ Transaction Date ]"]).strip()
|
|
|
+ transaction_time = str(row["交易时间[ Transaction time ]"]).strip()
|
|
|
+ amount = pd.to_numeric(row["交易金额[ Trade Amount ]"], errors='coerce')
|
|
|
+ balance = str(row["交易后余额[ After-transaction balance ]"]).strip()
|
|
|
+ reference = str(row["摘要[ Reference ]"]).strip()
|
|
|
+ payee_name = str(row["收款人名称[ Payee's Name ]"]).strip()
|
|
|
+ payee_bank = str(row["收款人开户行名[ Beneficiary account bank ]"]).strip()
|
|
|
+ payer_name = str(row["付款人名称[ Payer's Name ]"]).strip()
|
|
|
+ payer_bank = str(row["付款人开户行名[ Payer account bank ]"]).strip()
|
|
|
+
|
|
|
+ # 跳过空行
|
|
|
+ if pd.isna(amount) or amount == 0:
|
|
|
+ continue
|
|
|
+
|
|
|
+ # 根据交易类型确定收支
|
|
|
+ if transaction_type == "往账":
|
|
|
+ income = 0
|
|
|
+ expense = abs(amount)
|
|
|
+ opponent_name = payee_name
|
|
|
+ opponent_bank = payee_bank
|
|
|
+ elif transaction_type == "来账":
|
|
|
+ income = abs(amount)
|
|
|
+ expense = 0
|
|
|
+ opponent_name = payer_name
|
|
|
+ opponent_bank = payer_bank
|
|
|
+ else:
|
|
|
+ continue
|
|
|
+
|
|
|
+ # 合并日期和时间
|
|
|
+ transaction_datetime = f"{transaction_date} {transaction_time}"
|
|
|
+
|
|
|
+ standard_flow.append({
|
|
|
+ "交易时间": transaction_datetime,
|
|
|
+ "对方户名": opponent_name,
|
|
|
+ "摘要": reference,
|
|
|
+ "收入": income,
|
|
|
+ "支出": expense,
|
|
|
+ "对方开户机构": opponent_bank,
|
|
|
+ "备注": opponent_bank,
|
|
|
+ "余额": balance
|
|
|
+ })
|
|
|
+
|
|
|
+ return pd.DataFrame(standard_flow)
|
|
|
+ except Exception as e:
|
|
|
+ messagebox.showerror("错误", f"解析中国银行流水失败:{str(e)}")
|
|
|
+ return None
|
|
|
+
|
|
|
def generate_journal_data(company_name, bank_name, param_file, flow_file):
|
|
|
"""核心:生成日记账数据"""
|
|
|
# 1. 加载参数表
|
|
|
@@ -70,8 +149,15 @@ def generate_journal_data(company_name, bank_name, param_file, flow_file):
|
|
|
if account_params is None:
|
|
|
return None
|
|
|
|
|
|
- # 2. 解析建行流水
|
|
|
- flow_df = parse_ccb_flow(flow_file)
|
|
|
+ # 2. 根据银行名称选择不同的解析函数
|
|
|
+ if "中国银行" in bank_name:
|
|
|
+ flow_df = parse_boc_flow(flow_file)
|
|
|
+ elif "建设银行" in bank_name:
|
|
|
+ flow_df = parse_ccb_flow(flow_file)
|
|
|
+ else:
|
|
|
+ messagebox.showerror("错误", f"不支持的银行:{bank_name}")
|
|
|
+ return None
|
|
|
+
|
|
|
if flow_df is None:
|
|
|
return None
|
|
|
|
|
|
@@ -145,6 +231,7 @@ def generate_journal_data(company_name, bank_name, param_file, flow_file):
|
|
|
|
|
|
# 基础字段
|
|
|
journal_row = {
|
|
|
+ "编号": account_code,
|
|
|
"简称": account_short_name,
|
|
|
"企业": company_name_full,
|
|
|
"日期": formatted_date,
|
|
|
@@ -173,8 +260,8 @@ def generate_journal_data(company_name, bank_name, param_file, flow_file):
|
|
|
journal_row["资金分类-1级"] = "结算支出"
|
|
|
journal_row["资金分类-2级"] = "结算支出"
|
|
|
journal_row["资金分类-3级"] = "结算支出"
|
|
|
- # 规则2:摘要含"手续费" → 财务费用-财务费用-手续费
|
|
|
- elif "手续费" in str(row["摘要"]):
|
|
|
+ # 规则2:摘要含"手续费"或"对公跨行转账汇款手续费" → 财务费用-财务费用-手续费
|
|
|
+ elif "手续费" in str(row["摘要"]) or "对公跨行转账汇款手续费" in str(row["摘要"]):
|
|
|
journal_row["资金分类-1级"] = "财务费用"
|
|
|
journal_row["资金分类-2级"] = "财务费用"
|
|
|
journal_row["资金分类-3级"] = "手续费"
|
|
|
@@ -198,7 +285,7 @@ def generate_journal_data(company_name, bank_name, param_file, flow_file):
|
|
|
journal_df = pd.DataFrame(journal_data)
|
|
|
# 确保列顺序匹配参考日记账
|
|
|
journal_columns = [
|
|
|
- "简称", "企业", "日期", "月份", "收支",
|
|
|
+ "编号", "简称", "企业", "日期", "月份", "收支",
|
|
|
"资金分类-1级", "资金分类-2级", "资金分类-3级", "对手户", "备注", "发生额", "余额", "备注.1"
|
|
|
]
|
|
|
journal_df = journal_df[journal_columns]
|
|
|
@@ -217,8 +304,9 @@ def select_param_file():
|
|
|
|
|
|
def select_flow_file():
|
|
|
"""选择银行流水文件"""
|
|
|
+ bank = bank_var.get()
|
|
|
file_path = filedialog.askopenfilename(
|
|
|
- title="选择建行流水文件",
|
|
|
+ title=f"选择{bank}流水文件",
|
|
|
filetypes=[("Excel文件", "*.xlsx *.xls"), ("所有文件", "*.*")]
|
|
|
)
|
|
|
if file_path:
|
|
|
@@ -270,7 +358,7 @@ def generate_journal():
|
|
|
|
|
|
# 初始化GUI
|
|
|
root = tk.Tk()
|
|
|
-root.title("出纳日记账生成工具(建行版)")
|
|
|
+root.title("出纳日记账生成工具")
|
|
|
root.geometry("600x300")
|
|
|
|
|
|
# 变量定义
|
|
|
@@ -285,7 +373,7 @@ frame_company = ttk.Frame(root, padding="10")
|
|
|
frame_company.pack(fill=tk.X)
|
|
|
ttk.Label(frame_company, text="公司名称:").pack(side=tk.LEFT)
|
|
|
company_combo = ttk.Combobox(frame_company, textvariable=company_var, state="readonly")
|
|
|
-company_combo["values"] = ["成都锦高量科科技有限公司"] # 后续可扩展其他公司
|
|
|
+company_combo["values"] = ["成都锦高量科科技有限公司", "成都云启寰宇科技有限公司", "成都橙风有量科技有限公司"]
|
|
|
company_combo.pack(side=tk.LEFT, padx=5)
|
|
|
|
|
|
# 2. 银行选择
|
|
|
@@ -293,7 +381,7 @@ frame_bank = ttk.Frame(root, padding="10")
|
|
|
frame_bank.pack(fill=tk.X)
|
|
|
ttk.Label(frame_bank, text="开户银行:").pack(side=tk.LEFT)
|
|
|
bank_combo = ttk.Combobox(frame_bank, textvariable=bank_var, state="readonly")
|
|
|
-bank_combo["values"] = ["建设银行"] # 后续可扩展其他银行
|
|
|
+bank_combo["values"] = ["建设银行", "中国银行"]
|
|
|
bank_combo.pack(side=tk.LEFT, padx=5)
|
|
|
|
|
|
# 3. 参数表选择
|