diff --git a/estate/__init__.py b/estate/__init__.py new file mode 100644 index 00000000000..5b5301b06c3 --- /dev/null +++ b/estate/__init__.py @@ -0,0 +1,7 @@ + + +from . import models + + + +from odoo import api, SUPERUSER_ID \ No newline at end of file diff --git a/estate/__manifest__.py b/estate/__manifest__.py new file mode 100644 index 00000000000..c7e7431e9d3 --- /dev/null +++ b/estate/__manifest__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +{ + 'name':"estate", + 'author':"nutav", + 'licence':"none", + + 'summary': """ + Houses! + """, + + 'description': """ + Lots of Houses!!" + """, + + + 'application': True, + 'installable': True, + 'data':[ + 'security/ir.model.access.csv', + 'views/estate_property_views.xml', + 'views/estate_property_types_views.xml', + 'views/estate_property_tags_views.xml', + 'views/estate_property_offers_views.xml', + 'views/estate_menus.xml' + ] +} diff --git a/estate/models/__init__.py b/estate/models/__init__.py new file mode 100644 index 00000000000..0f14781160f --- /dev/null +++ b/estate/models/__init__.py @@ -0,0 +1,4 @@ +from . import est_test +from . import est_property_types +from . import est_property_tags +from . import est_property_offers \ No newline at end of file diff --git a/estate/models/est_property_offers.py b/estate/models/est_property_offers.py new file mode 100644 index 00000000000..91a63d74e92 --- /dev/null +++ b/estate/models/est_property_offers.py @@ -0,0 +1,51 @@ +from odoo import models, fields, api, exceptions +import datetime as dt + +class test(models.Model): + _name = "est_property_offers" + _description = "Property Offers" + + _check_price = models.Constraint( + 'CHECK (price >= 0)', + 'The Price should be positive!', + ) + + + name = fields.Char("name") + price = fields.Integer("price",required=True) + status = fields.Selection(string = "status", default = "Waiting", + selection = [ + ("Accepted","Accepted"), + ("Refused","Refused"), + ("Waiting","Waiting")]) + partner_id = fields.Many2one("res.partner") + property_id = fields.Many2one("est_test",required=True) + + + validity_date = fields.Date(compute="_update_validity_date",inverse="_update_validity_duration") + validity_duration = fields.Integer(default=7) + + @api.depends("validity_duration") + def _update_validity_date(self): + for record in self: + record.validity_date = fields.Date.today() + dt.timedelta(days=record.validity_duration) + + def _update_validity_duration(self): + for record in self: + record.validity_duration = (record.validity_date - fields.Date.today()).days + + def action_confirm(self): + if self.property_id.state == "Sold": + raise exceptions.UserError("Property was already sold!") + elif self.status == "Refused": + raise exceptions.UserError("Cannot accept a proposal that was already refused!") + else: + for record in self: + record.status = "Accepted" + self.property_id.selling_price = self.price + self.property_id.partner_id = self.partner_id + self.property_id.state = "Sold" + + def action_reject(self): + for record in self: + record.status = "Refused" \ No newline at end of file diff --git a/estate/models/est_property_tags.py b/estate/models/est_property_tags.py new file mode 100644 index 00000000000..3259a7371c9 --- /dev/null +++ b/estate/models/est_property_tags.py @@ -0,0 +1,12 @@ +from odoo import models, fields + +class test(models.Model): + _name = "est_property_tags" + _description = "Property tags" + + _check_name = models.Constraint( + 'unique(name)', + 'There is already a property tag with that name!', + ) + + name = fields.Char("name", required=True) \ No newline at end of file diff --git a/estate/models/est_property_types.py b/estate/models/est_property_types.py new file mode 100644 index 00000000000..cc517ed0dae --- /dev/null +++ b/estate/models/est_property_types.py @@ -0,0 +1,12 @@ +from odoo import models, fields + +class test(models.Model): + _name = "est_property_types" + _description = "Property types" + + _check_name = models.Constraint( + 'unique(name)', + 'There is already a property type with that name!', + ) + + name = fields.Char("name", required=True) \ No newline at end of file diff --git a/estate/models/est_test.py b/estate/models/est_test.py new file mode 100644 index 00000000000..d79d3fc663c --- /dev/null +++ b/estate/models/est_test.py @@ -0,0 +1,112 @@ +from odoo import models, fields, api, exceptions, tools +import datetime as dt + +class test(models.Model): + _name = "est_test" + _description = "Test Model" + + _check_expected_price = models.Constraint( + 'CHECK (expected_price >= 0)', + 'The Expected Price should be positive!', + ) + + _check_selling_price = models.Constraint( + 'CHECK (selling_price >= 0)', + 'The Selling Price should be positive!', + ) + + + name = fields.Char('Property Name', required=True) + description = fields.Text('Description', required=True) + post_code = fields.Char("Postal Code",required=True) + date_availability = fields.Date("Date Availability",default=(fields.Date.today() + dt.timedelta(days=90))) #add 90 days which is about 3 months + expected_price = fields.Float("Expected price",required=True) + selling_price = fields.Float("Selling price") + bedrooms = fields.Integer("Bedrooms",default=2) + living_area = fields.Integer("Living Area (sqm)") + facades = fields.Integer("Facades") + garage = fields.Boolean("Garage") + garden = fields.Boolean("Garden") + garden_area = fields.Integer("Garden Area") + garden_orientation = fields.Selection( + string = "Garden Orientation", + selection=[("North","North"),("South","South"),("East","East"),("West","West")]) + active = fields.Boolean("Active",default=True) + state = fields.Selection( + string = "State", + selection = [("New","New"),("Offer Received","Offer Received"),("Offer Accepted","Offer Accepted"),("Sold","Sold"),("Cancelled","Cancelled")] + ) + partner_id = fields.Many2one("res.partner", string="Buyer") + user_id = fields.Many2one("res.users", string="Salesman") + property_type = fields.Many2one("est_property_types", string="Property Type") + + tag_ids = fields.Many2many("est_property_tags",string="Tags") + + offers_ids = fields.One2many("est_property_offers","property_id",string="Offers") + + total_area = fields.Integer(compute="_compute_total", readonly=True) + max_offer = fields.Integer(compute="_compute_best_offer", readonly=True) + + + + @api.constrains("selling_price") + def _check_selling_price(self): + for record in self: + ## if different than 0 and selling_price < 90% of expected_price + if (not tools.float_utils.float_is_zero(self.selling_price,precision_digits=3) and (1 == tools.float_compare(self.expected_price * .9, self.selling_price, precision_digits=3))): + raise exceptions.ValidationError(r"Selling price can't be less than 90% expected price") + + + @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("offers_ids") + def _compute_best_offer(self): + + for record in self: + if record.offers_ids: + record.max_offer = max(record.offers_ids.mapped("price")) + else: + record.max_offer = 0 + ''' + if record.max_offer == None: + record.max_offer = 0 + ''' + + + @api.onchange("garden") + def _onchange_garden(self): + if self.garden: + self.garden_area = 10 + self.garden_orientation = "North" + else: + self.garden_area = 0 + self.garden_orientation = None + + # ------------- Actions ------------------------------- + + def sell_action(self): + for record in self: + if self.state == "Cancelled": + #Raise error + raise exceptions.UserError("Can't change to Sold if current state is Cancelled!") + else: + self.state = "Sold" + + def cancel_action(self): + for record in self: + if self.state =="Sold": + #Raise error + raise exceptions.UserError("Can't change to Cancel if current state is Sold!") + else: + self.state = "Cancelled" + +class testModelLine(models.Model): + _name = "test_model_line" + _description="Test Model Line" + model_id = fields.Many2one("est_test") + name = fields.Char() + price = fields.Char() + status = fields.Char() \ No newline at end of file diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv new file mode 100644 index 00000000000..03c2743066b --- /dev/null +++ b/estate/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink +access_test_model,access_test_model,model_est_test,base.group_user,1,1,1,1 +access_types,access_types,model_est_property_types,base.group_user,1,1,1,1 +access_tags,access_tags,model_est_property_tags,base.group_user,1,1,1,1 +access_offers,access_offers,model_est_property_offers,base.group_user,1,1,1,1 \ 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..8be4490abfc --- /dev/null +++ b/estate/views/estate_menus.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/estate/views/estate_property_offers_views.xml b/estate/views/estate_property_offers_views.xml new file mode 100644 index 00000000000..2c5a153cdcb --- /dev/null +++ b/estate/views/estate_property_offers_views.xml @@ -0,0 +1,36 @@ + + + + + est_property_offers_view_list + est_property_offers + + + + + + + + + + + +