From f30b837212a6b65406e33f1c66743370a260e104 Mon Sep 17 00:00:00 2001 From: liubiren Date: Sun, 11 Jan 2026 22:04:57 +0800 Subject: [PATCH] 1 --- .isort.cfg | 4 - .vscode/settings.json | 3 + utils/authenticator.py | 2 +- 票据理赔自动化/case.py | 259 +++- 票据理赔自动化/common.py | 3 +- 票据理赔自动化/database.db | Bin 85553152 -> 85553152 bytes 票据理赔自动化/dossiers/254728869001.html | 1509 --------------------- 票据理赔自动化/image.py | 30 +- 票据理赔自动化/main.py | 16 +- 票据理赔自动化/masterdata.py | 89 +- 票据理赔自动化/template.html | 1165 ++++++++-------- 11 files changed, 922 insertions(+), 2158 deletions(-) delete mode 100644 .isort.cfg create mode 100644 .vscode/settings.json diff --git a/.isort.cfg b/.isort.cfg deleted file mode 100644 index eb008e9..0000000 --- a/.isort.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[settings] -order_by_type = true -multi_line_output = 3 -indent = " " \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ff5300e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.languageServer": "None" +} \ No newline at end of file diff --git a/utils/authenticator.py b/utils/authenticator.py index e376b38..a14934b 100644 --- a/utils/authenticator.py +++ b/utils/authenticator.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -认证器 +认证器模块 """ import hashlib diff --git a/票据理赔自动化/case.py b/票据理赔自动化/case.py index 04dfeae..b5345bc 100644 --- a/票据理赔自动化/case.py +++ b/票据理赔自动化/case.py @@ -1,10 +1,13 @@ # -*- coding: utf-8 -*- """通用模块""" -from typing import Any, Dict, List from decimal import Decimal, ROUND_HALF_UP - +from pathlib import Path +from typing import Any, Dict, List +from datetime import datetime +from jinja2 import Environment, FileSystemLoader import pandas + from common import masterdata, rules_engine @@ -28,17 +31,75 @@ def case_adjust(dossier: Dict[str, Any]) -> None: return # 赔案理算记录 - adjustments = ( - pandas.DataFrame(data=dossier["receipts_layer"]).assing( - adjustments=lambda dataframe: dataframe.apply( - lambda row: receipt_adjust( - row=row, liabilities=dossier["liabilities_layer"] - ), - axis="columns", - ) # 票据理算 + receipts_adjustments = ( + ( + pandas.DataFrame(data=dossier["receipts_layer"]).assign( + receipt_adjustments=lambda dataframe: dataframe.apply( + lambda row: receipt_adjust( + row=row, liabilities=dossier["liabilities_layer"] + ), + axis="columns", + ) # 票据理算 + ) + ) + .explode(column="receipt_adjustments", ignore_index=True) + .pipe( + lambda dataframe: pandas.concat( + [ + dataframe.drop( + [ + "receipt_adjustments", + ], + axis="columns", + ), + pandas.json_normalize(dataframe["receipt_adjustments"]), + ], + axis="columns", + ) + ) + ) + + dossier["receipts_layer"] = receipts_adjustments.to_dict(orient="records") + + print(dossier["receipts_layer"]) + + # 赔案理算金额 + dossier["adjustment_layer"].update( + { + "adjustment_amount": ( + receipts_adjustments["adjustment_amount"] + .sum() + .quantize( + Decimal("0.00"), + rounding=ROUND_HALF_UP, + ) + ), # 理算金额 + } + ) + + # 实例化JINJA2 + environment = Environment( + loader=FileSystemLoader(file_path := Path(__file__).parent) + ) + # 添加过滤器 + environment.filters["DateTime"] = lambda i: ( + i.strftime("%Y-%m-%d") if i != datetime(9999, 12, 31) else "长期" + ) + # 加载赔案档案模版 + template = environment.get_template("template.html") + + with open( + file_path / f"dossiers/{dossier["report_layer"]["case_number"]}.html", + "w", + encoding="utf-8", + ) as file: + file.write( + template.render( + { + "dossier": dossier, + } + ) ) - ).explode("adjustments", ignore_index=True) - print(adjustments) def receipt_adjust( @@ -46,72 +107,140 @@ def receipt_adjust( ) -> List[Dict[str, Any]]: """ 理算票据 - :param row: 一张票据数据 + :param row: 票据数据 :param liabilities: 理算责任 :return: 理算记录 """ # 初始化票据理算记录 - adjustments = [] - # 初始化剩余个人自费金额 - remaining_personal_self_payment = row["personal_self_payment"] - # 初始化剩余个人自付金额 - remaining_non_medical_payment = row["non_medical_payment"] - # 初始化剩余合理金额 - remaining_reasonable_amount = row["reasonable_amount"] + receipt_adjustments = [] - # 出险事故 - accident = row["accident"] - # 出险人 - accident_person = row["payer"] - # 出险日期 - accident_date = row["date"] + # 初始化票据剩余可理算金额 + remaining_adjustable_amount = ( + row["personal_self_payment"] + + row["non_medical_payment"] + + row["reasonable_amount"] + ).quantize( # type: ignore[reportAttributeAccessIssue] + Decimal("0.00"), + rounding=ROUND_HALF_UP, + ) - # 查验状态 - verification = row["verification"] - - # 初始化理赔责任理算金额 - adjustment_amount = Decimal("0.00") - # 初始化理赔责任理赔金额 - claim_amount = Decimal("0.00") - - # 遍历所有理赔责任,根据出险事故、出险人、出险日期和查验状态匹配责任 + # 遍历所有理赔责任,根据出险人、出险事故、查验状态和出险日期匹配理赔责任 for liability in liabilities: if ( - accident == liability["accident"] - and accident_person == liability["insured_person"] + row["payer"] in [liability["insured_person"] for liability in liabilities] + and row["accident"] == liability["accident"] + and row["verification"] in ["真票", "无法查验"] and liability["commencement_date"] - <= accident_date + <= row["date"] <= liability["termination_date"] - and verification == "真票" ): - # 理赔责任理算金额 - adjustment_amount = ( - row["personal_self_payment"] - * liability["personal_self_ratio"] # 个人自费金额 - + row["non_medical_payment"] - * liability["non_medical_ratio"] # 个人自付金额 - + row["reasonable_amount"] * liability["reasonable_ratio"] # 合理金额 - ).quantize( - Decimal("0.00"), - rounding=ROUND_HALF_UP, - ) - - # 据变动保单唯一标识查询最新一条保额变动记录的变动后金额(理赔责任的理赔保单余额) + # 个单余额 remaining_amount = masterdata.query_remaining_amount( - policy_guid=liability["policy_guid"], - ) - # 理赔责任理赔金额 - claim_amount = min( - remaining_amount, - adjustment_amount, + person_policy_guid=liability["person_policy_guid"], ) - # 初始化票据理算记录 - adjustment = { - "liability": liability["liability"], # 理赔责任名称 - "type": row["就诊类型"], - "amount": row["合理金额"], - "payable": 0.0, + # 个人自费可理算金额 + personal_self_adjustable_amount = ( + row["personal_self_payment"] + * liability["personal_self_ratio"] + * Decimal("0.01") + ) + # 个人自付可理算金额 + non_medical_adjustable_amount = ( + row["non_medical_payment"] + * liability["non_medical_ratio"] + * Decimal("0.01") + ) + # 合理可理算金额 + reasonable_adjustable_amount = ( + row["reasonable_amount"] + * liability["reasonable_ratio"] + * Decimal("0.01") + ) + + # 理算金额 + adjustment_amount = max( + Decimal("0.00"), + min( + remaining_adjustable_amount, + remaining_amount, + adjustable_amount := ( + ( + personal_self_adjustable_amount + + non_medical_adjustable_amount + + reasonable_adjustable_amount + ).quantize( + Decimal("0.00"), + rounding=ROUND_HALF_UP, + ) + ), # 可理算金额 + ), + ) + + # 若理算金额大于0则新增保额扣减记录 + if adjustment_amount > Decimal("0.00"): + masterdata.add_coverage_change( + person_policy_guid=liability["person_policy_guid"], + before_change_amount=remaining_amount, + change_amount=adjustment_amount, + ) + + receipt_adjustments.append( + { + "person_policy": liability["person_policy"], # 个单号 + "liability": liability["liability"], # 理赔责任名称 + "personal_self_payment": row[ + "personal_self_payment" + ], # 个人自费金额 + "personal_self_ratio": liability[ + "personal_self_ratio" + ], # 个人自费比例 + "personal_self_adjustable_amount": personal_self_adjustable_amount, # 个人自费可理算金额 + "non_medical_payment": row["non_medical_payment"], # 个人自付金额 + "non_medical_ratio": liability["non_medical_ratio"], # 个人自付比例 + "non_medical_adjustable_amount": non_medical_adjustable_amount, # 个人自付可理算金额 + "reasonable_amount": row["reasonable_amount"], # 合理可理算金额 + "reasonable_ratio": liability["reasonable_ratio"], # 合理部分比例 + "reasonable_adjustable_amount": reasonable_adjustable_amount, # 合理可理算金额 + "adjustment_amount": adjustment_amount, # 理算金额 + "adjustment_explanation": f""" + 1、应理算金额:{remaining_adjustable_amount:.2f}; + 2、个单余额:{remaining_amount:.2f}; + 3、可理算金额:{adjustable_amount:.2f},其中: + 1)个人自费可理算金额:{personal_self_adjustable_amount:.2f}={row['personal_self_payment']:.2f}*{liability['personal_self_ratio']:.2f}%; + 2)个人自付可理算金额:{non_medical_adjustable_amount:.2f}={row['non_medical_payment']:.2f}*{liability['non_medical_ratio']:.2f}%; + 3)合理部分可理算金额:{reasonable_adjustable_amount:.2f}={row['reasonable_amount']:.2f}*{liability['reasonable_ratio']:.2f}%; + 4、理算金额:{adjustment_amount:.2f},即上述应理算金额、个人余额和可理算金额的最小值。 + """.replace( + "\n", "" + ).replace( + " ", "" + ), # 理算说明 + } + ) + + remaining_adjustable_amount -= adjustment_amount + # 若剩余可理算金额小于等于0则跳出循环 + if remaining_adjustable_amount <= Decimal("0.00"): + break + + if not receipt_adjustments: + receipt_adjustments.append( + { + "person_policy": None, # 个单号 + "liability": None, # 理赔责任名称 + "personal_self_payment": None, # 个人自费金额 + "personal_self_ratio": None, # 个人自费比例 + "personal_self_adjustable_amount": None, # 个人自费可理算金额 + "non_medical_payment": None, # 个人自付金额 + "non_medical_ratio": None, # 个人自付比例 + "non_medical_adjustable_amount": None, # 个人自付可理算金额 + "reasonable_amount": None, # 合理可理算金额 + "reasonable_ratio": None, # 合理部分比例 + "reasonable_adjustable_amount": None, # 合理可理算金额 + "adjustment_amount": Decimal("0.00"), # 理赔责任理算金额 + "adjustment_explanation": "票据不予理算", # 理算说明 } + ) - return adjustments + return receipt_adjustments diff --git a/票据理赔自动化/common.py b/票据理赔自动化/common.py index 552b8bc..db6d92a 100644 --- a/票据理赔自动化/common.py +++ b/票据理赔自动化/common.py @@ -1,14 +1,15 @@ # -*- coding: utf-8 -*- """通用模块""" -import sys from pathlib import Path +import sys from masterdata import MasterData sys.path.append(Path(__file__).parent.parent.as_posix()) from utils.rules_engine import RulesEngine + # 实例化主数据 masterdata = MasterData(database=Path(__file__).parent / "database.db") diff --git a/票据理赔自动化/database.db b/票据理赔自动化/database.db index ec40379ebe1c1ea789d2f144e77f41f299b1ba0d..822f3e123121b302ac87ff4d96bf0551a700b274 100644 GIT binary patch delta 8152 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 delta 5452 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 BW$yq0 diff --git a/票据理赔自动化/dossiers/254728869001.html b/票据理赔自动化/dossiers/254728869001.html index bb78b8a..e69de29 100644 --- a/票据理赔自动化/dossiers/254728869001.html +++ b/票据理赔自动化/dossiers/254728869001.html @@ -1,1509 +0,0 @@ - - - - - - 赔案档案 - - - -
-
-
-
-

