Skip to content
1 change: 1 addition & 0 deletions estate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
16 changes: 16 additions & 0 deletions estate/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
'name': 'Real Estate',
'depends': ['base'],
'application': True,
'data': [
'security/ir.model.access.csv',
'views/estate_property_views.xml',
'views/estate_property_type_views.xml',
'views/estate_property_tag_views.xml',
'views/estate_property_offer_views.xml',
'views/estate_menus.xml',
'data/data_type.xml',
'data/data_tags.xml',
'data/data.xml',
],
}
40 changes: 40 additions & 0 deletions estate/data/data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="estate_property_list_view_demo_1" model="estate.property">
<field name="name">ABC Ltd</field>
<field name="property_type_id" ref="estate_property_type_1"/>
<field name="tag_ids" eval="[(6, 0, [ref('estate_property_tag_1')])]"/>
<field name="postcode">123345</field>
<field name="bedrooms">2</field>
<field name="living_area">135765</field>
<field name="expected_price">5820000</field>
<field name="selling_price">0</field>
<field name="date_availability" eval="(datetime.today() + relativedelta(months=3)).strftime('%Y-%m-%d')"/>
</record>

<record id="estate_property_list_view_demo_2" model="estate.property">
<field name="name">XYZ Pvt Ltd</field>
<field name="property_type_id" ref="estate_property_type_2"/>
<field name="tag_ids" eval="[(6, 0, [ref('estate_property_tag_1')])]"/>
<field name="postcode">7865445</field>
<field name="bedrooms">4</field>
<field name="living_area">100000</field>
<field name="expected_price">200000</field>
<field name="selling_price">0</field>
<field name="date_availability" eval="(datetime.today() + relativedelta(months=3)).strftime('%Y-%m-%d')"/>
</record>

<record id="estate_property_list_view_demo_3" model="estate.property">
<field name="name">Umbrella Corp</field>
<field name="property_type_id" ref="estate_property_type_4"/>
<field name="tag_ids" eval="[(6, 0, [ref('estate_property_tag_3')])]"/>
<field name="postcode">908765</field>
<field name="bedrooms">3</field>
<field name="living_area">100000</field>
<field name="expected_price">700000</field>
<field name="selling_price">0</field>
<field name="date_availability" eval="(datetime.today() + relativedelta(months=3)).strftime('%Y-%m-%d')"/>
</record>

</odoo>
18 changes: 18 additions & 0 deletions estate/data/data_tags.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="estate_property_tag_1" model="estate.property.tag">
<field name="name">Cozy</field>
</record>
<record id="estate_property_tag_2" model="estate.property.tag">
<field name="name">Furnished</field>
</record>
<record id="estate_property_tag_3" model="estate.property.tag">
<field name="name">Renovated</field>
</record>
<record id="estate_property_tag_4" model="estate.property.tag">
<field name="name">Unfurnished</field>
</record>
<record id="estate_property_tag_5" model="estate.property.tag">
<field name="name">Semi-furnished</field>
</record>
</odoo>
21 changes: 21 additions & 0 deletions estate/data/data_type.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="estate_property_type_1" model="estate.property.type">
<field name="name">House</field>
</record>
<record id="estate_property_type_2" model="estate.property.type">
<field name="name">Apartment</field>
</record>
<record id="estate_property_type_3" model="estate.property.type">
<field name="name">Penthouse</field>
</record>
<record id="estate_property_type_4" model="estate.property.type">
<field name="name">Villa</field>
</record>
<record id="estate_property_type_5" model="estate.property.type">
<field name="name">Boat House</field>
</record>
<record id="estate_property_type_6" model="estate.property.type">
<field name="name">Mansion</field>
</record>
</odoo>
4 changes: 4 additions & 0 deletions estate/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from . import estate_property
from . import estate_property_type
from . import estate_property_tag
from . import estate_property_offer
129 changes: 129 additions & 0 deletions estate/models/estate_property.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from datetime import timedelta

from odoo import api, fields, models
from odoo.exceptions import UserError


class EstateProperty(models.Model):
_name = "estate.property"
_description = "Real Estate Property"

def _default_availability_date(self):
return fields.Date.today() + timedelta(days=90)

name = fields.Char(required=True)
description = fields.Text()
postcode = fields.Char()
property_type_id = fields.Many2one(
"estate.property.type",
string="Property Type",
)
tag_ids = fields.Many2many(
"estate.property.tag",
string="Tags",
)
buyer_id = fields.Many2one(
"res.partner",
string="Buyer",
copy=False,
)
salesperson_id = fields.Many2one(
"res.users",
string="Salesperson",
default=lambda self: self.env.user,
)
offer_ids = fields.One2many(
"estate.property.offer",
"property_id",
string="Offers",
)
date_availability = fields.Date(
copy=False,
default=lambda self: fields.Datetime.now() + timedelta(days=90),
)
expected_price = fields.Float(required=True)
selling_price = fields.Float(
readonly=True,
copy=False,
)
bedrooms = fields.Integer(
default=2,
)
facades = fields.Integer()
garage = fields.Boolean()
living_area = fields.Integer()
garden = fields.Boolean()
garden_area = fields.Integer()
total_area = fields.Integer(
compute="_compute_total_area",
)
best_price = fields.Float(
compute="_compute_best_price",
)
garden_orientation = fields.Selection([
('north', 'North'),
('south', 'South'),
('east', 'East'),
('west', 'West'),
])
active = fields.Boolean(
default=True,
)
state = fields.Selection(
[
('new', 'New'),
('offer_received', 'Offer Received'),
('offer_accepted', 'Offer Accepted'),
('sold', 'Sold'),
('cancelled', 'Cancelled'),
],
required=True,
copy=False,
default='new',
readonly=True,
)

