From 66ccb31413ef9bc9bb669db5267a8db77cf8ba29 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Mon, 23 Jun 2025 22:26:30 +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
---
.../property_accounts_receivable_views.xml | 13 +--
yuthon_property_approval/__manifest__.py | 1 +
.../models/inherit_yuthon_property.py | 96 ++++++++-----------
.../security/ir.model.access.csv | 1 +
.../views/inherit_yuthon_property_views.xml | 21 ++--
yuthon_property_approval/wizard/__init__.py | 3 +-
.../wizard/accounts_wizard.py | 86 +++++++++++++++++
.../wizard/accounts_wizard_views.xml | 29 ++++++
.../wizard/click_reconciliation_wizard.py | 13 ++-
9 files changed, 187 insertions(+), 76 deletions(-)
create mode 100644 yuthon_property_approval/wizard/accounts_wizard.py
create mode 100644 yuthon_property_approval/wizard/accounts_wizard_views.xml
diff --git a/yuthon_property/views/property_accounts_receivable_views.xml b/yuthon_property/views/property_accounts_receivable_views.xml
index f545ba841..201b889c6 100644
--- a/yuthon_property/views/property_accounts_receivable_views.xml
+++ b/yuthon_property/views/property_accounts_receivable_views.xml
@@ -9,11 +9,12 @@
-
-
-
-
+
+
+
+
+
@@ -31,10 +32,6 @@
-
-
-
-
diff --git a/yuthon_property_approval/__manifest__.py b/yuthon_property_approval/__manifest__.py
index ec934cd4e..4b6f3d30b 100644
--- a/yuthon_property_approval/__manifest__.py
+++ b/yuthon_property_approval/__manifest__.py
@@ -75,6 +75,7 @@
'wizard/property_reconciliation_wizard_views.xml',
'wizard/property_management_wizard.xml',
'wizard/click_reconciliation_wizard_views.xml',
+ 'wizard/accounts_wizard_views.xml',
'wizard/property_rental_wizard_views.xml',
'wizard/property_meeting_wizard_views.xml',
'views/property_menu_all.xml',
diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py
index 2cd7c7385..bb05c913f 100644
--- a/yuthon_property_approval/models/inherit_yuthon_property.py
+++ b/yuthon_property_approval/models/inherit_yuthon_property.py
@@ -300,7 +300,8 @@ class PropertyAccountsReceivable(models.Model):
('start_time', '<=', end_date),
])
if statements:
- receivable.payout_date = statements.start_time.date()
+ for statement in statements:
+ receivable.payout_date = statement.start_time.date()
else:
receivable.payout_date = receivable.due_date
@@ -348,43 +349,33 @@ class PropertyAccountsReceivable(models.Model):
penalty = days_difference * receivable.receivable_id.difference_amount
receivable.receivable_id.write({'penalty': penalty})
-
- def receivable_return(self):
- model_type_data = {
- '水费': 'property.water.list',
- '电费': 'property.tariff.list',
- '押金': 'property.deposit.list',
- '租金': 'property.rent.list'
- }
- for rec in self:
- model_type = model_type_data.get(rec.management_type_id.name)
- if model_type:
- model_id = self.env[model_type].search([('contract_id', '=', rec.contract_id.id)])
- if model_id:
- model_id.write({'is_push': False})
- # 银行流水对应的已对账改为未对账
- due_year = rec.due_date.year
- due_month = rec.due_date.month
- import calendar
- last_day = calendar.monthrange(due_year, due_month)[1]
-
- # 构建日期范围条件(使用正确的最后一天)
- start_date = f"{due_year}-{due_month:02d}-01"
- end_date = f"{due_year}-{due_month:02d}-{last_day}"
- # 搜索条件使用大于等于当月第一天,小于等于当月最后一天
- statements = self.env['property.bank.statements'].search([
- ('name_account', '=', rec.lessee_id.name),
- ('bank_state', '=', 'reconciled'),
- ('start_time', '>=', start_date),
- ('start_time', '<=', end_date),
- ])
- for statement in statements:
- statement.write({'bank_state': 'not_reconciled'})
- #删除原记录
- rec.unlink()
-
-
+ # 批量撤销
def batch_receivable_return(self):
+ archives_ids = self.env["property.accounts.receivable"].browse(
+ self._context.get('active_ids', self._context.get('active_id')))
+ for rec in archives_ids:
+ # 银行流水对应的已对账改为未对账
+ due_year = rec.due_date.year
+ due_month = rec.due_date.month
+ import calendar
+ last_day = calendar.monthrange(due_year, due_month)[1]
+
+ # 构建日期范围条件(使用正确的最后一天)
+ start_date = f"{due_year}-{due_month:02d}-01"
+ end_date = f"{due_year}-{due_month:02d}-{last_day}"
+ # 搜索条件使用大于等于当月第一天,小于等于当月最后一天
+ statements = self.env['property.bank.statements'].search([
+ ('name_account', '=', rec.lessee_id.name),
+ ('bank_state', '=', 'reconciled'),
+ ('start_time', '>=', start_date),
+ ('start_time', '<=', end_date),
+ ])
+ rec.is_reconciliation = False
+ for statement in statements:
+ statement.write({'bank_state': 'not_reconciled'})
+
+ # 批量退回
+ def action_refuse_all(self):
model_type_data = {
'水费': 'property.water.list',
'电费': 'property.tariff.list',
@@ -399,27 +390,20 @@ class PropertyAccountsReceivable(models.Model):
model_id = self.env[model_type].search([('contract_id', '=', rec.contract_id.id)])
if model_id:
model_id.write({'is_push': False})
- # 银行流水对应的已对账改为未对账
- due_year = rec.due_date.year
- due_month = rec.due_date.month
- import calendar
- last_day = calendar.monthrange(due_year, due_month)[1]
-
- # 构建日期范围条件(使用正确的最后一天)
- start_date = f"{due_year}-{due_month:02d}-01"
- end_date = f"{due_year}-{due_month:02d}-{last_day}"
- # 搜索条件使用大于等于当月第一天,小于等于当月最后一天
- statements = self.env['property.bank.statements'].search([
- ('name_account', '=', rec.lessee_id.name),
- ('bank_state', '=', 'reconciled'),
- ('start_time', '>=', start_date),
- ('start_time', '<=', end_date),
- ])
- for statement in statements:
- statement.write({'bank_state': 'not_reconciled'})
-
rec.unlink()
+ def button_accounts_wizard(self):
+ return {
+ "type": "ir.actions.act_window",
+ "name": "操作弹窗",
+ "res_model": "accounts.wizard",
+ "view_mode": "form",
+ "target": "new",
+ "context": {
+ "default_accounts_id": self.id
+ }
+ }
+
# 租金
class PropertyRentList(models.Model):
diff --git a/yuthon_property_approval/security/ir.model.access.csv b/yuthon_property_approval/security/ir.model.access.csv
index 9491d48b1..2ff3c8f56 100644
--- a/yuthon_property_approval/security/ir.model.access.csv
+++ b/yuthon_property_approval/security/ir.model.access.csv
@@ -98,4 +98,5 @@ access_property_management_line, property_management_line,model_property_managem
access_property_management_line2, property_management_line2,model_property_management_line2,base.group_user,1,1,1,1
access_property_management_wizard, property_management_wizard,model_property_management_wizard,base.group_user,1,1,1,1
access_click_reconciliation_wizard, click_reconciliation_wizard,model_click_reconciliation_wizard,base.group_user,1,1,1,1
+access_accounts_wizard, accounts_wizard,model_accounts_wizard,base.group_user,1,1,1,1
diff --git a/yuthon_property_approval/views/inherit_yuthon_property_views.xml b/yuthon_property_approval/views/inherit_yuthon_property_views.xml
index 6ed261383..7a1eaec77 100644
--- a/yuthon_property_approval/views/inherit_yuthon_property_views.xml
+++ b/yuthon_property_approval/views/inherit_yuthon_property_views.xml
@@ -373,18 +373,20 @@
[('is_push', '=', False)]
-
+
property.accounts.receivable.tree
property.accounts.receivable
+
+
+
-
@@ -393,9 +395,9 @@
property.accounts.receivable
-
-
-
+
@@ -562,12 +564,19 @@
action = model.all_penalty_date()
- 批量退回
+ 批量撤销
code
action = model.batch_receivable_return()
+
+ 批量退回
+
+
+ code
+ action = model.action_refuse_all()
+
property.bank.statements.tree
diff --git a/yuthon_property_approval/wizard/__init__.py b/yuthon_property_approval/wizard/__init__.py
index 41ae25d99..1ae37ba92 100644
--- a/yuthon_property_approval/wizard/__init__.py
+++ b/yuthon_property_approval/wizard/__init__.py
@@ -6,4 +6,5 @@ from . import property_physical_wizard
from . import property_reconciliation_wizard
from . import property_meeting_wizard
from . import property_management_wizard
-from . import click_reconciliation_wizard
\ No newline at end of file
+from . import click_reconciliation_wizard
+from . import accounts_wizard
\ No newline at end of file
diff --git a/yuthon_property_approval/wizard/accounts_wizard.py b/yuthon_property_approval/wizard/accounts_wizard.py
new file mode 100644
index 000000000..514df3db7
--- /dev/null
+++ b/yuthon_property_approval/wizard/accounts_wizard.py
@@ -0,0 +1,86 @@
+from odoo import models, fields, api, _, SUPERUSER_ID
+from datetime import datetime, timedelta
+from dateutil.relativedelta import relativedelta
+
+
+class AccountsWizard(models.Model):
+ _name = 'accounts.wizard'
+
+ accounts_id = fields.Many2one('property.accounts.receivable', string='对账单')
+
+ def invalid(self):
+ receivable_log = (f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.accounts_id.property_id.name}的应收账单状态修改为作废')
+ for record in self.accounts_id:
+ original_log = record.receivable_log or ''
+ if original_log:
+ new_log = f"{original_log}\n{receivable_log}"
+ else:
+ new_log = receivable_log
+ return self.accounts_id.write({'is_invalid': True,
+ 'receivable_log': new_log
+ })
+
+ # 激活
+ def suspend(self):
+ receivable_log = (
+ f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.accounts_id.property_id.name}的应收账单挂起')
+ for record in self.accounts_id:
+ original_log = record.receivable_log or ''
+ if original_log:
+ new_log = f"{original_log}\n{receivable_log}"
+ else:
+ new_log = receivable_log
+ return self.accounts_id.write({'is_suspend': False,'receivable_log': new_log})
+
+ # 挂起
+ def unsuspend(self):
+ receivable_log = (
+ f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.accounts_id.property_id.name}的应收账单取消挂起')
+ for record in self.accounts_id:
+ original_log = record.receivable_log or ''
+ if original_log:
+ new_log = f"{original_log}\n{receivable_log}"
+ else:
+ new_log = receivable_log
+ return self.accounts_id.write({'is_suspend': True,
+ 'receivable_log':new_log
+ })
+
+ # 撤销
+ def receivable_return(self):
+ for rec in self.accounts_id:
+ # 银行流水对应的已对账改为未对账
+ due_year = rec.due_date.year
+ due_month = rec.due_date.month
+ import calendar
+ last_day = calendar.monthrange(due_year, due_month)[1]
+
+ # 构建日期范围条件(使用正确的最后一天)
+ start_date = f"{due_year}-{due_month:02d}-01"
+ end_date = f"{due_year}-{due_month:02d}-{last_day}"
+ # 搜索条件使用大于等于当月第一天,小于等于当月最后一天
+ statements = self.env['property.bank.statements'].search([
+ ('name_account', '=', rec.lessee_id.name),
+ ('bank_state', '=', 'reconciled'),
+ ('start_time', '>=', start_date),
+ ('start_time', '<=', end_date),
+ ])
+ rec.is_reconciliation = False
+ for statement in statements:
+ statement.write({'bank_state': 'not_reconciled'})
+
+ # 退回
+ def action_refuse(self):
+ model_type_data = {
+ '水费': 'property.water.list',
+ '电费': 'property.tariff.list',
+ '押金': 'property.deposit.list',
+ '租金': 'property.rent.list'
+ }
+ for rec in self.accounts_id:
+ model_type = model_type_data.get(rec.management_type_id.name)
+ if model_type:
+ model_id = self.env[model_type].search([('contract_id', '=', rec.contract_id.id)])
+ if model_id:
+ model_id.write({'is_push': False})
+ rec.unlink()
diff --git a/yuthon_property_approval/wizard/accounts_wizard_views.xml b/yuthon_property_approval/wizard/accounts_wizard_views.xml
new file mode 100644
index 000000000..1212c773b
--- /dev/null
+++ b/yuthon_property_approval/wizard/accounts_wizard_views.xml
@@ -0,0 +1,29 @@
+
+
+
+ 应收对账操作
+ accounts.wizard
+
+
+
+
+
\ No newline at end of file
diff --git a/yuthon_property_approval/wizard/click_reconciliation_wizard.py b/yuthon_property_approval/wizard/click_reconciliation_wizard.py
index 2bf33e7de..88dccf0e3 100644
--- a/yuthon_property_approval/wizard/click_reconciliation_wizard.py
+++ b/yuthon_property_approval/wizard/click_reconciliation_wizard.py
@@ -9,13 +9,16 @@ class ClickReconciliationWizard(models.Model):
message = fields.Text(string='确认信息', readonly=True)
def action_confirm(self):
- statements_ids = self.env["property.bank.statements"].search([('bank_state', '=', 'not_reconciled')])
- contracts = self.env["property.accounts.receivable"].search([
- ('is_reconciliation', '=', False)
+ unreconciled_contract_ids = self.env["property.accounts.receivable"].search([
+ ('is_reconciliation', '=', False),
+ ]).mapped('contract_id')
+ # 直接查询符合条件的对账单
+ statements_ids = self.env["property.bank.statements"].search([
+ ('bank_state', '=', 'not_reconciled'),
+ ('contract_ids', 'in', unreconciled_contract_ids.ids if unreconciled_contract_ids else [])
])
- contract_ids = contracts.mapped('contract_id')
# 只处理合同ID存在于应收账款合同中的对账单记录
- for record in statements_ids.filtered(lambda r: r.contract_id in contract_ids):
+ for record in statements_ids:
all_vals, total_rent_month = record._get_reconciliation_vals(record)
# 更新对账状态
if total_rent_month == record.original_amount: