Skip to content

Commit

Permalink
[ADD] estate:[FIX] estate: added different functionalities and actions.
Browse files Browse the repository at this point in the history
Enhanced estate module by updating estate_property model and views, adding new m
odels for estate_property_offer, estate_property_tag, and estate_property_type,
and refining access control and menus. Improved estate_property_views functional
ity for better user experience.
  • Loading branch information
akya-odoo committed Aug 6, 2024
1 parent f8bc4ff commit 6aa9cca
Show file tree
Hide file tree
Showing 8 changed files with 331 additions and 25 deletions.
2 changes: 1 addition & 1 deletion estate/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from . import estate_property
from . import estate_property, estate_property_type, estate_property_tag, estate_property_offer
83 changes: 70 additions & 13 deletions estate/models/estate_property.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
from odoo import models, fields
from odoo import models, fields, api
from odoo.exceptions import UserError, ValidationError
from odoo.tools.float_utils import float_is_zero, float_compare


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

Title = fields.Char(required=True)
Description = fields.Text()
Postcode = fields.Char()
Availability_date = fields.Date(copy=False)
Expected_price = fields.Float(required=True, default=0.0)
Selling_price = fields.Float(string="Selling Price", readonly=True)
Bedrooms = fields.Integer(default=2)
Living_area = fields.Integer()
Facades = fields.Integer()
Garage = fields.Boolean()
Garden = fields.Boolean()
title = fields.Char(required=True)
description = fields.Text()
postcode = fields.Char()
availability_date = fields.Date(copy=False)
expected_price = fields.Float(required=True, default=0.0)
selling_price = fields.Float(string="Selling Price", readonly=True)
bedrooms = fields.Integer(default=2)
living_area = fields.Integer()
facades = fields.Integer()
garage = fields.Boolean()
garden = fields.Boolean()
garden_area = fields.Integer()
best_price = fields.Float(compute="_compute_best_price")
total_area = fields.Float(compute="_compute_total")
garden_orientation = fields.Selection([
('north', 'North'),
('south', 'South'),
Expand All @@ -25,6 +29,59 @@ class EstateProperty(models.Model):
])
state = fields.Selection([
('new', 'New'),
('used', 'Used'),
('offer_accepted', 'Offer_accepted'),
('sold', 'Sold'),
('canceled', 'Canceled')
], string='Status', default='new')
active = fields.Boolean(string='Active', default=True)
property_type_id = fields.Many2one('estate.property.type', string="Property Type")
buyer_id = fields.Many2one('res.partner', string="Buyer")
seller_id = fields.Many2one('res.users', string="Salesperson", default=lambda self: self.env.user)
tag_ids = fields.Many2many('estate.property.tag')
offer_ids = fields.One2many('estate.property.offer', 'property_id', string="Offers")

@api.depends('living_area', 'garden_area')
def _compute_total(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:
if record.offer_ids:
record.best_price = max(record.offer_ids.mapped('price'))
else:
record.best_price = 0.0

@api.onchange('garden')
def _onchange_garden(self):
if self.garden:
self.garden_area = 10.0
self.garden_orientation = 'north'
else:
self.garden_area = 0.0
self.garden_orientation = False

def action_cancel(self):
for record in self:
if record.state == 'sold':
raise UserError("Sold properties cannot be canceled.")
record.state = 'canceled'

def action_sold(self):
for record in self:
if record.state == 'canceled':
raise UserError("Canceled properties cannot be sold.")
record.state = 'sold'

_sql_constraints = [
('check_expected_price', 'CHECK(expected_price > 0)', 'The expected price must be strictly positive.'),
('check_selling_price', 'CHECK(selling_price >= 0)', 'The selling price must be positive.')
]

@api.constrains('selling_price', 'expected_price')
def _check_selling_price(self):
for record in self:
if not float_is_zero(record.selling_price, precision_rounding=0.01):
if float_compare(record.selling_price, record.expected_price * 0.9, precision_rounding=0.01) == -1:
raise ValidationError("The selling price cannot be lower than 90% of the expected price.")
55 changes: 55 additions & 0 deletions estate/models/estate_property_offer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# estate_property_offer.py
from odoo import models, fields, api
from datetime import timedelta
from odoo.exceptions import UserError


class EstatePropertyOffer(models.Model):
_name = 'estate.property.offer'
_description = 'Property Offer'

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

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

def _inverse_date_deadline(self):
for record in self:
if record.date_deadline and record.create_date:
# Convert create_date to date before subtracting
create_date_date = record.create_date.date()
record.validity = (record.date_deadline - create_date_date).days
else:
record.validity = 0

def action_confirm(self):
for record in self:
if record.status == 'accepted':
raise UserError("This offer has already been accepted.")
record.status = 'accepted'
record.property_id.write({
'selling_price': record.price,
'buyer_id': record.partner_id.id,
'state': 'offer_accepted',
})

_sql_constraints = [
('check_offer_price', 'CHECK(price > 0)', 'The offer price must be strictly positive.')
]

def action_cancel(self):
for record in self:
if record.status == 'refused':
raise UserError("This offer has already been refused.")
record.status = 'refused'

12 changes: 12 additions & 0 deletions estate/models/estate_property_tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from odoo import models, fields


class EstatePropertyTag(models.Model):
_name = 'estate.property.tag'
_description = 'Property Tag'

name = fields.Char(string="Name", required=True)

_sql_constraints = [
('unique_name', 'UNIQUE(name)', 'This property tag already exists.'),
]
12 changes: 12 additions & 0 deletions estate/models/estate_property_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from odoo import models, fields


class EstateProperty(models.Model):
_name = 'estate.property.type'
_description = 'Estate Property Type'

name = fields.Char(string="Name", required=True)

_sql_constraints = [
('unique_name', 'UNIQUE(name)', 'This property type already exists.'),
]
5 changes: 5 additions & 0 deletions estate/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
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
estate.access_estate_property_type,access_estate_property_type,estate.model_estate_property_type,base.group_user,1,1,1,1
estate.access_estate_property_tag,access_estate_property_tag,estate.model_estate_property_tag,base.group_user,1,1,1,1
estate.access_estate_property_offer,access_estate_property_offer,estate.model_estate_property_offer,base.group_user,1,1,1,1


7 changes: 6 additions & 1 deletion estate/views/estate_menus.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<menuitem id="test_menu_root" name="Test">
<menuitem id="estate_menu_root" name="Real Estate">
<menuitem id="Advertisements" name="Advertisements">
<menuitem id="Properties" action="action_estate_property"/>
</menuitem>
<menuitem id="Settings" name="Settings">
<menuitem id="Properties_Types" name="Property Types" action="action_estate_property_type"/>
<menuitem id="Properties_Tags" name="Property Tags" action="action_estate_property_tag"/>

</menuitem>
</menuitem>
</odoo>
Loading

0 comments on commit 6aa9cca

Please sign in to comment.