Skip to content
Open
Show file tree
Hide file tree
Changes from 8 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
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
27 changes: 27 additions & 0 deletions estate/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
'name': "Estate",
'summary': """
The Real Estate Advertisement module
""",

'description': """
The Real Estate Advertisement module
""",
'author': "Odoo",
'website': "https://www.odoo.com/",
'category': 'Tutorials',
'version': '19.0.0.1.0',
'application': True,
'depends': [
'base',
],
'data': [
'data/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',
],
'license': 'LGPL-3',
}
5 changes: 5 additions & 0 deletions estate/data/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
estate_property_access_user,estate.property.user,model_estate_property,base.group_user,1,1,1,1
estate_property_type_access_user,estate.property.type.user,model_estate_property_type,base.group_user,1,1,1,1
estate_property_tag_access_user,estate.property.tag.user,model_estate_property_tag,base.group_user,1,1,1,1
estate_property_offer_access_user,estate.property.offer.user,model_estate_property_offer,base.group_user,1,1,1,1
1 change: 1 addition & 0 deletions estate/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import estate_property, estate_property_type, estate_property_tag, estate_property_offer
64 changes: 64 additions & 0 deletions estate/models/estate_property.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from odoo import api, fields, models


class EstateProperty(models.Model):
_name = "estate.property"
_description = "Estate Property"
name = fields.Char('Property Name', required=True)
description = fields.Text('Description')
postcode = fields.Char('Postcode')
date_availability = fields.Date('Availability Date', copy=False, default=lambda self: fields.Date.add(fields.Date.today(), months=3))
expected_price = fields.Float('Expected Price', required=True)
selling_price = fields.Float('Selling Price', readonly=True, copy=False)
bedrooms = fields.Integer('Bedrooms', default=2)
living_area = fields.Integer('Living Area')
facades = fields.Integer('Facades')
garage = fields.Boolean('Garage')
garden = fields.Boolean('Garden')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Strings are not needed in most of those. The default would work.


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

garden_area = fields.Integer('Garden Area')
garden_orientation = fields.Selection(
selection=[
('north', 'North'),
('south', 'South'),
('east', 'East'),
('west', 'West'),
],
)
state = fields.Selection(
selection=[
('new', 'New'),
('offer received', 'Offer Received'),
('offer accepted', 'Offer Accepted'),
('sold', 'Sold'),
('cancelled', 'Cancelled'),
],
default='new',
required=True,
)
property_type_id = fields.Many2one('estate.property.type', string="Property Type")
buyer_id = fields.Many2one('res.partner', string="Buyer", copy=False)
salesperson_id = fields.Many2one('res.users', string="Salesperson", default=lambda self: self.env.uid)
tag_ids = fields.Many2many('estate.property.tag', string="Property Tag")
offer_ids = fields.One2many('estate.property.offer', 'property_id', string="Offer")

@api.depends('living_area', 'garden_area')
def _compute_total_area(self):
for line in self:
line.total_area = line.living_area + line.garden_area
total_area = fields.Integer('Total Area', compute="_compute_total_area")

@api.depends('offer_ids.price')
def _compute_best_price(self):
for line in self:
line.best_price = max(line.mapped('offer_ids.price') or [0])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
line.best_price = max(line.mapped('offer_ids.price') or [0])
line.best_price = max(line.mapped('offer_ids.price'), default=0)

a little bit better :)

best_price = fields.Float('Best Offer', compute="_compute_best_price")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Be careful about attribute ordering in a model. fields should be before the rest and every type of method should be appearing in a set order

41 changes: 41 additions & 0 deletions estate/models/estate_property_offer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from odoo import api, fields, models
from datetime import timedelta


class EstatePropertyOffer(models.Model):
_name = "estate.property.offer"
_description = "Estate Property Offer"
price = fields.Float("Price")
status = fields.Selection(
selection=[
('accepted', 'Accepted'),
('refused', 'Refused'),
],
copy=False,
)
partner_id = fields.Many2one("res.partner", string="Partner", required=True)
property_id = fields.Many2one("estate.property", string="Property", required=True)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

On a many2one default string attribute is what comes before _id capitalized, so here it'd be the same, so you don't need to add it :)
Also works with many2many and one2many but with _ids instead of _id :D

validity = fields.Integer("Validity (days)", default=7)

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

Choose a reason for hiding this comment

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

Validity is an integer field, it always has a value

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


def _inverse_date_deadline(self):
for offer in self:
if offer.date_deadline:
if offer.create_date:
offer.validity = (offer.date_deadline - offer.create_date).days
else:
offer.validity = (offer.date_deadline - fields.Date.today()).days
else:
offer.validity = 0
Comment on lines +38 to +45
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same here


date_deadline = fields.Date("Deadline", compute="_compute_date_deadline", inverse="_inverse_date_deadline", store=True)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Attribute ordering here too

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


class EstatePropertyTag(models.Model):
_name = "estate.property.tag"
_description = "Estate Property Tag"
name = fields.Char('Property Tag Name', required=True)
7 changes: 7 additions & 0 deletions estate/models/estate_property_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from odoo import fields, models


