Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ADD] estate: create real estate module with basic property managemen… #136

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/material_theme_project_new.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/tutorials.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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
30 changes: 30 additions & 0 deletions estate/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "Real_estate",
"version": "0.1",
"license": "LGPL-3",
"category": "Real Estate/Brokerage",
"author": "sahilpanghal(span)",
"summary": "Real estate module",
"description": "Real estate module",
"installable": True,
"application": True,
"icons": ["static/description/realestate.png"],
"depends": ["base"],
"data": [
"security/security.xml",
"security/ir.model.access.csv",
"data/estate.property.type.csv",
"report/estate_property_offer_report.xml",
"report/estate_property_offer_subTemplate.xml",
"report/estate_property_offer_report_template.xml",
"views/estate_property_view.xml",
"views/estate_property_offer_view.xml",
"views/estate_property_type_view.xml",
"views/estate_property_tag_view.xml",
"views/estate_menu.xml",
"views/res_users.xml",
],
"demo": [
"demo/estate_property_demo.xml",
],
}
5 changes: 5 additions & 0 deletions estate/data/estate.property.type.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
id,name
id1,Residential
id2,Commercial
id3,Industrial
id4,Land
86 changes: 86 additions & 0 deletions estate/demo/estate_property_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>

<record id="demo_data_1" model="estate.property">
<field name="name">Big Villa</field>
<field name="state">new</field>
<field name="description">A nice and big villa</field>
<field name="postcode">12345</field>
<field name="date_availablity">2020-02-02</field>
<field name="expected_price">1600000</field>
<field name="bedrooms">6</field>
<field name="living_area">100</field>
<field name="facades">4</field>
<field name="garage">True</field>
<field name="garden">True</field>
<field name="garden_area">100000</field>
<field name="garden_orientation">south</field>
<field name="property_type_id" ref="estate.id1" />
</record>

<record id="demo_data_2" model="estate.property">
<field name="name">Trailer home</field>
<field name="state">canceled</field>
<field name="description">Home in a trailer park</field>
<field name="postcode">54321</field>
<field name="date_availablity">1970-01-01</field>
<field name="expected_price">100000</field>
<field name="selling_price">120000</field>
<field name="bedrooms">1</field>
<field name="living_area">10</field>
<field name="facades">4</field>
<field name="garage">False</field>
<field name="property_type_id" ref="estate.id1" />
</record>

<record id="demo_data_3" model="estate.property">
<field name="name">Luxury villa</field>
<field name="state">new</field>
<field name="description">A very nice villa</field>
<field name="postcode">12345</field>
<field name="date_availablity">2020-02-02</field>
<field name="expected_price">100</field>
<field name="bedrooms">6</field>
<field name="living_area">100</field>
<field name="garage">True</field>
<field name="garden">True</field>
<field name="garden_area">100000</field>
<field name="garden_orientation">south</field>
<field name="facades">4</field>
<field name="offer_ids"
eval="[
Command.create({
'partner_id': ref('base.res_partner_2'),
'price': 190000000,
'Validity': 14
}),

]" />
<field name="property_type_id" ref="estate.id1"></field>
</record>

<record id="offer_demo_data_1" model="estate.property.offer">
<field name="partner_id" ref="base.res_partner_12" />
<field name="property_id" ref="demo_data_1" />
<field name="price">10000</field>
<field name="deadline" eval="(datetime.now() + relativedelta(days=20))" />
</record>

<record id="offer_demo_data_2" model="estate.property.offer">
<field name="partner_id" ref="base.res_partner_12" />
<field name="property_id" ref="demo_data_1" />
<field name="price">1500000</field>
<field name="Validity">14</field>
</record>

<record id="offer_demo_data_3" model="estate.property.offer">
<field name="partner_id" ref="base.res_partner_2" />
<field name="property_id" ref="demo_data_1" />
<field name="price">1500001</field>
<field name="Validity">14</field>
</record>

