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 + +
+ + + + + + + + + + + + + + + + + +
+
+
+
+