赔案档案

-
-

赔案编号: 254728869001 | 保险总公司: 中银保险有限公司

-
-
-
-
- -
-

影像件层

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
影像件序号影像件名称已分类(含旋正)影像件类型已识别
01application_1.jpg理赔申请书
02beneficiary_1.jpg银行卡否,无需识别
03insurant_1.jpg居民身份证(正背面)
04invoice_1.jpg增值税发票
05invoice_10.jpg增值税发票
06invoice_11.jpg增值税发票
07invoice_12.jpg增值税发票
08invoice_2.jpg增值税发票
09invoice_3.jpg增值税发票
10invoice_4.jpg增值税发票
11invoice_5.jpg增值税发票
12invoice_6.jpg增值税发票
13invoice_7.jpg增值税发票
14invoice_8.jpg增值税发票
15invoice_9.jpg增值税发票
-
- -
-

赔案层

-
-
-

申请人信息

-
-
-
与被保险人关系
-
本人
-
-
-
姓名
-
唐敏华
-
-
-
证件类型
-
居民身份证
-
-
-
证件号码
-
320602197401310029
-
-
-
证件有效期
-
2016-06-28 至 2036-06-28 -
-
-
-
性别
-
-
-
-
出生
-
1974-01-31 | 51岁 -
-
-
-
手机号
-
13962635271
-
-
-
住址
-
江苏省 苏州市 昆山市 -
-
玉山镇许文塘新村45幢301室
-
-
-
- -
-

