{"id":19566537,"url":"https://github.com/bushmusi/odoo-real-state-module","last_synced_at":"2025-04-22T14:22:27.333Z","repository":{"id":104218798,"uuid":"559825021","full_name":"bushmusi/odoo-real-state-module","owner":"bushmusi","description":"This is my opensource module for making Real State Module. Here I implement odoo docs beginner tutorial in estate and estate_account and also advanced topics in property and property_account","archived":false,"fork":false,"pushed_at":"2022-11-26T06:52:41.000Z","size":1334,"stargazers_count":3,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-29T15:51:09.308Z","etag":null,"topics":["odoo","odoo-13","odoo-tutorials","python","real-estate","xml"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bushmusi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-31T07:05:34.000Z","updated_at":"2024-07-23T11:45:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"f76491c0-23ac-452a-b7eb-82b3ce7788c4","html_url":"https://github.com/bushmusi/odoo-real-state-module","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"bushmusi/readme-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bushmusi%2Fodoo-real-state-module","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bushmusi%2Fodoo-real-state-module/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bushmusi%2Fodoo-real-state-module/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bushmusi%2Fodoo-real-state-module/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bushmusi","download_url":"https://codeload.github.com/bushmusi/odoo-real-state-module/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250255987,"owners_count":21400448,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["odoo","odoo-13","odoo-tutorials","python","real-estate","xml"],"created_at":"2024-11-11T05:32:31.783Z","updated_at":"2025-04-22T14:22:27.306Z","avatar_url":"https://github.com/bushmusi.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Odoo Real State module\n\nTutorial https://www.odoo.com/documentation/11.0/howtos/backend.html\n\n## VCode plugins\n\n- Python\n- XML Tools\n\n## Resources\n\n**Deploy**\n\n- 📄 How to deploy Odoo 11 on Ubuntu 18.04 https://linuxize.com/post/how-to-deploy-odoo-11-on-ubuntu-18-04/\n- 📄 Instalar Odoo 11 Ubuntu Server 18.04 LTShttps://odooerpcloud.com/instalar-odoo-11-ubuntu-server-18-04-lts\n- 📄 Install an Odoo 11 Stack on Ubuntu 16.04 https://www.linode.com/docs/websites/cms/install-an-odoo-11-stack-on-ubuntu-16-04/#before-you-begin\n- 📄 Install Odoo version 11 in Docker containerhttps://unkkuri.com/blog/unkkuri-blog-1/post/install-odoo-version-11-in-docker-container-21\n\n**Docker**\n- https://blog.desdelinux.net/instalar-odoo-docker-anadir-modulos-externos/\n- https://hub.docker.com/_/odoo/\n- https://github.com/odoo/docker\n\n**Module**\n\n- 🎥 How To Install Custom Module In Odoo  https://www.youtube.com/watch?v=-sTtSG6m2z4\n- 🎥 Tutorial - Develop an App with the Odoo Framework - Odoo Experience 2017 https://www.youtube.com/watch?v=Q2mQTXghc4o\n- 📄 How to Create a Module in Odoo https://www.cybrosys.com/blog/how-create-module-odoo https://www.cybrosys.com/blog/how-to-create-module-in-odoo12\n- 📄 A step by step guide to creating Odoo Addon Modules https://www.google.com/amp/s/hub.packtpub.com/step-by-step-guide-to-creating-odoo-addon-modules/amp/\n- 📄 How to install new module in Odoo 11  https://www.odoo.com/es_ES/forum/ayuda-1/question/how-to-install-new-module-in-odoo-11-129844\n- 📄  Odoo.sh Your first module  https://www.odoo.com/documentation/user/11.0/odoo_sh/getting_started/first_module.html\n\n\n## Scaffolding\n\n```bash\n$ odoo-bin scaffold openacademy addons\n```\n\nAdd custon addons path\n\n- Go to location: /etc/odoo/odoo-server.conf\n- Add path in that file: addons_path = /opt/odoo/enterprise,/opt/odoo/addons,/opt/odoo/custom-addons\n\n```bash\n$ ./odoo-bin --addons-path=enterprise/,../custom-addons/,../odoo/addons/\n```\n\n```\nmy_module\n├── __init__.py\n├── __manifest__.py\n├── controllers\n│   ├── __init__.py\n│   └── controllers.py\n├── demo\n│   └── demo.xml\n├── models\n│   ├── __init__.py\n│   └── models.py\n├── security\n│   └── ir.model.access.csv\n└── views\n    ├── templates.xml\n    └── views.xml\n```\n\n## Manifest\n\n__manifest__.py \n\nThe manifest ofthe module, including for instance its title, description and data files to load.\n\n```xml\n{ \n    'name': \"Title\", \n    'summary': \"Short subtitle phrase\", \n    'description': \"\"\"Long description\"\"\", \n    'author': \"Your name\", \n    'license': \"AGPL-3\", \n    'website': \"http://www.example.com\", \n    'category': 'Uncategorized', \n    'version': '11.0.1.0.0', \n    'depends': ['base'], \n    'data': ['views.xml'], \n    'demo': ['demo.xml'], \n}\n```\n\n![Module](/img/01_module_manifest.png)\n\n![Module](/img/01_module_technical_data.png)\n\n![Module](/img/01_module_installed_features.png)\n\n## Models\n\nmodels/models.py\n\nBusiness objects are declared as Python classes extending Model which integrates them into the automated persistence system. Models can be configured by setting a number of attributes at their definition.\n\n\n```python\n    # Strings\n    name = fields.Char(string=\"Title\", required=True)\n    description = fields.Text()\n\n    # Date\n    start_date = fields.Date()\n    start_datetime = fields.Datetime('Start time', default=lambda self: fields.Datetime.now())\n    \n    # Numbers\n    duration = fields.Float(digits=(6, 2), help=\"Duration in days\")\n    seats = fields.Integer(string=\"Number of seats\")\n    active = fields.Boolean(default=True) # Boolena\n\n    # Relational fields\n    responsible_id = fields.Many2one('res.users', ondelete='set null', string=\"Responsible\", index=True)\n    instructor_id = fields.Many2one('res.partner', string=\"Instructor\")\n    course_id = fields.Many2one('openacademy.course', ondelete='cascade', string=\"Course\", required=True)\n    session_ids = fields.One2many('openacademy.session', 'course_id', string=\"Sessions\")\n```\n\nWhen a new fields are adding is necessary to restart Odoo and upgrading the module.\n\n```bash\n$ service odoo restart\n```\n\n### Computed fields\n\n```python\n    taken_seats = fields.Float(string=\"Taken seats\", compute='_taken_seats')\n\n    @api.depends('seats', 'attendee_ids')\n    def _taken_seats(self):\n        for r in self:\n            if not r.seats:\n                r.taken_seats = 0.0\n            else:\n                r.taken_seats = 100.0 * len(r.attendee_ids) / r.seats\n```\n\n### Inheritance\n\n```python\n# -*- coding: utf-8 -*-\nfrom odoo import fields, models\n\nclass Partner(models.Model):\n    _inherit = 'res.partner'\n\n    # Add a new column to the res.partner model, by default partners are not\n    # instructors\n    instructor = fields.Boolean(\"Instructor\", default=False)\n\n    session_ids = fields.Many2many('openacademy.session',\n        string=\"Attended Sessions\", readonly=True)\n```\n\n### Onchange\n\nThe “onchange” mechanism provides a way for the client interface to update a form whenever the user has filled in a value in a field, without saving anything to the database.\n\n```python\n    @api.onchange('seats', 'attendee_ids')\n    def _verify_valid_seats(self):\n        if self.seats \u003c 0:\n            return {\n                'warning': {\n                    'title': \"Incorrect 'seats' value\",\n                    'message': \"The number of available seats may not be negative\",\n                },\n            }\n        if self.seats \u003c len(self.attendee_ids):\n            return {\n                'warning': {\n                    'title': \"Too many attendees\",\n                    'message': \"Increase seats or remove excess attendees\",\n                },\n            }\n```\n\n### Constrains\n\n- Python constraints\n- SQL constraints\n\n```python\n\nfrom odoo import models, fields, api, exceptions\n\n....\n\n    @api.constrains('instructor_id', 'attendee_ids')\n    def _check_instructor_not_in_attendees(self):\n        for r in self:\n            if r.instructor_id and r.instructor_id in r.attendee_ids:\n                raise exceptions.ValidationError(\"A session's instructor can't be an attendee\")\n```\n## Views\n\nviews/views.xml\n\nTree and a form views, with the menus opening them. Actions and menus are regular records in database, usually declared through data files. Actions can be triggered in three ways:\n\n- by clicking on menu items (linked to specific actions)\n- by clicking on buttons in views (if these are connected to actions)\n- as contextual actions on object\n\n\n**Basics views*\n\n- Tree views \u003ctree\u003e. List views, display records in a tabular form.\n- Form views \u003cform\u003e. Forms are used to create and edit single records. \n- Search views \u003csearch\u003e. Search views customize the search field associated with the list view (and other aggregated views).\n\nAdding in __manifest__.py\n\n```xml\n    # always loaded\n    'data': [\n        # 'security/ir.model.access.csv',\n        # 'views/views.xml',\n        'views/templates.xml',\n        'views/openacademy.xml',\n        'views/partner.xml',\n        'reports.xml',\n\n    ],\n```\n## Menus and actions \n\n```xml\n\u003crecord model=\"ir.actions.act_window\" id=\"course_list_action\"\u003e\n        \u003cfield name=\"name\"\u003eCursos\u003c/field\u003e\n        \u003cfield name=\"res_model\"\u003eopenacademy.course\u003c/field\u003e\n        \u003cfield name=\"view_type\"\u003eform\u003c/field\u003e\n        \u003cfield name=\"view_mode\"\u003etree,form\u003c/field\u003e\n        \u003c!-- Personalización de Búsquedas --\u003e\n        \u003cfield name=\"context\" eval=\"{'search_default_my_courses': 1}\"/\u003e\n        \u003cfield name=\"help\" type=\"html\"\u003e\n            \u003cp class=\"oe_view_nocontent_create\"\u003eCrea el primer curso\n            \u003c/p\u003e\n        \u003c/field\u003e\n    \u003c/record\u003e\n\n    \u003c!-- top level menu: no parent --\u003e\n    \u003cmenuitem id=\"main_openacademy_menu\" name=\"Open Academy\"/\u003e\n    \u003c!-- A first level in the left side menu is needed before using action= attribute --\u003e\n    \u003cmenuitem id=\"openacademy_menu\" name=\"Open Academy\" parent=\"main_openacademy_menu\"/\u003e\n    \u003c!-- the following menuitem should appear *after* its parent openacademy_menu and *after* its\n             action course_list_action --\u003e\n    \u003cmenuitem id=\"courses_menu\" name=\"Courses\" parent=\"openacademy_menu\" action=\"course_list_action\"/\u003e\n    \u003c!-- Full id location: action=\"openacademy.course_list_action\"  It is not required when it is the same module --\u003e\n\n```\n\n![Module](/img/02_menus.png)\n\n## Tree views\n\n```xml\n    \u003crecord model=\"ir.ui.view\" id=\"course_tree_view\"\u003e\n        \u003cfield name=\"name\"\u003ecourse.tree\u003c/field\u003e\n        \u003cfield name=\"model\"\u003eopenacademy.course\u003c/field\u003e\n        \u003cfield name=\"arch\" type=\"xml\"\u003e\n            \u003ctree string=\"Course Tree\"\u003e\n                \u003cfield name=\"name\"/\u003e\n                \u003cfield name=\"responsible_id\"/\u003e\n            \u003c/tree\u003e\n        \u003c/field\u003e\n    \u003c/record\u003e\n```\n\n![Module](/img/03_tree.png)\n\n![Module](/img/03_tree2.png)\n\n## Form views\n\n```xml\n    \u003c!-- Sesión Formulario --\u003e\n    \u003crecord model=\"ir.ui.view\" id=\"session_form_view\"\u003e\n        \u003cfield name=\"name\"\u003esession.form\u003c/field\u003e\n        \u003cfield name=\"model\"\u003eopenacademy.session\u003c/field\u003e\n        \u003cfield name=\"arch\" type=\"xml\"\u003e\n            \u003cform string=\"Session Form\"\u003e\n                \u003csheet\u003e\n                    \u003cgroup\u003e\n                        \u003cgroup string=\"General\"\u003e\n                            \u003cfield name=\"course_id\"/\u003e\n                            \u003cfield name=\"name\"/\u003e\n                            \u003cfield name=\"instructor_id\"/\u003e\n                            \u003cfield name=\"active\"/\u003e\n                        \u003c/group\u003e\n                        \u003cgroup string=\"Schedule\"\u003e\n                            \u003cfield name=\"start_date\"/\u003e\n                            \u003cfield name=\"duration\"/\u003e\n                            \u003cfield name=\"seats\"/\u003e\n                            \u003c!-- Computed fields --\u003e\n                            \u003cfield name=\"taken_seats\" widget=\"progressbar\"/\u003e\n                        \u003c/group\u003e\n                    \u003c/group\u003e\n                    \u003clabel for=\"attendee_ids\"/\u003e\n                    \u003cfield name=\"attendee_ids\"/\u003e\n                \u003c/sheet\u003e\n            \u003c/form\u003e\n        \u003c/field\u003e\n    \u003c/record\u003e\n```\n\n![Module](/img/04_form02.png)\n\n## Search views\n```xml\n    \u003crecord model=\"ir.ui.view\" id=\"course_search_view\"\u003e\n        \u003cfield name=\"name\"\u003ecourse.search\u003c/field\u003e\n        \u003cfield name=\"model\"\u003eopenacademy.course\u003c/field\u003e\n        \u003cfield name=\"arch\" type=\"xml\"\u003e\n            \u003csearch\u003e\n                \u003cfield name=\"name\"/\u003e\n                \u003cfield name=\"description\"/\u003e\n                \u003c!-- Advanced search--\u003e\n                \u003cfilter name=\"my_courses\" string=\"My Courses\" domain=\"[('responsible_id', '=', uid)]\"/\u003e\n                \u003cgroup string=\"Group By\"\u003e\n                    \u003cfilter name=\"by_responsible\" string=\"Responsible\" context=\"{'group_by': 'responsible_id'}\"/\u003e\n                \u003c/group\u003e\n\n            \u003c/search\u003e\n        \u003c/field\u003e\n    \u003c/record\u003e\n```\n\n![Module](/img/05_search.png)\n\n![Module](/img/05_search_personalizado.png)\n\n## Calendar\n\n![Module](/img/06_calendar.png)\n\n## Graph\n\n![Module](/img/07_graph.png)\n\n## Report\n\n- https://github.com/OCA/reporting-engine\n- https://www.cybrosys.com/blog/basic-qweb-operations\n- https://www.cybrosys.com/blog/qweb-reports-in-odoo12\n- \n\n```xml\n\u003codoo\u003e\n\n    \u003creport\n        id=\"report_session\"\n        model=\"openacademy.session\"\n        string=\"Session Report\"\n        name=\"openacademy.report_session_view\"\n        file=\"openacademy.report_session\"\n        report_type=\"qweb-pdf\" /\u003e\n\n    \u003ctemplate id=\"report_session_view\"\u003e\n        \u003ct t-call=\"web.html_container\"\u003e\n            \u003ct t-foreach=\"docs\" t-as=\"doc\"\u003e\n                \u003ct t-call=\"web.external_layout\"\u003e\n                    \u003cdiv class=\"page\"\u003e\n                        \u003ch2 t-field=\"doc.name\"/\u003e\n                        \u003cp\u003eFrom \u003cspan t-field=\"doc.start_date\"/\u003e to \u003cspan t-field=\"doc.end_date\"/\u003e\u003c/p\u003e\n                        \u003ch3\u003eAttendees:\u003c/h3\u003e\n                        \u003cul\u003e\n                            \u003ct t-foreach=\"doc.attendee_ids\" t-as=\"attendee\"\u003e\n                                \u003cli\u003e\u003cspan t-field=\"attendee.name\"/\u003e\u003c/li\u003e\n                            \u003c/t\u003e\n                        \u003c/ul\u003e\n                    \u003c/div\u003e\n                \u003c/t\u003e\n            \u003c/t\u003e\n        \u003c/t\u003e\n    \u003c/template\u003e\n\n\u003c/odoo\u003e\n```\n\n![Module](/img/08_report02.png)\n\n## Controllers\n\ncontrollers/controllers.py\n\n## Demos\ndemo/demo.xml, demo records for the above example model\n\nDefine demonstration data. The content of the data files is only loaded when a module is installed or updated.After making some changes, do not forget to use *odoo-bin -u openacademy* to save the changes to your database.\n\n## Security\n\n## Links\n\n- 📕 Odoo Development Essentials Book https://fundamentos-de-desarrollo-en-odoo.readthedocs.io/es/latest/capitulos/comenzando-con-odoo.html\n- https://www.odoo.yenthevg.com\n- http://odoowikia.com/blog\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbushmusi%2Fodoo-real-state-module","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbushmusi%2Fodoo-real-state-module","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbushmusi%2Fodoo-real-state-module/lists"}