From f689a0f586f80ceb074e0ab80b17fdc62b2dd2ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Thu, 24 Sep 2026 19:38:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- soong_workflow/models/soong_workflow_mixin.py | 16 ++ .../wizard/soong_workflow_comment_wizard.py | 4 + yuthon_property/__manifest__.py | 3 + .../models/property_bank_statements.py | 8 + .../models/property_evaluation_plan.py | 149 +++++++--- yuthon_property/models/yuthon_property.py | 215 ++++++++++++-- yuthon_property/security/ir.model.access.csv | 4 +- yuthon_property/views/menuitem.xml | 16 ++ .../views/property_bank_statements_views.xml | 30 +- .../views/property_evaluation_plan_view.xml | 98 ++++++- .../views/yuthon_property_views.xml | 71 ++++- yuthon_property/wizard/__init__.py | 2 + .../wizard/evaluation_plan_wizard.py | 30 +- .../wizard/evaluation_plan_wizard_views.xml | 3 +- .../data/property_contract_time.xml | 14 + .../models/inherit_yuthon_property.py | 5 +- .../models/property_confirm.py | 107 ++++++- .../models/property_evaluate_application.py | 267 +++++++++++++++++- .../models/property_lease_contract.py | 46 ++- .../models/property_meeting_approval.py | 10 +- .../models/property_rental_form.py | 121 +++++++- .../models/property_transaction_confirmed.py | 17 +- .../views/property_confirm_views.xml | 14 +- .../property_evaluate_application_views.xml | 23 +- .../views/property_menu_all.xml | 10 +- .../views/property_merge_approval_views.xml | 2 +- .../views/property_rental_form_views.xml | 15 +- .../views/property_split_approval_views.xml | 2 +- .../views/property_transaction_confirmed.xml | 3 + .../wizard/property_reconciliation_wizard.py | 49 ++++ 30 files changed, 1219 insertions(+), 135 deletions(-) diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index c1fcc080a..a8d77aeb7 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -2053,6 +2053,22 @@ class SoongWorkflowMixin(models.AbstractModel): return record_id.users_id.employee_id return self.env['hr.employee'] # 默认返回空记录集 + def _get_active_workflow_record(self): + """本单据「未进回收站」的工作流记录(没有则返回空记录集)。 + + 按 res_model + res_id 匹配;回收站里的记录 reclaim_state=True,不算有效记录。 + """ + self.ensure_one() + return self.env['soong.workflow.record'].sudo().search([ + ('res_model', '=', self._name), + ('res_id', '=', self.id), + ('reclaim_state', '=', False), + ], limit=1) + + def _has_active_workflow_record(self): + """本单据是否存在「未进回收站」的工作流记录(回收站里的不算)""" + return bool(self._get_active_workflow_record()) + # ---- 公司历史名称展示:web_read 直接改写指向 res.company 的公司字段显示名(见 web_read)---- company_id = fields.Many2one('res.company', string='公司') diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py index 2edd501c8..e3d822fa5 100644 --- a/soong_workflow/wizard/soong_workflow_comment_wizard.py +++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py @@ -806,6 +806,10 @@ class SoongWorkflowCommentWizard(models.TransientModel): title=title + '传阅/抄送,测试提醒', description=description, url=url, btntxt="查看详情") + # 转交成功:仅这几类单据需要推进业务状态 + # (评估申请 -> 物业/方案「评估中」;挂牌申报表 待挂牌 -> 挂牌中;成交确认书 待签约 -> 签约中) + if self.res_model in ('property.evaluate.application', 'property.rental.form', 'property.confirm'): + record_id._on_workflow_transfer() self._handle_avoidance() if self.node_btn_name == '退回': if not self.return_link_id: diff --git a/yuthon_property/__manifest__.py b/yuthon_property/__manifest__.py index 1aee4363f..4b855096a 100644 --- a/yuthon_property/__manifest__.py +++ b/yuthon_property/__manifest__.py @@ -15,6 +15,9 @@ 'data/data_yuthon_resource_mgmt_config.xml', 'data/yuthon_property_approval_data.xml', 'data/yuthon_new_property.xml', + # 必须早于 yuthon_property_views.xml:物业列表头部按钮用 %(...)d 引用该动作 + 'wizard/property_import_wizard_views.xml', + 'wizard/property_evaluation_import_wizard_views.xml', 'views/yuthon_property_views.xml', 'views/property_patrol_duty.xml', 'views/property_patrol_plan.xml', diff --git a/yuthon_property/models/property_bank_statements.py b/yuthon_property/models/property_bank_statements.py index 040033113..6330e8be4 100644 --- a/yuthon_property/models/property_bank_statements.py +++ b/yuthon_property/models/property_bank_statements.py @@ -54,6 +54,14 @@ class PropertyBankStatements(models.Model): change_amount = fields.Float(string='修改金额') receivable_modify_ids = fields.One2many('receivable.modify.line', 'bank_id', string='修改应收单') + # 对账(贷)列表排序用:挂账的行排最前面(挂账=0,其余=1),配合「交易时间倒序」使用 + bank_state_sort = fields.Integer(string='排序(挂账优先)', compute='_compute_bank_state_sort', store=True) + + @api.depends('bank_state') + def _compute_bank_state_sort(self): + for rec in self: + rec.bank_state_sort = 0 if rec.bank_state == 'registered' else 1 + def open_record(self): return { "type": "ir.actions.act_window", diff --git a/yuthon_property/models/property_evaluation_plan.py b/yuthon_property/models/property_evaluation_plan.py index b0e8b3e97..3b889967c 100644 --- a/yuthon_property/models/property_evaluation_plan.py +++ b/yuthon_property/models/property_evaluation_plan.py @@ -9,41 +9,77 @@ class PropertyEvaluationPlan(models.Model): name = fields.Char(string='物业名称') evaluation_area = fields.Float(string='评估面积(m²)') - property_ids = fields.Many2many('yuthon.property', string='物业') + property_id = fields.Many2one('yuthon.property', string='物业') + # 业务状态:取关联物业的业务状态(只读展示) + business_state = fields.Selection(related='property_id.business_state', string='业务状态') company_id = fields.Many2one('yuthon.property.company', string='评估公司', compute='_compute_search', store=True) admin_id = fields.Many2one('res.users', string="管理员", compute='_compute_search', store=True) assessment_category = fields.Selection([('rent_money', '租金'), ('value', '价值')], string="评估类别", default='rent_money') - owner_id = fields.Many2one('yuthon.owner.message', string="权属人") - registered_id = fields.Many2one('yuthon.purpose.evidence', string='证载用途') - registered_id2 = fields.Many2one('yuthon.purpose.evidence', string='设定用途') + # 以下字段均从关联物业带出,属计算字段,不落库(口径见 _compute_from_property) + owner_id = fields.Many2one('yuthon.owner.message', string="权属人", compute='_compute_from_property') + registered_id = fields.Many2one('yuthon.purpose.evidence', string='证载用途', compute='_compute_from_property') + registered_id2 = fields.Many2one('yuthon.resource.type', string='设定用途', compute='_compute_from_property') rent_id = fields.Many2one('rent.free.setting', string="办法") - lease_period = fields.Integer(string='租赁期限(<=)') - first_years_begin = fields.Integer(string='第几年开始') - increments_few_years = fields.Integer(string='每几年递增') + lease_period = fields.Integer(string='租赁期限(<=)', compute='_compute_from_property') + first_years_begin = fields.Integer(string='第几年开始', compute='_compute_from_property') + increments_few_years = fields.Integer(string='每几年递增', compute='_compute_from_property') lease_form = fields.Selection([('sublease', '分租'), ('whole', '整租')], string="租赁形式", compute='compute_lease_form') - 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)) + annual_increase_percentage = fields.Float(string='递增百分比', igits=(6, 2), compute='_compute_from_property') + annual_increase_amount = fields.Float(string='递增金额', igits=(6, 2), compute='_compute_from_property') + rent_unit = fields.Float(string='递增单价', igits=(6, 2), compute='_compute_from_property') remake = fields.Text(string='备注') - property_state = fields.Selection([('to', '待审批'), ('done', '已审批')], string="状态", default='to') + property_state = fields.Selection([('to', '待评估'), ('ing', '评估中'), ('done', '已评估')], + string="状态", default='to') - @api.depends('property_ids') + @api.depends('property_id') def _compute_search(self): for record in self: - if record.property_ids: - record.company_id = record.property_ids[0].company_id.id - record.admin_id = record.property_ids[0].admin_id.id + if record.property_id: + record.company_id = record.property_id.company_id.id + record.admin_id = record.property_id.admin_id.id - @api.depends('property_ids') + @api.depends('property_id', + 'property_id.asset_type_id', + 'property_id.reference_ids.start_date', + 'property_id.reference_ids.end_date', + 'property_id.reference_ids.lease_period', + 'property_id.reference_ids.rent_period', + 'property_id.reference_ids.first_years_begin', + 'property_id.reference_ids.increments_few_years', + 'property_id.reference_ids.annual_increase_amount', + 'property_id.reference_ids.rent_unit', + 'property_id.reference_ids.annual_increase_percentage', + 'property_id.title_information_ids.start_time', + 'property_id.title_information_ids.end_date', + 'property_id.title_information_ids.owner_id', + 'property_id.title_information_ids.registered_id') + def _compute_from_property(self): + """从关联物业带出: + - 租赁期限 / 第几年开始 / 每几年递增 / 递增金额 / 递增单价 / 递增百分比 ← 物业「出租参考条件」中日期范围覆盖当天的那行 + - 权属人 / 证载用途 ← 物业「产权信息明细」中日期范围覆盖当天的那行 + - 设定用途 ← 物业的「出租类型」(asset_type_id) + """ + for plan in self: + prop = plan.property_id + ref_line = prop._get_valid_reference_line() if prop else prop + title_line = prop._get_valid_title_line() if prop else prop + + plan.lease_period = ref_line.lease_period if ref_line else 0 + plan.first_years_begin = ref_line.first_years_begin if ref_line else 0 + plan.increments_few_years = ref_line.increments_few_years if ref_line else 0 + plan.annual_increase_amount = ref_line.annual_increase_amount if ref_line else 0.0 + plan.rent_unit = ref_line.rent_unit if ref_line else 0.0 + plan.annual_increase_percentage = ref_line.annual_increase_percentage if ref_line else 0.0 + + plan.owner_id = title_line.owner_id.id if title_line and title_line.owner_id else False + plan.registered_id = title_line.registered_id.id if title_line and title_line.registered_id else False + plan.registered_id2 = prop.asset_type_id.id if prop and prop.asset_type_id else False + + @api.depends('property_id') def compute_lease_form(self): + # 一个方案只对应一个物业 → 恒为「整租」(原「多物业=分租」的判断随 m2o 改造取消) for record in self: - if record.property_ids: - if len(record.property_ids) > 1: - record.lease_form = 'sublease' - else: - record.lease_form = 'whole' - else: - record.lease_form = False + record.lease_form = 'whole' if record.property_id else False def put_assessment_approval(self): @@ -52,12 +88,14 @@ class PropertyEvaluationPlan(models.Model): form_id = self.env.ref('yuthon_property_approval.property_evaluate_application_form').id property_list = [] for i in property_evaluation_ids: - if i.property_state == 'done': - raise UserError('该方案不可提交') + # 仅「待评估」可提交评估申请;评估中 / 已评估不再提供该入口 + if i.property_state != 'to': + raise UserError('仅「待评估」的方案可以提交评估申请') property_list.append([0, 0, { 'property_evaluation_id': i.id, }]) - i.write({'property_state': 'done'}) + # 此处只负责跳转,状态改为「评估中」由评估申请保存成功时触发 + # (见 property.evaluate.application.create) return { 'name': '提交物业评估', 'view_mode': 'form', @@ -69,27 +107,60 @@ class PropertyEvaluationPlan(models.Model): } } + def action_listing_rental(self): + """挂牌招租:把所选评估方案关联的物业带进「挂牌申报表」明细行""" + property_evaluation_ids = self.env["property.evaluation.plan"].browse( + self._context.get('active_ids', self._context.get('active_id'))) + properties = property_evaluation_ids.mapped('property_id') + if not properties: + raise UserError('所选评估方案未关联物业,无法挂牌招租') + # 已进入签约流程(待签约/签约中/已签约)的物业不放进挂牌申报表 + form_model = self.env['property.rental.form'] + properties = form_model._get_listable_properties(properties) + if not properties: + raise UserError('所选物业均已进入签约流程(待签约/签约中/已签约),不能在挂牌申报表中提交') + form_model._check_listing_available(properties) + form_id = self.env.ref('yuthon_property_approval.view_property_rental_form_form').id + line_list = [] + for prop in properties: + line_list.append([0, 0, { + 'property_id': prop.id, + }]) + return { + 'name': '挂牌招租', + 'type': 'ir.actions.act_window', + 'res_model': 'property.rental.form', + 'view_mode': 'form', + 'views': [(form_id, 'form')], + 'target': 'current', + 'context': { + 'default_property_rental_form_line_ids': line_list, + }, + } + def button_source(self): - domain = [('id', 'in', self.property_ids.ids)] + """详情:跳转到对应物业的表单""" + self.ensure_one() + prop = self.property_id + if not prop: + raise UserError('该评估方案未关联物业,无法查看详情') return { "name": "物业", "type": "ir.actions.act_window", - "view_mode": "tree", "res_model": "yuthon.property", - 'tree_view_ref': 'yuthon_property.view_property_evaluation_plan_tree1', - "domain": domain, - "target": "new", + "view_mode": "form", + "views": [[self.env.ref('yuthon_property.yuthon_property_form').id, 'form']], + "target": "current", + "res_id": prop.id, } + DERIVED_FIELDS = ['owner_id', 'registered_id', 'registered_id2', 'lease_period', + 'first_years_begin', 'increments_few_years', 'annual_increase_amount', + 'rent_unit', 'annual_increase_percentage'] + def update_message(self): + """这些字段已改为从关联物业实时计算、不落库,这里只需清缓存触发重算""" property_evaluation_ids = self.env["property.evaluation.plan"].browse( self._context.get('active_ids', self._context.get('active_id'))) - for record in property_evaluation_ids: - property_id = self.sudo().env['yuthon.property'].search([('name', '=', record.name)]) - if property_id: - record.write({ - 'owner_id': property_id.owner_id, - 'lease_period': property_id.lease_period, - 'registered_id': property_id.registered_id, - }) + property_evaluation_ids.invalidate_recordset(self.DERIVED_FIELDS) diff --git a/yuthon_property/models/yuthon_property.py b/yuthon_property/models/yuthon_property.py index 8ece14979..00dab2cab 100644 --- a/yuthon_property/models/yuthon_property.py +++ b/yuthon_property/models/yuthon_property.py @@ -1,7 +1,7 @@ from odoo import models, fields, api from odoo.exceptions import UserError, ValidationError from pypinyin import pinyin,lazy_pinyin -from datetime import datetime,date +from datetime import datetime,date,timedelta import calendar @@ -39,7 +39,24 @@ class YuthonProperty(models.Model): 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') + # 业务状态:评估 → 挂牌 → 签约 的完整链路 + # (原先拆成「评估状态 property_leasing」+「挂牌状态 listing_state」两个字段,现合并为一个) + # 流转:保存只置「待X」,转交才置「X中」 + business_state = fields.Selection([ + ('', ''), + ('to', '待评估'), + ('ing', '评估中'), + ('done', '已评估'), + ('to_list', '待挂牌'), + ('listing', '挂牌中'), + ('listed', '已挂牌'), + ('to_sign', '待签约'), + ('signing', '签约中'), + ('signed', '已签约'), + ], string='业务状态', default='to') + # 该物业走过的所有审批(soong.workflow.record):展示用,不落库 + workflow_record_ids = fields.Many2many('soong.workflow.record', string='审批流程', + compute='_compute_workflow_record_ids') 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="居住用房") @@ -97,6 +114,42 @@ class YuthonProperty(models.Model): 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") + # 基本信息补充(建筑 / 土地) + building_structure = fields.Char(string='建筑结构') + rental_floor = fields.Char(string='出租楼层') + land_nature = fields.Char(string='土地性质') + land_acquisition = fields.Selection([('transfer', '出让'), ('allocation', '划拨')], string='取得方式') + land_end_date = fields.Date(string='土地终止日期') + construction_year = fields.Char(string='建筑年代') + shared_land_area = fields.Float(string='共用地面积(㎡)', digits=(16, 4)) + + def _evaluation_date_deadline(self): + """评估基准日对应区间的最后一天:基准日「年份 +1」的同一天再减 1 天 + + 例:基准日 2026-09-24 → 区间 2026-09-24 ~ 2027-09-23 + (2 月 29 日在次年不存在时按 2 月 28 日算) + """ + self.ensure_one() + base = self.evaluation_date + if not base: + return False + try: + next_year = base.replace(year=base.year + 1) + except ValueError: + next_year = base.replace(year=base.year + 1, day=28) + return next_year - timedelta(days=1) + + @api.onchange('evaluation_date') + def _onchange_evaluation_date(self): + """修改评估基准日后:若当前日期已超出「基准日 ~ 次年同日 - 1 天」这个区间, + 物业业务状态回到「待评估」;业务状态是「已签约」的物业不做处理。 + """ + for record in self: + if not record.evaluation_date or record.business_state == 'signed': + continue + deadline = record._evaluation_date_deadline() + if deadline and fields.Date.context_today(record) > deadline: + record.business_state = 'to' def update_property_state(self): today = date.today() @@ -197,17 +250,115 @@ class YuthonProperty(models.Model): record.is_new = has_valid_line - @api.onchange('reference_ids') + # 「审批流程」页只显示这几类单据(评估审批 / 挂牌审批 / 成交确认书审批) + WORKFLOW_PAGE_MODELS = ( + 'property.evaluate.application', # 评估审批(物业评估申请) + 'property.rental.form', # 挂牌审批(挂牌申报表) + 'property.confirm', # 成交确认书审批 + ) + + @api.model + def _get_workflow_source_paths(self, only_models=None): + """自动发现「挂了工作流、且能关联到本物业」的单据,返回 [(模型名, 到物业的域路径)] + + 覆盖两层: + ① 单据上有指向 yuthon.property 的 Many2one 字段(如 property.split.approval.property_id); + ② 单据的明细行(One2many / Many2many)上有指向 yuthon.property 的 Many2one(如 + property.rental.form.property_rental_form_line_ids.property_id、 + property.confirm.lease_ids.address_id)。 + + :param only_models: 只在这些模型里找(传 None 表示全库扫描) + """ + mixin_cls = self.env['soong.workflow.mixin'].__class__ + paths = [] + for model_name in list(self.env.registry): + if model_name not in self.env: + continue + if only_models and model_name not in only_models: + continue + cls = self.env.registry[model_name] + try: + if not issubclass(cls, mixin_cls): + continue + except TypeError: + continue + for fname, field in self.env[model_name]._fields.items(): + if field.type == 'many2one' and field.comodel_name == 'yuthon.property': + paths.append((model_name, fname)) + elif field.type in ('one2many', 'many2many') and field.comodel_name in self.env: + for sname, sfield in self.env[field.comodel_name]._fields.items(): + if sfield.type == 'many2one' and sfield.comodel_name == 'yuthon.property': + paths.append((model_name, '%s.%s' % (fname, sname))) + return paths + + @api.depends() + def _compute_workflow_record_ids(self): + """本物业相关的审批流程记录:只取「评估审批 / 挂牌审批 / 成交确认书审批」且**审批已结束**的""" + Workflow = self.env['soong.workflow.record'].sudo() + paths = {} + for model_name, path in self._get_workflow_source_paths(self.WORKFLOW_PAGE_MODELS): + paths.setdefault(model_name, []).append(path) + + for record in self: + found_ids = set() + for model_name, model_paths in paths.items(): + source = self.env[model_name].sudo() + res_ids = set() + for path in model_paths: + res_ids.update(source.search([(path, '=', record.id)]).ids) + if res_ids: + found_ids.update(Workflow.search([ + ('res_model', '=', model_name), ('res_id', 'in', list(res_ids)), + ('approve_state', '=', 'end'), + ]).ids) + record.workflow_record_ids = Workflow.browse(list(found_ids)) + + def _get_valid_reference_line(self): + """取出租参考条件明细行:优先取 [开始日期, 结束日期] 覆盖当天的那条; + 没有命中时回退到原有行为(最后一条)。""" + self.ensure_one() + lines = self.reference_ids + if not lines: + return lines + today = fields.Date.context_today(self) + valid = lines.filtered( + lambda line: (not line.start_date or line.start_date <= today) + and (not line.end_date or line.end_date >= today) + ) + if not valid: + return lines[-1:] + # 多条命中时取开始日期最新的一条 + return valid.sorted(lambda line: line.start_date or today, reverse=True)[:1] + + def _get_valid_title_line(self): + """取产权信息明细行:优先取 [生效日期, 失效日期] 覆盖当天的那条; + 没有命中时回退到最后一条。""" + self.ensure_one() + lines = self.title_information_ids + if not lines: + return lines + today = fields.Date.context_today(self) + valid = lines.filtered( + lambda line: (not line.start_time or line.start_time <= today) + and (not line.end_date or line.end_date >= today) + ) + if not valid: + return lines[-1:] + # 多条命中时取生效日期最新的一条 + return valid.sorted(lambda line: line.start_time or today, reverse=True)[:1] + + @api.onchange('reference_ids', 'reference_ids.start_date', 'reference_ids.end_date') 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 + line = record._get_valid_reference_line() + if line: + record.lease_period = line.lease_period + record.rent_period = line.rent_period + record.first_years_begin = line.first_years_begin + record.increments_few_years = line.increments_few_years + record.annual_increase_percentage = line.annual_increase_percentage + record.annual_increase_amount = line.annual_increase_amount + record.rent_unit = line.rent_unit else: record.lease_period = 0.0 record.rent_period = 0.0 @@ -386,6 +537,13 @@ class YuthonProperty(models.Model): evaluation_rent_total = fields.Float(string='评估总价(元•月,散租)') evaluation_whole_rent_price = fields.Float(string='评估整租单价(元/m² •月)') evaluation_whole_rent_total = fields.Float(string='评估总价(元•月,整租)') + # 评估信息页(物业表单「评估信息」tab) + evaluation_date = fields.Date(string='基准日') + evaluation_info = fields.Char(string='评估信息') + evaluation_agency = fields.Char(string='评估机构') + evaluation_code = fields.Char(string='评估编号') + evaluation_method = fields.Char(string='评估方法') + evaluation_remark = fields.Char(string='备注') def update_precinct(self): property_ids = self.env["yuthon.property"].browse( @@ -397,6 +555,12 @@ class YuthonProperty(models.Model): def put_declare_approval(self): property_ids = self.env["yuthon.property"].browse( self._context.get('active_ids', self._context.get('active_id'))) + # 已进入签约流程(待签约/签约中/已签约)的物业不放进挂牌申报表 + form_model = self.env['property.rental.form'] + property_ids = form_model._get_listable_properties(property_ids) + if not property_ids: + raise UserError('所选物业均已进入签约流程(待签约/签约中/已签约),不能在挂牌申报表中提交') + form_model._check_listing_available(property_ids) form_id = self.env.ref('yuthon_property_approval.view_property_rental_form_form').id property_list = [] for record in property_ids: @@ -498,9 +662,10 @@ class YuthonProperty(models.Model): def put_assessment_approval(self): for record in self: + ref_line = record._get_valid_reference_line() self.env['property.evaluation.plan'].create({ 'name': record.name, - 'property_ids': [(6, 0, [record.id])], + 'property_id': 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, @@ -509,7 +674,7 @@ class YuthonProperty(models.Model): '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, + 'annual_increase_percentage': ref_line.annual_increase_percentage if ref_line else None, 'assessment_category': 'rent_money', 'remake': record.remark, }) @@ -525,11 +690,12 @@ class YuthonProperty(models.Model): 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': + if record.business_state == 'ing': raise UserError(f'{record.name}该物业已在评估,请勿重复提交') + ref_line = record._get_valid_reference_line() self.env['property.evaluation.plan'].create({ 'name': record.name, - 'property_ids': [(6, 0, [record.id])], + 'property_id': 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, @@ -538,11 +704,11 @@ class YuthonProperty(models.Model): '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, + 'annual_increase_percentage': ref_line.annual_increase_percentage if ref_line else None, 'assessment_category': 'rent_money', 'remake': record.remark, }) - record.write({'property_leasing': 'ing'}) + record.write({'business_state': 'ing'}) return { "name": "物业评估方案", 'type': 'ir.actions.act_window', @@ -612,12 +778,13 @@ class YuthonProperty(models.Model): 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 '' + ref_line = record._get_valid_reference_line() + lease_period = ref_line.lease_period if ref_line else '' + rent_period = ref_line.rent_period if ref_line else '' + first_years_begin = ref_line.first_years_begin if ref_line else '' + increments_few_years = ref_line.increments_few_years if ref_line else '' + annual_increase_amount = ref_line.annual_increase_amount if ref_line else '' + rent_unit = ref_line.rent_unit if ref_line 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 '' @@ -905,6 +1072,8 @@ class YuthonReferenceConditions(models.Model): _description = '出租参考条件' yuthon_property_id = fields.Many2one('yuthon.property', string="关联物业信息") + start_date = fields.Date(string='开始日期') + end_date = fields.Date(string='结束日期') lease_period = fields.Integer(string='租赁期限(<=)') rent_period = fields.Integer(string="免租期(<=)") first_years_begin = fields.Integer(string='第几年开始') diff --git a/yuthon_property/security/ir.model.access.csv b/yuthon_property/security/ir.model.access.csv index 10fa872c0..faf5de156 100644 --- a/yuthon_property/security/ir.model.access.csv +++ b/yuthon_property/security/ir.model.access.csv @@ -104,4 +104,6 @@ access_task_push_wizard,task.push.wizard,model_task_push_wizard,base.group_user, access_utility_meter_wizard,utility.meter.wizard,model_utility_meter_wizard,base.group_user,1,1,1,1 access_invoicing_information_line,invoicing.information.line,model_invoicing_information_line,base.group_user,1,1,1,1 access_tenant_import_wizard,tenant.import.wizard,model_tenant_import_wizard,base.group_user,1,1,1,1 -access_batch_invoice_export_wizard,batch.invoice.export.wizard,model_batch_invoice_export_wizard,base.group_user,1,1,1,1 \ No newline at end of file +access_batch_invoice_export_wizard,batch.invoice.export.wizard,model_batch_invoice_export_wizard,base.group_user,1,1,1,1 +access_property_import_wizard,property.import.wizard,model_property_import_wizard,base.group_user,1,1,1,1 +access_property_evaluation_import_wizard,property.evaluation.import.wizard,model_property_evaluation_import_wizard,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/yuthon_property/views/menuitem.xml b/yuthon_property/views/menuitem.xml index 6261f5ae7..88f54f1a2 100644 --- a/yuthon_property/views/menuitem.xml +++ b/yuthon_property/views/menuitem.xml @@ -24,6 +24,22 @@ parent="yuthon_property_menu" action="view_property_evaluation_plan_action" /> + + + + + + + property.bank.statements.tree.loan + property.bank.statements + primary + 99 + + + + + + + + + + + + + + +