diff --git a/estate/__init__.py b/estate/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/estate/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/estate/__manifest__.py b/estate/__manifest__.py new file mode 100644 index 00000000000..751f021a763 --- /dev/null +++ b/estate/__manifest__.py @@ -0,0 +1,21 @@ +{ + 'name': 'Real Estate', + 'version': '1.0', + 'depends': ['base'], + 'author': 'viwar-odoo', + 'category': 'real estate', + 'description': "real estate App.", + 'data': [ + 'security/ir.model.access.csv', + 'views/estate_property_view.xml', + 'views/estate_property_tag_view.xml', + 'views/estate_property_type_view.xml', + 'views/estate_property_offer_view.xml', + 'views/estate_maintainance_form.xml', + 'views/estate_menus.xml' + ], + 'application': True, + 'installable': True, + 'license': 'LGPL-3', + 'website': 'https://odoo.com', +} diff --git a/estate/models/__init__.py b/estate/models/__init__.py new file mode 100644 index 00000000000..16c5f25b0e4 --- /dev/null +++ b/estate/models/__init__.py @@ -0,0 +1,5 @@ +from . import estate_maintainance_request +from . import estate_property +from . import estate_property_offer +from . import estate_property_tag +from . import estate_property_type diff --git a/estate/models/estate_maintainance_request.py b/estate/models/estate_maintainance_request.py new file mode 100644 index 00000000000..4b8f11ec6b2 --- /dev/null +++ b/estate/models/estate_maintainance_request.py @@ -0,0 +1,37 @@ +from odoo import api, models, fields + + +class EstateMaintainanceRequest(models.Model): + _name = 'estate.maintainance.request' + _description = 'table for the technician maintainance request' + + property_id = fields.Many2one('estate.property', required=True, readonly=True) + buyer_id = fields.Many2one('res.users', required=True, default='self.env.uid') + technician_id = fields.Many2one('res.partner', required=False) + state = fields.Selection( + string='state', + default='new', + selection=[ + ('new', "New"), + ('assigned', "Assigned"), + ('inprogress', "Inprogress"), + ('done', "Done"), + ('cancelled', "Cancelled"), + ], + ) + estimate_cost = fields.Float(required=False) + actual_cost = fields.Float(compute='_compute_actual_cost', store=True) + current_stage = fields.Char(compute='_compute_state_after_assigned', store=True) + + @api.depends('state', 'estimate_cost') + def _compute_actual_cost(self): + if self.state == 'done': + self.actual_cost = self.estimate_cost * 1.18 + + @api.depends('technician_id', 'state') + def _compute_state_after_assigned(self): + if self.state == 'new' and self.technician_id: + self.state = 'assigned' + self.current_stage = 'assigned' + else: + self.current_stage = self.state diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py new file mode 100644 index 00000000000..97a545b2b05 --- /dev/null +++ b/estate/models/estate_property.py @@ -0,0 +1,89 @@ +from odoo import api, fields, models +from odoo.exceptions import UserError + + +class EstateProperty(models.Model): + _name = "estate.property" + _description = "Test Model for real estate" + + name = fields.Char(default="Unknown") + last_seen = fields.Datetime("Last Seen", default=fields.Datetime.now) + description = fields.Text() + postcode = fields.Char() + date_availability = fields.Date( + copy=False, default=fields.Date.add(fields.Date.today(), months=3) + ) + expected_price = fields.Float() + selling_price = fields.Float(copy=False, readonly=True) + bedrooms = fields.Integer(default=2) + living_area = fields.Integer() + facades = fields.Integer() + garage = fields.Boolean() + garden = fields.Boolean() + state = fields.Selection( + string="status", + selection=[ + ('new', "New"), + ('offer received', "Offer Received"), + ('offer accepted', "Offer Accepted"), + ('sold', "Sold"), + ('cancelled', "Cancelled"), + ], + default='new', + ) + active = fields.Boolean(default=True) + garden_area = fields.Integer() + garden_orientation = fields.Selection( + string="garden orientation direction", + selection=[ + ('north', "North"), + ('south', "South"), + ('east', "East"), + ('west', "West"), + ], + ) + property_type_id = fields.Many2one("estate.property.type") + salesperson_id = fields.Many2one( + 'res.users', + string='Salesperson', + index=True, + default=lambda self: self.env.user, + ) + buyer_id = fields.Many2one('res.partner', default='None', copy=False) + tag_ids = fields.Many2many('estate.property.tag') + offer_ids = fields.One2many('estate.property.offer', 'property_id', string='offers') + total_area = fields.Float(compute='_compute_total_area') + + estate_maintainance_id = fields.One2many( + 'estate.maintainance.request', 'property_id' + ) + + @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.onchange('garden') + def _onchange_garden(self): + if self.garden: + self.garden_area = 10 + self.garden_orientation = "north" + else: + self.garden_area = None + self.garden_orientation = None + + def button_cancel(self): + if self.state == "cancelled": + raise UserError("The property is already cancelled") + elif self.state == "sold": + raise UserError("The property is already sold, you cannot cancel it") + else: + self.state = "cancelled" + + def button_sold(self): + if self.state == "sold": + raise UserError("The property is already sold") + elif self.state == "cancelled": + raise UserError("The property is already cancelled, and cannot be sold") + else: + self.state = "sold" diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py new file mode 100644 index 00000000000..d75f703b281 --- /dev/null +++ b/estate/models/estate_property_offer.py @@ -0,0 +1,15 @@ +from odoo import fields, models + + +class EstatePropertyOffer(models.Model): + _name = 'estate.property.offer' + _description = 'estate property offer' + + price = fields.Float(copy=False) + status = fields.Selection( + copy=False, + string="status", + selection=[('accepted', "Accepted"), ('refused', "Refused")], + ) + partner_id = fields.Many2one('res.partner', required=True) + property_id = fields.Many2one('estate.property', required=True) diff --git a/estate/models/estate_property_tag.py b/estate/models/estate_property_tag.py new file mode 100644 index 00000000000..705c601b7a2 --- /dev/null +++ b/estate/models/estate_property_tag.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class EstatePropertytTag(models.Model): + _name = 'estate.property.tag' + _description = 'Estate_property_tag' + + name = fields.Char(required=True) diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py new file mode 100644 index 00000000000..c8bb7809002 --- /dev/null +++ b/estate/models/estate_property_type.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class EstatePropertyType(models.Model): + _name = 'estate.property.type' + _description = 'Estate_property_type' + + name = fields.Char(required=True) diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv new file mode 100644 index 00000000000..20bb0f606f0 --- /dev/null +++ b/estate/security/ir.model.access.csv @@ -0,0 +1,6 @@ +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 +access_estate_maintainance_request,access_estate_maintainance_request,model_estate_maintainance_request,base.group_user,1,1,1,1 diff --git a/estate/views/estate_maintainance_form.xml b/estate/views/estate_maintainance_form.xml new file mode 100644 index 00000000000..337add65e89 --- /dev/null +++ b/estate/views/estate_maintainance_form.xml @@ -0,0 +1,30 @@ + + + + estate_maintainance_action + estate.maintainance.request + list,form + + + estate.maintainance.type.form.view + estate.maintainance.request + +
+ + + + + + + + + + + + + + +
+
+
+
\ No newline at end of file diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml new file mode 100644 index 00000000000..550f3cda546 --- /dev/null +++ b/estate/views/estate_menus.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/estate/views/estate_property_offer_view.xml b/estate/views/estate_property_offer_view.xml new file mode 100644 index 00000000000..ce4f749652f --- /dev/null +++ b/estate/views/estate_property_offer_view.xml @@ -0,0 +1,44 @@ + + + + + + estate_property_offer + estate.property.offer + list,form + + + + + estate.property.offer.list.view + estate.property.offer + + + + + + + + + + + + + estate.property.offer.form.view + estate.property.offer + +
+ + + + + + + + +
+
+
+ + +
\ No newline at end of file diff --git a/estate/views/estate_property_tag_view.xml b/estate/views/estate_property_tag_view.xml new file mode 100644 index 00000000000..787f6775bf8 --- /dev/null +++ b/estate/views/estate_property_tag_view.xml @@ -0,0 +1,42 @@ + + + + + + + estate_property_tag + estate.property.tag + list,form + + + + + estate.property.tag.list.view + estate.property.tag + + + + + + + + + estate.property.tag.form.view + estate.property.tag + +
+ + + + + +
+
+
+ + + + + + +
\ No newline at end of file diff --git a/estate/views/estate_property_type_view.xml b/estate/views/estate_property_type_view.xml new file mode 100644 index 00000000000..207d1a69b56 --- /dev/null +++ b/estate/views/estate_property_type_view.xml @@ -0,0 +1,21 @@ + + + + estate_property_type_action + estate.property.type + list,form + + + estate.property.type.form.view + estate.property.type + +
+ + + + + +
+
+
+
\ No newline at end of file diff --git a/estate/views/estate_property_view.xml b/estate/views/estate_property_view.xml new file mode 100644 index 00000000000..9fb13e55777 --- /dev/null +++ b/estate/views/estate_property_view.xml @@ -0,0 +1,110 @@ + + + + Real-estate Property"s + estate.property + list,form + + + estate.property.list.view + estate.property + + + + + + + + + + + + estate.property.form.view + estate.property + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + estate.property.search.view + estate.property + + + + + + + + + + + + + + + +