受益人信息

-
-
-
与被保险人关系
-
本人
-
-
-
户名
-
唐敏华
-
-
-
开户银行
-
中国银行昆山分行营业部
-
-
-
银行账号
-
6217566101001926753
-
-
-
-
-
- -
-

发票层

- -
-
-
-
增值税普通发票(卷票) | 06413154
- 关联影像件序号: 06 -
-
- - 无法查验 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
032002200307
-
-
-
校验码后六位
-
875292
-
-
-
开票日期
-
2024-10-16
-
-
-
票据金额
-
53.88元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
苏州雷允上国药连锁总店有限公司
-
-
-
推定疾病
-
类风湿关节炎
-
-
- - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
化学药品制剂塞来昔布胶囊2.0053.88元
-
总金额: 53.88元
-
- -
-
-
-
数电票 | 24412000000199673775
- 关联影像件序号: 07 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
673775
-
-
-
开票日期
-
2024-11-11
-
-
-
票据金额
-
50.80元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
荥阳市药之佳缘大药房有限公司
-
-
-
推定疾病
-
急性鼻咽炎
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
中成药香菊感冒颗粒2.0035.00元
化学药品制剂感冒灵颗粒1.0015.80元
-
总金额: 50.80元
-
- -
-
-
-
数电票 | 24127200000191481229
- 关联影像件序号: 14 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
481229
-
-
-
开票日期
-
2024-12-30
-
-
-
票据金额
-
69.00元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
天津美团大药房有限公司
-
-
-
推定疾病
-
类风湿关节炎
-
-
- - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
化学药品制剂塞来昔布胶囊0.2g*18粒/盒1.0069.00元
-
总金额: 69.00元
-
- -
-
-
-
数电票 | 25447200000004924953
- 关联影像件序号: 13 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
924953
-
-
-
开票日期
-
2025-01-11
-
-
-
票据金额
-
607.00元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
广州美团大药房有限公司
-
-
-
推定疾病
-
类风湿关节炎
-
-
- - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
化学药品制剂吗替麦考酚酯胶囊10.00607.00元
-
总金额: 607.00元
-
- -
-
-
-
数电票 | 25447200000004924954
- 关联影像件序号: 12 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
924954
-
-
-
开票日期
-
2025-01-11
-
-
-
票据金额
-
607.00元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
广州美团大药房有限公司
-
-
-
推定疾病
-
类风湿关节炎
-
-
- - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
化学药品制剂吗替麦考酚酯胶囊10.00607.00元
-
总金额: 607.00元
-
- -
-
-
-
数电票 | 25447200000045325946
- 关联影像件序号: 05 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
325946
-
-
-
开票日期
-
2025-01-20
-
-
-
票据金额
-
119.56元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
广州美团大药房有限公司
-
-
-
推定疾病
-
干眼病
-
-
- - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
化学药品制剂玻璃酸钠滴眼液0.1%*10ml/支/盒2.00119.56元
-
总金额: 119.56元
-
- -
-
-
-
数电票 | 25127200000015649326
- 关联影像件序号: 15 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
649326
-
-
-
开票日期
-
2025-02-13
-
-
-
票据金额
-
123.48元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
天津美团大药房有限公司
-
-
-
推定疾病
-
干眼病
-
-
- - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
化学药品制剂玻璃酸钠滴眼液0.1%*10ml/支/盒2.00123.48元
-
总金额: 123.48元
-
- -
-
-
-
数电票 | 25427000000241125962
- 关联影像件序号: 04 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
125962
-
-
-
开票日期
-
2025-07-08
-
-
-
票据金额
-
480.80元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
湖北美团大药房有限公司
-
-
-
推定疾病
-
干燥综合征
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
医疗仪器器械口腔溃疡含漱液40ml1.0013.00元
营养保健食品Swisse钙维生素D片6.00467.80元
-
总金额: 480.80元
-
- -
-
-
-
数电票 | 25427000000241125963
- 关联影像件序号: 08 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
125963
-
-
-
开票日期
-
2025-07-08
-
-
-
票据金额
-
299.50元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
湖北美团大药房有限公司
-
-
-
推定疾病
-
类风湿关节炎
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
营养保健食品SwisseSwisse斯维诗鱼油软胶囊160g0.8g/粒*200粒1.00146.90元
营养保健食品Swisse钙维生素D片2.00152.60元
-
总金额: 299.50元
-
- -
-
-
-
数电票 | 25427000000307614028
- 关联影像件序号: 10 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
614028
-
-
-
开票日期
-
2025-07-19
-
-
-
票据金额
-
131.50元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
湖北美团大药房有限公司
-
-
-
推定疾病
-
骨质疏松症
-
-
- - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
化学药品制剂海德威骨化三醇软胶囊5.00131.50元
-
总金额: 131.50元
-
- -
-
-
-
数电票 | 25342000000125542290
- 关联影像件序号: 11 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
542290
-
-
-
开票日期
-
2025-07-23
-
-
-
票据金额
-
156.20元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
安徽国胜大药房连锁有限公司
-
-
-
推定疾病
-
-
-
- - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
中成药麝香痔疮栓10.00156.20元
-
总金额: 156.20元
-
- -
-
-
-
数电票 | 25622000000034278010
- 关联影像件序号: 09 -
-
- - 真票 - -
-
- -
-
-
就诊人
-
唐敏华
-
-
-
票据代码
-
--
-
-
-
校验码后六位
-
278010
-
-
-
开票日期
-
2025-07-23
-
-
-
票据金额
-
103.20元
-
-
-
就诊类型
-
药店购药
-
-
-
医药机构
-
德生堂医药股份有限公司
-
-
-
推定疾病
-
-
-
- - - - - - - - - - - - - - - - - - - - -
大项小项数量金额
中成药麝香痔疮栓6.00103.20元
-
总金额: 103.20元
-
- -
- -
-

