From 4af434af721834cdbe80e6951760ecac3713b533 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: Tue, 14 Apr 2026 17:14:35 +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_property_approval/__manifest__.py | 1 +
.../models/property_bills_list.py | 6 ++
.../models/property_lease_contract.py | 22 ++++
.../models/property_lease_renewal.py | 2 +
.../security/ir.model.access.csv | 5 +-
.../views/property_bills_list_views.xml | 8 ++
.../views/property_lease_contract.xml | 8 ++
yuthon_property_approval/wizard/__init__.py | 3 +-
.../wizard/refund_wizard.py | 102 ++++++++++++++++++
.../wizard/refund_wizard_views.xml | 32 ++++++
10 files changed, 187 insertions(+), 2 deletions(-)
create mode 100644 yuthon_property_approval/wizard/refund_wizard.py
create mode 100644 yuthon_property_approval/wizard/refund_wizard_views.xml
diff --git a/yuthon_property_approval/__manifest__.py b/yuthon_property_approval/__manifest__.py
index 638b6376d..8523f90bf 100644
--- a/yuthon_property_approval/__manifest__.py
+++ b/yuthon_property_approval/__manifest__.py
@@ -96,6 +96,7 @@
'wizard/property_reconciliation_wizard_views.xml',
'wizard/property_management_wizard.xml',
'wizard/click_reconciliation_wizard_views.xml',
+ 'wizard/refund_wizard_views.xml',
'wizard/print_payment_wizard_views.xml',
'wizard/accounts_wizard_views.xml',
'wizard/binding_information_wizard_views.xml',
diff --git a/yuthon_property_approval/models/property_bills_list.py b/yuthon_property_approval/models/property_bills_list.py
index 2c6d0bfef..15c87a2bf 100644
--- a/yuthon_property_approval/models/property_bills_list.py
+++ b/yuthon_property_approval/models/property_bills_list.py
@@ -13,12 +13,18 @@ class PropertyBillsList(models.Model):
amount_actual = fields.Float(string='实付')
receivables_id = fields.Many2one('property.accounts.receivable', string='应收账单')
contract_id = fields.Many2one('property.lease.contract', string="合同编号")
+ lessor_id = fields.Many2one('yuthon.property.company', string="支付公司")
lessee_id = fields.Many2one(related="contract_id.lessee_id", string="承租方", store=True)
property_name = fields.Char(related='contract_id.property_name', string="物业信息")
workflow_record_id = fields.Many2one('soong.workflow.record', string="流程")
fee_id = fields.Many2one('property.fee.form', string="费用")
remake = fields.Text(string="备注")
+ def update_lessor_id(self):
+ for record in self:
+ if record.contract_id:
+ record.lessor_id = record.contract_id.lessor_id.id
+
def open_record(self):
return {
"type": "ir.actions.act_window",
diff --git a/yuthon_property_approval/models/property_lease_contract.py b/yuthon_property_approval/models/property_lease_contract.py
index 49990cdaa..f865ff138 100644
--- a/yuthon_property_approval/models/property_lease_contract.py
+++ b/yuthon_property_approval/models/property_lease_contract.py
@@ -330,6 +330,27 @@ class PropertyLeaseContract(models.Model):
employee_ids = fields.Many2many('hr.employee', string="当前经办人", compute='_compute_workflow')
approve_state = fields.Selection([("start", "草稿"), ("pending", "审批中"), ("end", "结束")], string="审批状态", compute='_compute_workflow')
+ def refund_wizard(self):
+ contract_ids = self.env["property.lease.contract"].browse(
+ self._context.get('active_ids', [])
+ )
+ line_vals = []
+ for contract in contract_ids:
+ line_vals.append((0, 0, {
+ 'contract_id': contract.id,
+ }))
+ wizard = self.env['refund.wizard'].create({
+ 'refund_line_ids': line_vals,
+ })
+ return {
+ 'type': 'ir.actions.act_window',
+ 'name': '批量退押',
+ 'res_model': 'refund.wizard',
+ 'view_mode': 'form',
+ 'res_id': wizard.id,
+ 'target': 'new',
+ }
+
def update_lessor_line(self):
contract_ids = self.env["property.lease.contract"].browse(
self._context.get('active_ids', self._context.get('active_id')))
@@ -855,6 +876,7 @@ class PropertyLeaseContract(models.Model):
[("res_model", "=", self._name), ("res_id", "=", self.id)])
if not bills_list:
self.env['property.bills.list'].create({
+ 'lessor_id': self.contract_id.lessor_id.id,
'due_date': self.contract_id.actual_end_time + timedelta(days=1), # 原合同
'management_type_id': management_type_id.id,
'amount': self.contract_id.deposit,
diff --git a/yuthon_property_approval/models/property_lease_renewal.py b/yuthon_property_approval/models/property_lease_renewal.py
index 880bf0d0c..e552303f2 100644
--- a/yuthon_property_approval/models/property_lease_renewal.py
+++ b/yuthon_property_approval/models/property_lease_renewal.py
@@ -256,6 +256,7 @@ class PropertyLeaseRenewal(models.Model):
if refund_lines:
for refund_line in refund_lines:
bills_line_list.append({
+ 'lessor_id': rec.contract_id.lessor_id.id,
'due_date': fields.Date.today(),
'management_type_id': refund_line.management_type_id.id,
'amount': refund_line.refund_amount,
@@ -271,6 +272,7 @@ class PropertyLeaseRenewal(models.Model):
deposit_amount = rec.deposit if rec.is_full_refund else rec.refund_amount
if deposit_amount > 0:
bills_line_list.append({
+ 'lessor_id': rec.contract_id.lessor_id.id,
'due_date': fields.Date.today(),
'management_type_id': deposit_management_type.id,
'amount': deposit_amount,
diff --git a/yuthon_property_approval/security/ir.model.access.csv b/yuthon_property_approval/security/ir.model.access.csv
index 24fb7a2d8..b085ab4aa 100644
--- a/yuthon_property_approval/security/ir.model.access.csv
+++ b/yuthon_property_approval/security/ir.model.access.csv
@@ -137,4 +137,7 @@ access_choose_confirm_property_wizard,choose_confirm_property_wizard,model_choos
access_lessee_alteration_line,lessee.alteration.line,model_lessee_alteration_line,base.group_user,1,1,1,1
access_lessor_alteration_line,lessor.alteration.line,model_lessor_alteration_line,base.group_user,1,1,1,1
access_property_fee_form,property_fee_form,model_property_fee_form,base.group_user,1,1,1,1
-access_property_fee_form_line,property_fee_form_line,model_property_fee_form_line,base.group_user,1,1,1,1
\ No newline at end of file
+access_property_fee_form_line,property_fee_form_line,model_property_fee_form_line,base.group_user,1,1,1,1
+
+access_refund_wizard,refund_wizard,model_refund_wizard,base.group_user,1,1,1,1
+access_refund_wizard_line,refund_wizard_line,model_refund_wizard_line,base.group_user,1,1,1,1
\ No newline at end of file
diff --git a/yuthon_property_approval/views/property_bills_list_views.xml b/yuthon_property_approval/views/property_bills_list_views.xml
index b4e083e91..49a89742b 100644
--- a/yuthon_property_approval/views/property_bills_list_views.xml
+++ b/yuthon_property_approval/views/property_bills_list_views.xml
@@ -13,6 +13,7 @@
+
@@ -28,6 +29,13 @@
property.bills.list
tree
+
+ 更新支付公司
+
+
+ code
+ action = model.update_lessor_id()
+
diff --git a/yuthon_property_approval/views/property_lease_contract.xml b/yuthon_property_approval/views/property_lease_contract.xml
index e43b9db80..b6d43e6a5 100644
--- a/yuthon_property_approval/views/property_lease_contract.xml
+++ b/yuthon_property_approval/views/property_lease_contract.xml
@@ -1202,6 +1202,14 @@
code
action = model.set_actual_time_to_contract_time()
+
+ 批量退押(管理员)
+
+
+ code
+ action = model.refund_wizard()
+
+
同步物业合同信息
diff --git a/yuthon_property_approval/wizard/__init__.py b/yuthon_property_approval/wizard/__init__.py
index 971eca0f7..acb43fd48 100644
--- a/yuthon_property_approval/wizard/__init__.py
+++ b/yuthon_property_approval/wizard/__init__.py
@@ -17,4 +17,5 @@ from . import property_bills_wizard
from . import action_refuse_wizard
from . import property_deposit_wizard
from . import build_fee_wizard
-from . import choose_confirm_property_wizard
\ No newline at end of file
+from . import choose_confirm_property_wizard
+from . import refund_wizard
\ No newline at end of file
diff --git a/yuthon_property_approval/wizard/refund_wizard.py b/yuthon_property_approval/wizard/refund_wizard.py
new file mode 100644
index 000000000..a3f0e7e68
--- /dev/null
+++ b/yuthon_property_approval/wizard/refund_wizard.py
@@ -0,0 +1,102 @@
+from odoo import models, fields, api, _, SUPERUSER_ID
+from datetime import datetime, timedelta
+from dateutil.relativedelta import relativedelta
+from datetime import datetime, timedelta, date
+
+
+class RefundWizard(models.TransientModel):
+ _name = 'refund.wizard'
+ _description = '批量退押'
+
+ refund_type = fields.Selection([('out','外退'),('in','内退')],string='退押类型',default='out')
+ refund_line_ids = fields.One2many('refund.wizard.line','refund_id',string='退押明细')
+ start_index = fields.Date(string='生效时间', default=fields.Date.today())
+
+ def confirm(self):
+ deposit_management_type = self.env['yuthon.management.type'].search([('name', '=', '押金')], limit=1)
+ if self.refund_type == 'out':
+ bills_line_list = []
+ for line in self.refund_line_ids:
+ existing_bill = self.env['property.bills.list'].search([
+ ('contract_id', '=', line.contract_id.id),
+ ('due_date', '=', self.start_index),
+ ('management_type_id', '=', deposit_management_type.id),
+ ], limit=1)
+ if existing_bill:
+ continue
+ bills_line_list.append({
+ 'lessor_id': line.contract_id.lessor_id.id,
+ 'due_date': self.start_index,
+ 'management_type_id': deposit_management_type.id,
+ 'amount': line.deposit,
+ 'contract_id': line.contract_id.id,
+ })
+ if bills_line_list:
+ self.env['property.bills.list'].create(bills_line_list)
+
+ elif self.refund_type == 'in':
+ for line in self.refund_line_ids:
+ lessor_id = line.contract_id.lessor_id
+ company_id = self.env['res.company'].search([('name', '=', '集团本部')], limit=1)
+
+ if lessor_id.referred in ['天河投资', '天投城建']:
+ company_id = self.env['res.company'].search([('name', '=', '集团本部')], limit=1)
+ elif lessor_id.referred in ['天河物管']:
+ company_id = self.env['res.company'].search([('name', '=', '天河物管')], limit=1)
+ elif lessor_id.referred in ['天河粮储']:
+ company_id = self.env['res.company'].search([('name', '=', '天河粮储')], limit=1)
+
+ bank_accounts = self.env['property.bank.line'].search([
+ ('tenant_id', '=', line.lessee_id.id)
+ ]).mapped('bank')
+ bank_accounts = [acc for acc in bank_accounts if acc]
+ bank_account = bank_accounts[0] if bank_accounts else False
+
+ existing_receivable = self.env['property.accounts.receivable'].search([
+ ('contract_id', '=', line.contract_id.id),
+ ('management_type_id', '=', deposit_management_type.id),
+ ('due_date', '=', self.start_index),
+ ('original_amount', '=', line.deposit),
+ ('remark', '=', '出租方变更调整'),
+ ], limit=1)
+ if not existing_receivable:
+ self.env['property.accounts.receivable'].create({
+ 'contract_id': line.contract_id.id,
+ 'management_type_id': deposit_management_type.id,
+ 'due_date': self.start_index,
+ 'original_amount': line.deposit,
+ 'remark': '出租方变更调整',
+ })
+ existing_bank_statement = self.env['property.bank.statements'].sudo().search([
+ ('start_time', '=', self.start_index),
+ ('original_amount', '=', line.deposit),
+ ('name_account', '=', line.lessee_id.name),
+ ('remake', '=', '出租方变更调整'),
+ ], limit=1)
+ if not existing_bank_statement and bank_account:
+ bank_id = self.env['property.bank.statements'].sudo().create({
+ 'start_time': self.start_index,
+ 'name': bank_account,
+ 'original_amount': line.deposit,
+ 'name_account': line.lessee_id.name,
+ 'remake': '出租方变更调整',
+ 'lending_direction': 'loan',
+ 'company_id': company_id.id if company_id else False,
+ 'your_own_unit': lessor_id.referred,
+ 'your_own_account': lessor_id.rent_account,
+ })
+ bank_id._compute_property_employee_id()
+
+
+class RefundWizardLine(models.TransientModel):
+ _name = 'refund.wizard.line'
+ _description = '退押明细'
+
+ refund_id = fields.Many2one('refund.wizard',string='退押单')
+ contract_id = fields.Many2one('property.lease.contract',string='合同编号')
+ property_name = fields.Char(related='contract_id.property_name',string='物业名称')
+ lessee_id = fields.Many2one(related='contract_id.lessee_id', string='承租方')
+ lessor_id = fields.Many2one(related='contract_id.lessor_id', string='出租方')
+ deposit= fields.Float(related='contract_id.deposit',string='押金')
+
+
diff --git a/yuthon_property_approval/wizard/refund_wizard_views.xml b/yuthon_property_approval/wizard/refund_wizard_views.xml
new file mode 100644
index 000000000..9f76f16f2
--- /dev/null
+++ b/yuthon_property_approval/wizard/refund_wizard_views.xml
@@ -0,0 +1,32 @@
+
+
+
+ refund.wizard.form
+ refund.wizard
+
+
+
+
+
+