添加功能

This commit is contained in:
李鹏宇
2026-06-03 17:52:24 +08:00
parent 6a562e1d30
commit 8f1f2fa32b
2 changed files with 130 additions and 0 deletions
@@ -5,6 +5,7 @@ from odoo import models, fields, api, exceptions, _
from datetime import timedelta
from dateutil.relativedelta import relativedelta
import calendar
import re
from datetime import datetime, date
@@ -44,6 +45,7 @@ class PropertyManagement(models.Model):
name_title = fields.Char(default=_get_default_name_title)
document_ids = fields.Many2many('ir.attachment', string="附件")
is_generate_new_contract = fields.Boolean(string='是否生成新合同', default=False)
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
@api.onchange('precinct_id')
@@ -80,8 +82,132 @@ class PropertyManagement(models.Model):
'tenure_type': line.tenure_type
})]
def _generate_and_resolve_contracts(self):
"""
如果勾选"生成新合同",为每个物业对应的合同创建新合同副本。
返回 {old_contract_id: new_contract_id} 映射,没勾选返回空字典
"""
new_contract_map = {}
if not self.is_generate_new_contract:
return new_contract_map
processed = set()
for manage_line in self.management_line2_ids:
if not manage_line.property_id:
continue
lease_line = self.env['property.lease.contract.line'].search([
('address_id', '=', manage_line.property_id.id),
('lease_id', '!=', False),
], limit=1)
if not lease_line:
continue
old_contract = lease_line.lease_id
if old_contract.id in processed:
continue
processed.add(old_contract.id)
# 编号尾部数字+1:租(2023)37号-2 → 租(2023)37号-3
base_code = old_contract.contract_code or ''
match = re.match(r'^(.+)-(\d+)$', base_code)
if match:
prefix = match.group(1)
counter = int(match.group(2)) + 1
else:
prefix = base_code
counter = 1
new_code = f"{prefix}-{counter}"
while self.env['property.lease.contract'].search(
[('contract_code', '=', new_code)], limit=1):
counter += 1
new_code = f"{prefix}-{counter}"
new_contract = old_contract.copy({
'contract_code': new_code,
'contract_source_id': old_contract.id,
'condition': 'new', # 进入合同审批列表
})
new_contract_map[old_contract.id] = new_contract.id
# 手动复制物业明细行(copy 未复制 One2many)
for old_line in old_contract.lease_ids:
old_line.copy({'lease_id': new_contract.id})
# 时间处理
day_before = self.start_time - timedelta(days=1)
old_contract.write({'actual_end_time': day_before})
new_contract.write({'actual_start_time': self.start_time,
'is_child_contract': True})
# 触发原合同状态更新
old_contract.contract_time()
new_contract._onchange_action_generate_details()
return new_contract_map
def _handle_rent_account_change(self, manage_line, prev_info, new_contract_map):
"""
收租公司账号变更时触发:
① 原合同 → property.bills.list 应付账单(押金)
② 当前合同 → property.accounts.receivable 押金应收
勾了生成新合同 → current_contract 直接取 new_contract_map 里的新合同ID
"""
if prev_info.yuthon_property_id.company_id.id == self.company_id.id:
return
if prev_info.yuthon_property_id.company_id.rent_account == self.company_id.rent_account:
return
# 找现有合同
lease_line = self.env['property.lease.contract.line'].search([
('address_id', '=', manage_line.property_id.id),
('lease_id', '!=', False),
('lease_id.contact_state', '=', 'ing'),
], limit=1)
if not lease_line:
return
old_contract = lease_line.lease_id
# 勾了新合同 → 直接用新合同ID;没勾 → 用现有合同
new_cid = new_contract_map.get(old_contract.id)
current_contract = self.env['property.lease.contract'].browse(new_cid) if new_cid else old_contract
original_contract = current_contract.contract_source_id
# 获取或创建"押金"管理类型
deposit_type = self.env['yuthon.management.type'].search(
[('name', '=', '押金')], limit=1)
if not deposit_type:
deposit_type = self.env['yuthon.management.type'].create({'name': '押金'})
# ① 原合同:创建应付账单 property.bills.list
if original_contract and original_contract.deposit:
existing_bill = self.env['property.bills.list'].search([
('contract_id', '=', original_contract.id),
('management_type_id', '=', deposit_type.id),
], limit=1)
if not existing_bill:
self.env['property.bills.list'].create({
'contract_id': original_contract.id,
'amount': original_contract.deposit,
'due_date': self.start_time,
'management_type_id': deposit_type.id,
})
# ② 当前合同:查找或创建押金应收 property.accounts.receivable
if current_contract and current_contract.deposit:
existing_receivable = self.env['property.accounts.receivable'].search([
('contract_id', '=', current_contract.id),
('management_type_id', '=', deposit_type.id),
], limit=1)
if not existing_receivable:
self.env['property.accounts.receivable'].create({
'contract_id': current_contract.id,
'due_date': self.start_time,
'original_amount': current_contract.deposit,
'management_type_id': deposit_type.id,
})
def approval_end(self):
for record in self:
new_contract_map = record._generate_and_resolve_contracts()
for manage_line in record.management_line2_ids:
# 更新信息行的结束日期
if manage_line.information_line_id:
@@ -145,6 +271,9 @@ class PropertyManagement(models.Model):
})
lease_contract_ids.version = new_version
# 收租账号变更 → 应付账单 + 押金应收
record._handle_rent_account_change(manage_line, prev_info, new_contract_map)
existing_info = self.env['manage.information.line'].search([
('yuthon_property_id', '=', target_property_id),
('start_time', '=', target_start_time)
@@ -56,6 +56,7 @@
<field name="reason_change"/>
<field name="handling_opinions"/>
<field name="document_ids" widget="preview_many2many"/>
<field name="is_generate_new_contract"/>
</group>
<button type="object" class="btn btn-primary" name="put_property_management" string="添加物业" invisible="state != '申请人'"/>
<button type="object" class="btn btn-primary" name="clear_the_details" string="清空明细" invisible="state != '申请人'"/>