<function model="estate.property.offer" name="action_accept">
<value eval="[ref('offer_demo_data_3')]" />
</function>
</odoo>
6 changes: 6 additions & 0 deletions estate/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# imported all the models taht are made inside the model folder
from . import estate_property
from . import estate_property_type
from . import estate_property_tag
from . import estate_property_offer
from . import res_users
128 changes: 128 additions & 0 deletions estate/models/estate_property.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models
from odoo.exceptions import UserError, ValidationError


class EstateProperty(models.Model):
_name = "estate.property"
_description = "EstateProperty"
_order = "id desc"
# created the field for the estate.property model
name = fields.Char(required=True, default="Unkown")
description = fields.Text()
property_type_id = fields.Many2one("estate.property.type", string="Property Types")
postcode = fields.Char()
date_availablity = fields.Date(
copy=False, default=lambda self: fields.Date.today() + relativedelta(months=3)
)
expected_price = fields.Float(required=True)
selling_price = fields.Float(readonly=True, copy=False)
bedrooms = fields.Integer(default="2")
living_area = fields.Integer()
facades = fields.Integer()
garage = fields.Boolean()
garden = fields.Boolean()
garden_area = fields.Integer()
garden_orientation = fields.Selection(
[("north", "North"), ("south", "South"), ("east", "East"), ("west", "West")]
)
state = fields.Selection(
[
("new", "New"),
("offer_recieved", "Offer Recieved"),
("offer_accepted", "Offer Accepted"),
("sold", "Sold"),
("canceled", "Canceled"),
],
default="new",
readonly=True,
)
active = fields.Boolean(default=True)
saler_id = fields.Many2one(
"res.users",
string="Salesperson",
index=True,
default=lambda self: self.env.user,
)
buyer_id = fields.Many2one("res.partner", string="Buyer", index=True)
tag_ids = fields.Many2many("estate.property.tag", string="Tags")
offer_ids = fields.One2many("estate.property.offer", "property_id")
total = fields.Integer(compute="_compute_area")
best_price = fields.Integer(compute="_compute_bestprice")

# created the sql constraints for only accepting positive values for expected price and selling price
_sql_constraints = [
(
"check_expected_price",
"CHECK(expected_price > 0.0)",
"A property expected price must be strictly positive and Grater then Zero.",
),
(
"check_selling_price",
"CHECK(selling_price > 0.0)",
"A property selling price must be positive and Grater then Zero.",
),
]

# created the area computation function that will compute area from living area and garden area i.e living area + garden area
@api.depends("living_area", "garden_area")
def _compute_area(self):
for record in self:
record.total = record.living_area + record.garden_area

# created the best price computation function that will compute best price from offers i.e maximum from the offers
@api.depends("offer_ids")
def _compute_bestprice(self):
for record in self:
if record.offer_ids:
max1 = 0
for i in record.offer_ids:
if i.price > max1:
max1 = i.price
record.best_price = max1
else:
record.best_price = 0

# created the garden onchange function that will change the values of the dependent fiels when the particular field triger is activated i.e turning on the garden field will affect the dependent fields
@api.onchange("garden")
def _onchange_garden(self):
if self.garden:
self.garden_area = 10
self.garden_orientation = "north"

# created a python constraint that will check weather the selling price is grater then the 90% of the expected price
@api.constrains("selling_price")
def _check_selling_price(self):
for record in self:
if record.selling_price <= (90 / 100) * record.expected_price:
raise ValidationError(
"the selling price cannot be lower than 90'%' of the expected price."
)

# creating a delection check function that will check if the property is sold or not
@api.ondelete(at_uninstall=False)
def _check_property(self):
if any(user.state not in ("new", "canceled") for user in self):
raise UserError("You can't delete a property that is in process.")

# created the action for the sold button that will chage the state field of the property to sold
def action_sold(self):
for record in self:
if record.state in ["sold", "canceled"]:
raise UserError(
"This property is alredy sold or canceled. You can't sell it."
)
else:
record.state = "sold"
return True

# created the action for the cancel button that will change the state of the property to canceled
def action_cancel(self):
for record in self:
if record.state == "sold":

Choose a reason for hiding this comment

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

Try same as above

raise UserError("This property is alredy sold. You can't cancel it.")
elif record.state == "canceled":
raise UserError("This property is alredy canceled.")
else:
record.state = "canceled"
return True
Loading