@liubiren.cloud

-
-
- - \ No newline at end of file diff --git a/票据理赔自动化/image.py b/票据理赔自动化/image.py index c428b05..214f3c2 100644 --- a/票据理赔自动化/image.py +++ b/票据理赔自动化/image.py @@ -3,27 +3,27 @@ 影像件处理模块 """ -import json -import re -import sys from base64 import b64encode from datetime import datetime -from decimal import ROUND_HALF_UP, Decimal +from decimal import Decimal, ROUND_HALF_UP from hashlib import md5 +import json from pathlib import Path +import re +import sys from typing import Any, Dict, List, Optional, Tuple import cv2 -import numpy -import pandas -from common import masterdata, rules_engine from fuzzywuzzy import fuzz from jionlp import parse_location +import numpy +import pandas -from utils.authenticator import Authenticator -from utils.request import Request +from common import masterdata, rules_engine sys.path.append(Path(__file__).parent.parent.as_posix()) +from utils.authenticator import Authenticator +from utils.request import Request # 实例化认证器 @@ -139,12 +139,10 @@ def image_read( :return: 影像件图像数组 """ try: - with open(image_path, "rb") as file: - image_bytes = file.read() # 读取影像件字节流 - - # 先将影像件字节流转为 numpy.ndarray 对象,再解码为单通道灰度图数组对象 + # 先使用读取影像件,再解码为单通道灰度图数组对象 image_ndarray = cv2.imdecode( - buf=numpy.frombuffer(image_bytes, numpy.uint8), flags=cv2.IMREAD_GRAYSCALE + buf=numpy.fromfile(file=image_path, dtype=numpy.uint8), + flags=cv2.IMREAD_GRAYSCALE, ) if image_ndarray is None: raise RuntimeError(f"影像件不存在") @@ -600,7 +598,9 @@ def receipt_recognize( "token": authenticator.get_token(servicer="szkt"), # 获取深圳快瞳访问令牌 "imgBase64": f"data:image/{image["image_format"].lstrip(".")};base64,{image["image_base64"]}", # 将影像件格式和BASE64编码嵌入数据统一资源标识符 }, - guid=md5(string=(url + image["image_guid"]).encode("utf-8")).hexdigest().upper(), + guid=md5(string=(url + image["image_guid"]).encode("utf-8")) + .hexdigest() + .upper(), ) # 若查验状态为真票或红票则直接整合至赔案档案 if response.get("status") == 200 and response.get("code") == 10000: diff --git a/票据理赔自动化/main.py b/票据理赔自动化/main.py index 6694a62..fa80064 100644 --- a/票据理赔自动化/main.py +++ b/票据理赔自动化/main.py @@ -10,7 +10,6 @@ from pathlib import Path from case import case_adjust from image import image_classify, image_recognize -from jinja2 import Environment, FileSystemLoader if __name__ == "__main__": # 初始化文件路径 @@ -20,27 +19,18 @@ if __name__ == "__main__": folder_path = file_path / "directory" folder_path.mkdir(parents=True, exist_ok=True) # 若文件夹路径不存在则创建 - # 实例化JINJA2环境 - environment = Environment(loader=FileSystemLoader(file_path)) - # 添加DATE过滤器 - environment.filters["date"] = lambda date: ( - date.strftime("%Y-%m-%d") if date else "长期" - ) - # 加载赔案档案模版 - template = environment.get_template("template.html") - # 遍历文件夹中赔案文件夹并创建赔案档案 for case_path in [x for x in folder_path.iterdir() if x.is_dir()]: # 初始化赔案档案(推送至TPA时,保险公司会提保险分公司名称、报案时间和影像件等,TPA签收后生成赔案号) dossier = { "report_layer": { - "report_time": datetime( - 2025, 7, 25, 12, 0, 0 - ), # 指定报案时间,默认为 datetime对象 "case_number": case_path.stem, # 默认为赔案文件夹名称 "insurer_company": ( insurer_company := "中银保险有限公司苏州分公司" ), # 默认为中银保险有限公司苏州分公司 + "report_time": datetime( + 2025, 7, 25, 12, 0, 0 + ), # 指定报案时间,默认为 datetime对象 }, # 报案层 "images_layer": [], # 影像件层 "insured_person_layer": {}, # 出险人层 diff --git a/票据理赔自动化/masterdata.py b/票据理赔自动化/masterdata.py index 83675a0..9ea0247 100644 --- a/票据理赔自动化/masterdata.py +++ b/票据理赔自动化/masterdata.py @@ -3,11 +3,12 @@ 主数据模块 """ -import sys from datetime import datetime -from decimal import ROUND_HALF_UP, Decimal +from decimal import Decimal, ROUND_HALF_UP +from hashlib import md5 from pathlib import Path -from typing import Any, Dict, List, Optional +import sys +from typing import Any, Dict, List sys.path.append(Path(__file__).parent.parent.as_posix()) from utils.sqlite import SQLite @@ -104,8 +105,6 @@ class MasterData(SQLite): non_medical_ratio TEXT NOT NULL, --合理理算比例 reasonable_ratio TEXT NOT NULL, - --理赔保单唯一标识 - claim_policy_guid TEXT NOT NULL, --个单唯一标识 person_policy_guid TEXT NOT NULL ) @@ -128,8 +127,8 @@ class MasterData(SQLite): after_change_amount TEXT NOT NULL, --变动时间 change_time TEXT NOT NULL, - --变动保单唯一标识 - change_policy_guid TEXT NOT NULL + --个单唯一标识 + person_policy_guid TEXT NOT NULL ) """ ) @@ -200,7 +199,7 @@ class MasterData(SQLite): liabilities.personal_self_ratio, liabilities.non_medical_ratio, liabilities.reasonable_ratio, - liabilities.claim_policy_guid + liabilities.person_policy_guid FROM insured_persons INNER JOIN person_policies ON insured_persons.person_policy_guid = person_policies.guid @@ -212,10 +211,10 @@ class MasterData(SQLite): INNER JOIN liabilities ON person_policies.guid = liabilities.person_policy_guid INNER JOIN coverage_changes - ON liabilities.claim_policy_guid = coverage_changes.change_policy_guid + ON liabilities.person_policy_guid = coverage_changes.person_policy_guid AND coverage_changes.change_time = (SELECT MAX(change_time) FROM coverage_changes - WHERE liabilities.claim_policy_guid = change_policy_guid) + WHERE liabilities.person_policy_guid = person_policy_guid) WHERE group_policies.insurer_company = ? AND insured_persons.insured_person = ? AND insured_persons.identity_type = ? @@ -312,11 +311,11 @@ class MasterData(SQLite): def query_remaining_amount( self, - policy_guid: str, + person_policy_guid: str, ) -> Decimal: """ - 根据变动保单唯一标识查询最新一条保额变动记录的变动后金额 - :param policy_guid: 变动保单唯一标识 + 根据个单唯一标识查询最新一条保额变动记录的变动后金额 + :param person_policy_guid: 个单唯一标识 :return: 变动后金额 """ try: @@ -325,11 +324,11 @@ class MasterData(SQLite): sql=""" SELECT after_change_amount FROM coverage_changes - WHERE change_policy_guid = ? + WHERE person_policy_guid = ? ORDER BY change_time DESC LIMIT 1; """, - parameters=(policy_guid,), + parameters=(person_policy_guid,), ) if not result: raise RuntimeError("查无数据") @@ -341,3 +340,63 @@ class MasterData(SQLite): except Exception as exception: raise RuntimeError(f"{str(exception)}") from exception + + def add_coverage_change( + self, + person_policy_guid: str, + before_change_amount: Decimal, + change_amount: Decimal, + ) -> None: + """ + 新增保额扣减记录 + :param person_policy_guid: 个单唯一标识 + :param before_change_amount: 变动前金额 + :param change_amount: 变动金额 + :return: 无 + """ + if before_change_amount != self.query_remaining_amount( + person_policy_guid=person_policy_guid, + ): + raise ValueError("变动前金额不等于最新一条保额变动记录的变动后金额") + + # 变动后金额 + after_change_amount = (before_change_amount - change_amount).quantize( + Decimal("0.00"), + rounding=ROUND_HALF_UP, + ) + if after_change_amount < Decimal("0.00"): + raise ValueError("变动后金额小于0") + + # 当前时间 + current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f") + + # 构建保额变动唯一标识 + guid = ( + md5( + string=f"{person_policy_guid} 保额扣减 {before_change_amount:.2f} {change_amount:.2f} {after_change_amount:.2f} {current_time}".encode( + "utf-8" + ) + ) + .hexdigest() + .upper() + ) + + with self: + if not self.execute( + sql=""" + INSERT INTO coverage_changes + (guid, change_type, before_change_amount, change_amount, after_change_amount, change_time, person_policy_guid) + VALUES + (?, ?, ?, ?, ?, ?, ?) + """, + parameters=( + guid, + "保额扣减", + f"{before_change_amount:.2f}", + f"{change_amount:.2f}", + f"{after_change_amount:.2f}", + current_time, + person_policy_guid, + ), + ): + raise RuntimeError("新增保额扣减记录发生异常") diff --git a/票据理赔自动化/template.html b/票据理赔自动化/template.html index e0355b9..5a6d11e 100644 --- a/票据理赔自动化/template.html +++ b/票据理赔自动化/template.html @@ -1,602 +1,697 @@ - - - + + + 赔案档案 - - -
-
+ + +
+
-
-

