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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+