| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import pandas as pd
- from tkinter import messagebox
- class JournalGenerator:
- """日记账生成器"""
-
- def __init__(self, account_param_sheet="账户信息参数", category_param_sheet="收支分类参数"):
- self.account_param_sheet = account_param_sheet
- self.category_param_sheet = category_param_sheet
- self.settlement_companies = ["成都合煦商贸有限公司", "四川泗讯科技有限公司"]
-
- def load_parameter_table(self, param_file_path):
- """加载参数表,返回账户信息和收支分类"""
- try:
- account_params = pd.read_excel(param_file_path, sheet_name=self.account_param_sheet, header=1)
- category_params = pd.read_excel(param_file_path, sheet_name=self.category_param_sheet, header=1)
- return account_params, category_params
- except Exception as e:
- messagebox.showerror("错误", f"加载参数表失败:{str(e)}")
- return None, None
-
- def generate_journal_data(self, company_name, bank_name, param_file, flow_df):
- """核心:生成日记账数据"""
- account_params, category_params = self.load_parameter_table(param_file)
- if account_params is None:
- return None
-
- account_filter = account_params["公司"] == company_name
- account_info = account_params[account_filter]
-
- if not account_info.empty and bank_name not in account_info["开户行"].values:
- account_filter = account_filter & account_params["开户行"].str.contains(bank_name, na=False)
- account_info = account_params[account_filter]
-
- if account_info.empty:
- messagebox.showerror("错误", f"参数表中未找到{company_name}-{bank_name}的账户信息")
- return None
-
- account_code = account_info["编号"].iloc[0]
- account_short_name = account_info["简称"].iloc[0]
- company_name_full = account_info["公司"].iloc[0]
-
- journal_data = []
- for _, row in flow_df.iterrows():
- if pd.isna(row["交易时间"]) or str(row["交易时间"]).strip() == "":
- continue
-
- income = row["收入"] if pd.notna(row["收入"]) else 0
- expense = row["支出"] if pd.notna(row["支出"]) else 0
-
- if income > 0:
- shouzhi_type = "收入"
- amount = income
- elif expense > 0:
- shouzhi_type = "支出"
- amount = expense
- else:
- shouzhi_type = ""
- amount = 0
-
- try:
- date_obj = pd.to_datetime(row["交易时间"], errors='coerce')
- month = date_obj.month if pd.notna(date_obj) else ""
- except:
- month = ""
-
- try:
- date_obj = pd.to_datetime(row["交易时间"], errors='coerce')
- if pd.notna(date_obj):
- formatted_date = f"{date_obj.year}/{date_obj.month}/{date_obj.day}"
- else:
- formatted_date = row["交易时间"]
- except:
- formatted_date = row["交易时间"]
-
- opponent_name = str(row["对方户名"]).strip()
- is_personal = len(opponent_name) < 5 or "公司" not in opponent_name
-
- if is_personal:
- remark = f"{opponent_name}{row['备注']}"
- else:
- remark = f"{opponent_name}{row['对方开户机构']}"
-
- journal_row = {
- "编号": account_code,
- "简称": account_short_name,
- "企业": company_name_full,
- "日期": formatted_date,
- "月份": month,
- "收支": shouzhi_type,
- "资金分类-1级": "",
- "资金分类-2级": "",
- "资金分类-3级": "",
- "对手户": opponent_name,
- "备注": remark,
- "发生额": amount,
- "余额": row["余额"],
- "备注.1": ""
- }
-
- if (opponent_name in account_params["公司"].values) or (opponent_name in self.settlement_companies):
- if income > 0:
- journal_row["资金分类-1级"] = "结算收入"
- journal_row["资金分类-2级"] = "结算收入"
- journal_row["资金分类-3级"] = "结算收入"
- else:
- journal_row["资金分类-1级"] = "结算支出"
- journal_row["资金分类-2级"] = "结算支出"
- journal_row["资金分类-3级"] = "结算支出"
- elif "手续费" in str(row["摘要"]) or "对公跨行转账汇款手续费" in str(row["摘要"]):
- journal_row["资金分类-1级"] = "财务费用"
- journal_row["资金分类-2级"] = "财务费用"
- journal_row["资金分类-3级"] = "手续费"
- journal_row["对手户"] = "手续费"
- journal_row["备注"] = "手续费"
- elif "会长提现" in str(row["备注"]):
- journal_row["资金分类-1级"] = "结算支出"
- journal_row["资金分类-2级"] = "结算支出"
- journal_row["资金分类-3级"] = "会长提现支付"
- else:
- journal_row["资金分类-1级"] = "待分类"
- journal_row["资金分类-2级"] = "待分类"
- journal_row["资金分类-3级"] = "待分类"
-
- journal_data.append(journal_row)
-
- journal_df = pd.DataFrame(journal_data)
- journal_columns = [
- "编号", "简称", "企业", "日期", "月份", "收支",
- "资金分类-1级", "资金分类-2级", "资金分类-3级", "对手户", "备注", "发生额", "余额", "备注.1"
- ]
- journal_df = journal_df[journal_columns]
-
- return journal_df
-
- def save_journal(self, journal_df, save_path):
- """保存日记账到Excel文件"""
- try:
- from openpyxl.styles import Font
-
- with pd.ExcelWriter(save_path, engine="openpyxl") as writer:
- journal_df.to_excel(writer, index=False, sheet_name="日记账")
-
- workbook = writer.book
- worksheet = writer.sheets["日记账"]
-
- bold_font = Font(bold=True)
-
- for cell in worksheet[1]:
- cell.font = bold_font
-
- return True
- except Exception as e:
- messagebox.showerror("错误", f"保存日记账失败:{str(e)}")
- return False
|