赔案档案

-
-

赔案编号: {{ dossier.赔案层.赔案编号 }} | 保险总公司: {{ dossier.赔案层.保险总公司 }}

-
+
+

赔案档案

+
+

+ 赔案编号: {{ dossier.report_layer.case_number }} | 保险分公司: + {{ dossier.report_layer.insurer_company }} | 报案时间: {{ + dossier.report_layer.report_time | DateTime }} +

+
-
+
-
+

影像件层

- + - - - - - + + + + - - - {% for image in dossier.影像件层 %} + + + {% for image in dossier.images_layer %} - - - - - + + + + {% endfor %} - +
影像件序号影像件名称已分类(含旋正)影像件类型已识别影像件唯一标识影像件编号影像件名称影像件类型
{{ image.影像件序号 }}{{ image.影像件名称 }}{{ image.已分类 }}{{ image.影像件类型 }}{{ image.已识别 }}{{ image.image_guid }}{{ image.image_index }}{{ image.image_name }}{{ image.image_type }}
-
+
-
+

赔案层

-
-

申请人信息

-
-
-
与被保险人关系
-
{{ dossier.赔案层.申请人信息.与被保险人关系 }}
-
-
-
姓名
-
{{ dossier.赔案层.申请人信息.姓名 }}
-
-
-
证件类型
-
{{ dossier.赔案层.申请人信息.证件类型 }}
-
-
-
证件号码
-
{{ dossier.赔案层.申请人信息.证件号码 }}
-
-
-
证件有效期
-
{{ dossier.赔案层.申请人信息.证件有效期起 | date }} 至 {{ - dossier.赔案层.申请人信息.证件有效期止 | date }} -
-
-
-
性别
-
{{ dossier.赔案层.申请人信息.性别 }}
-
-
-
出生
-
{{ dossier.赔案层.申请人信息.出生 | date }} | {{ - dossier.赔案层.申请人信息.年龄 }}岁 -
-
-
-
手机号
-
{{ dossier.赔案层.申请人信息.手机号 }}
-
-
-
住址
-
{{ dossier.赔案层.申请人信息.省 }} {{ dossier.赔案层.申请人信息.地 }} {{ - dossier.赔案层.申请人信息.县 }} -
-
{{ dossier.赔案层.申请人信息.详细地址 }}
-
+
+

