From a31591db253529ccff5c4ae68884423771c7e696 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?=
<9664676+pengyuthon@user.noreply.gitee.com>
Date: Sat, 29 Nov 2025 16:31:20 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
yuthon_account_report/data/account_task.xml | 29 +++
.../models/financial_sheet_collection.py | 37 ++-
.../models/information_summary_table.py | 33 ++-
.../security/ir.model.access.csv | 2 +
.../financial_sheet_collection_views.xml | 46 +++-
.../views/information_summary_table_views.xml | 42 +++-
.../wizard/property_reconciliation_wizard.py | 212 +++++++++---------
yuthon_work_brand/views/hr_menus.xml | 10 +
8 files changed, 293 insertions(+), 118 deletions(-)
create mode 100644 yuthon_account_report/data/account_task.xml
diff --git a/yuthon_account_report/data/account_task.xml b/yuthon_account_report/data/account_task.xml
new file mode 100644
index 000000000..6e422a6a5
--- /dev/null
+++ b/yuthon_account_report/data/account_task.xml
@@ -0,0 +1,29 @@
+
+
+
+ 定时任务:财务数据表
+
+ code
+ model.account_task()
+
+
+ 1
+ weeks
+
+ -1
+
+
+
+ 定时任务:信息汇总表
+
+ code
+ model.account_task()
+
+
+ 1
+ months
+
+ -1
+
+
+
\ No newline at end of file
diff --git a/yuthon_account_report/models/financial_sheet_collection.py b/yuthon_account_report/models/financial_sheet_collection.py
index 577e44068..b8a68a295 100644
--- a/yuthon_account_report/models/financial_sheet_collection.py
+++ b/yuthon_account_report/models/financial_sheet_collection.py
@@ -5,14 +5,47 @@ class FinancialSheetCollection(models.Model):
_name = 'financial.sheet.collection'
_description = '财务数据表收集'
- collection_id = fields.Many2one('sheet.collection.setting', string='项目名称')
employee_id = fields.Many2one('hr.employee', string='人员')
company_id = fields.Many2one('res.company', string='公司')
department_id = fields.Many2one('hr.department', string="部门")
user_role_id = fields.Many2one('soong.user.role', string="角色")
+ create_date = fields.Datetime(string='创建日期', default=fields.Datetime.now)
+ account_type = fields.Selection([('to', '待确认',), ('ok', '已确认')], string='状态', default='to')
+ sheet_line_ids = fields.One2many('financial.sheet.line', 'sheet_id', string='财务数据表行')
+
+ def open_record(self):
+ return {
+ "type": "ir.actions.act_window",
+ "res_model": 'financial.sheet.collection',
+ "res_id": self.id,
+ "name": "详情",
+ "view_mode": "form",
+ }
+
+ def button_put(self):
+ menu_id = self.env['ir.ui.menu'].search([('name', '=', '财务数据表收集')])
+ for record in self.search([('account_type', '=', 'to')]):
+ url = f'https://oa.thtzjt.com/web#id={self.id}&cids=2&action={menu_id.action.id}&model=financial.sheet.collection&view_type=list&menu_id={menu_id.id}'
+ self.sudo().env["wecom.apps"].sync_send_message_textcard(category='notice',
+ user_id=record.employee_id.wecom_userid,
+ title="财务数据表",
+ description="您有待确认的财务数据表请尽快确认",
+ url=url, btntxt="详细信息")
+ record.account_type = 'ok'
+
+ def account_task(self):
+ pass
+
+
+class FinancialSheetLine(models.Model):
+ _name = 'financial.sheet.line'
+ _description = '财务数据表行'
+
+ sheet_id = fields.Many2one('financial.sheet.collection', string='关联财务数据表')
+ collection_id = fields.Many2one('sheet.collection.setting', string='项目名称')
this_issue_number = fields.Integer(string='本期数')
same_last_year = fields.Integer(string='上年同期数')
remake = fields.Text(string='说明')
- create_date = fields.Datetime(string='创建日期', default=fields.Datetime.now)
+
diff --git a/yuthon_account_report/models/information_summary_table.py b/yuthon_account_report/models/information_summary_table.py
index 6a6e9acdf..197104fde 100644
--- a/yuthon_account_report/models/information_summary_table.py
+++ b/yuthon_account_report/models/information_summary_table.py
@@ -7,10 +7,39 @@ class InformationSummaryTable(models.Model):
_name = 'information.summary.table'
_description = '信息汇总表收集'
- table_id = fields.Many2one('summary.table.setting', string='项目名称')
- this_year = fields.Float(string='本年底')
employee_id = fields.Many2one('hr.employee', string='人员')
company_id = fields.Many2one('res.company', string='公司')
department_id = fields.Many2one('hr.department', string="部门")
user_role_id = fields.Many2one('soong.user.role', string="角色")
+ account_type = fields.Selection([('to', '待确认', ), ('ok', '已确认')], string='状态', default='to')
+ summary_line = fields.One2many('information.summary.line', 'summary_id', string='汇总表')
+
+ def open_record(self):
+ return {
+ "type": "ir.actions.act_window",
+ "res_model": 'information.summary.table',
+ "res_id": self.id,
+ "name": "详情",
+ "view_mode": "form",
+ }
+
+ def button_put(self):
+ menu_id = self.env['ir.ui.menu'].search([('name', '=', '信息汇总表收集')])
+ for record in self.search([('account_type', '=', 'to')]):
+ url = f'https://oa.thtzjt.com/web#id={self.id}&cids=2&action={menu_id.action.id}&model=information.summary.table&view_type=list&menu_id={menu_id.id}'
+ self.sudo().env["wecom.apps"].sync_send_message_textcard(category='notice', user_id=record.employee_id.wecom_userid, title="信息汇总表",
+ description="您有待确认的信息汇总表请尽快确认", url=url, btntxt="详细信息")
+ record.account_type = 'ok'
+
+ def account_task(self):
+ pass
+
+
+class InformationSummaryLine(models.Model):
+ _name = 'information.summary.line'
+ _description = '信息汇总表明细'
+
+ summary_id = fields.Many2one('information.summary.table', string='关联汇总表')
+ table_id = fields.Many2one('summary.table.setting', string='项目名称')
+ this_year = fields.Float(string='本年底')
remake = fields.Text(string='说明')
diff --git a/yuthon_account_report/security/ir.model.access.csv b/yuthon_account_report/security/ir.model.access.csv
index abe2a92c1..aba3fd29e 100644
--- a/yuthon_account_report/security/ir.model.access.csv
+++ b/yuthon_account_report/security/ir.model.access.csv
@@ -3,3 +3,5 @@ access_financial_sheet_collection,financial_sheet_collection,model_financial_she
access_summary_table_setting,summary_table_setting,model_summary_table_setting,base.group_system,1,1,1,1
access_information_summary_table,information_summary_table,model_information_summary_table,base.group_system,1,1,1,1
access_sheet_collection_setting,sheet_collection_setting,model_sheet_collection_setting,base.group_system,1,1,1,1
+access_financial_sheet_line,financial_sheet_line,model_financial_sheet_line,base.group_system,1,1,1,1
+access_information_summary_line,information_summary_line,model_information_summary_line,base.group_system,1,1,1,1
\ No newline at end of file
diff --git a/yuthon_account_report/views/financial_sheet_collection_views.xml b/yuthon_account_report/views/financial_sheet_collection_views.xml
index 22817587e..8574f6259 100644
--- a/yuthon_account_report/views/financial_sheet_collection_views.xml
+++ b/yuthon_account_report/views/financial_sheet_collection_views.xml
@@ -5,22 +5,58 @@
financial.sheet.collection
-
-
-
-
+
+
+
+
+ financial.sheet.collection.form
+ financial.sheet.collection
+
+
+
+
财务数据表收集
financial.sheet.collection
- tree
+ tree,form
diff --git a/yuthon_account_report/views/information_summary_table_views.xml b/yuthon_account_report/views/information_summary_table_views.xml
index bd76792ee..4a860606b 100644
--- a/yuthon_account_report/views/information_summary_table_views.xml
+++ b/yuthon_account_report/views/information_summary_table_views.xml
@@ -5,16 +5,52 @@
information.summary.table
-
-
-
+
+
+
+
+ information.summary.table.form
+ information.summary.table
+
+
+
+
信息汇总表
information.summary.table
diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
index 3fdae2909..41c959351 100644
--- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py
+++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
@@ -249,115 +249,115 @@ class PropertyReconciliationWizard(models.Model):
total = sum(line.rent for line in self.reconciliation_line_ids)
self.receivable_total = total
- all_due_dates = []
- for line in self.reconciliation_line_ids:
- if line.collection_type == 'rent' and line.due_date:
- all_due_dates.append(fields.Date.from_string(line.due_date))
- # 2. 找到最早的到期日期
- if all_due_dates:
- earliest_due_date = min(all_due_dates)
- # 获取实际日期(假设actual_date是日期对象,如果是字符串需要先转换)
- actual_date = fields.Date.from_string(self.actual_date) if isinstance(self.actual_date,
- str) else self.actual_date
-
- # 计算起始月份(最早到期日的月份)和结束月份(实际日期的月份)
- start_month = earliest_due_date + relativedelta(months=1)
- end_month = actual_date - relativedelta(months=1)
-
- temp_rent_set = set()
- target_rent_months = []
-
- # 遍历从起始月到结束月的所有月份
- current_month = start_month
- while current_month <= end_month:
- due_month = current_month.strftime('%Y-%m')
- # 为每个租金行添加当前月份的记录(去重)
- for line in self.reconciliation_line_ids:
- if line.collection_type == 'rent':
- unique_key = (
- line.contract_id.id if line.contract_id else None,
- due_month
- )
- if unique_key not in temp_rent_set:
- temp_rent_set.add(unique_key)
- target_rent_months.append({
- 'contract_id': line.contract_id,
- 'due_month': due_month
- })
- # 移动到下个月
- if current_month.month == 12:
- current_month = current_month.replace(year=current_month.year + 1, month=1, day=1)
- else:
- current_month = current_month.replace(month=current_month.month + 1, day=1)
- else:
+ # all_due_dates = []
+ # for line in self.reconciliation_line_ids:
+ # if line.collection_type == 'rent' and line.due_date:
+ # all_due_dates.append(fields.Date.from_string(line.due_date))
+ # # 2. 找到最早的到期日期
+ # if all_due_dates:
+ # earliest_due_date = min(all_due_dates)
+ # # 获取实际日期(假设actual_date是日期对象,如果是字符串需要先转换)
+ # actual_date = fields.Date.from_string(self.actual_date) if isinstance(self.actual_date,
+ # str) else self.actual_date
+ #
+ # # 计算起始月份(最早到期日的月份)和结束月份(实际日期的月份)
+ # start_month = earliest_due_date + relativedelta(months=1)
+ # end_month = actual_date - relativedelta(months=1)
+ #
+ # temp_rent_set = set()
+ # target_rent_months = []
+ #
+ # # 遍历从起始月到结束月的所有月份
+ # current_month = start_month
+ # while current_month <= end_month:
+ # due_month = current_month.strftime('%Y-%m')
+ # # 为每个租金行添加当前月份的记录(去重)
+ # for line in self.reconciliation_line_ids:
+ # if line.collection_type == 'rent':
+ # unique_key = (
+ # line.contract_id.id if line.contract_id else None,
+ # due_month
+ # )
+ # if unique_key not in temp_rent_set:
+ # temp_rent_set.add(unique_key)
+ # target_rent_months.append({
+ # 'contract_id': line.contract_id,
+ # 'due_month': due_month
+ # })
+ # # 移动到下个月
+ # if current_month.month == 12:
+ # current_month = current_month.replace(year=current_month.year + 1, month=1, day=1)
+ # else:
+ # current_month = current_month.replace(month=current_month.month + 1, day=1)
+ # else:
# 没有符合条件的明细行时,返回空列表
target_rent_months = []
- if target_rent_months:
- existing_penalty_months = set()
- for line in self.reconciliation_line_ids:
- if line.collection_type == 'penalty' and line.due_date:
- penalty_month = fields.Date.from_string(line.due_date).strftime('%Y-%m')
- penalty_key = (
- line.contract_id.id if line.contract_id else None,
- penalty_month
- )
- existing_penalty_months.add(penalty_key)
-
- # # 3. 补全缺失的跨月违约金(按合同+年月匹配,缺失则新增)
- # missing_penalty_lines = []
- # for rent_info in target_rent_months:
- # contract = rent_info['contract_id']
- # due_month = rent_info['due_month']
- #
- # # 构建待检查的违约金key(合同+年月)
- # check_key = (
- # contract.id if contract else None,
- # due_month
- # )
- #
- # if check_key not in existing_penalty_months:
- # year, month = map(int, due_month.split('-'))
- # first_day = datetime(year, month, 1).date()
- # penalty_days = (self.actual_date - first_day).days + 1
- #
- # # 计算补全违约金的日期范围:当月1号 ~ 当月最后1天
- # # 查找上个月的租金明细行
- # if month == 1:
- # last_month_year = year - 1
- # last_month = 12
- # else:
- # last_month_year = year
- # last_month = month - 1
- # last_month_str = f"{last_month_year}-{last_month:02d}"
- #
- # last_month_rent_line = next((
- # line for line in self.reconciliation_line_ids
- # if line.collection_type == 'rent'
- # and line.contract_id == contract
- # and line.due_date # 有到期日期
- # and fields.Date.from_string(line.due_date).strftime('%Y-%m') == last_month_str
- # ), None)
- # # 提取上个月租金的rent金额
- # last_month_rent = last_month_rent_line.rent if last_month_rent_line else 0.0
- # penalty_amount = penalty_days * round(
- # last_month_rent * float(contract.percentage_liquidated_damages.name), 2
- # ) if (contract and last_month_rent > 0) else 0.0
- #
- # if penalty_amount > 0:
- # missing_penalty_lines.append((0, 0, {
- # 'contract_id': contract.id if contract else None,
- # 'rent_month': 0,
- # 'due_date': fields.Date.to_string(first_day),
- # 'rent': penalty_amount,
- # 'amount': 0,
- # 'collection_type': 'penalty',
- # 'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(self.actual_date)},共{penalty_days}天',
- # }))
- #
- # # 添加缺失的违约金记录
- # if missing_penalty_lines:
- # self.write({'reconciliation_line_ids': missing_penalty_lines})
+ # if target_rent_months:
+ # existing_penalty_months = set()
+ # for line in self.reconciliation_line_ids:
+ # if line.collection_type == 'penalty' and line.due_date:
+ # penalty_month = fields.Date.from_string(line.due_date).strftime('%Y-%m')
+ # penalty_key = (
+ # line.contract_id.id if line.contract_id else None,
+ # penalty_month
+ # )
+ # existing_penalty_months.add(penalty_key)
+ #
+ # # # 3. 补全缺失的跨月违约金(按合同+年月匹配,缺失则新增)
+ # # missing_penalty_lines = []
+ # # for rent_info in target_rent_months:
+ # # contract = rent_info['contract_id']
+ # # due_month = rent_info['due_month']
+ # #
+ # # # 构建待检查的违约金key(合同+年月)
+ # # check_key = (
+ # # contract.id if contract else None,
+ # # due_month
+ # # )
+ # #
+ # # if check_key not in existing_penalty_months:
+ # # year, month = map(int, due_month.split('-'))
+ # # first_day = datetime(year, month, 1).date()
+ # # penalty_days = (self.actual_date - first_day).days + 1
+ # #
+ # # # 计算补全违约金的日期范围:当月1号 ~ 当月最后1天
+ # # # 查找上个月的租金明细行
+ # # if month == 1:
+ # # last_month_year = year - 1
+ # # last_month = 12
+ # # else:
+ # # last_month_year = year
+ # # last_month = month - 1
+ # # last_month_str = f"{last_month_year}-{last_month:02d}"
+ # #
+ # # last_month_rent_line = next((
+ # # line for line in self.reconciliation_line_ids
+ # # if line.collection_type == 'rent'
+ # # and line.contract_id == contract
+ # # and line.due_date # 有到期日期
+ # # and fields.Date.from_string(line.due_date).strftime('%Y-%m') == last_month_str
+ # # ), None)
+ # # # 提取上个月租金的rent金额
+ # # last_month_rent = last_month_rent_line.rent if last_month_rent_line else 0.0
+ # # penalty_amount = penalty_days * round(
+ # # last_month_rent * float(contract.percentage_liquidated_damages.name), 2
+ # # ) if (contract and last_month_rent > 0) else 0.0
+ # #
+ # # if penalty_amount > 0:
+ # # missing_penalty_lines.append((0, 0, {
+ # # 'contract_id': contract.id if contract else None,
+ # # 'rent_month': 0,
+ # # 'due_date': fields.Date.to_string(first_day),
+ # # 'rent': penalty_amount,
+ # # 'amount': 0,
+ # # 'collection_type': 'penalty',
+ # # 'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(self.actual_date)},共{penalty_days}天',
+ # # }))
+ # #
+ # # # 添加缺失的违约金记录
+ # # if missing_penalty_lines:
+ # # self.write({'reconciliation_line_ids': missing_penalty_lines})
self.create_reconciliation_vals()
line_types = []
diff --git a/yuthon_work_brand/views/hr_menus.xml b/yuthon_work_brand/views/hr_menus.xml
index f0f8cdcb3..81a9560a1 100644
--- a/yuthon_work_brand/views/hr_menus.xml
+++ b/yuthon_work_brand/views/hr_menus.xml
@@ -797,6 +797,16 @@
parent="yuthon_account_report"
action="yuthon_account_report.information_summary_table_action"
sequence="5"/>
+
+