class EstatePropertyType(models.Model):
_name = "estate.property.type"
_description = "Estate Property Type"
name = fields.Char('Property Type Name', required=True)
12 changes: 12 additions & 0 deletions estate/views/estate_menus.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<odoo>
<menuitem id="estate_menu_root" name="Estate">
<menuitem id="estate_menu_advertisement" name="Advertisements">
<menuitem id="estate_property_menu" action="estate_property_action"/>
</menuitem>

<menuitem id="estate_menu_settings" name="Settings">
<menuitem id="estate_property_type_menu" action="estate_property_type_action"/>
<menuitem id="estate_property_tag_menu" action="estate_property_tag_action"/>
</menuitem>
</menuitem>
</odoo>
33 changes: 33 additions & 0 deletions estate/views/estate_property_offer_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<odoo>
<record id="estate_property_offer_view_form" model="ir.ui.view">
<field name="name">estate.property.offer.form</field>
<field name="model">estate.property.offer</field>
<field name="arch" type="xml">
<form string="New Property Offer">
<sheet>
<group>
<field name="price" />
<field name="partner_id" />
<field name="validity" />
<field name="date_deadline" />
<field name="status" />
</group>
</sheet>
</form>
</field>
</record>

<record id="estate_property_offer_view_list" model="ir.ui.view">
<field name="name">estate.property.offer.list</field>
<field name="model">estate.property.offer</field>
<field name="arch" type="xml">
<list string="Property Offers">
<field name="price" width="200px"/>
<field name="partner_id" width="240px" />
<field name="validity" width="240px" />
Comment on lines +25 to +27
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why the widths here ? Would this work correctly on all screen sizes or just yours ?

<field name="date_deadline" />
<field name="status" />
</list>
</field>
</record>
</odoo>
21 changes: 21 additions & 0 deletions estate/views/estate_property_tag_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<odoo>
<record id="estate_property_tag_view_form" model="ir.ui.view">
<field name="name">estate.property.tag.form</field>
<field name="model">estate.property.tag</field>
<field name="arch" type="xml">
<form string="New Property Tag">
<sheet>
<group>
<field name="name" string="Name"/>
</group>
</sheet>
</form>
</field>
</record>

<record id="estate_property_tag_action" model="ir.actions.act_window">
<field name="name">Property Tags</field>
<field name="res_model">estate.property.tag</field>
<field name="view_mode">list,form</field>
</record>
</odoo>
19 changes: 19 additions & 0 deletions estate/views/estate_property_type_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<odoo>
<record id="estate_property_type_view_form" model="ir.ui.view">
<field name="name">estate.property.type.form</field>
<field name="model">estate.property.type</field>
<field name="arch" type="xml">
<form string="New Property Type">
<h1>
<field name="name" />
</h1>
</form>
</field>
</record>

<record id="estate_property_type_action" model="ir.actions.act_window">
<field name="name">Property Types</field>
<field name="res_model">estate.property.type</field>
<field name="view_mode">list,form</field>
</record>
</odoo>
100 changes: 100 additions & 0 deletions estate/views/estate_property_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<odoo>
<record id="estate_property_search" model="ir.ui.view">
<field name="name">estate.property.search</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<search>
<field name="name" string="Title" />
<field name="postcode" />
<field name="expected_price" />
<field name="bedrooms" />
<field name="living_area" string="Living Area (sqm)" />
<field name="facades" />
<separator />
<filter name="available_properties" string="Available properties"
domain="
['|',
('state', '=', 'new'),
('state', '=', 'offer received'),
]" />
<filter name="postcode_group"
context="{'group_by':'postcode'}" />
</search>
</field>
</record>

<record id="estate_property_view_form" model="ir.ui.view">
<field name="name">estate.property.form</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<form string="New Property">
<h1>
<field name="name" />
</h1>
<sheet>
<field name="tag_ids" widget="many2many_tags"/>
<group>
<group>
<field name="property_type_id" />
<field name="postcode" />
<field name="date_availability" />
</group>
<group>
<field name="expected_price" />
<field name="best_price" />
<field name="selling_price" />
</group>
</group>
<notebook>
<page string="Description">
<group>
<field name="description" />
<field name="bedrooms" />
<field name="living_area" string="Living Area (sqm)" />
<field name="facades" />
<field name="garage" />
<field name="garden" />
<field name="garden_area" />
<field name="garden_orientation" />
<field name="total_area" />
</group>
</page>
<page string="Offers">
<group>
<field name="offer_ids" />
</group>
</page>
<page string="Other Info">
<group>
<field name="salesperson_id" />
<field name="buyer_id" />
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>

<record id="estate_property_view_list" model="ir.ui.view">
<field name="name">estate.property.list</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<list string="Properties">
<field name="name" string="Title" width="260px" />
<field name="postcode" width="100px" />
<field name="bedrooms" />
<field name="living_area" string="Living Area (sqm)" />
<field name="expected_price" />
<field name="selling_price" />
<field name="date_availability" string="Available From" />
</list>
</field>
</record>

<record id="estate_property_action" model="ir.actions.act_window">
<field name="name">Properties</field>
<field name="res_model">estate.property</field>
<field name="view_mode">list,form</field>
</record>
</odoo>