出险人(被保险人)信息

+
+
+
姓名
+
+ {{ dossier.insured_person_layer.insured_person }}
-
+
+
+
证件类型
+
+ {{ dossier.insured_person_layer.identity_type }} +
+
+
+
证件号码
+
+ {{ dossier.insured_person_layer.identity_number }} +
+
+
+
证件有效期
+
+ {{ dossier.insured_person_layer.commencement_date | DateTime + }} 至 {{ dossier.insured_person_layer.termination_date | + DateTime }} +
+
+
+
性别
+
+ {{ dossier.insured_person_layer.gender }} +
+
-
-

受益人信息

-
-
-
与被保险人关系
-
{{ dossier.赔案层.受益人信息.与被保险人关系 }}
-
-
-
户名
-
{{ dossier.赔案层.受益人信息.户名 }}
-
-
-
开户银行
-
{{ dossier.赔案层.受益人信息.开户银行 }}
-
-
-
银行账号
-
{{ dossier.赔案层.受益人信息.银行账号 }}
-
+
+
出生
+
+ {{ dossier.insured_person_layer.birth_date | DateTime }} | {{ + dossier.insured_person_layer.age }}岁
+
+
+
手机号
+
+ {{ dossier.insured_person_layer.phone_number }} +
+
+
+
住址
+
+ {{ dossier.insured_person_layer.province }} {{ + dossier.insured_person_layer.city }} {{ + dossier.insured_person_layer.district }} +
+
+ {{ dossier.insured_person_layer.detailed_address }} +
+
-
-
+
-
-

