!10185 !10184 银行流水导入

Merge pull request !10185 from 李鹏宇/dev
This commit is contained in:
李鹏宇
2026-03-24 13:16:35 +00:00
committed by Gitee
2 changed files with 78 additions and 30 deletions
@@ -11,7 +11,7 @@ class PropertyStatementsWizard(models.Model):
_name = 'property.statements.wizard'
_description = '银行流水向导弹窗'
selection_bank = fields.Selection([('js', '建设银行'), ('gs', '工商银行'), ('sh', '农商'), ('ms', '民生'), ('zc', '广州银行(中城)'), ('dj', '农商行(东进)')], string="选择银行")
selection_bank = fields.Selection([('js', '建设银行'), ('gs', '工商银行'), ('sh', '农商'), ('ms', '民生'), ('zc', '广州银行(中城)'), ('dj', '农商行(东进)'), ('xy', '工商银行(兴源)')], string="选择银行")
excel_file = fields.Binary(string="上传Excel表")
excel_name = fields.Char(string="文件名")
@@ -57,6 +57,8 @@ class PropertyStatementsWizard(models.Model):
self.property_bank_statements_ms_data(row)
elif self.selection_bank == 'gs':
self.property_bank_statements_gc_data(row)
elif self.selection_bank == 'xy':
self.property_bank_statements_xy_data(row)
return {
'type': 'ir.actions.client',
@@ -344,10 +346,11 @@ class PropertyStatementsWizard(models.Model):
existing_record.write(bank_data)
def property_bank_statements_gc_data(self, row):
"""工商银行(兴苑)解析:数据从第2行开始,列结构(共34列):
0:交易时间, 1:对方单位, 2:摘要, 7:借贷标志, 8:发生额,
9:对方账号, 16:本方账号, 22:对方行名, 31:顺序号
def property_bank_statements_xy_data(self, row):
"""工商银行(兴源)解析:数据从第2行开始,列结构(共34列):
0:交易时间, 1:对方单位, 2:摘要, 4:转入金额(贷时取), 7:借贷标志,
8:发生额(借时取), 9:对方账号, 16:本方账号, 22:对方行名, 31:顺序号
金额取数规则:H列=贷 取E列(索引4转入金额),H列=借 取I列(索引8发生额)
"""
serial_number = str(row[31].value).strip() if row[31].value else ''
@@ -361,17 +364,17 @@ class PropertyStatementsWizard(models.Model):
else:
start_time = None
# 借贷方向
# 借贷方向,并按规则取对应金额列
direction_val = str(row[7].value).strip() if row[7].value else ''
if direction_val == '贷':
lending_direction = 'loan'
amount_str = str(row[4].value).replace(',', '').strip() if row[4].value else '' # E列:转入金额
elif direction_val == '借':
lending_direction = 'borrow'
amount_str = str(row[8].value).replace(',', '').strip() if row[8].value else '' # I列:发生额
else:
return
# 金额(去逗号)
amount_str = str(row[8].value).replace(',', '').strip() if row[8].value else ''
try:
original_amount = float(amount_str)
except Exception:
@@ -414,6 +417,41 @@ class PropertyStatementsWizard(models.Model):
else:
existing_record.write(bank_data)
def property_bank_statements_gc_data(self, row):
"""工商银行(原始格式)解析"""
if row[0].value:
start_time = datetime.strptime(row[0].value, '%Y-%m-%d %H:%M:%S')
else:
start_time = None
name = row[4].value
name_account = row[1].value
remake = row[2].value
original_amount = row[3].value
your_own_account = row[6].value
cleaned_amount = str(original_amount).replace(',', '')
float_amount = float(cleaned_amount)
your_own_unit = self.classify_by_last_four(your_own_account)
company_id = self._get_company_by_unit(your_own_unit)
if not company_id:
return
sequence_number = row[5].value
bank_data = {
'name': name,
'your_own_unit': your_own_unit,
'original_amount': float_amount,
'company_id': company_id.id,
'sequence_number': sequence_number,
'start_time': start_time - timedelta(hours=8) if start_time else False,
'your_own_account': your_own_account,
'name_account': name_account,
'remake': remake,
}
existing_record = self.env['property.bank.statements'].search(
[('sequence_number', '=', sequence_number)], limit=1
)
if not existing_record:
self.env['property.bank.statements'].create(bank_data)
def _get_company_by_unit(self, unit_name):
"""根据账号单位返回对应公司"""
if unit_name in ['天河投资', '天投城建']:
+32 -22
View File
@@ -71,25 +71,36 @@ class ReceivableFlowReport(models.Model):
for ml in all_modify_lines:
modify_map.setdefault(ml.receivable_id.id, []).append(ml)
# 2. 批量查违约金wizard(sudo跳过多公司权限)
# 2. 直接查询所有 penalty.pay.line 记录
# 先查询所有相关的 penalty.line.wizard
all_wizards = self.env['penalty.line.wizard'].sudo().search([
('receivable_id', 'in', rec_ids),
])
all_wizard_ids = all_wizards.ids
# 批量查所有 penalty.pay.line(不再只查最新wizard)
# 然后查询所有相关的 penalty.pay.line
if all_wizard_ids:
all_penalty_pay_lines = self.env['penalty.pay.line'].sudo().search([
('penalty_id', 'in', all_wizard_ids),
])
else:
all_penalty_pay_lines = self.env['penalty.pay.line']
all_penalty_pay_lines.mapped('management_type_id') # 预加载类型
# 调试信息
import logging
_logger = logging.getLogger(__name__)
_logger.info(f"查询的 rec_ids 数量: {len(rec_ids)}, 示例: {rec_ids[:5] if len(rec_ids) > 5 else rec_ids}")
_logger.info(f"查询到的 all_wizards 数量: {len(all_wizards)}")
_logger.info(f"查询到的 all_penalty_pay_lines 数量: {len(all_penalty_pay_lines)}")
# 按 receivable_id 分组 {receivable_id: [penalty_pay_lines]}
penalty_pay_map = {}
for ppl in all_penalty_pay_lines:
rid = ppl.penalty_id.receivable_id.id if ppl.penalty_id and ppl.penalty_id.receivable_id else None
if rid:
penalty_pay_map.setdefault(rid, []).append(ppl)
_logger.info(f"penalty_pay_map 中的 receivable_id 数量: {len(penalty_pay_map)}, 示例: {list(penalty_pay_map.keys())[:5] if len(penalty_pay_map) > 5 else list(penalty_pay_map.keys())}")
# ===== 预加载结束 =====
rows = []
@@ -169,35 +180,34 @@ class ReceivableFlowReport(models.Model):
if rec.submitted == 0:
charge_status = "已收"
# 违约金收款:直接从 penalty.pay.line 取(持久化数据源)
rec_penalty_pay_lines = penalty_pay_map.get(rec.id, [])
# 违约金收款:直接从 penalty.pay.line 计算
pay_lines = penalty_pay_map.get(rec.id, [])
# 调试信息
import logging
_logger = logging.getLogger(__name__)
_logger.info(f"应收记录ID: {rec.id}, penalty_type: {penalty_type}, penalty_type.id: {penalty_type.id if penalty_type else None}")
_logger.info(f"rec_penalty_pay_lines 数量: {len(rec_penalty_pay_lines)}")
for ppl in rec_penalty_pay_lines:
_logger.info(f"pay_lines 数量: {len(pay_lines)}")
for ppl in pay_lines:
_logger.info(f" - penalty.pay.line ID: {ppl.id}, management_type_id: {ppl.management_type_id}, management_type_id.id: {ppl.management_type_id.id if ppl.management_type_id else None}, amount: {ppl.amount}, date: {ppl.date}")
# 违约金收款金额:类型为“违约金”的金额之和
# 违约金收款金额:使用你提到的方法计算
if penalty_type:
collected = sum(pay_line.amount for pay_line in pay_lines
if pay_line.management_type_id == penalty_type)
else:
collected = 0.0
total_penalty_collected = round(collected, 2)
# 违约金收款时间:类型为“违约金”的最新收款日期
penalty_payment_date = None
if penalty_type:
penalty_pay_collected = [
l for l in rec_penalty_pay_lines
if l.management_type_id and l.management_type_id.id == penalty_type.id
l for l in pay_lines
if l.management_type_id == penalty_type and l.date
]
else:
penalty_pay_collected = []
_logger.info(f"penalty_pay_collected 数量: {len(penalty_pay_collected)}")
total_penalty_collected = sum(l.amount for l in penalty_pay_collected)
# 违约金收款时间:类型为“违约金”的最新收款日期
latest_penalty_pay = sorted(
[l for l in penalty_pay_collected if l.date],
key=lambda l: l.date, reverse=True
)
penalty_payment_date = latest_penalty_pay[0].date if latest_penalty_pay else None
latest_penalty_pay = sorted(penalty_pay_collected, key=lambda l: l.date, reverse=True)
penalty_payment_date = latest_penalty_pay[0].date if latest_penalty_pay else None
_logger.info(f"total_penalty_collected: {total_penalty_collected}, penalty_payment_date: {penalty_payment_date}")