1726 lines
90 KiB
Python
1726 lines
90 KiB
Python
# -*- coding: utf-8 -*-
|
||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
import pandas as pd
|
||
import calendar
|
||
from dateutil.relativedelta import relativedelta
|
||
from datetime import datetime, timedelta, date
|
||
from odoo.tools.float_utils import float_round
|
||
from numpy.ma.core import default_filler
|
||
import re
|
||
from odoo import models, fields, api, exceptions, _
|
||
from odoo.exceptions import UserError, ValidationError
|
||
|
||
|
||
class PropertyContractLine(models.Model):
|
||
_name = 'property.contract.line'
|
||
_description = '物业合同明细行'
|
||
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息")
|
||
lease_contract_id = fields.Many2one('property.lease.contract', string="合同编号")
|
||
lessee_id = fields.Many2one('property.tenant.information', string='承租方')
|
||
rent = fields.Float(string="租金")
|
||
start_time = fields.Date(string="生效日期")
|
||
end_date = fields.Date(string="失效日期")
|
||
|
||
class PropertyTenantLine(models.Model):
|
||
_name = 'property.tenant.line'
|
||
_description = '物业承租方合同明细行'
|
||
|
||
tenant_id = fields.Many2one('property.tenant.information', string="关联租户信息")
|
||
property_ids = fields.Many2many('yuthon.property', string="物业信息")
|
||
lease_contract_id = fields.Many2one('property.lease.contract', string="合同编号")
|
||
rent = fields.Float(related='lease_contract_id.rent', string="租金")
|
||
start_time = fields.Date(related='lease_contract_id.actual_start_time', string="生效日期")
|
||
end_date = fields.Date(related='lease_contract_id.actual_end_time',string="失效日期")
|
||
|
||
@api.model
|
||
def create(self, vals):
|
||
"""在创建记录时自动关联合同对应的物业"""
|
||
if vals.get('lease_contract_id'):
|
||
# 获取合同关联的物业明细行并直接提取物业ID列表
|
||
contract = self.env['property.lease.contract'].browse(vals['lease_contract_id'])
|
||
property_ids = contract.lease_ids.mapped('address_id.id')
|
||
if property_ids:
|
||
vals['property_ids'] = [(6, 0, property_ids)]
|
||
return super(PropertyTenantLine, self).create(vals)
|
||
|
||
class PropertyLeaseContract(models.Model):
|
||
_name = 'property.lease.contract'
|
||
_description = '租赁合同审批'
|
||
_inherit = ['mail.thread.main.attachment', 'mail.activity.mixin', 'soong.workflow.mixin']
|
||
_rec_name = 'contract_code'
|
||
|
||
property_name = fields.Char(string='物业信息')
|
||
code = fields.Char(string="流水号", default=lambda self: self.env['ir.sequence'].next_by_code('property_lease_contract_code'))
|
||
admin_id = fields.Many2one('res.users', string="管理员", compute='_compute_admin_id', store=True)
|
||
tenure_type = fields.Selection([('self', '自有'), ('agency', '代管')], string='权属类型')
|
||
contract_code = fields.Char(string="合同编号")
|
||
contract_date = fields.Date(string="合同签订日期")
|
||
property_documents_ids = fields.Many2many(
|
||
'ir.attachment',
|
||
relation='property_lease_contract_documents_rel',
|
||
column1='property_lease_contract_id',
|
||
column2='attachment_id',
|
||
string="租赁合同文件"
|
||
)
|
||
title_address = fields.Char(string="产权地址")
|
||
handling_opinions = fields.Text(string="经办意见")
|
||
lessor_id = fields.Many2one('yuthon.property.company', string="出租方公司")
|
||
rent_company = fields.Char(related='lessor_id.name', string="收租公司名称")
|
||
rent_account = fields.Char(related='lessor_id.rent_account', string="收租公司账号")
|
||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||
department_id = fields.Many2one('hr.department', string="部门", store=True, compute='_compute_department_id')
|
||
company_id = fields.Many2one(related='users_id.employee_id.company_id', string="公司")
|
||
# 承租方的个人信息
|
||
lessee_id = fields.Many2one('property.tenant.information', string='承租方')
|
||
lessee_name = fields.Char(related='lessee_id.name', string="承租方姓名")
|
||
contact = fields.Char(related='lessee_id.contact', string="联系人")
|
||
phone = fields.Char(related='lessee_id.phone', string="联系电话")
|
||
email = fields.Char(related='lessee_id.email', string="电子邮箱")
|
||
card = fields.Char(related='lessee_id.card', string="身份证号")
|
||
invoicing_type = fields.Selection([('spot', '专票'), ('cape', '普票')], related='lessee_id.invoicing_type', string="开票类型")
|
||
rental_purposes = fields.Many2one('yuthon.rental.purpose', string="出租用途")
|
||
invoicing_begins = fields.Char(related='lessee_id.invoicing_begins', string="开票抬头")
|
||
tax_number = fields.Char(related='lessee_id.tax_number', string="税号")
|
||
industry_id = fields.Many2one(related='lessee_id.industry_id', string="行业")
|
||
address_for_delivery = fields.Char(string="送达地址")
|
||
precinct_id = fields.Many2one('yuthon.precinct.message', string="所属片区")
|
||
active = fields.Boolean('Active', default=True, tracking=True)
|
||
|
||
lease_term_year = fields.Integer(string="租期(年)")
|
||
lease_term_month = fields.Integer(string="租期(月)")
|
||
lease_term_day = fields.Integer(string="租期(日)")
|
||
is_less_than_2 = fields.Boolean(string="是否小于2年")
|
||
term_start_time = fields.Date(string="合约开始时间", default=fields.Datetime.now)
|
||
term_end_time = fields.Date(string="合约结束时间")
|
||
actual_start_time = fields.Date(string="实际开始时间")
|
||
actual_end_time = fields.Date(string="实际结束时间")
|
||
end_comparison = fields.Selection([('red', '红'),('yellow', '黄'),('blue', '蓝')], string="结束时间对比(颜色)", compute='_compute_end_comparison', store=True)
|
||
expiration_coming = fields.Selection([('coming', '即将到期'), ('due', '已到期')], string="结束时间对比(状态)", compute='_compute_expiration_coming', store=True)
|
||
is_equal = fields.Boolean(string="是否相等", compute='_compute_end_comparison', store=True)
|
||
|
||
cycle_dict = fields.Selection([('monthly', '月度'), ('quarter', '季度'), ('half', '半年'),('year', '年度')],string='付款方式', default='monthly', help="应收")
|
||
cycle_mode = fields.Selection([('fixed_monthly', '合同月'), ('floating_monthly', '自然月'), ('fixed_quarter', '合同季'), ('floating_quarter', '自然季'),
|
||
('fixed_year', '合同年'), ('floating_year', '自然年')], string='周期方式', default='fixed_monthly')
|
||
expected_reminders = fields.Char(string="逾期提醒", default=25)
|
||
increment_method = fields.Selection([('percentage', '百分比'),('increment_price', '递增单价'),('increment_amount', '递增金额')], string='每月递增', default='percentage')
|
||
|
||
increment_percentage = fields.Float(string="递增百分比")
|
||
increment_price = fields.Float(string="递增单价")
|
||
increment_amount = fields.Float(string="递增金额")
|
||
increment_value = fields.Float(string="递增值")
|
||
|
||
first_years_begin = fields.Integer(string="第几年开始", default=2)
|
||
increments_every_few_years = fields.Integer(string="每几年递增")
|
||
|
||
rent_free_period = fields.Datetime(string="免租期")
|
||
rent_free_period_month = fields.Integer(string="免租期")
|
||
rent_free_period_days = fields.Integer(string="免租期")
|
||
|
||
breach = fields.Integer(string="违约计算时点", default=1)
|
||
is_split = fields.Boolean(string="是否合同拆分")
|
||
|
||
def _get_percentage_liquidated_damages(self):
|
||
default_rate = self.env['yuthon.penalty.setting'].search(
|
||
[('name', '=', 0.001)], limit=1
|
||
)
|
||
return default_rate.id if default_rate else False
|
||
|
||
percentage_liquidated_damages = fields.Many2one('yuthon.penalty.setting', string="违约金比例", default=_get_percentage_liquidated_damages)
|
||
percentage_damages= fields.Float(string="违约金")
|
||
date_of_payment = fields.Selection([('five', '5'), ('fifteen', '15'), ('twenty', '20'), ('twentyfive', '25')], string="支付日期")
|
||
first_pay = fields.Date(string="首次付款日")
|
||
unit_price = fields.Float(string="单价", store=True, digits=(16, 4))
|
||
deposit_type = fields.Selection([('deposit', '押金'), ('performance', '履约保证金')], string="押金/履约保证金")
|
||
deposit_status = fields.Selection([('unpaid', '未支付'), ('paid', '已支付'), ('returned','已退'),('no_paid', '没收')], string='押金状态')
|
||
deposit = fields.Float(string="押金/履约保证金", store=True)
|
||
performance_bonds_write = fields.Char(string="履约保证金大写")
|
||
first_year_rent = fields.Float(string="首年租金")
|
||
rent = fields.Float(string="租金", help='第一笔合同的应收')
|
||
total_contract_receivables = fields.Float(string="合同总应收", compute="_compute_total_contract_receivables")
|
||
|
||
def _get_default_tax_rate(self):
|
||
default_rate = self.env['yuthon.tariff.setting'].search(
|
||
[('name', '=', 0.05)], limit=1
|
||
)
|
||
return default_rate.id if default_rate else False
|
||
|
||
tax_rate = fields.Many2one('yuthon.tariff.setting', string="税率", default=_get_default_tax_rate)
|
||
use_address = fields.Char(string="财务专用地址")
|
||
not_tax_amount = fields.Float(string="不含税价")
|
||
tax = fields.Float(string="税金")
|
||
is_water = fields.Boolean(string="是否有水费", compute='_compute_lease_ids')
|
||
is_electricity = fields.Boolean(string="是否有电费", compute='_compute_lease_ids')
|
||
is_mange = fields.Boolean(string="是否有管理费")
|
||
miscellaneous = fields.Text(string="其他约定")
|
||
water_price = fields.Float(string="水费单价")
|
||
ele_price = fields.Float(string="电费单价")
|
||
number = fields.Integer(string="次数", default=0)
|
||
total_area = fields.Float(string="总面积", digits=(16, 4))
|
||
not_received = fields.Float(string="未收", compute="_compute_not_received", store=True)
|
||
actual_receivable = fields.Float(string="实际应收")
|
||
now_receivable = fields.Float(string="当期应收")
|
||
total_receivable = fields.Float(string="总已收")
|
||
comparison = fields.Selection([('outweigh', '大于'), ('equal', '等于'), ('less', '小于')], string="对比", compute='_compute_comparison')
|
||
progress_percentage = fields.Float(string="合同进度", compute="_compute_progress_percentage")
|
||
condition = fields.Selection([('new', '新建'), ('approval', '审批中'), ('cancel', '作废'), ('be_executed', '待执行'), ('executed', '已执行'), ('expired', '已终止')], string="状态", default='new')
|
||
contract_type = fields.Selection([('lease_renewal', '续租'), ('interim', '临租'), ('new', '补充协议'), ('first', '首租')], string="合同类型", default='first')
|
||
contract_id = fields.Many2one('property.lease.contract', string="原合同")
|
||
performance_bonds = fields.Float(string="经营履约保证金")
|
||
utility_bills = fields.Float(string="水电费押金")
|
||
renovation_deposit = fields.Float(string="装修押金")
|
||
lease_ids = fields.One2many('property.lease.contract.line', 'lease_id',string="物业信息明细行")
|
||
subset_ids = fields.One2many('property.subset.contract', 'subset_id',string="子集明细")
|
||
breakdown_ids = fields.One2many('property.rent.breakdown.line', 'breakdown_id', string="物业租金明细行")
|
||
water_fee_ids = fields.One2many('property.water.fee.line', 'contract_id', string="物业水费明细行", compute='_compute_lease_ids', store=True)
|
||
electricity_fee_ids = fields.One2many('property.electric.fee.line', 'contract_id', string="物业电费明细行", compute='_compute_lease_ids', store=True)
|
||
mange_fee_ids = fields.One2many('property.manage.fee.line', 'contract_id', string="物业管理费明细行")
|
||
other_ids = fields.One2many('property.other.fee.line', 'other_id', string="其他费用明细行")
|
||
rent_list_ids = fields.One2many('property.rent.list', 'contract_id', string="租金明细行")
|
||
lease_bank_ids = fields.One2many('property.bank.line', 'contract_id', string="承租方账户明细行")
|
||
bank_statements_ids = fields.One2many('property.bank.statements', 'contract_id', string="银行流水明细行")
|
||
management_list_ids = fields.One2many('property.management.list', 'contract_id', string="管理费用明细行")
|
||
contact_state = fields.Selection([('to', '待执行' ), ('ing', '执行中'), ('terminate', '中止'), ('complete', '完成'), ('early_termination', '提前终止')], string='状态', default='to')
|
||
# 附件
|
||
license_id = fields.Many2one('ir.attachment', string="营业执照")
|
||
legal_entity_id = fields.Many2one('ir.attachment', string="身份证")
|
||
power_attorney_id = fields.Many2one('ir.attachment', string="授权委托书")
|
||
asset_valuation_id = fields.Many2one('ir.attachment', string="资产评估结果明细表")
|
||
lease_contract = fields.Many2one('ir.attachment', string="合同/协议")
|
||
confirmation_transaction_id = fields.Many2one('ir.attachment', string="成交确认书")
|
||
responsibility_book_id = fields.Many2one('ir.attachment', string="安全生产责任书(住宅)")
|
||
other_ment_ids = fields.Many2many(
|
||
'ir.attachment',
|
||
relation='property_lease_contract_other_rel',
|
||
column1='contract_id',
|
||
column2='attachment_id',
|
||
string="其他"
|
||
)
|
||
handover_time = fields.Date(string="交接日期")
|
||
contract_source_id = fields.Many2one('property.lease.contract', string="合同来源")
|
||
is_child_contract = fields.Boolean(string="是否子合同")
|
||
is_contract = fields.Boolean(string="是否主合同")
|
||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||
default='normal')
|
||
work_end = fields.Boolean(string="结束")
|
||
|
||
name = fields.Char(compute='_compute_name', store=True)
|
||
|
||
license_name = fields.Char(string="营业执照名称", compute='_compute_attachment_names', store=True)
|
||
legal_entity_name = fields.Char(string="身份证名称", compute='_compute_attachment_names', store=True)
|
||
asset_valuation_name = fields.Char(string="资产评估结果明细表名称", compute='_compute_attachment_names')
|
||
lease_contract_name = fields.Char(string="合同/协议", compute='_compute_attachment_names')
|
||
confirmation_transaction_name = fields.Char(string="成交确认书名称", compute='_compute_attachment_names',
|
||
store=True)
|
||
responsibility_book_name = fields.Char(string="安全生产责任书(住宅)名称", compute='_compute_attachment_names',
|
||
store=True)
|
||
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
|
||
title_information = fields.Text(string="产权证信息")
|
||
contract_count = fields.Integer(string="联系人数量", compute='_compute_contract_count')
|
||
reconciliation_count = fields.Integer(string="对账数量", compute='_compute_reconciliation_count')
|
||
process_count = fields.Integer(string="流程数量", compute='_compute_process_count')
|
||
|
||
@api.depends('users_id')
|
||
def _compute_department_id(self):
|
||
for record in self:
|
||
record.department_id = record.users_id.employee_ids.department_id.id
|
||
|
||
def _compute_contract_count(self):
|
||
for record in self:
|
||
record.contract_count = self.env['property.accounts.receivable'].search_count([('contract_id', '=', record.id)])
|
||
|
||
def _compute_reconciliation_count(self):
|
||
for record in self:
|
||
record.reconciliation_count = self.env['property.bank.statements'].search_count([('contract_id', '=', record.id),
|
||
('name_account', '=', record.lessee_id.name)
|
||
])
|
||
def _compute_process_count(self):
|
||
for record in self:
|
||
record.process_count = self.env['soong.workflow.record'].search_count([('code', '=', record.code)])
|
||
|
||
def action_open_contract(self):
|
||
self.ensure_one()
|
||
action = self.env["ir.actions.actions"]._for_xml_id("yuthon_property_approval.property_accounts_receivable_action")
|
||
action.update({'domain': [('contract_id', '=', self.id)]})
|
||
return action
|
||
|
||
def action_open_reconciliation(self):
|
||
self.ensure_one()
|
||
action = self.env["ir.actions.actions"]._for_xml_id("yuthon_property.view_property_bank_statements_action1")
|
||
action.update({'domain': [('contract_id', '=', self.id),
|
||
('name_account', '=', self.lessee_id.name)
|
||
]
|
||
})
|
||
return action
|
||
|
||
def action_open_process(self):
|
||
self.ensure_one()
|
||
action = self.env["ir.actions.actions"]._for_xml_id("soong_workflow.soong_workflow_other_record_action")
|
||
action.update({'domain': [('code', '=', self.code)]})
|
||
return action
|
||
|
||
|
||
@api.depends()
|
||
def _compute_not_received(self):
|
||
not_reconciled_records = self.env['property.accounts.receivable'].search([
|
||
('contract_id', '=', self.id),
|
||
('is_reconciliation', '=', False)
|
||
])
|
||
self.not_received = sum(record.submitted for record in not_reconciled_records)
|
||
|
||
def update_not_received(self):
|
||
contract_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for rec in contract_ids:
|
||
not_reconciled_records = self.env['property.accounts.receivable'].search([
|
||
('contract_id', '=', rec.id),
|
||
('is_reconciliation', '=', False)
|
||
])
|
||
rec.not_received = sum(record.submitted for record in not_reconciled_records)
|
||
|
||
def update_admin_id(self):
|
||
contract_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for rec in contract_ids:
|
||
if rec.lease_ids:
|
||
rec.admin_id = rec.lease_ids[0].admin_line_id.id
|
||
|
||
@api.depends("lease_ids")
|
||
def _compute_lease_ids(self):
|
||
for rec in self:
|
||
# 初始化值
|
||
rec.is_water = False
|
||
rec.is_electricity = False
|
||
rec.water_fee_ids = [(5, 0, 0)]
|
||
rec.electricity_fee_ids = [(5, 0, 0)]
|
||
|
||
water_fee_values = []
|
||
electricity_fee_values = []
|
||
if rec.lease_ids:
|
||
|
||
# 处理每个租赁记录
|
||
for lease in rec.lease_ids:
|
||
if lease.address_id:
|
||
# 处理水表
|
||
if lease.address_id.is_meter:
|
||
active_water_meters = lease.address_id.water_meter_ids.filtered(
|
||
lambda m: not m.demolition_date or m.demolition_date > fields.Date.today()
|
||
)
|
||
for meter in active_water_meters:
|
||
# 确保meter记录有效
|
||
if meter.property_meter_water_id:
|
||
water_fee_values.append([0, 0, {
|
||
'contract_id': rec.id,
|
||
'property_meter_water_id': meter.property_meter_water_id.id,
|
||
}])
|
||
|
||
# 处理电表
|
||
if lease.address_id.is_electricity_meter:
|
||
rec.is_electricity = True
|
||
active_electric_meters = lease.address_id.energy_meter_ids.filtered(
|
||
lambda m: not m.demolition_date or m.demolition_date > fields.Date.today()
|
||
)
|
||
for meter in active_electric_meters:
|
||
# 确保meter记录有效
|
||
if meter.property_meter_archives_id:
|
||
electricity_fee_values.append([0, 0, {
|
||
'contract_id': rec.id,
|
||
'property_meter_archives_id': meter.property_meter_archives_id.id,
|
||
}])
|
||
|
||
rec.is_water = bool(water_fee_values)
|
||
rec.is_electricity = bool(electricity_fee_values)
|
||
if water_fee_values:
|
||
rec.water_fee_ids = water_fee_values
|
||
if electricity_fee_values:
|
||
rec.electricity_fee_ids = electricity_fee_values
|
||
rec.admin_id = rec.lease_ids[0].admin_line_id.id
|
||
rec.users_id = rec.lease_ids[0].admin_line_id.id
|
||
|
||
|
||
@api.depends(
|
||
'license_id.name',
|
||
'legal_entity_id.name',
|
||
'asset_valuation_id.name',
|
||
'lease_contract.name',
|
||
'confirmation_transaction_id.name',
|
||
'responsibility_book_id.name'
|
||
)
|
||
def _compute_attachment_names(self):
|
||
"""计算附件名称字段"""
|
||
for record in self:
|
||
# 营业执照名称
|
||
record.license_name = record.license_id.name if record.license_id else ''
|
||
# 身份证名称
|
||
record.legal_entity_name = record.legal_entity_id.name if record.legal_entity_id else ''
|
||
# 资产评估结果明细表名称
|
||
record.asset_valuation_name = record.asset_valuation_id.name if record.asset_valuation_id else ''
|
||
# 租赁合同(住宅)名称
|
||
record.lease_contract_name = record.lease_contract.name if record.lease_contract else ''
|
||
# 成交确认书名称
|
||
record.confirmation_transaction_name = record.confirmation_transaction_id.name if record.confirmation_transaction_id else ''
|
||
# 安全生产责任书(住宅)名称
|
||
record.responsibility_book_name = record.responsibility_book_id.name if record.responsibility_book_id else ''
|
||
|
||
def all_end_approval(self):
|
||
contract_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for contract in contract_ids:
|
||
contract.write({'condition': 'be_executed',
|
||
'work_end': True})
|
||
logs_to_update = self.env["soong.workflow.log"].search([
|
||
("model", "=", self._name),
|
||
("res_id", "=", contract.id),
|
||
])
|
||
if logs_to_update:
|
||
last_log = logs_to_update[-1]
|
||
last_log.write({
|
||
"comment": " ",
|
||
"approval_state": "3",
|
||
"lase_click_date": fields.Datetime.now()
|
||
})
|
||
|
||
def end_approval(self):
|
||
self.write({'condition': 'be_executed'})
|
||
|
||
def open_record(self):
|
||
return {
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'property.lease.contract',
|
||
'res_id': self.id,
|
||
'view_mode': 'form',
|
||
}
|
||
|
||
@api.depends('contract_code', 'name', 'contract_type')
|
||
def _compute_name(self):
|
||
contract_dict = {
|
||
'lease_renewal': '续租',
|
||
'interim': '临租',
|
||
'new': '补充协议',
|
||
'first': '首租'
|
||
}
|
||
for record in self:
|
||
if record.contract_code and record.property_name and record.contract_type:
|
||
record.name = f"{record.contract_code}{contract_dict.get(record.contract_type)}{record.property_name}"
|
||
elif record.contract_code and record.property_name:
|
||
record.name = f"{record.contract_code}{record.property_name}"
|
||
elif record.name:
|
||
record.name = record.property_name
|
||
else:
|
||
record.name = self._description
|
||
|
||
def update_property(self):
|
||
contract_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for contract_id in contract_ids:
|
||
for record in contract_id.lease_ids:
|
||
record.address_id.write({'property_contract_ids': [(5, 0, 0)]})
|
||
contract_list = []
|
||
contract_list.append([0, 0,{
|
||
'yuthon_property_id': record.address_id.id,
|
||
'lease_contract_id': contract_id.id,
|
||
'lessee_id': contract_id.lessee_id.id,
|
||
'rent': contract_id.rent,
|
||
'start_time': contract_id.actual_start_time,
|
||
'end_date': contract_id.actual_end_time,
|
||
}])
|
||
record.address_id.write({'property_contract_ids': contract_list})
|
||
|
||
@api.onchange('lessee_id')
|
||
def _onchange_lessee_id(self):
|
||
for record in self:
|
||
if record.lessee_id:
|
||
lease_bank_ids = self.env['property.bank.line'].search([('tenant_id', '=', record.lessee_id.id)])
|
||
record.lease_bank_ids = lease_bank_ids.ids
|
||
|
||
def set_actual_time_to_contract_time(self):
|
||
contract_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in contract_ids:
|
||
if record.term_start_time:
|
||
record.actual_start_time = record.term_start_time
|
||
if record.term_end_time:
|
||
record.actual_end_time = record.term_end_time
|
||
|
||
@api.depends('not_received', 'now_receivable')
|
||
def _compute_comparison(self):
|
||
for record in self:
|
||
if record.not_received and record.now_receivable:
|
||
if record.not_received > record.now_receivable:
|
||
record.comparison = 'outweigh'
|
||
elif record.not_received < record.now_receivable:
|
||
record.comparison = 'less'
|
||
else:
|
||
record.comparison = 'equal'
|
||
else:
|
||
record.comparison = None
|
||
|
||
@api.depends('term_end_time', 'actual_end_time', 'term_start_time')
|
||
def _compute_end_comparison(self):
|
||
for record in self:
|
||
if record.term_end_time and record.actual_end_time and record.term_start_time:
|
||
delta = record.term_end_time - record.actual_end_time
|
||
if 60<= abs(delta.days) < 90:
|
||
record.end_comparison = 'blue'
|
||
elif 30<= abs(delta.days) < 60:
|
||
record.end_comparison = 'yellow'
|
||
elif 30 > abs(delta.days):
|
||
record.end_comparison = 'red'
|
||
else:
|
||
record.end_comparison = None
|
||
if record.actual_end_time == record.term_start_time:
|
||
record.is_equal = True
|
||
else:
|
||
record.end_comparison = None
|
||
|
||
@api.depends('term_end_time', 'actual_end_time')
|
||
def _compute_expiration_coming(self):
|
||
for record in self:
|
||
if record.term_end_time and record.actual_end_time:
|
||
if record.actual_end_time < record.term_end_time:
|
||
delta = record.term_end_time - record.actual_end_time
|
||
if 30< delta.days < 90:
|
||
record.expiration_coming = 'coming'
|
||
elif delta.days <=30:
|
||
record.expiration_coming = 'due'
|
||
else:
|
||
record.expiration_coming = None
|
||
else:
|
||
record.expiration_coming = None
|
||
else:
|
||
record.expiration_coming = None
|
||
|
||
@api.onchange('total_area', 'rent')
|
||
def _onchange_unit_price(self):
|
||
for i in self:
|
||
if i.total_area and i.rent:
|
||
i.unit_price = i.rent / i.total_area
|
||
|
||
@api.depends('breakdown_ids')
|
||
def _compute_total_contract_receivables(self):
|
||
for record in self:
|
||
record.total_contract_receivables = sum(line.period_rent for line in record.breakdown_ids)
|
||
|
||
# @api.onchange("term_start_time", "term_end_time",
|
||
# "increments_every_few_years", "unit_price",
|
||
# "first_years_begin", "increment_method",
|
||
# "increment_price", "increment_percentage", "increment_amount",
|
||
# "rent_free_period_year", "rent_free_period_month", "total_area")
|
||
# def onchange_first_year_rent(self):
|
||
# for record in self:
|
||
# if record.term_start_time and record.term_end_time:
|
||
# start_date = record.term_start_time
|
||
# end_date = record.term_end_time + relativedelta(days=1)
|
||
# if start_date + relativedelta(months=12) < end_date:
|
||
# end_date = start_date + relativedelta(months=12)
|
||
# all_period_rent = record.my_compute_all_period_rent(start_date, end_date)
|
||
# record.first_year_rent = all_period_rent
|
||
# all_start_date = record.term_start_time
|
||
# all_end_date = record.term_end_time + relativedelta(days=1)
|
||
# record.total_contract_receivables = record.my_compute_all_period_rent(all_start_date, all_end_date)
|
||
|
||
@api.onchange("lease_term_year", "lease_term_month", "term_start_time" , "lease_term_day")
|
||
def onchange_lease_term_year(self):
|
||
for record in self:
|
||
if record.lease_term_year < 2:
|
||
record.is_less_than_2 = True
|
||
else:
|
||
record.is_less_than_2 = False
|
||
if record.lease_term_year or record.lease_term_month:
|
||
if not record.lease_term_day:
|
||
if record.term_start_time:
|
||
year = record.lease_term_year if record.lease_term_year else 0
|
||
month = record.lease_term_month if record.lease_term_month else 0
|
||
months = year * 12 + month
|
||
record.term_end_time = record.term_start_time + relativedelta(months=months) - relativedelta(days=1)
|
||
else:
|
||
if record.term_start_time:
|
||
year = record.lease_term_year if record.lease_term_year else 0
|
||
month = record.lease_term_month if record.lease_term_month else 0
|
||
months = year * 12 + month
|
||
record.term_end_time = record.term_start_time + relativedelta(months=months) - relativedelta(days=1) + relativedelta(days=record.lease_term_day)
|
||
|
||
@api.onchange("total_contract_receivables", "tax_rate")
|
||
def onchange_total_contract_receivables(self):
|
||
for record in self:
|
||
if record.total_contract_receivables and record.tax_rate:
|
||
record.not_tax_amount = record.total_contract_receivables/(1+float(record.tax_rate.name))
|
||
record.tax = record.total_contract_receivables - record.not_tax_amount
|
||
|
||
@staticmethod
|
||
def divide_time_range_fixed(start_time, end_time, months):
|
||
time_ranges = []
|
||
while start_time < end_time:
|
||
end_of_range = start_time + relativedelta(months=months)
|
||
if end_of_range > end_time:
|
||
end_of_range = end_time
|
||
time_range = [start_time, end_of_range]
|
||
time_ranges.append(time_range)
|
||
start_time = end_of_range
|
||
return time_ranges
|
||
|
||
@api.onchange('cycle_dict')
|
||
def onchange_cycle_dict(self):
|
||
if self.cycle_dict == 'monthly':
|
||
self.cycle_mode = 'fixed_monthly'
|
||
elif self.cycle_dict == 'quarter':
|
||
self.cycle_mode = 'fixed_quarter'
|
||
elif self.cycle_dict == 'year':
|
||
self.cycle_mode = 'fixed_year'
|
||
|
||
# @staticmethod
|
||
# def divide_time_range_floating(start_time, end_time, months):
|
||
# time_ranges = []
|
||
# while start_time < end_time:
|
||
# start_time = start_time.replace(day=1)
|
||
# end_of_range = start_time + relativedelta(months=months)
|
||
# time_range = [start_time, end_of_range - relativedelta(days=1)]
|
||
# time_ranges.append(time_range)
|
||
# start_time = end_of_range
|
||
# return time_ranges
|
||
|
||
# def my_compute_all_period_rent(self, start_date, end_date):
|
||
# first_years_begin = self.first_years_begin if self.first_years_begin else 0
|
||
# increments_every_few_years = self.increments_every_few_years
|
||
# monthly_amount = self.total_area * self.unit_price # 月租金
|
||
# unit_price = self.unit_price # 单价
|
||
# rent_free_period_month = 0
|
||
# # 先计算免租期
|
||
# # if self.rent_free_period_year:
|
||
# # rent_free_period_month += self.rent_free_period_year * 12
|
||
# if self.rent_free_period_month:
|
||
# rent_free_period_month += self.rent_free_period_month
|
||
# free_start = start_date # 免租期开始
|
||
# if rent_free_period_month:
|
||
# free_start = start_date + relativedelta(months=rent_free_period_month)
|
||
#
|
||
# all_period_rent = 0
|
||
# if not increments_every_few_years:
|
||
# # 计算剩余日期
|
||
# delta = relativedelta(end_date, free_start)
|
||
# months = delta.years * 12 + delta.months
|
||
# all_period_rent += monthly_amount * months
|
||
# else:
|
||
# # 不递增年份的计算
|
||
# increments_start = free_start # 平稳和递增开始
|
||
# all_months = 0 # 第几月份
|
||
# # 有免递增年份的计算
|
||
# if first_years_begin:
|
||
# first_index = 0 # 第几递增周期年
|
||
# divided_year_segments = self.divide_time_range_fixed(start_date, end_date, 12)
|
||
# for segment_year in divided_year_segments:
|
||
# first_index += 1
|
||
# increments_start = segment_year[1]
|
||
# if first_years_begin and first_index >= first_years_begin:
|
||
# # 进入 递增时间 跳出平稳计费极端
|
||
# break
|
||
# delta = relativedelta(segment_year[1], segment_year[0])
|
||
# months = delta.years * 12 + delta.months
|
||
# for month in range(months):
|
||
# all_months += 1
|
||
# # 判断是否是免租期
|
||
# if all_months > rent_free_period_month:
|
||
# all_period_rent += monthly_amount
|
||
# # 开始递增
|
||
# divided_increments_segments = self.divide_time_range_fixed(increments_start, end_date, increments_every_few_years * 12)
|
||
# index = 0 # 第几递增周期年
|
||
# for increments_year in divided_increments_segments:
|
||
# index += 1
|
||
# """
|
||
# increment_percentage = fields.Float(string="递增百分比")
|
||
# increment_price = fields.Float(string="递增单价")
|
||
# increment_amount = fields.Float(string="递增金额")
|
||
# """
|
||
# increments_month = 0
|
||
# if self.increment_method == "increment_price" and self.increment_value:
|
||
# unit_price = unit_price + self.increment_value
|
||
# monthly_amount = self.total_area * unit_price
|
||
# if self.increment_method == "percentage" and self.increment_value:
|
||
# monthly_amount = monthly_amount * self.increment_value
|
||
# if self.increment_method == "increment_amount" and self.increment_value:
|
||
# monthly_amount = monthly_amount + self.increment_value
|
||
# delta = relativedelta(increments_year[1], increments_year[0])
|
||
# months = delta.years * 12 + delta.months
|
||
# # 判断第几月份进入 付费租期
|
||
# for month in range(months):
|
||
# all_months += 1
|
||
# # 判断是否是免租期
|
||
# if all_months > rent_free_period_month:
|
||
# increments_month += 1
|
||
# if increments_month:
|
||
# all_period_rent += monthly_amount * increments_month
|
||
# return all_period_rent
|
||
|
||
def action_generate_rental_charges(self):
|
||
"""
|
||
跳转租金费用弹窗
|
||
:return:
|
||
"""
|
||
return {
|
||
'name': '租金费用弹窗',
|
||
'type': 'ir.actions.act_window',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.rental.wizard',
|
||
'target': 'new',
|
||
'context': {
|
||
'default_lease_contract_id': self.id,
|
||
}
|
||
}
|
||
|
||
|
||
def action_generate_administrative_expenses(self):
|
||
"""
|
||
跳转租金费用弹窗
|
||
:return:
|
||
"""
|
||
return {
|
||
'name': '租金费用弹窗',
|
||
'type': 'ir.actions.act_window',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.rental.wizard',
|
||
'target': 'new',
|
||
'context': {
|
||
'default_lease_contract_id': self.id,
|
||
}
|
||
}
|
||
|
||
@api.onchange("term_start_time", "term_end_time", "rent",
|
||
"increments_every_few_years", "unit_price",
|
||
"first_years_begin", "increment_method", "increment_value",
|
||
"rent_free_period_month", "rent_free_period_days", "total_area")
|
||
def _onchange_action_generate_details(self):
|
||
"""
|
||
生产租金明细
|
||
:return:
|
||
"""
|
||
# todo 还没有计算递增递减
|
||
# todo 还没有计算首月优惠
|
||
# todo 还没有计算开始和结束不足月份和季度的计算比例
|
||
|
||
for record in self:
|
||
if record.term_start_time and record.term_end_time:
|
||
record.write({'breakdown_ids': [(5, 0, 0)]})
|
||
start_date = record.term_start_time
|
||
end_date = record.term_end_time + relativedelta(days=1)
|
||
record.do_generate_details_core(start_date, end_date, True)
|
||
|
||
# 计算首年租金
|
||
first_year_end_date = start_date + relativedelta(months=12)
|
||
if first_year_end_date > end_date:
|
||
first_year_end_date = end_date
|
||
all_period_rent = record.do_generate_details_core(start_date, first_year_end_date, False)
|
||
record.first_year_rent = all_period_rent
|
||
|
||
def all_action_generate_details(self):
|
||
property_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in property_ids:
|
||
if record.term_start_time and record.term_end_time:
|
||
record.write({'breakdown_ids': [(5, 0, 0)]})
|
||
start_date = record.term_start_time
|
||
end_date = record.term_end_time + relativedelta(days=1)
|
||
record.do_generate_details_core(start_date, end_date, True)
|
||
# 计算首年租金
|
||
first_year_end_date = start_date + relativedelta(months=12)
|
||
if first_year_end_date > end_date:
|
||
first_year_end_date = end_date
|
||
all_period_rent = record.do_generate_details_core(start_date, first_year_end_date, False)
|
||
record.first_year_rent = all_period_rent
|
||
|
||
def do_generate_details_core(self, start_date, end_date, write_db=False):
|
||
all_period_rent = 0
|
||
|
||
unit_price = self.unit_price # 单价
|
||
unit_price = float_round(unit_price, precision_digits=2, rounding_method='HALF-UP')
|
||
monthly_amount = self.rent
|
||
monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金
|
||
|
||
|
||
# 如果有免租期 月 时间进行到 start_date
|
||
free_start_dict = {}
|
||
free_start = start_date
|
||
if self.rent_free_period_month:
|
||
free_start = start_date + relativedelta(months=self.rent_free_period_month)
|
||
if free_start > end_date:
|
||
free_start = end_date
|
||
delta = relativedelta(free_start, start_date)
|
||
month_number = delta.years * 12 + delta.months
|
||
if delta.days:
|
||
month_number += 1
|
||
free_start_dict = {
|
||
"unit_price": unit_price,
|
||
"monthly_amount": monthly_amount,
|
||
"breakdown_id": self.id,
|
||
"start_data": start_date,
|
||
"end_data": free_start - relativedelta(days=1),
|
||
"month_number": month_number,
|
||
"period_rent": 0,
|
||
}
|
||
|
||
|
||
free_day_start = free_start
|
||
|
||
add_year_index = 0 # 第几年
|
||
year_month_index = 0 # 第几个月
|
||
|
||
|
||
free_start_day_dict = {}
|
||
monthly_amount_last_dict = {}
|
||
monthly_amount_new_dict = {}
|
||
|
||
# 说明存在免增期 单独计算
|
||
if start_date < end_date:
|
||
one_years_list = self.divide_time_range_fixed(start_date, end_date, 12)
|
||
for one_year in one_years_list:
|
||
add_year_index += 1
|
||
# 是否存在免增期
|
||
first_years_begin = self.first_years_begin if self.first_years_begin else 0
|
||
# 存在递增期 并且进入递增金额计算
|
||
if self.increments_every_few_years > 0 and add_year_index >= first_years_begin:
|
||
if add_year_index % self.increments_every_few_years == 0:
|
||
# 单价和金额计算
|
||
if self.increment_method == "increment_price" and self.increment_value:
|
||
unit_price = unit_price + self.increment_value
|
||
unit_price = float_round(unit_price, precision_digits=2, rounding_method='HALF-UP')
|
||
monthly_amount = self.total_area * unit_price
|
||
monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金
|
||
if self.increment_method == "percentage" and self.increment_value:
|
||
unit_price = unit_price * (1 + (self.increment_value / 100))
|
||
unit_price = float_round(unit_price, precision_digits=2, rounding_method='HALF-UP')
|
||
monthly_amount = self.total_area * unit_price
|
||
monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金
|
||
if self.increment_method == "increment_amount" and self.increment_value:
|
||
monthly_amount = monthly_amount + self.increment_value
|
||
monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金
|
||
unit_price = monthly_amount / self.total_area
|
||
unit_price = float_round(unit_price, precision_digits=2, rounding_method='HALF-UP')
|
||
# 开始时间, 结束时间
|
||
one_year_start = one_year[0]
|
||
one_year_end = one_year[1]
|
||
one_month_list = self.divide_time_range_fixed(one_year_start, one_year_end, 1)
|
||
for one_month in one_month_list:
|
||
period_rent = round(monthly_amount)
|
||
# 所有月统计
|
||
year_month_index += 1
|
||
# 如果开始时间 是 免租期月的结束时间,那么进入免租期日
|
||
if one_month[0] == free_start:
|
||
# 如果免租期有天那么默认增加一个月
|
||
if self.rent_free_period_days:
|
||
# 免租日的截至日期
|
||
free_day_start = one_month[1]
|
||
# 计算这个月的天数
|
||
total_days = (one_month[1] - one_month[0]).days
|
||
current_no_free = (total_days - self.rent_free_period_days) / total_days
|
||
period_rent = round(monthly_amount * current_no_free) if monthly_amount * current_no_free > 0 else 0
|
||
# 计算 免租期天的比值
|
||
free_start_day_dict = {
|
||
"unit_price": unit_price,
|
||
"monthly_amount": monthly_amount,
|
||
"breakdown_id": self.id,
|
||
"start_data": one_month[0],
|
||
"end_data": one_month[1] - relativedelta(days=1),
|
||
"month_number": 1,
|
||
"period_rent": period_rent,
|
||
}
|
||
all_period_rent += period_rent
|
||
|
||
# 已经跳出 免租期了 开始计费
|
||
if one_month[0] >= free_day_start:
|
||
current_days = calendar.monthrange(one_month[0].year, one_month[0].month)[1]
|
||
total_days = (one_month[1] - one_month[0]).days
|
||
# 说明不足月 单独计算
|
||
if current_days > total_days:
|
||
current_no_free = total_days / current_days
|
||
period_rent = round(monthly_amount * current_no_free) if monthly_amount * current_no_free > 0 else 0
|
||
monthly_amount_last_dict = {
|
||
"unit_price": unit_price,
|
||
"monthly_amount": monthly_amount,
|
||
"breakdown_id": self.id,
|
||
"start_data": one_month[0],
|
||
"end_data": one_month[1] - relativedelta(days=1),
|
||
"month_number": 1,
|
||
"period_rent": period_rent,
|
||
}
|
||
# 足月的单独进行计算
|
||
else:
|
||
if str(monthly_amount) in monthly_amount_new_dict:
|
||
amount_dict = monthly_amount_new_dict.get(str(monthly_amount))
|
||
old_period_rent = amount_dict.get("period_rent")
|
||
old_start_data = amount_dict.get("start_data")
|
||
old_end_data = amount_dict.get("end_data")
|
||
|
||
start_data = min(old_start_data, one_month[0])
|
||
end_data = max(old_end_data, one_month[1])
|
||
|
||
delta = relativedelta(end_data, start_data)
|
||
month_number = delta.years * 12 + delta.months
|
||
if delta.days:
|
||
month_number += 1
|
||
|
||
monthly_amount_new_dict[str(monthly_amount)] = {
|
||
"unit_price": unit_price,
|
||
"monthly_amount": monthly_amount,
|
||
"breakdown_id": self.id,
|
||
"start_data": start_data,
|
||
"end_data": end_data - relativedelta(days=1),
|
||
"month_number": month_number,
|
||
"period_rent": old_period_rent + period_rent,
|
||
}
|
||
else:
|
||
monthly_amount_new_dict[str(monthly_amount)] = {
|
||
"unit_price": unit_price,
|
||
"monthly_amount": monthly_amount,
|
||
"breakdown_id": self.id,
|
||
"start_data": one_month[0],
|
||
"end_data": one_month[1] - relativedelta(days=1),
|
||
"month_number": 1,
|
||
"period_rent": period_rent,
|
||
}
|
||
all_period_rent += period_rent
|
||
if write_db:
|
||
# 是否免租期 月
|
||
if free_start_dict:
|
||
self.sudo().write({'breakdown_ids': [(0, 0, free_start_dict)]})
|
||
|
||
# 是否免租期 日
|
||
if free_start_day_dict:
|
||
self.sudo().write({'breakdown_ids': [(0, 0, free_start_day_dict)]})
|
||
|
||
# 开始统计月份阶段金额
|
||
for k, v in monthly_amount_new_dict.items():
|
||
self.sudo().write({'breakdown_ids': [(0, 0, v)]})
|
||
|
||
# 最后有不足月的单独计算
|
||
if monthly_amount_last_dict:
|
||
self.sudo().write({'breakdown_ids': [(0, 0, monthly_amount_last_dict)]})
|
||
|
||
return all_period_rent
|
||
|
||
# def do_generate_details_core_1(self, start_date, end_date):
|
||
# """
|
||
# 计算核心算法
|
||
# :return:
|
||
# """
|
||
# all_period_rent = 0 # 总金额
|
||
# monthly_amount = self.total_area * self.unit_price
|
||
# monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金
|
||
# # 月租金
|
||
# unit_price = self.unit_price # 单价
|
||
#
|
||
# # 如果有免租期 月 时间进行到 start_date
|
||
# free_start = start_date
|
||
# if self.rent_free_period_month:
|
||
# free_start = start_date + relativedelta(months=self.rent_free_period_month)
|
||
# if free_start > end_date:
|
||
# free_start = end_date
|
||
# self.sudo().write({'breakdown_ids': [(0, 0, {
|
||
# "unit_price": unit_price,
|
||
# "monthly_amount": monthly_amount,
|
||
# "breakdown_id": self.id,
|
||
# "start_data": start_date,
|
||
# "end_data": free_start - relativedelta(days=1),
|
||
# "month_number": self.rent_free_period_month,
|
||
# "period_rent": 0,
|
||
# })]})
|
||
#
|
||
# # 如果没有递增 那么计算全部
|
||
# if not self.increments_every_few_years:
|
||
# # 如果免租期有天那么默认增加一个月
|
||
# # 如果有免增期 日
|
||
# free_start_day = free_start
|
||
# if self.rent_free_period_days:
|
||
# free_start_day = free_start + relativedelta(months=self.rent_free_period_days)
|
||
# if free_start_day < end_date:
|
||
# # 计算这个月的天数
|
||
# current_days = calendar.monthrange(free_start.year, free_start.month)[1]
|
||
# current_no_free = (current_days - self.rent_free_period_days) / current_days
|
||
# period_rent = monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0
|
||
# # 计算 免租期天的比值
|
||
# self.sudo().write({'breakdown_ids': [(0, 0, {
|
||
# "unit_price": unit_price,
|
||
# "monthly_amount": monthly_amount,
|
||
# "breakdown_id": self.id,
|
||
# "start_data": free_start,
|
||
# "end_data": free_start_day - relativedelta(days=1),
|
||
# "month_number": 1,
|
||
# "period_rent": period_rent,
|
||
# })]})
|
||
# all_period_rent += period_rent
|
||
#
|
||
# # 计算 剩余日期的金额
|
||
# if free_start_day < end_date:
|
||
# delta = relativedelta(end_date, free_start_day)
|
||
# months = delta.years * 12 + delta.months
|
||
# free_start_day_end = free_start_day + relativedelta(months=months)
|
||
# self.sudo().write({'breakdown_ids': [(0, 0, {
|
||
# "unit_price": unit_price,
|
||
# "monthly_amount": monthly_amount,
|
||
# "breakdown_id": self.id,
|
||
# "start_data": free_start_day,
|
||
# "end_data": free_start_day_end - relativedelta(days=1),
|
||
# "month_number": months,
|
||
# "period_rent": monthly_amount * months,
|
||
# })]})
|
||
# all_period_rent += monthly_amount * months
|
||
# # 说明最后还有几天
|
||
# if delta.days > 0:
|
||
# current_days = calendar.monthrange(free_start_day_end.year, free_start_day_end.month)[1]
|
||
# current_no_free = delta.days / current_days
|
||
# period_rent = monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0
|
||
# # 计算 免租期天的比值
|
||
# self.sudo().write({'breakdown_ids': [(0, 0, {
|
||
# "unit_price": unit_price,
|
||
# "monthly_amount": monthly_amount,
|
||
# "breakdown_id": self.id,
|
||
# "start_data": free_start_day_end,
|
||
# "end_data": end_date,
|
||
# "month_number": 1,
|
||
# "period_rent": period_rent,
|
||
# })]})
|
||
#
|
||
# # 如果有递增
|
||
# else:
|
||
# first_years_begin_end = start_date
|
||
# # 免递增年份计算
|
||
# if self.first_years_begin > 1:
|
||
# # 免递增结束时间
|
||
# first_years_begin_end = start_date + relativedelta(months=(self.first_years_begin -1) * 12)
|
||
# # 免租期结束时间 free_start
|
||
# # 计算免租期和免增期的差值, 如果免租期超过免增期那么不存在免增期
|
||
# if first_years_begin_end > free_start:
|
||
# # 如果免租期有天那么默认增加一个月
|
||
# if self.rent_free_period_days:
|
||
# # 计算这个月的天数
|
||
# current_days = calendar.monthrange(free_start.year, free_start.month)[1]
|
||
# current_no_free = (current_days - self.rent_free_period_days) / current_days
|
||
# # 计算 免租期天的比值
|
||
# self.sudo().write({'breakdown_ids': [(0, 0, {
|
||
# "unit_price": unit_price,
|
||
# "monthly_amount": monthly_amount,
|
||
# "breakdown_id": self.id,
|
||
# "start_data": free_start,
|
||
# "end_data": free_start + relativedelta(months=1) - relativedelta(days=1),
|
||
# "month_number": 1,
|
||
# "period_rent": monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0,
|
||
# })]})
|
||
# new_free_day_amount = monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0
|
||
# all_period_rent += new_free_day_amount
|
||
# # 免租期后退一个月
|
||
# free_start = free_start + relativedelta(months=1)
|
||
# # 计算剩下的免增期
|
||
# delta = relativedelta(first_years_begin_end, free_start)
|
||
# first_months = delta.years * 12 + delta.months
|
||
# self.sudo().write({'breakdown_ids': [(0, 0, {
|
||
# "unit_price": unit_price,
|
||
# "monthly_amount": monthly_amount,
|
||
# "breakdown_id": self.id,
|
||
# "start_data": free_start,
|
||
# "end_data": first_years_begin_end - relativedelta(days=1),
|
||
# "month_number": first_months,
|
||
# "period_rent": first_months * monthly_amount,
|
||
# })]})
|
||
# all_period_rent += first_months * monthly_amount
|
||
# # 免增期结束开始递增
|
||
# divided_increments_segments = self.divide_time_range_fixed(first_years_begin_end, end_date, increments_every_few_years*12)
|
||
# year_index = 0 # 第几递增周期年
|
||
# all_months = 0 # 递增的第几个月
|
||
# # 如果免租期 超过 免增期 那么递增期也需要排除
|
||
# if first_years_begin_end < free_start:
|
||
# delta = relativedelta(free_start, first_years_begin_end)
|
||
# free_first_months = delta.years * 12 + delta.months
|
||
# # 如果免租期有天那么默认增加一个月
|
||
# if self.rent_free_period_days:
|
||
# free_first_months = free_first_months + 1
|
||
# else:
|
||
# free_first_months = 0
|
||
#
|
||
# for increments_year in divided_increments_segments:
|
||
# year_index += 1
|
||
# """
|
||
# increment_percentage = fields.Float(string="递增百分比")
|
||
# increment_price = fields.Float(string="递增单价")
|
||
# increment_amount = fields.Float(string="递增金额")
|
||
# """
|
||
# increments_month = 0
|
||
# # delta = relativedelta(increments_year[1], increments_year[0])
|
||
# # months = delta.years * 12 + delta.months
|
||
# if self.increment_method == "increment_price" and self.increment_value:
|
||
# unit_price = unit_price + self.increment_value
|
||
# monthly_amount = self.total_area * unit_price
|
||
# monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金
|
||
# if self.increment_method == "percentage" and self.increment_value:
|
||
# unit_price = unit_price * (1 + (self.increment_value / 100))
|
||
# monthly_amount = self.total_area * unit_price
|
||
# monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金
|
||
# if self.increment_method == "increment_amount" and self.increment_value:
|
||
# monthly_amount = monthly_amount + self.increment_value
|
||
# monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金
|
||
# unit_price = monthly_amount / self.total_area
|
||
#
|
||
# delta = relativedelta(increments_year[1], increments_year[0])
|
||
# months = delta.years * 12 + delta.months
|
||
# month_index = 0
|
||
# # 判断第几月份进入 付费租期
|
||
# for month in range(months):
|
||
# month_index += 1 # 当前第个月
|
||
# # 判断第几月份进入 付费租期
|
||
# all_months += 1
|
||
# if all_months == free_first_months:
|
||
# # 如果免租期有天那么默认增加一个月
|
||
# if self.rent_free_period_days:
|
||
# current_now = increments_year[0] + relativedelta(months=month_index)
|
||
# # 计算这个月的天数
|
||
# current_days = calendar.monthrange(current_now.year, current_now.month)[1]
|
||
# current_no_free = (current_days - self.rent_free_period_days) / current_days
|
||
# # 计算 免租期天的比值
|
||
# self.sudo().write({'breakdown_ids': [(0, 0, {
|
||
# "unit_price": unit_price,
|
||
# "monthly_amount": monthly_amount,
|
||
# "breakdown_id": self.id,
|
||
# "start_data": current_now,
|
||
# "end_data": current_now + relativedelta(months=1) - relativedelta(days=1),
|
||
# "month_number": 1,
|
||
# "period_rent": monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0,
|
||
# })]})
|
||
# new_free_day_amount = monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0
|
||
# all_period_rent += new_free_day_amount
|
||
# # 判断是否是免租期
|
||
# if all_months > free_first_months:
|
||
# increments_month += 1
|
||
# if increments_month:
|
||
# self.sudo().write({'breakdown_ids': [(0, 0, {
|
||
# "unit_price": unit_price,
|
||
# "monthly_amount": monthly_amount,
|
||
# "breakdown_id": self.id,
|
||
# "start_data": increments_year[1] - relativedelta(months=increments_month),
|
||
# "end_data": increments_year[1] - relativedelta(days=1),
|
||
# "month_number": increments_month,
|
||
# "period_rent": monthly_amount * increments_month,
|
||
# })]})
|
||
# all_period_rent += monthly_amount * increments_month
|
||
# return all_period_rent
|
||
|
||
# @api.onchange("first_year_rent")
|
||
# def _onchange_first_year_rent(self):
|
||
# for rec in self:
|
||
# rec.performance_bonds = rec.first_year_rent * 2
|
||
|
||
# @api.onchange("total_area", "unit_price")
|
||
# def _onchange_deposit(self):
|
||
# for record in self:
|
||
# record.deposit = record.total_area * record.unit_price * 2 # 月租金
|
||
|
||
@api.onchange('rent')
|
||
def _onchange_deposit(self):
|
||
for record in self:
|
||
if record.rent:
|
||
record.deposit = record.rent * 2
|
||
else:
|
||
record.deposit = 0.0
|
||
|
||
def update_lease_ids(self):
|
||
property_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for rec in property_ids:
|
||
lease_name = []
|
||
electricity_list = []
|
||
water_list = []
|
||
title_address = []
|
||
fee_list = []
|
||
for record in rec.lease_ids:
|
||
if record.address_id and record.address_id.title_address:
|
||
lease_name.append(record.address_id.name)
|
||
title_address.append(record.address_id.title_address.name)
|
||
rec.name = ','.join(lease_name)
|
||
rec.use_address = ','.join(lease_name)
|
||
rec.title_address = ','.join(title_address)
|
||
property_id = self.env['yuthon.property'].search([('id', '=', record.address_id.id)])
|
||
if property_id.energy_meter_ids:
|
||
rec.is_electricity = True
|
||
for electricity_id in property_id.energy_meter_ids:
|
||
electricity_list.append([0, 0, {
|
||
'fees_id': electricity_id.standard_id.id,
|
||
'proportional': electricity_id.rate,
|
||
}])
|
||
else:
|
||
rec.is_electricity = False
|
||
if property_id.water_meter_ids:
|
||
rec.is_water = True
|
||
for water_id in property_id.water_meter_ids:
|
||
water_list.append([0, 0, {
|
||
'fees_id': water_id.standard_id.id,
|
||
'proportional': water_id.rate,
|
||
}])
|
||
else:
|
||
rec.is_water = False
|
||
if property_id.is_message_fee:
|
||
rec.is_mange = True
|
||
standard_id = property_id.message_standard_id
|
||
fee_list.append([0, 0, {
|
||
'fees_id': standard_id.id,
|
||
'proportional': standard_id.amount}])
|
||
else:
|
||
rec.is_mange = False
|
||
|
||
rec.electricity_fee_ids = [(5, 0, 0)]
|
||
rec.mange_fee_ids = [(5, 0, 0)]
|
||
rec.admin_id = rec.lease_ids[0].admin_line_id.id if rec.lease_ids else ''
|
||
rec.tenure_type = rec.lease_ids[0].address_id.tenure_type if rec.lease_ids else ''
|
||
rec.lessor_id = rec.lease_ids[0].address_id.company_id.id if rec.lease_ids else ''
|
||
rec.precinct_id = rec.lease_ids[0].address_id.precinct_id.id if rec.lease_ids else ''
|
||
rec.total_area = sum([lease.property_area for lease in rec.lease_ids])
|
||
rec.electricity_fee_ids = electricity_list
|
||
rec.mange_fee_ids = fee_list
|
||
|
||
def trigger_lease_ids(self):
|
||
property_ids = self.env["property.lease.contract"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in property_ids:
|
||
lessor_id = record.lease_ids[-1].address_id.company_id.id if record.lease_ids else ''
|
||
admin_id = record.lease_ids[-1].admin_line_id.id if record.lease_ids else ''
|
||
tenure_type = record.lease_ids[-1].address_id.tenure_type if record.lease_ids else ''
|
||
record.sudo().write({'lessor_id': lessor_id,
|
||
'admin_id': admin_id,
|
||
'tenure_type':tenure_type,
|
||
'precinct_id': record.lease_ids[0].address_id.precinct_id.id if record.lease_ids else '',})
|
||
|
||
def action_yuthon_property_contract_wizard(self):
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"name": "批量导入物业合同",
|
||
"res_model": "property.contract.wizard",
|
||
"view_mode": "form",
|
||
"target": "new",
|
||
}
|
||
|
||
def action_relevance_property(self):
|
||
contract_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id'))
|
||
)
|
||
contract_dict = {
|
||
'lease_renewal': '续租',
|
||
'interim': '临租',
|
||
'new': '补充协议',
|
||
'first': '首租'
|
||
}
|
||
for record in contract_ids:
|
||
if record.contract_code and record.property_name and record.contract_type:
|
||
record.name = f"{record.contract_code}{contract_dict.get(record.contract_type)}{record.property_name}"
|
||
elif record.contract_code and record.property_name:
|
||
record.name = f"{record.contract_code}{record.property_name}"
|
||
elif record.name:
|
||
record.name = record.property_name
|
||
else:
|
||
record.name = self._description
|
||
|
||
lease_name = []
|
||
if record.lease_ids:
|
||
for lease in record.lease_ids:
|
||
if lease.address_id and lease.address_id.name:
|
||
lease_name.append(str(lease.address_id.name))
|
||
record.write({
|
||
'property_name': ','.join(lease_name) if lease_name else ''
|
||
})
|
||
|
||
def action_update_contract(self):
|
||
contract_ids = self.env["property.lease.contract"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in contract_ids:
|
||
record._compute_department_id()
|
||
|
||
@api.constrains("contract_code")
|
||
def _check_contract_code(self):
|
||
"""检查合同编号的唯一性(不区分中英文括号)"""
|
||
if self.env.context.get('skip_contract_code_check'):
|
||
return
|
||
for record in self:
|
||
normalized_code = self._normalize_contract_code(record.contract_code)
|
||
existing_records = self.search([
|
||
('id', '!=', record.id),
|
||
('contract_code', '!=', False),
|
||
])
|
||
for existing in existing_records:
|
||
if self._normalize_contract_code(existing.contract_code) == normalized_code:
|
||
raise ValidationError(_(
|
||
f"合同编号必须唯一!已存在编号:{existing.contract_code}",
|
||
))
|
||
|
||
def _normalize_contract_code(self, code):
|
||
"""将合同编号中的括号统一为中文括号"""
|
||
if not code:
|
||
return code
|
||
|
||
# 替换中英文括号为统一格式
|
||
code = re.sub(r'[(]', '(', code) # 替换左括号
|
||
code = re.sub(r'[)]', ')', code) # 替换右括号
|
||
return code
|
||
|
||
def action_copy_record1(self):
|
||
lease_contract_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in lease_contract_ids:
|
||
if len(lease_contract_ids) > 1:
|
||
raise UserError("只能选择一个拆分")
|
||
record.is_contract = True
|
||
record.is_child_contract = False
|
||
record.is_split = True
|
||
record.number += 1
|
||
contract_id = self.env['property.lease.contract'].create({
|
||
'property_name': record.property_name,
|
||
'is_child_contract': True,
|
||
'is_contract': False,
|
||
'contract_source_id': record.id,
|
||
'actual_start_time': record.actual_start_time,
|
||
'actual_end_time': record.actual_end_time,
|
||
'contract_code': record.contract_code+ f'-{record.number}',
|
||
'contract_date': record.contract_date,
|
||
'lessee_id': record.lessee_id.id,
|
||
'use_address': record.use_address,
|
||
'condition':'new',
|
||
'admin_id': record.admin_id.id,
|
||
'lessor_id':record.lessor_id.id,
|
||
'rental_purposes': record.rental_purposes.id,
|
||
'address_for_delivery': record.address_for_delivery,
|
||
# 'lease_term': record.lease_term,
|
||
'lease_term_year': record.lease_term_year,
|
||
'lease_term_month': record.lease_term_month,
|
||
'term_end_time': record.term_end_time,
|
||
'cycle_dict': record.cycle_dict,
|
||
'cycle_mode': record.cycle_mode,
|
||
'increment_method': record.increment_method,
|
||
# 'increment_percentage': record.increment_percentage,
|
||
# 'increment_price': record.increment_price,
|
||
# 'increment_amount': record.increment_amount,
|
||
'increment_value': record.increment_value,
|
||
'first_years_begin': record.first_years_begin,
|
||
'increments_every_few_years': record.increments_every_few_years,
|
||
'rent_free_period': record.rent_free_period,
|
||
'rent_free_period_month': record.rent_free_period_month,
|
||
'rent_free_period_days': record.rent_free_period_days,
|
||
'breach': record.breach,
|
||
'percentage_liquidated_damages': record.percentage_liquidated_damages.id,
|
||
'first_pay': record.first_pay,
|
||
'unit_price': record.unit_price,
|
||
'deposit_type': record.deposit_type,
|
||
'performance_bonds_write': record.performance_bonds_write,
|
||
'first_year_rent': record.first_year_rent,
|
||
'deposit': record.deposit,
|
||
'rent': record.rent,
|
||
'total_contract_receivables': record.total_contract_receivables,
|
||
'tax_rate': record.tax_rate.id,
|
||
'not_tax_amount': record.not_tax_amount,
|
||
'tax': record.tax,
|
||
'is_water': record.is_water,
|
||
'is_electricity': record.is_electricity,
|
||
'is_mange': record.is_mange,
|
||
'miscellaneous': record.miscellaneous,
|
||
'total_area': record.total_area,
|
||
'contract_type': record.contract_type,
|
||
})
|
||
lease_list = []
|
||
for lease_id in record.lease_ids:
|
||
lease_list.append([0, 0, {
|
||
'lease_id':contract_id.id,
|
||
'address_id':lease_id.address_id.id,
|
||
'evaluate_unit_price': lease_id.evaluate_unit_price,
|
||
}])
|
||
breakdown_list = []
|
||
if record.breakdown_ids:
|
||
for breakdown_id in record.breakdown_ids:
|
||
breakdown_list.append([0, 0, {
|
||
'breakdown_id':contract_id.id,
|
||
'charges': breakdown_id.charges,
|
||
'unit_price': breakdown_id.unit_price,
|
||
'monthly_amount': breakdown_id.monthly_amount,
|
||
'start_data': breakdown_id.start_data,
|
||
'end_data': breakdown_id.end_data,
|
||
'month_number': breakdown_id.month_number,
|
||
'period_rent': breakdown_id.period_rent,
|
||
}])
|
||
water_fee_list = []
|
||
if record.water_fee_ids:
|
||
for water_fee_id in record.water_fee_ids:
|
||
water_fee_list.append([0, 0, {
|
||
'contract_id':contract_id.id,
|
||
'address_id':water_fee_id.address_id.id,
|
||
'charges': water_fee_id.charges,
|
||
'fees_id': water_fee_id.fees_id.id,
|
||
'proportional': water_fee_id.proportional,
|
||
}])
|
||
electricity_fee_list = []
|
||
if record.electricity_fee_ids:
|
||
for electricity_fee_id in record.electricity_fee_ids:
|
||
electricity_fee_list.append([0, 0, {
|
||
'contract_id':contract_id.id,
|
||
'charges': electricity_fee_id.charges,
|
||
'fees_id': electricity_fee_id.fees_id.id,
|
||
'proportional': electricity_fee_id.proportional,
|
||
}])
|
||
mange_fee_list = []
|
||
if record.mange_fee_ids:
|
||
for mange_fee_id in record.mange_fee_ids:
|
||
mange_fee_list.append([0, 0, {
|
||
'contract_id': contract_id.id,
|
||
'charges': mange_fee_id.charges,
|
||
'fees_id': mange_fee_id.fees_id.id,
|
||
'proportional': mange_fee_id.proportional,
|
||
}])
|
||
other_list = []
|
||
if record.other_ids:
|
||
for other_id in record.other_ids:
|
||
other_list.append([0, 0, {
|
||
'other_id': contract_id.id,
|
||
'charges': other_id.charges,
|
||
'coping': other_id.coping.id,
|
||
'coping_time': other_id.coping_time,
|
||
}])
|
||
rent_list = []
|
||
if record.rent_list_ids:
|
||
for rent in record.rent_list_ids:
|
||
rent_list.append([0, 0, {
|
||
'contract_id': contract_id.id,
|
||
}])
|
||
|
||
# management_list = []
|
||
# if record.management_list_ids:
|
||
# for record in record.management_list_ids:
|
||
# management_list.append([0, 0, {
|
||
# 'contract_id': contract_id.id,
|
||
# }])
|
||
subset_list = []
|
||
subset_list.append([0, 0, {
|
||
'subset_id': record.id,
|
||
'contract_id': contract_id.id}])
|
||
record.subset_ids = subset_list
|
||
contract_id.write({
|
||
'lease_ids': lease_list,
|
||
'breakdown_ids': breakdown_list,
|
||
'water_fee_ids': water_fee_list,
|
||
'electricity_fee_ids': electricity_fee_list,
|
||
'mange_fee_ids': mange_fee_list,
|
||
'other_ids': other_list,
|
||
'rent_list_ids': rent_list,})
|
||
# 'management_list_ids':management_list,})
|
||
|
||
def disposable_button(self):
|
||
property_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in property_ids:
|
||
admin_id = record.admin_id
|
||
if admin_id:
|
||
record.write({
|
||
'users_id': admin_id.id,
|
||
'company_id' : admin_id.employee_id.company_id.id,
|
||
})
|
||
|
||
def choose_property_button(self):
|
||
address_ids = self.lease_ids.mapped('address_id').filtered(lambda r: r)
|
||
property_ids2 = address_ids.ids
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"name": "批量选择物业信息",
|
||
"res_model": "choose.property.wizard",
|
||
"view_mode": "form",
|
||
"target": "new",
|
||
"context": {
|
||
'default_lease_contract_id': self.id,
|
||
'default_property_ids2': property_ids2,
|
||
}
|
||
}
|
||
|
||
@api.depends('term_start_time', 'term_end_time')
|
||
def _compute_progress_percentage(self):
|
||
for record in self:
|
||
if record.term_start_time and record.term_end_time:
|
||
# 将字段值从 Date 类型转换为 datetime 类型(默认为 00:00:00 时间)
|
||
start_time = fields.Date.from_string(record.term_start_time)
|
||
end_time = fields.Date.from_string(record.term_end_time)
|
||
current_time = fields.Date.today()
|
||
total_duration = (end_time - start_time).days
|
||
elapsed_time = (current_time - start_time).days
|
||
if current_time < start_time:
|
||
record.progress_percentage = 0
|
||
# 如果总天数差不为零,则计算进度百分比
|
||
elif total_duration > 0:
|
||
record.progress_percentage = (elapsed_time / total_duration) * 100
|
||
else:
|
||
record.progress_percentage = 0
|
||
else:
|
||
record.progress_percentage = 0
|
||
|
||
@api.onchange("name")
|
||
def _onchange_name(self):
|
||
if self.property_name:
|
||
self.address_for_delivery = self.property_name
|
||
self.use_address = self.property_name
|
||
|
||
@api.depends("lease_ids")
|
||
def _compute_admin_id(self):
|
||
for record in self:
|
||
if record.lease_ids:
|
||
record.admin_id = record.lease_ids[0].admin_line_id.id
|
||
|
||
@api.onchange("admin_id")
|
||
def _onchange_admin_id(self):
|
||
if self.admin_id:
|
||
self.users_id = self.admin_id.user_id.id
|
||
|
||
|
||
def get_property_contract_time(self):
|
||
records_only_in_tree1 = self.env['property.lease.contract'].search([
|
||
('condition', 'not in', ['new', 'approval', 'cancel'])
|
||
])
|
||
today = fields.Date.today()
|
||
for contract in records_only_in_tree1:
|
||
# 获取时间字段
|
||
actual_start = contract.actual_start_time
|
||
actual_end = contract.actual_end_time
|
||
term_end = contract.term_end_time
|
||
effective_month = None
|
||
if actual_end:
|
||
# 获取实际结束日期所在月的最后一天
|
||
last_day_of_month = calendar.monthrange(actual_end.year, actual_end.month)[1]
|
||
if actual_end.day == last_day_of_month:
|
||
# 如果是最后一天,生效月份为下月
|
||
effective_month = fields.Date.to_date(f"{actual_end.year}-{actual_end.month}-{last_day_of_month}")
|
||
else:
|
||
# 如果不是最后一天,生效月份为当月
|
||
effective_month = fields.Date.to_date(f"{actual_end.year}-{actual_end.month}-01")
|
||
|
||
# 根据时间条件更新状态
|
||
if not actual_start or today < actual_start:
|
||
# 待执行:实际开始时间未到或未设置
|
||
contract.contact_state = 'to'
|
||
elif actual_start and (not actual_end or today < actual_end):
|
||
# 执行中:已开始且未结束(或结束时间未设置)
|
||
contract.contact_state = 'ing'
|
||
elif today >= actual_end == term_end:
|
||
contract.contact_state = 'complete'
|
||
elif effective_month and today >= effective_month < term_end:
|
||
contract.contact_state = 'terminate'
|
||
|
||
|
||
# 续租
|
||
def button_lease_extension(self):
|
||
lease_contract_ids = self.env["property.lease.contract"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
if len(lease_contract_ids) > 1:
|
||
raise UserError("只能单个操作合同续租")
|
||
for original_contract in lease_contract_ids:
|
||
new_contract = original_contract.with_context(skip_contract_code_check=True).copy()
|
||
new_term_start = original_contract.term_end_time + timedelta(
|
||
days=1) if original_contract.term_end_time else False
|
||
new_contract.write({
|
||
'admin_id': original_contract.admin_id,
|
||
'contract_code': None,
|
||
'lease_term_year': None,
|
||
'term_start_time': new_term_start,
|
||
'term_end_time': None,
|
||
'condition':'new',
|
||
'contract_id': original_contract.id,
|
||
'contract_type': 'lease_renewal'
|
||
})
|
||
water_lines = self.env['property.water.fee.line'].search([
|
||
('contract_id', '=', original_contract.id)
|
||
])
|
||
for line in water_lines:
|
||
line.copy({'contract_id': new_contract.id})
|
||
# 复制电费明细行
|
||
electric_lines = self.env['property.electric.fee.line'].search([
|
||
('contract_id', '=', original_contract.id)
|
||
])
|
||
for line in electric_lines:
|
||
line.copy({'contract_id': new_contract.id})
|
||
# 复制物业管理费明细行
|
||
manage_lines = self.env['property.manage.fee.line'].search([
|
||
('contract_id', '=', original_contract.id)
|
||
])
|
||
for line in manage_lines:
|
||
line.copy({'contract_id': new_contract.id})
|
||
# 复制其他费用明细行
|
||
other_lines = self.env['property.other.fee.line'].search([
|
||
('other_id', '=', original_contract.id)
|
||
])
|
||
for line in other_lines:
|
||
line.copy({'other_id': new_contract.id})
|
||
# 复制子合同明细
|
||
subset_lines = self.env['property.subset.contract'].search([
|
||
('subset_id', '=', original_contract.id)
|
||
])
|
||
for line in subset_lines:
|
||
line.copy({'subset_id': new_contract.id})
|
||
lease_lines = self.env['property.lease.contract.line'].search([
|
||
('lease_id', '=', original_contract.id)
|
||
])
|
||
for line in lease_lines:
|
||
line.copy({'lease_id': new_contract.id})
|
||
new_contract._compute_name()
|
||
return {
|
||
'type': 'ir.actions.act_window',
|
||
'name': '续期合同',
|
||
'res_model': 'property.lease.contract',
|
||
'view_mode': 'form',
|
||
'res_id': new_contract.id, # 指定新合同的ID
|
||
'target': 'current',
|
||
}
|
||
|
||
# 变更
|
||
def button_lease_change(self):
|
||
form_id = self.env.ref('yuthon_property_approval.view_property_lease_renewal_form').id
|
||
return {
|
||
'name': '变更申请',
|
||
"type": "ir.actions.act_window",
|
||
'view_mode': 'form',
|
||
'res_model': 'property.lease.renewal',
|
||
"views": [[form_id, "form"]],
|
||
"context": {
|
||
'default_renewal_type': 'lease',
|
||
'default_contract_id': self.id,
|
||
},
|
||
}
|
||
|
||
def read_coming_count(self):
|
||
return self.search_count([('expiration_coming', '=', 'coming'), ('admin_id', '=', self.env.user.id)])
|
||
|
||
def read_due_count(self):
|
||
return self.search_count([('expiration_coming', '=', 'due'), ('admin_id', '=', self.env.user.id)])
|
||
|
||
def put_evaluation_plan(self):
|
||
for record in self:
|
||
property_ids = []
|
||
rent_area = 0
|
||
first_address_id = record.lease_ids[0].admin_line_id if record.lease_ids else None
|
||
for lease_id in record.lease_ids:
|
||
property_ids.append(lease_id.address_id.id)
|
||
rent_area += lease_id.address_id.rent_area
|
||
self.env['property.evaluation.plan'].create({
|
||
'property_name': record.property_name,
|
||
'property_ids': [(6, 0, property_ids)],
|
||
'evaluation_area': rent_area,
|
||
'owner_id': first_address_id.title_information_ids[0].owner_id.id if first_address_id and first_address_id.title_information_ids else None,
|
||
'registered_id': first_address_id.title_information_ids[0].registered_id.id if first_address_id and first_address_id.title_information_ids else None,
|
||
'rent_id': first_address_id.reference_ids[0].rent_id.id if first_address_id and first_address_id.reference_ids else None,
|
||
'lease_period': first_address_id.reference_ids[0].lease_period if first_address_id and first_address_id.reference_ids else None,
|
||
'annual_increase_percentage': first_address_id.reference_ids[0].annual_increase_percentage if first_address_id and first_address_id.reference_ids else None,
|
||
'remake': first_address_id.remark if first_address_id else None,
|
||
'assessment_category': 'rent_money',
|
||
})
|
||
record.write({'contact_state': 'ing'})
|
||
return {
|
||
"name": "物业评估方案",
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'property.evaluation.plan',
|
||
"view_mode": "tree",
|
||
}
|
||
|
||
def all_put_evaluation_plan(self):
|
||
contract_ids = self.env["property.lease.contract"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in contract_ids:
|
||
property_ids = []
|
||
property_id = record.lease_ids[0].admin_line_id
|
||
if record.contact_state == 'done':
|
||
raise UserError(f'{record.property_name}该物业已评估,请勿重复评估')
|
||
rent_area = 0
|
||
for lease_id in record.lease_ids:
|
||
property_ids.append(lease_id.address_id.id)
|
||
rent_area += lease_id.address_id.rent_area
|
||
self.env['property.evaluation.plan'].create({
|
||
'property_name': record.property_name,
|
||
'property_ids': property_ids,
|
||
'evaluation_area': property_id.rent_area,
|
||
'owner_id': property_id.title_information_ids[0].owner_id.id if property_id.title_information_ids else None,
|
||
'registered_id': property_id.title_information_ids[0].registered_id.id if property_id.title_information_ids else None,
|
||
'rent_id': property_id.reference_ids[0].rent_id.id if property_id.reference_ids else None,
|
||
'lease_period': property_id.reference_ids[0].lease_period if property_id.reference_ids else None,
|
||
'annual_increase_percentage': property_id.reference_ids[0].annual_increase_percentage if property_id.reference_ids else None,
|
||
'remake': property_id.remark,
|
||
'assessment_category': 'rent_money',
|
||
})
|
||
record.write({'contact_state': 'ing'})
|
||
return {
|
||
"name": "物业评估方案",
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'property.evaluation.plan',
|
||
"view_mode": "tree",
|
||
}
|
||
|
||
class PropertyLeaseContractLine(models.Model):
|
||
_name = 'property.lease.contract.line'
|
||
_description = '物业列表明细行'
|
||
|
||
lease_id = fields.Many2one('property.lease.contract', string="关联凭租合同审批")
|
||
address_id = fields.Many2one('yuthon.property', string="物业地址")
|
||
admin_line_id = fields.Many2one(related='address_id.admin_id', string="管理员")
|
||
property_area = fields.Float(related='address_id.management_area', string="面积")
|
||
message_standard_id = fields.Many2one(related='address_id.message_standard_id', string="管理费标准")
|
||
evaluate_unit_price = fields.Float(string="评估单价")
|
||
|
||
|
||
class PropertyRentBreakdownLine(models.Model):
|
||
_name = 'property.rent.breakdown.line'
|
||
_description = '物业租金明细行'
|
||
|
||
breakdown_id = fields.Many2one('property.lease.contract', string="关联租赁合同审批")
|
||
charges = fields.Char(string="收费项")
|
||
unit_price = fields.Float(string="单价")
|
||
monthly_amount = fields.Float(string="月租金", digits=(16, 2))
|
||
start_data = fields.Date(string="开始日期")
|
||
end_data = fields.Date(string="结束日期")
|
||
month_number = fields.Integer(string="期间月数")
|
||
period_rent = fields.Float(string="期间租金", digits=(16, 2))
|
||
|
||
@api.onchange('monthly_amount')
|
||
def _onchange_monthly_amount(self):
|
||
self.period_rent = self.monthly_amount * self.month_number
|
||
|
||
class PropertyWaterFeeLine(models.Model):
|
||
_name = 'property.water.fee.line'
|
||
_description = '物业水费明细行'
|
||
|
||
contract_id = fields.Many2one('property.lease.contract', string="关联租赁合同审批")
|
||
property_meter_water_id = fields.Many2one('property.meter.water', string="水表库")
|
||
rate = fields.Integer(related='property_meter_water_id.gauge_magnification', string="倍率", store=True)
|
||
standard_id = fields.Many2one(related='property_meter_water_id.standards_id', string="标准", store=True)
|
||
installation_date = fields.Date(related='property_meter_water_id.start_time', string="安装日期")
|
||
demolition_date = fields.Date(related='property_meter_water_id.end_time', string="拆除日期")
|
||
location = fields.Char(related='property_meter_water_id.installation_location', string="位置")
|
||
|
||
class PropertyElectricFeeLine(models.Model):
|
||
_name = 'property.electric.fee.line'
|
||
_description = '物业电费明细行'
|
||
|
||
contract_id = fields.Many2one('property.lease.contract', string="关联租赁合同审批")
|
||
property_meter_archives_id = fields.Many2one('property.meter.archives', string="电表库")
|
||
rate = fields.Integer(related='property_meter_archives_id.gauge_magnification', string="倍率", store=True)
|
||
standard_id = fields.Many2one(related='property_meter_archives_id.standards_id', string="标准", store=True)
|
||
installation_date = fields.Date(related='property_meter_archives_id.start_time', string="安装日期")
|
||
demolition_date = fields.Date(related='property_meter_archives_id.end_time', string="拆除日期")
|
||
location = fields.Char(related='property_meter_archives_id.installation_location', string="位置")
|
||
|
||
|
||
class PropertyManageFeeLine(models.Model):
|
||
_name = 'property.manage.fee.line'
|
||
_description = '物业管理费明细行'
|
||
|
||
contract_id = fields.Many2one('property.lease.contract', string="关联租赁合同审批")
|
||
charges = fields.Char(string="收费项")
|
||
fees_id = fields.Many2one('property.message.fee', string="收费标准")
|
||
proportional = fields.Float(string="倍率/比例")
|
||
|
||
|
||
class PropertyOtherFeeLine(models.Model):
|
||
_name = 'property.other.fee.line'
|
||
_description = '物业其他费用明细行'
|
||
|
||
other_id = fields.Many2one('property.lease.contract', string="关联租赁合同审批")
|
||
charges = fields.Char(string="收费项")
|
||
coping = fields.Float(string="应收")
|
||
coping_time = fields.Date(string="应收日期")
|
||
|
||
class PropertySubsetContract(models.Model):
|
||
_name = 'property.subset.contract'
|
||
_description = '物业子合同明细'
|
||
|
||
subset_id = fields.Many2one('property.lease.contract', string="关联租赁合同审批")
|
||
contract_id = fields.Many2one('property.lease.contract', string="合同")
|
||
name = fields.Char(related='contract_id.name', string="物业信息")
|
||
lessee_id = fields.Many2one(related='contract_id.lessee_id', string="承租方")
|
||
rental_purposes = fields.Many2one(related='contract_id.rental_purposes', string="出租用途") |