发票层

- {% for invoice in dossier.发票层 %} -
-
-
-
{{ invoice.票据类型 }} | {{ invoice.票据号码 }}
- 关联影像件序号: {{ invoice.关联影像件序号 }} +
+

领款信息

+
+
+
户名
+
+ {{ dossier.insured_person_layer.account }}
-
- {% if invoice.查验状态 == '真票' %} - {{ invoice.查验状态 }} - {% elif invoice.查验状态 == '无法查验' %} - {{ invoice.查验状态 }} - {% else %} - {{ invoice.查验状态 }} - {% endif %} -
-
- -
-
-
就诊人
-
{{ invoice.就诊人 }}
-
-
-
票据代码
-
{{ invoice.票据代码 }}
-
-
-
校验码后六位
-
{{ invoice.校验码后六位 }}
-
-
-
开票日期
-
{{ invoice.开票日期 | date }}
-
-
-
票据金额
-
{{ invoice.票据金额 }}元
-
-
-
就诊类型
-
{{ invoice.就诊类型 }}
-
-
-
医药机构
-
{{ invoice.医药机构 }}
-
-
-
推定疾病
-
{{ invoice.推定疾病 }}
+
+
+
开户银行
+
+ {{ dossier.insured_person_layer.account_bank }}
+
+
+
户号
+
+ {{ dossier.insured_person_layer.account_number }} +
+
+
+
+