@api.depends("living_area", "garden_area")
def _compute_total_area(self):
for property in self:
property.total_area = (
property.living_area +
property.garden_area
)

@api.depends("offer_ids.price")
def _compute_best_price(self):
for property in self:
prices = property.offer_ids.mapped("price")
property.best_price = max(prices) if prices else 0.0

@api.onchange("garden")
def _onchange_garden(self):
if self.garden:
self.garden_area = 10
self.garden_orientation = "north"
else:
self.garden_area = 0
self.garden_orientation = False

# Mark the property as sold
def action_sold(self):
for property in self:
# A cancelled property cannot be sold
if property.state == "cancelled":
raise UserError(
"Cancelled properties cannot be sold."
)
property.state = "sold"
return True

# Mark the property as cancelled
def action_cancel(self):
for property in self:
# A sold property cannot be cancelled
if property.state == "sold":
raise UserError(
"Sold properties cannot be cancelled."
)
property.state = "cancelled"
return True
93 changes: 93 additions & 0 deletions estate/models/estate_property_offer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from datetime import timedelta

from odoo import api, fields, models
from odoo.exceptions import UserError


class EstatePropertyOffer(models.Model):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be 2 blank lines before it.

_name = "estate.property.offer"
_description = "Real Estate Property Offer"

price = fields.Float()
validity = fields.Integer(
default=7,
)
date_deadline = fields.Date(
compute="_compute_date_deadline",
inverse="_inverse_date_deadline",
)
status = fields.Selection(
[
("accepted", "Accepted"),
("refused", "Refused"),
],
copy=False,
)
partner_id = fields.Many2one(
"res.partner",
required=True,
)
property_id = fields.Many2one(
"estate.property",
required=True,
)

@api.depends("create_date", "validity")
def _compute_date_deadline(self):
for offer in self:
create_date = (
offer.create_date.date()
if offer.create_date
else fields.Date.today()
)
offer.date_deadline = (
create_date +
timedelta(days=offer.validity)
)

def _inverse_date_deadline(self):
for offer in self:
create_date = (
offer.create_date.date()
if offer.create_date
else fields.Date.today()
)
if offer.date_deadline:
offer.validity = (
offer.date_deadline -
create_date
).days

# Accept the offer
def action_accept(self):
for offer in self:
# Check if another offer for this property has already been accpted
if offer.property_id.offer_ids.filtered(
lambda o: o.status == "accepted" and o.id != offer.id
):
raise UserError(
"Another offer for this property has already been accepted."
)
# Set the status to "accepted"
offer.status = "accepted"
# Updating the related property fields
offer.property_id.write({
"buyer_id": offer.partner_id.id,
"selling_price": offer.price,
"state": "offer_accepted",
})
return True

# Refuse the offer and set the status to "refused"
def action_refuse(self):
for offer in self:
offer.status = "refused"
return True

@api.model_create_multi
def create(self, vals_list):
offers = super().create(vals_list)
for offer in offers:
if offer.property_id.state == "new":
offer.property_id.state = "offer_received"
return offers
8 changes: 8 additions & 0 deletions estate/models/estate_property_tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo import fields, models


class EstatePropertyTag(models.Model):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be 2 blank lines before it.

_name = "estate.property.tag"
_description = "Real Estate Property Tag"

name = fields.Char(required=True)
8 changes: 8 additions & 0 deletions estate/models/estate_property_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo import fields, models


class EstatePropertyType(models.Model):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be 2 blank lines before it.

_name = "estate.property.type"
_description = "Real Estate Property Type"

name = fields.Char(required=True)
5 changes: 5 additions & 0 deletions estate/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_estate_property,access_estate_property,model_estate_property,base.group_user,1,1,1,1
access_estate_property_type,access_estate_property_type,model_estate_property_type,base.group_user,1,1,1,1
access_estate_property_tag,access_estate_property_tag,model_estate_property_tag,base.group_user,1,1,1,1
access_estate_property_offer,access_estate_property_offer,model_estate_property_offer,base.group_user,1,1,1,1
42 changes: 42 additions & 0 deletions estate/views/estate_menus.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<menuitem
id="estate_menu_root"
name="Real Estate"
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unneccary diff.

<menuitem
id="estate_advertisements_menu"
name="Advertisements"
parent="estate_menu_root"
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unneccary diff.

<menuitem
id="estate_settings_menu"
name="Settings"
parent="estate_menu_root"
/>

<menuitem
id="estate_property_type_menu_action"
name="Property Types"
parent="estate_settings_menu"
action="estate_property_type_action"
/>

<menuitem
id="estate_property_tag_menu_action"
name="Property Tags"
parent="estate_settings_menu"
action="estate_property_tag_action"
/>

<menuitem
id="estate_property_menu_action"
parent="estate_advertisements_menu"
action="estate_property_action"
/>

</odoo>

Loading