194 lines
7.0 KiB
Python
194 lines
7.0 KiB
Python
from odoo import models, fields, api
|
|
from datetime import timedelta
|
|
from odoo.exceptions import UserError, ValidationError
|
|
|
|
# 导入异常类
|
|
|
|
|
|
class EstateProperty(models.Model):
|
|
_name = "estate.property"
|
|
_description = "房地产属性"
|
|
# 继承邮件线程和活动混合类
|
|
_inherit = ["mail.thread", "mail.activity.mixin"]
|
|
# 默认按ID降序排列
|
|
_order = "id desc"
|
|
|
|
name = fields.Char(string="名称", required=True)
|
|
description = fields.Text(string="描述")
|
|
postcode = fields.Char(string="邮政编码")
|
|
# 默认日期为三个月后
|
|
date_availability = fields.Date(
|
|
string="可用日期",
|
|
copy=False,
|
|
default=lambda self: fields.Date.today() + timedelta(days=90),
|
|
)
|
|
expected_price = fields.Float(string="预期价格", required=True)
|
|
selling_price = fields.Float(string="销售价格", copy=False)
|
|
bedrooms = fields.Integer(string="卧室数量", default=2)
|
|
living_area = fields.Integer(string="居住面积")
|
|
facades = fields.Integer(string="立面")
|
|
garage = fields.Boolean(string="是否有车库")
|
|
garden = fields.Boolean(string="是否有花园")
|
|
garden_area = fields.Integer(string="花园面积")
|
|
garden_orientation = fields.Selection(
|
|
[("north", "北"), ("south", "南"), ("east", "东"), ("west", "西")],
|
|
string="花园朝向",
|
|
)
|
|
# 默认货币为公司货币
|
|
currency_id = fields.Many2one(
|
|
"res.currency",
|
|
string="货币",
|
|
required=True,
|
|
default=lambda self: self.env.ref("base.CNY").id,
|
|
)
|
|
|
|
active = fields.Boolean(string="是否归档", default=True)
|
|
# 房屋类型
|
|
state = fields.Selection(
|
|
[
|
|
("new", "新"),
|
|
("offer_received", "已收到报价"),
|
|
("offer_accepted", "已接受报价"),
|
|
("sold", "已售出"),
|
|
("canceled", "已取消"),
|
|
],
|
|
string="状态",
|
|
default="new",
|
|
required=True,
|
|
copy=False,
|
|
)
|
|
versionflog = fields.Integer(string="换版", default=1)
|
|
# 关联房屋类型模型
|
|
property_type_id = fields.Many2one(
|
|
"estate.property.type", string="房屋类型", required=True
|
|
)
|
|
# 买家
|
|
buyer_id = fields.Many2one("res.partner", string="买家", copy=False)
|
|
# 关联联系人模型卖家
|
|
seller_id = fields.Many2one(
|
|
"res.users", string="卖家", required=True, default=lambda self: self.env.user
|
|
)
|
|
# 房屋标签
|
|
tag_ids = fields.Many2many("estate.property.tag", string="房屋标签")
|
|
# 房屋报价
|
|
offer_ids = fields.One2many(
|
|
"estate.property.offer", "property_id", string="房屋报价"
|
|
)
|
|
# 房屋总面积
|
|
total_area = fields.Float(
|
|
string="总面积", compute="_compute_total_area", store=True
|
|
)
|
|
# 最佳报价
|
|
best_price = fields.Float(
|
|
string="最佳报价", compute="_compute_best_price", store=True
|
|
)
|
|
create_date_month = fields.Char(string="创建月份", index=True, copy=False)
|
|
# 房产预期价格必须严格为正数
|
|
_sql_constraints = [
|
|
("check_expected_price", "CHECK(expected_price > 0)", "预期价格必须为正数"),
|
|
("check_selling_price", "CHECK(selling_price > 0)", "销售价格必须为正数"),
|
|
("check_bedrooms", "CHECK(bedrooms > 0)", "卧室数量必须为正数"),
|
|
("check_living_area", "CHECK(living_area > 0)", "居住面积必须为正数"),
|
|
("check_facades", "CHECK(facades > 0)", "立面数量必须为正数"),
|
|
]
|
|
|
|
# 无法接受低于预期价格 90% 的报价
|
|
@api.constrains("selling_price", "expected_price") # 添加约束
|
|
def _check_selling_price(self):
|
|
for record in self:
|
|
if record.selling_price < record.expected_price * 0.9:
|
|
raise ValidationError("销售价格不能低于预期价格的90%")
|
|
|
|
@api.depends("living_area", "garden_area") # 计算字段
|
|
def _compute_total_area(self):
|
|
"""计算房屋总面积"""
|
|
for record in self:
|
|
record.total_area = record.living_area + record.garden_area
|
|
|
|
@api.depends("offer_ids.price") # 计算字段
|
|
def _compute_best_price(self):
|
|
"""计算最佳报价"""
|
|
for record in self:
|
|
best_price = 0.0
|
|
if record.offer_ids:
|
|
best_price = max(record.offer_ids.mapped("price"))
|
|
record.best_price = best_price
|
|
|
|
def action_sold(self):
|
|
"""标记为已售(需先接受报价)"""
|
|
if self.state != "offer_accepted":
|
|
raise UserError("必须接受报价后才能标记已售")
|
|
return self.write({"state": "sold"})
|
|
|
|
def action_cancel(self):
|
|
"""取消交易"""
|
|
if self.state == "sold":
|
|
raise UserError("已售房产不可取消")
|
|
return self.write({"state": "canceled"})
|
|
|
|
# 如果有花园,设置默认花园面积为50,朝向为南,若没有花园,则设置花园面积为0,朝向为无
|
|
@api.onchange("garden")
|
|
def _onchange_garden(self):
|
|
if self.garden:
|
|
self.garden_area = 50
|
|
self.garden_orientation = "south"
|
|
else:
|
|
self.garden_area = 0
|
|
self.garden_orientation = False
|
|
|
|
# 若取消选择车库则弹出警告
|
|
@api.onchange("garage")
|
|
def _onchange_garage(self):
|
|
if not self.garage == False:
|
|
return {"warning": {"title": "警告", "message": "确定取消车库吗?"}}
|
|
|
|
# •如果房产的状态不是‘新建’或‘已取消’,则阻止删除房产
|
|
@api.ondelete(at_uninstall=True)
|
|
def _unlink_except_new_canceled(self):
|
|
"""删除房产"""
|
|
for record in self:
|
|
if record.state not in ["new", "canceled"]:
|
|
raise UserError("只能删除新建或已取消的房产")
|
|
|
|
# 设置版本日志
|
|
def setversionflog(self):
|
|
# 空函数,不做任何操作
|
|
pass
|
|
|
|
def write(self, vals):
|
|
vals["create_uid"] = self.create_uid
|
|
return super(EstateProperty, self).write(vals)
|
|
|
|
# 定义按钮
|
|
def action_set_offer_received(self):
|
|
"""设置为已收到报价"""
|
|
return self.write({"state": "offer_received"})
|
|
|
|
def action_set_offer_accepted(self):
|
|
"""设置为已接受报价"""
|
|
return self.write({"state": "offer_accepted"})
|
|
|
|
def action_set_sold(self):
|
|
"""设置为已售出"""
|
|
# 将状态设置为已售出
|
|
return self.write({"state": "sold"})
|
|
|
|
def do_reject_new(self):
|
|
"""拒绝新建报价"""
|
|
# 将状态设置为"new"
|
|
return self.write({"state": "new"})
|
|
|
|
def do_reject_offer(self):
|
|
"""拒绝报价"""
|
|
return self.write({"state": "offer_received"})
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
records = super().create(vals_list)
|
|
for rec in records:
|
|
if rec.create_date:
|
|
rec.create_date_month = rec.create_date.strftime("%Y-%m")
|
|
else:
|
|
rec.create_date_month = fields.Date.today().strftime("%Y-%m")
|
|
return records
|