在保个单

- + - - - - + + + + + + + - - - {% for item in invoice.项目 %} + + + {% for liability in dossier.liabilities_layer %} - - - - + + + + + + + {% endfor %} - +
大项小项数量金额团单号保险分公司名称被保险人姓名主被保险人与主被保险人关系保险期理赔责任名称
{{ item.大项 }}{{ item.小项 }}{{ item.数量 }}{{ item.金额 }}元{{ liability.group_policy }}{{ liability.insurer_company }}{{ liability.insured_person }}{{ liability.master_insured_person }}{{ liability.relationship }} + {{ liability.commencement_date | DateTime }} 至 {{ + liability.termination_date | DateTime }} + {{ liability.liability }}
-
总金额: {{ invoice.票据金额 }}元
+
+
+
+ +
+

票据层

+ {% for receipt in dossier.receipts_layer %} +
+
+
+
{{ receipt.receipt_number }}
+ 关联影像件序号: {{ receipt.image_index }} +
+
+ {% if receipt.verification == '真票' %} + {{ receipt.verification }} + {% elif receipt.verification == '无法查验' %} + {{ receipt.verification }} + {% else %} + {{ receipt.verification }} + {% endif %} +
+
+ +
+
+
出险人
+
{{ receipt.payer }}
+
+
+
票据代码
+
{{ receipt.code }}
+
+
+
校验码后六位
+
{{ receipt.verification_code }}
+
+
+
开票日期
+
{{ receipt.date | DateTime }}
+
+
+
票据金额
+
{{ receipt.amount }}元
+
+
+
出险事故
+
{{ receipt.accident }}
+
+
+
购药及就医机构
+
+ {{ receipt.institution }} | {{ receipt.institution_type }} +
+
+
+
医疗诊断
+
{{ receipt.diagnosis }}
+
+
+ + + + + + + + + + + + {% for item in receipt.items %} + + + + + + + {% endfor %} + +
类别药品/医疗服务数量金额
{{ item.category }}{{ item.medicine }}{{ item.quantity }}{{ item.amount }}元
+ + + + + + + + + + + + {% for adjustment in receipt.adjustments %} + + + + + + + {% endfor %} + +
个人自费可理算金额个人自付可理算金额合理可理算金额理算金额
+ {{ adjustment.personal_self_adjustable_amount }} = {{ + adjustment.personal_self_payment }} * {{ + adjustment.personal_self_ratio }} % + + {{ adjustment.non_medical_adjustable_amount }} = {{ + adjustment.non_medical_payment }} * {{ + adjustment.non_medical_ratio }} % + + {{ adjustment.reasonable_adjustable_amount }} = {{ + adjustment.reasonable_amount }} * {{ + adjustment.reasonable_ratio }} % + {{ adjustment.adjustment_amount }}元
+
总金额: {{ receipt.amount }}元
{% endfor %} -
+
-
- - \ No newline at end of file + +
+ +