960 lines
46 KiB
Python
960 lines
46 KiB
Python
from odoo import models, fields, api
|
||
from odoo.exceptions import UserError, ValidationError
|
||
from pypinyin import pinyin,lazy_pinyin
|
||
from datetime import datetime,date
|
||
import calendar
|
||
|
||
|
||
class YuthonProperty(models.Model):
|
||
_name = 'yuthon.property'
|
||
_description = '物业管理'
|
||
_inherit = ['mail.thread.main.attachment', 'mail.activity.mixin']
|
||
_rec_name = 'name'
|
||
_order = 'first_letter'
|
||
|
||
name = fields.Text(string="资产名称")
|
||
tax = fields.Float(string="税率", default=0.09)
|
||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||
code = fields.Char(string="物业编号", default=lambda self: self.env['ir.sequence'].next_by_code('yuthon_property_message_code'))
|
||
referred_id = fields.Many2one('yuthon.lot.setting', string="地段")
|
||
units = fields.Char(string="单元")
|
||
house_type_id = fields.Many2one('yuthon.resource.house.type', string="户型")
|
||
district = fields.Char(string="区")
|
||
|
||
building_area = fields.Float(string="建筑面积", digits=(16, 4))
|
||
title_deed = fields.Char(string="产权证号", compute="_compute_title_information_fields", store=True)
|
||
effective_date = fields.Date(string="生效日期", compute="compute_information_fields", store=True)
|
||
end_date = fields.Date(string="失效日期", compute="compute_information_fields", store=True)
|
||
property_source = fields.Selection([('cut', '划入'), ('self', '自建'),
|
||
('replace', '置换'), ('buy', '购入'),
|
||
('entrust', '委托'), ('Rent', '租入')], string='资产来源')
|
||
remark = fields.Char(string="备注")
|
||
vr_link = fields.Char(string="VR链接")
|
||
current_rent = fields.Float(string="现租金")
|
||
is_done_split = fields.Boolean(string="已拆分")
|
||
is_done_merge = fields.Boolean(string="已合并")
|
||
property_building_id = fields.Many2one('property.floor.setting', string="楼盘")
|
||
property_floor_id = fields.Many2one('property.floor.setting', string="楼层")
|
||
property_orientation = fields.Selection([('north', '东'), ('south', '南'), ('east', '西'), ('west', '北')],
|
||
string="朝向")
|
||
street = fields.Char(string="街道")
|
||
property_state = fields.Selection([('on_rent', '在租'), ('vacant', '空置')], string='租赁状态', default='on_rent')
|
||
property_leasing = fields.Selection([('to', '待评估'), ('ing', '评估中'), ('done', '已评估'), ('net', '挂网'), ('signing', '签约中')], string='评估状态', default='to')
|
||
purpose_id = fields.Many2one('yuthon.resource.purpose', string="管理类型", compute="compute_information_fields", store=True)
|
||
is_meter = fields.Boolean(string="水表")
|
||
live_room = fields.Many2one('yuthon.live.room', string="居住用房")
|
||
is_electricity_meter = fields.Boolean(string="电表")
|
||
is_confirm_authorization = fields.Boolean(string="确权")
|
||
property_card = fields.Html(string="产权证")
|
||
asset_type_id = fields.Many2one('yuthon.resource.type', string="出租类型")
|
||
is_hvac = fields.Boolean(string="使用中央空调")
|
||
is_handle_land = fields.Boolean(string="办理土地有偿使用手续")
|
||
property_use_id = fields.Integer(string="物业用途ID")
|
||
image_1920 = fields.Image(string="图片")
|
||
description = fields.Html(string="描述")
|
||
is_message_fee = fields.Boolean(string="管理费")
|
||
financial_address = fields.Char(string="财务地址")
|
||
message_standard_id = fields.Many2one('property.message.fee', string="管理费标准")
|
||
rental_unit_price = fields.Float(string="评估单价")
|
||
title_number = fields.Char(string="产权编号")
|
||
suite_area = fields.Float(string="套内面积", digits=(16, 4))
|
||
admin_id = fields.Many2one('res.users', string="片区管理员", compute="compute_information_fields", store=True)
|
||
lessee_id = fields.Many2one('property.tenant.information', string='承租方', compute="_compute_lessee_id")
|
||
title_address = fields.Many2one('yuthon.property.message', string="产权地址", compute="_compute_title_information_fields", store=True)
|
||
company_id = fields.Many2one('yuthon.property.company', string="公司", compute="compute_information_fields", store=True)
|
||
rental_address = fields.Text(string="出租地址")
|
||
tenure_type = fields.Selection([('self', '自有'), ('agency', '代管')], string='权属类型', compute="compute_information_fields", store=True)
|
||
ame = fields.Char(string='标题')
|
||
management_area = fields.Float(string="管理面积", digits=(16, 4), compute="compute_information_fields", store=True)
|
||
rent_area = fields.Float(string="可租面积", digits=(16, 4), compute="compute_information_fields", store=True)
|
||
equity_area = fields.Float(string="产权面积", group_operator=None, digits=(16, 4), compute="_compute_title_information_fields", store=True)
|
||
decoration_type = fields.Selection([('blank', '毛坯'), ('hardcover', '精装'), ('brands', '简装'), ('rsz', '豪装')],
|
||
string="装修类型")
|
||
feature_ids = fields.Many2many('feature.setting', string="特色")
|
||
major_ids = fields.One2many('yuthon.major.event.line', 'yuthon_property_id', string="重大事项明细行")
|
||
water_meter_ids = fields.One2many('yuthon.property.water', 'yuthon_property_id', string='水表列表')
|
||
energy_meter_ids = fields.One2many('yuthon.property.energy', 'yuthon_property_id', string='电表列表')
|
||
title_information_ids = fields.One2many('title.information.line', 'yuthon_property_id', string='关联产权信息明细行')
|
||
manage_information_ids = fields.One2many('manage.information.line', 'yuthon_property_id',
|
||
string='关联管理信息明细行')
|
||
disassembly_information_ids = fields.One2many('disassembly.information.line', 'yuthon_property_id',
|
||
string='关联拆分信息明细行')
|
||
assessment_ids = fields.One2many('yuthon.property.assessment', 'yuthon_property_id', string='关联评估明细行')
|
||
repair_ids = fields.One2many('yuthon.property.repair', 'yuthon_property_id', string='关联维修明细行')
|
||
produce_ids = fields.One2many('yuthon.property.production', 'yuthon_property_id', string='关联安全生产明细行')
|
||
property_merge_approval_id = fields.Many2one('yuthon.property', string='关联物业信息')
|
||
reference_ids = fields.One2many('yuthon.reference.conditions', 'yuthon_property_id', string='关联出租参考条件明细行')
|
||
first_letter = fields.Char(string="首字母", compute='_compute_first_letter', store=True)
|
||
owner_id = fields.Many2one('yuthon.owner.message', string="权属人", compute='_compute_title_information_fields', store=True)
|
||
vacant_duration = fields.Float(string="空置时长", digits=(16, 2))
|
||
lease_period = fields.Integer(string='租赁期限(<=)')
|
||
rent_period = fields.Integer(string="免租期(<=)")
|
||
first_years_begin = fields.Integer(string='第几年开始')
|
||
increments_few_years = fields.Integer(string='每几年递增')
|
||
annual_increase_percentage = fields.Float(string='递增百分比', igits=(6, 2))
|
||
annual_increase_amount = fields.Float(string='递增金额', igits=(6, 2))
|
||
rent_unit = fields.Float(string='租金单价', igits=(6, 2))
|
||
property_type = fields.Selection([('property', '物业'), ('guanggao', '广告位'), ('guanzi', '管子间'), ('room', '机房'), ('base_station','基站'), ('other', '其他')], string="资产类型", default='property')
|
||
is_new = fields.Boolean(string="是否最新物业", compute= 'compute_is_new', default=True, store=True)
|
||
kingdee_property_id = fields.Char(string="金蝶云物业资产id")
|
||
|
||
def update_property_state(self):
|
||
today = date.today()
|
||
current_year = today.year
|
||
current_month = today.month
|
||
# rentable_properties = self.env["yuthon.property"].browse(
|
||
# self._context.get('active_ids', self._context.get('active_id')))
|
||
rentable_properties = self.search([('purpose_id.name', '=', '可租')])
|
||
for prop in rentable_properties:
|
||
contract_lines = self.env['property.lease.contract.line'].search([
|
||
('address_id', '=', prop.id),
|
||
('lease_id.is_contract', '=', False),
|
||
])
|
||
if contract_lines:
|
||
sorted_lines = sorted(
|
||
contract_lines,
|
||
key=lambda line: line.lease_id.actual_end_time or date.max,
|
||
reverse=True
|
||
)
|
||
lease_id = sorted_lines[0]
|
||
else:
|
||
lease_id = self.env['property.lease.contract.line']
|
||
|
||
if not lease_id:
|
||
prop.write({'property_state': 'vacant'})
|
||
continue
|
||
actual_end = lease_id.lease_id.actual_end_time
|
||
if not actual_end:
|
||
prop.write({'property_state': 'on_rent'})
|
||
continue
|
||
|
||
end_day = actual_end.day
|
||
# 判断实际结束日期是否在本月
|
||
is_current_month = (actual_end.year == current_year) and (actual_end.month == current_month)
|
||
# 获取本月最后一天
|
||
last_day = calendar.monthrange(current_year, current_month)[1]
|
||
if is_current_month:
|
||
# 实际结束日期在本月
|
||
if end_day == last_day:
|
||
# 是本月月底 → 状态为在租
|
||
prop.write({'property_state': 'on_rent'})
|
||
else:
|
||
# 非月底 → 直接空置(无论是否大于今天)
|
||
prop.write({'property_state': 'vacant'})
|
||
else:
|
||
# 实际结束日期不在本月 → 按大于/小于今天判断
|
||
if actual_end > today:
|
||
prop.write({'property_state': 'on_rent'})
|
||
else:
|
||
prop.write({'property_state': 'vacant'})
|
||
|
||
def update_mange(self):
|
||
property_ids = self.env['yuthon.property'].search([('name', 'ilike', '天河商贸大厦')])
|
||
for property_id in property_ids:
|
||
property_id.is_message_fee = True
|
||
|
||
def update_is_new(self):
|
||
# property_ids = self.env["yuthon.property"].browse(
|
||
# self._context.get('active_ids', self._context.get('active_id')))
|
||
property_ids = self.env['yuthon.property'].search([])
|
||
for property_id in property_ids:
|
||
property_id.compute_is_new()
|
||
|
||
def update_message(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for property_rec in property_ids:
|
||
if not property_rec.manage_information_ids:
|
||
continue
|
||
date_groups = {}
|
||
for line in property_rec.manage_information_ids:
|
||
date_key = line.start_time or 'no_date'
|
||
if date_key not in date_groups:
|
||
date_groups[date_key] = []
|
||
date_groups[date_key].append(line.id)
|
||
ids_to_unlink = []
|
||
for date_key, line_ids in date_groups.items():
|
||
if len(line_ids) > 1:
|
||
ids_to_unlink.extend(line_ids[1:])
|
||
if ids_to_unlink:
|
||
self.env['manage.information.line'].browse(ids_to_unlink).unlink()
|
||
|
||
@api.depends('manage_information_ids', 'manage_information_ids.start_time',
|
||
'manage_information_ids.end_date', 'is_done_split')
|
||
def compute_is_new(self):
|
||
current_date = fields.Date.today()
|
||
for record in self:
|
||
has_valid_line = True
|
||
if record.disassembly_information_ids:
|
||
record.is_new = False
|
||
continue
|
||
for line in record.manage_information_ids:
|
||
start_valid = line.start_time <= current_date if line.start_time else False
|
||
end_valid = (not line.end_date) or (line.end_date >= current_date)
|
||
if start_valid and end_valid:
|
||
has_valid_line = True
|
||
break
|
||
record.is_new = has_valid_line
|
||
|
||
|
||
@api.onchange('reference_ids')
|
||
def _onchange_reference_ids(self):
|
||
for record in self:
|
||
if record.reference_ids:
|
||
record.lease_period = record.reference_ids[-1].lease_period
|
||
record.rent_period = record.reference_ids[-1].rent_period
|
||
record.first_years_begin = record.reference_ids[-1].first_years_begin
|
||
record.increments_few_years = record.reference_ids[-1].increments_few_years
|
||
record.annual_increase_percentage = record.reference_ids[-1].annual_increase_percentage
|
||
record.annual_increase_amount = record.reference_ids[-1].annual_increase_amount
|
||
record.rent_unit = record.reference_ids[-1].rent_unit
|
||
else:
|
||
record.lease_period = 0.0
|
||
record.rent_period = 0.0
|
||
record.first_years_begin = 0.0
|
||
record.increments_few_years = 0.0
|
||
record.annual_increase_percentage = 0.0
|
||
record.annual_increase_amount = 0.0
|
||
record.rent_unit = 0.0
|
||
|
||
@api.depends('name')
|
||
def _compute_first_letter(self):
|
||
for record in self:
|
||
name = record.name
|
||
if name:
|
||
first_char = name[0]
|
||
pinyin_list = lazy_pinyin(first_char)
|
||
if pinyin_list:
|
||
record.first_letter = pinyin_list[0][0].upper()
|
||
else:
|
||
record.first_letter = ''
|
||
else:
|
||
record.first_letter = ''
|
||
|
||
@api.depends('title_information_ids.start_time', 'title_information_ids.owner_id',
|
||
'title_information_ids.title_certificate', 'title_information_ids.registered_id',
|
||
'title_information_ids.property_message_id',
|
||
'title_information_ids.equity_area')
|
||
def _compute_title_information_fields(self):
|
||
for rec in self:
|
||
if rec.title_information_ids:
|
||
latest_title = rec.title_information_ids.sorted('start_time', reverse=True)[0]
|
||
rec.update({
|
||
'title_address': latest_title.property_message_id,
|
||
'owner_id': latest_title.owner_id,
|
||
'title_deed': latest_title.title_certificate,
|
||
'registered_id': latest_title.registered_id,
|
||
'equity_area': latest_title.equity_area,
|
||
})
|
||
|
||
def update_manage(self):
|
||
property_ids = self.env['yuthon.property'].search([])
|
||
for record in property_ids:
|
||
record.compute_information_fields()
|
||
|
||
@api.depends('manage_information_ids.start_time', 'manage_information_ids.end_date',
|
||
'manage_information_ids.precinct_id', 'manage_information_ids.tenure_type',
|
||
'manage_information_ids.management_area', 'manage_information_ids.rent_area',
|
||
'manage_information_ids.admin_id', 'manage_information_ids.purpose_id',
|
||
'manage_information_ids.company_id')
|
||
def compute_information_fields(self):
|
||
current_date = fields.Date.today() # 获取当前日期
|
||
for rec in self:
|
||
valid_info = rec.manage_information_ids.filtered(
|
||
lambda info: info.start_time <= current_date and
|
||
(not info.end_date or info.end_date >= current_date)
|
||
)
|
||
if valid_info:
|
||
current_info = valid_info[0]
|
||
rec.update({
|
||
'effective_date': current_info.start_time,
|
||
'end_date': current_info.end_date,
|
||
'purpose_id': current_info.purpose_id,
|
||
'precinct_id': current_info.precinct_id,
|
||
'tenure_type': current_info.tenure_type,
|
||
'management_area': current_info.management_area,
|
||
'rent_area': current_info.rent_area,
|
||
'admin_id': current_info.admin_id,
|
||
'company_id': current_info.company_id,
|
||
})
|
||
contract_lines = self.env['property.lease.contract.line'].search([
|
||
('address_id', '=', rec.id)
|
||
])
|
||
if contract_lines:
|
||
contract_lines.write({'admin_line_id': current_info.admin_id})
|
||
else:
|
||
rec.update({
|
||
'purpose_id': False,
|
||
'precinct_id': False,
|
||
'tenure_type': False,
|
||
'management_area': False,
|
||
'rent_area': False,
|
||
'admin_id': False,
|
||
'company_id': False,
|
||
})
|
||
|
||
# 物业关联电表按钮
|
||
def add_archives_meter_button(self):
|
||
"""
|
||
关联水电表按钮
|
||
:return:
|
||
"""
|
||
return {
|
||
'name': '物业关联电表弹窗',
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'utility.meter.wizard',
|
||
'view_mode': 'form',
|
||
'target': 'new',
|
||
'context': {
|
||
'default_property_id': self.id,
|
||
'default_meter_type': 'archives',
|
||
}
|
||
}
|
||
|
||
# 物业关联水表按钮
|
||
def add_water_meter_button(self):
|
||
return {
|
||
'name': '物业关联水表弹窗',
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'utility.meter.wizard',
|
||
'view_mode': 'form',
|
||
'target': 'new',
|
||
'context': {
|
||
'default_property_id': self.id,
|
||
'default_meter_type': 'water',
|
||
}
|
||
}
|
||
|
||
# @api.onchange('energy_meter_ids')
|
||
# def _onchange_energy_meter_ids(self):
|
||
# if not hasattr(self.id, 'origin') or not self.id.origin:
|
||
# return
|
||
# target_property_id = self.id.origin
|
||
# meter_model = self.env['property.meter.archives']
|
||
# related_meters = meter_model.search([
|
||
# ('yuthon_property_ids', 'in', [target_property_id])
|
||
# ])
|
||
# if related_meters:
|
||
# related_meters.write({
|
||
# 'yuthon_property_ids': [(6, 0, [])]
|
||
# })
|
||
# for rec in self.energy_meter_ids:
|
||
# meter_id = meter_model.browse(rec.property_meter_archives_id.id)
|
||
# meter_id.write({
|
||
# 'yuthon_property_ids': [(6, 0, [target_property_id])]
|
||
# })
|
||
|
||
@api.onchange('water_meter_ids')
|
||
def _onchange_water_meter_idss(self):
|
||
if not hasattr(self.id, 'origin') or not self.id.origin:
|
||
return
|
||
target_property_id = self.id.origin
|
||
water_meter_model = self.env['property.meter.water']
|
||
related_water_meters = water_meter_model.search([
|
||
('yuthon_property_ids', 'in', [target_property_id])
|
||
])
|
||
if related_water_meters:
|
||
related_water_meters.write({
|
||
'yuthon_property_ids': [(6, 0, [])]
|
||
})
|
||
for rec in self.water_meter_ids:
|
||
meter_id = water_meter_model.browse(rec.property_meter_water_id.id)
|
||
meter_id.write({
|
||
'yuthon_property_ids': [(6, 0, [target_property_id])]
|
||
})
|
||
|
||
@api.onchange('building_area')
|
||
def _onchange_building_area(self):
|
||
for rec in self:
|
||
rec.management_area = rec.building_area
|
||
rec.rent_area = rec.building_area
|
||
|
||
# 待评估物业相关信息
|
||
unit_price = fields.Float(string='单价')
|
||
current_status = fields.Date(string='现状(合同到期日)')
|
||
registered_id = fields.Many2one('yuthon.purpose.evidence', string='证载用途', compute="_compute_title_information_fields", store=True)
|
||
rental_conditions = fields.Text(string='出租条件')
|
||
district_manager = fields.Char(string='片区负责人')
|
||
remarks = fields.Text(string='备注')
|
||
evaluation_asset = fields.Char(string='评估资产')
|
||
evaluation_area = fields.Float(string='评估面积(m²)')
|
||
evaluation_category = fields.Char(string='评估类别')
|
||
precinct_id = fields.Many2one('yuthon.precinct.message', string="所属片区", compute="compute_information_fields", store=True)
|
||
last_hand_rent_price = fields.Float(string='上一手历史租金单价(元/m²•月)')
|
||
gov_rent_price = fields.Float(string='政府租金参考价')
|
||
evaluation_rent_price = fields.Float(string='评估散租单价(元/m²•月)')
|
||
evaluation_rent_total = fields.Float(string='评估总价(元•月,散租)')
|
||
evaluation_whole_rent_price = fields.Float(string='评估整租单价(元/m² •月)')
|
||
evaluation_whole_rent_total = fields.Float(string='评估总价(元•月,整租)')
|
||
|
||
def update_precinct(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for rec in property_ids:
|
||
rec.compute_information_fields()
|
||
|
||
|
||
def put_declare_approval(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
form_id = self.env.ref('yuthon_property_approval.view_property_rental_form_form').id
|
||
property_list = []
|
||
for record in property_ids:
|
||
property_list.append([0, 0, {'property_id': record.id}])
|
||
return {
|
||
'name': '提交出租申报',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.rental.form',
|
||
'type': 'ir.actions.act_window',
|
||
'views': [(form_id, 'form')],
|
||
"context": {'default_property_rental_form_line_ids': property_list}
|
||
}
|
||
|
||
def open_record(self):
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"res_model": 'yuthon.property',
|
||
"res_id": self.id,
|
||
"name": '物业详情',
|
||
"view_mode": "form",
|
||
}
|
||
|
||
def put_offline_approval(self):
|
||
form_id = self.env.ref('yuthon_property_approval.view_property_offline_registration_form').id
|
||
return {
|
||
'name': '提交下线出租',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.offline.registration',
|
||
'type': 'ir.actions.act_window',
|
||
'views': [(form_id, 'form')],
|
||
"context": {
|
||
'default_property_id': self.id
|
||
}
|
||
}
|
||
|
||
|
||
def put_adjustment_approval(self):
|
||
form_id = self.env.ref('yuthon_property_approval.view_property_rental_conditions_form').id
|
||
return {
|
||
'name': '出租价格调整申请',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.rental.conditions',
|
||
'type': 'ir.actions.act_window',
|
||
'views': [(form_id, 'form')],
|
||
"context": {
|
||
'default_property_id': self.id
|
||
}
|
||
}
|
||
|
||
def put_property_handover(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
form_id = self.env.ref('yuthon_property_approval.view_property_handover_form').id
|
||
property_list = []
|
||
for record in property_ids:
|
||
property_list.append([0, 0, {'property_id': record.id}])
|
||
return {
|
||
'name': '提交物业移交',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.handover',
|
||
'type': 'ir.actions.act_window',
|
||
'views': [(form_id, 'form')],
|
||
"context": {
|
||
'default_property_handover_ids': property_list
|
||
}
|
||
}
|
||
|
||
|
||
def put_property_management(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
form_id = self.env.ref('yuthon_property_approval.view_property_management_form').id
|
||
property_list = []
|
||
today = fields.Date.today()
|
||
for record in property_ids:
|
||
for manage in record.manage_information_ids:
|
||
# 判断记录是否有效:start_time ≤ today ≤ end_date(或end_date为空)
|
||
if manage.start_time and manage.start_time <= today:
|
||
if not manage.end_date or manage.end_date >= today:
|
||
manage_id = manage
|
||
else:
|
||
manage_id = False
|
||
else:
|
||
manage_id = False
|
||
property_list.append([0, 0, {'property_id': record.id,
|
||
'precinct_id': record.precinct_id.id,
|
||
'purpose_id': manage_id.purpose_id.id if manage_id else None,
|
||
'information_line_id': manage_id.id if manage_id else None}])
|
||
return {
|
||
'name': '提交物业变更',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.management',
|
||
'type': 'ir.actions.act_window',
|
||
'views': [(form_id, 'form')],
|
||
"context": {
|
||
'default_management_line2_ids': property_list
|
||
}
|
||
}
|
||
|
||
def put_assessment_approval(self):
|
||
for record in self:
|
||
self.env['property.evaluation.plan'].create({
|
||
'name': record.name,
|
||
'property_ids': [(6, 0, [record.id])],
|
||
'evaluation_area': record.rent_area,
|
||
'owner_id': record.owner_id.id if record.owner_id else None,
|
||
'registered_id': record.registered_id.id if record.registered_id else None,
|
||
'lease_period': record.lease_period,
|
||
'first_years_begin': record.first_years_begin,
|
||
'increments_few_years': record.increments_few_years,
|
||
'annual_increase_amount': record.annual_increase_amount,
|
||
'rent_unit': record.rent_unit,
|
||
'annual_increase_percentage': record.reference_ids[-1].annual_increase_percentage if record.reference_ids else None,
|
||
'assessment_category': 'rent_money',
|
||
'remake': record.remark,
|
||
})
|
||
record.write({'property_state': 'ing'})
|
||
return {
|
||
"name": "物业评估方案",
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'property.evaluation.plan',
|
||
"view_mode": "tree",
|
||
}
|
||
|
||
def all_assessment_approval(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in property_ids:
|
||
if record.property_leasing == 'ing':
|
||
raise UserError(f'{record.name}该物业已在评估,请勿重复提交')
|
||
self.env['property.evaluation.plan'].create({
|
||
'name': record.name,
|
||
'property_ids': [(6, 0, [record.id])],
|
||
'evaluation_area': record.rent_area,
|
||
'owner_id': record.owner_id.id if record.owner_id else None,
|
||
'registered_id': record.registered_id.id if record.registered_id else None,
|
||
'lease_period': record.lease_period,
|
||
'first_years_begin': record.first_years_begin,
|
||
'increments_few_years': record.increments_few_years,
|
||
'annual_increase_amount': record.annual_increase_amount,
|
||
'rent_unit': record.rent_unit,
|
||
'annual_increase_percentage': record.reference_ids[-1].annual_increase_percentage if record.reference_ids else None,
|
||
'assessment_category': 'rent_money',
|
||
'remake': record.remark,
|
||
})
|
||
record.write({'property_leasing': 'ing'})
|
||
return {
|
||
"name": "物业评估方案",
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'property.evaluation.plan',
|
||
"view_mode": "tree",
|
||
}
|
||
|
||
# 拆分
|
||
def put_split_approval(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in property_ids:
|
||
form_id = self.env.ref('yuthon_property_approval.view_property_split_approval_form').id
|
||
return {
|
||
'name': '拆分物业审批',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.split.approval',
|
||
'type': 'ir.actions.act_window',
|
||
'views': [(form_id, 'form')],
|
||
'context': {
|
||
'default_property_id': record.id
|
||
}}
|
||
# 合并
|
||
def put_merge_approval(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
form_id = self.env.ref('yuthon_property_approval.view_property_merge_approval_form').id
|
||
property_list = []
|
||
for record in property_ids:
|
||
property_list.append([0, 0, {
|
||
'property_id': record.id
|
||
}])
|
||
return {
|
||
'name': '合并物业审批',
|
||
'view_mode': 'form',
|
||
'res_model': 'property.merge.approval',
|
||
'type': 'ir.actions.act_window',
|
||
'views': [(form_id, 'form')],
|
||
'context': {
|
||
'default_property_merge_approval_line_ids':property_list
|
||
}}
|
||
|
||
def action_yuthon_property_wizard(self):
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"name": "批量导入物业",
|
||
"res_model": "yuthon.property.wizard",
|
||
"view_mode": "form",
|
||
"target": "new",
|
||
}
|
||
|
||
def action_relevance_contract(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
property_contract_list = []
|
||
for record in property_ids:
|
||
contract_ids = self.env["'property.lease.contract.line"].search([('address_id', '=', record.id)])
|
||
if contract_ids:
|
||
for contract in contract_ids:
|
||
record.write({'contract_id': contract.lease_id.id})
|
||
|
||
|
||
def trigger_company_id(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in property_ids:
|
||
precinct_id = self.env["yuthon.precinct.message"].search([('employee_id.name', '=', record.owner_id.name)])
|
||
owner_id = record.title_information_ids[-1].owner_id.id if record.title_information_ids else ''
|
||
company_id = record.manage_information_ids[-1].company_id.id if record.manage_information_ids else ''
|
||
lease_period = record.reference_ids[-1].lease_period if record.reference_ids else ''
|
||
rent_period = record.reference_ids[-1].rent_period if record.reference_ids else ''
|
||
first_years_begin = record.reference_ids[-1].first_years_begin if record.reference_ids else ''
|
||
increments_few_years = record.reference_ids[-1].increments_few_years if record.reference_ids else ''
|
||
annual_increase_amount = record.reference_ids[-1].annual_increase_amount if record.reference_ids else ''
|
||
rent_unit = record.reference_ids[-1].rent_unit if record.reference_ids else ''
|
||
title_address = record.title_information_ids[-1].property_message_id if record.title_information_ids else ''
|
||
title_deed = record.title_information_ids[-1].title_certificate if record.title_information_ids else ''
|
||
registered_id = record.title_information_ids[-1].registered_id.id if record.title_information_ids else ''
|
||
record.registered_id = registered_id
|
||
record.company_id = company_id
|
||
record.title_address = title_address
|
||
record.rent_period = rent_period
|
||
record.first_years_begin = first_years_begin
|
||
record.increments_few_years = increments_few_years
|
||
record.annual_increase_amount = annual_increase_amount
|
||
record.rent_unit = rent_unit
|
||
record.owner_id = owner_id
|
||
record.company_id = company_id
|
||
record.lease_period = lease_period
|
||
record.title_deed = title_deed
|
||
record.precinct_id = precinct_id.id if precinct_id else ''
|
||
if record.manage_information_ids:
|
||
record.manage_information_ids[-1].precinct_id = precinct_id.id if precinct_id else ''
|
||
|
||
def revert_change(self):
|
||
property_ids = self.env["yuthon.property"].browse(
|
||
self._context.get('active_ids', self._context.get('active_id')))
|
||
for record in property_ids:
|
||
lines = record.manage_information_ids
|
||
prev_line = lines[-2]
|
||
# 删除最后一条记录
|
||
lines[-1].unlink()
|
||
# 更新当前记录的字段
|
||
record.write({
|
||
'purpose_id': prev_line.purpose_id.id,
|
||
'admin_id': prev_line.admin_id.id,
|
||
'precinct_id': prev_line.precinct_id.id,
|
||
'company_id': prev_line.company_id.id,
|
||
'management_area': prev_line.management_area,
|
||
'rent_area': prev_line.rent_area,
|
||
'tenure_type': prev_line.tenure_type,
|
||
})
|
||
# 合同信息还原
|
||
contract = self.env['property.lease.contract.line'].search(
|
||
[('address_id', '=', record.id)],
|
||
limit=1
|
||
)
|
||
if contract:
|
||
lease_id = contract.lease_id
|
||
lease_id.write({'admin_id': prev_line.admin_id.id})
|
||
return {
|
||
'type': 'ir.actions.client',
|
||
'tag': 'display_notification',
|
||
'params': {
|
||
'title': '操作成功',
|
||
'message': '物业变更信息已成功还原',
|
||
'sticky': False, # 不显示关闭按钮,自动消失
|
||
'type': 'success', # 成功消息样式
|
||
}
|
||
}
|
||
|
||
def copy(self, default=None):
|
||
new_record = super(YuthonProperty, self).copy(default=default)
|
||
for title_line in self.title_information_ids:
|
||
title_line.copy({
|
||
'yuthon_property_id': new_record.id,
|
||
})
|
||
for manage_line in self.manage_information_ids:
|
||
manage_line.copy({
|
||
'yuthon_property_id': new_record.id,
|
||
})
|
||
|
||
return new_record
|
||
|
||
class YuthonPropertyWater(models.Model):
|
||
_name = 'yuthon.property.water'
|
||
_description = '水表'
|
||
|
||
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="拆除日期")
|
||
epitope_values_id = fields.Many2one(related='property_meter_water_id.epitope_values_id', string="位置")
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="物业管理")
|
||
|
||
# 水表跳转
|
||
def detail(self):
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"name": "水表库",
|
||
"res_model": "property.meter.water",
|
||
"res_id": self.property_meter_water_id.id,
|
||
"view_mode": "form",
|
||
"target": "new"
|
||
}
|
||
|
||
def unlink(self):
|
||
for record in self:
|
||
if record.property_meter_water_id and record.yuthon_property_id:
|
||
if record.yuthon_property_id in record.property_meter_water_id.yuthon_property_ids:
|
||
record.property_meter_water_id.write({
|
||
'yuthon_property_ids': [(3, record.yuthon_property_id.id)]
|
||
})
|
||
return super().unlink()
|
||
|
||
|
||
class YuthonPropertyEnergy(models.Model):
|
||
_name = 'yuthon.property.energy'
|
||
_description = '电表'
|
||
|
||
property_meter_archives_id = fields.Many2one('property.meter.archives', string="电表编号")
|
||
unit_number = fields.Char(related='property_meter_archives_id.unit_number', 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="拆除日期")
|
||
epitope_values_id = fields.Many2one(related='property_meter_archives_id.epitope_values_id', string="位置")
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="物业管理")
|
||
|
||
# 电表跳转
|
||
def detail(self):
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"name": "电表库",
|
||
"res_model": "property.meter.archives",
|
||
"res_id": self.property_meter_archives_id.id,
|
||
"view_mode": "form",
|
||
"target": "new"
|
||
}
|
||
|
||
# 补充删除取消关联的逻辑
|
||
def unlink(self):
|
||
for record in self:
|
||
if record.property_meter_archives_id and record.yuthon_property_id:
|
||
if record.yuthon_property_id in record.property_meter_archives_id.yuthon_property_ids:
|
||
record.property_meter_archives_id.write({
|
||
'yuthon_property_ids': [(3, record.yuthon_property_id.id)]
|
||
})
|
||
return super().unlink()
|
||
|
||
|
||
class TitleInformationLine(models.Model):
|
||
_name = 'title.information.line'
|
||
_description = '产权信息明细行'
|
||
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息")
|
||
property_message_id = fields.Many2one('yuthon.property.message', string='产权地址')
|
||
owner_id = fields.Many2one(related='property_message_id.owner_id', string="权属人")
|
||
equity_area = fields.Float(related='property_message_id.equity_area', string="产权面积", digits=(16, 4))
|
||
registered_id = fields.Many2one(related='property_message_id.registered_id', string='证载用途')
|
||
property_use_time = fields.Selection(related='property_message_id.property_use_time', string="产权年限")
|
||
life_timer = fields.Date(related='property_message_id.life_timer', string="使用时间")
|
||
title_certificate = fields.Char(related='property_message_id.title_certificate', string="产权证号")
|
||
|
||
start_time = fields.Date(string="生效日期", default=fields.Date.today)
|
||
end_date = fields.Date(string="失效日期")
|
||
|
||
def _check_duplicate_date(self, prop_id, date_val, exclude_id=None):
|
||
"""Block duplicate effective dates for the same property."""
|
||
if not prop_id or not date_val:
|
||
return
|
||
domain = [
|
||
('yuthon_property_id', '=', prop_id),
|
||
('start_time', '=', date_val),
|
||
]
|
||
if exclude_id:
|
||
domain.append(('id', '!=', exclude_id))
|
||
if self.search_count(domain):
|
||
raise UserError('同一物业的产权信息生效日期不能重复。')
|
||
|
||
@api.model
|
||
def create(self, vals):
|
||
prop_id = vals.get('yuthon_property_id')
|
||
date_val = vals.get('start_time') or fields.Date.context_today(self)
|
||
self._check_duplicate_date(prop_id, date_val)
|
||
return super().create(vals)
|
||
|
||
def write(self, vals):
|
||
for rec in self:
|
||
prop_id = vals.get('yuthon_property_id', rec.yuthon_property_id.id)
|
||
date_val = vals.get('start_time', rec.start_time)
|
||
rec._check_duplicate_date(prop_id, date_val, exclude_id=rec.id)
|
||
return super().write(vals)
|
||
|
||
def message_record(self):
|
||
return {
|
||
"type": "ir.actions.act_window",
|
||
"res_model": 'yuthon.property.message',
|
||
"res_id": self.property_message_id.id,
|
||
"name": "详情",
|
||
"view_mode": "form",
|
||
}
|
||
|
||
|
||
class ManageInformationLine(models.Model):
|
||
_name = 'manage.information.line'
|
||
_description = '管理信息明细行'
|
||
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息")
|
||
purpose_id = fields.Many2one('yuthon.resource.purpose', string="管理类型")
|
||
precinct_id = fields.Many2one('yuthon.precinct.message', string="所属片区")
|
||
tenure_type = fields.Selection([('self', '自有'), ('agency', '代管')], string='权属类型')
|
||
management_area = fields.Float(string="管理面积", digits=(16, 4))
|
||
rent_area = fields.Float(string="可租面积", digits=(16, 4))
|
||
admin_id = fields.Many2one('res.users', string="管理员")
|
||
company_id = fields.Many2one('yuthon.property.company', string="公司")
|
||
start_time = fields.Date(string="生效日期", default=fields.Date.today)
|
||
end_date = fields.Date(string="失效日期")
|
||
create_date = fields.Date(string="创建日期", default=fields.Date.today)
|
||
|
||
def _check_duplicate_date(self, prop_id, date_val, exclude_id=None):
|
||
if not prop_id or not date_val:
|
||
return
|
||
domain = [
|
||
('yuthon_property_id', '=', prop_id),
|
||
('start_time', '=', date_val),
|
||
]
|
||
if exclude_id:
|
||
domain.append(('id', '!=', exclude_id))
|
||
# 临时因报错注释掉
|
||
# if self.search_count(domain):
|
||
# property_name = self.env['yuthon.property'].search([('id', '=', prop_id)]).name
|
||
# raise UserError(f'同一物业的管理信息生效日期不能重复。当前物业:{property_name}id:{prop_id}')
|
||
|
||
@api.model
|
||
def create(self, vals):
|
||
prop_id = vals.get('yuthon_property_id')
|
||
date_val = vals.get('start_time') or fields.Date.context_today(self)
|
||
self._check_duplicate_date(prop_id, date_val)
|
||
return super().create(vals)
|
||
|
||
def write(self, vals):
|
||
for rec in self:
|
||
prop_id = vals.get('yuthon_property_id', rec.yuthon_property_id.id)
|
||
date_val = vals.get('start_time', rec.start_time)
|
||
rec._check_duplicate_date(prop_id, date_val, exclude_id=rec.id)
|
||
return super().write(vals)
|
||
|
||
@api.onchange('precinct_id')
|
||
def _onchange_precinct_id(self):
|
||
for record in self:
|
||
if record.precinct_id:
|
||
record.admin_id = record.precinct_id.employee_id.user_id
|
||
|
||
class DisassemblyInformationLine(models.Model):
|
||
_name = 'disassembly.information.line'
|
||
_description = '拆分信息明细行'
|
||
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息")
|
||
property_id = fields.Many2one('yuthon.property', string="物业名称")
|
||
rent_area = fields.Float(related='property_id.rent_area', string="可租面积")
|
||
start_time = fields.Date(related='property_id.effective_date',string="生效日期")
|
||
end_date = fields.Date(related='property_id.end_date',string="失效日期")
|
||
|
||
|
||
class YuthonPropertyAssessment(models.Model):
|
||
_name = 'yuthon.property.assessment'
|
||
_description = '物业评估'
|
||
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息")
|
||
name = fields.Char(string="评估名称")
|
||
|
||
|
||
class YuthonPropertyRepair(models.Model):
|
||
_name = 'yuthon.property.repair'
|
||
_description = '维修'
|
||
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息")
|
||
name = fields.Char(string="维修名称")
|
||
|
||
class YuthonPropertyProduction(models.Model):
|
||
_name = 'yuthon.property.production'
|
||
_description = '安全生产'
|
||
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息")
|
||
produce_id = fields.Many2one('yuthon.property.produce', string="检查项目")
|
||
check_context = fields.Text(related='produce_id.check_context', string='检查内容')
|
||
check_results = fields.Text(related='produce_id.check_results', string='检查结果')
|
||
check_criteria = fields.Text(related='produce_id.check_criteria', string='检查标准')
|
||
there_problem = fields.Text(related='produce_id.there_problem', string='存在问题')
|
||
problem_suggestion = fields.Text(related='produce_id.problem_suggestion', string='整改措施')
|
||
problem_date = fields.Date(related='produce_id.problem_date', string='整改期限')
|
||
review_situation = fields.Text(related='produce_id.review_situation', string='复查情况')
|
||
check_people = fields.Many2one(related='produce_id.check_people', string="检查人")
|
||
check_date = fields.Date(related='produce_id.check_date', string="检查日期")
|
||
|
||
|
||
class YuthonReferenceConditions(models.Model):
|
||
_name = 'yuthon.reference.conditions'
|
||
_description = '出租参考条件'
|
||
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息")
|
||
lease_period = fields.Integer(string='租赁期限(<=)')
|
||
rent_period = fields.Integer(string="免租期(<=)")
|
||
first_years_begin = fields.Integer(string='第几年开始')
|
||
increments_few_years = fields.Integer(string='每几年递增')
|
||
annual_increase_percentage = fields.Float(string='递增百分比', igits=(6, 2))
|
||
annual_increase_amount = fields.Float(string='递增金额', igits=(6, 2))
|
||
rent_unit = fields.Float(string='递增单价', igits=(6, 2))
|
||
|
||
class YuthonMajorEventLine(models.Model):
|
||
_name = 'yuthon.major.event.line'
|
||
_description = '重大事件'
|
||
|
||
yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息")
|
||
major_id = fields.Many2one('major.event.setting', string="重大事件")
|
||
inspector_html = fields.Html(related='major_id.inspector_html', string="内容")
|
||
documents_ids = fields.Many2many(related='major_id.documents_ids', string="附件")
|
||
start_date = fields.Date(related='major_id.start_date', store=True)
|
||
|
||
def _get_date_from_vals(self, vals):
|
||
"""Get start_date considering related major_id."""
|
||
if vals.get('start_date'):
|
||
return vals['start_date']
|
||
major_id = vals.get('major_id')
|
||
if major_id:
|
||
return self.env['major.event.setting'].browse(major_id).start_date
|
||
return None
|
||
|
||
def _check_duplicate_date(self, prop_id, date_val, exclude_id=None):
|
||
if not prop_id or not date_val:
|
||
return
|
||
domain = [
|
||
('yuthon_property_id', '=', prop_id),
|
||
('start_date', '=', date_val),
|
||
]
|
||
if exclude_id:
|
||
domain.append(('id', '!=', exclude_id))
|
||
if self.search_count(domain):
|
||
raise UserError('同一物业的重大事项生效日期不能重复。')
|
||
|
||
@api.model
|
||
def create(self, vals):
|
||
prop_id = vals.get('yuthon_property_id')
|
||
date_val = self._get_date_from_vals(vals)
|
||
self._check_duplicate_date(prop_id, date_val)
|
||
return super().create(vals)
|
||
|
||
def write(self, vals):
|
||
for rec in self:
|
||
prop_id = vals.get('yuthon_property_id', rec.yuthon_property_id.id)
|
||
date_val = self._get_date_from_vals(vals) if 'major_id' in vals or 'start_date' in vals else rec.start_date
|
||
rec._check_duplicate_date(prop_id, date_val, exclude_id=rec.id)
|
||
return super().write(vals)
|