├── models ├── __init__.py └── models.py ├── controllers ├── __init__.py └── api.py ├── __init__.py ├── static └── description │ ├── icon.png │ ├── odoo.png │ ├── authors.PNG │ ├── categories.PNG │ ├── publishers.PNG │ ├── books_actions.PNG │ ├── books_create.PNG │ └── books_search.PNG ├── .idea ├── vcs.xml ├── misc.xml ├── inspectionProfiles │ └── profiles_settings.xml ├── modules.xml ├── odoo_flutter_backend.iml └── workspace.xml ├── __manifest__.py ├── security ├── ir.model.access.csv └── security.xml ├── .gitignore ├── views └── view.xml └── README.md /models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models -------------------------------------------------------------------------------- /controllers/__init__.py: -------------------------------------------------------------------------------- 1 | from . import api -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | from . import controllers -------------------------------------------------------------------------------- /static/description/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3mrdevs/odoo_flutter_backend/HEAD/static/description/icon.png -------------------------------------------------------------------------------- /static/description/odoo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3mrdevs/odoo_flutter_backend/HEAD/static/description/odoo.png -------------------------------------------------------------------------------- /static/description/authors.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3mrdevs/odoo_flutter_backend/HEAD/static/description/authors.PNG -------------------------------------------------------------------------------- /static/description/categories.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3mrdevs/odoo_flutter_backend/HEAD/static/description/categories.PNG -------------------------------------------------------------------------------- /static/description/publishers.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3mrdevs/odoo_flutter_backend/HEAD/static/description/publishers.PNG -------------------------------------------------------------------------------- /static/description/books_actions.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3mrdevs/odoo_flutter_backend/HEAD/static/description/books_actions.PNG -------------------------------------------------------------------------------- /static/description/books_create.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3mrdevs/odoo_flutter_backend/HEAD/static/description/books_create.PNG -------------------------------------------------------------------------------- /static/description/books_search.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3mrdevs/odoo_flutter_backend/HEAD/static/description/books_search.PNG -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/odoo_flutter_backend.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /__manifest__.py: -------------------------------------------------------------------------------- 1 | { 2 | 'name': 'Odoo Flutter Backend', 3 | 'sequence': -1, 4 | 'version': '13.0.1', 5 | 'summary': 'Odoo flutter back-end example', 6 | 'description': 'Simple example of Odoo back-end for a flutter application with API controller', 7 | 'category': 'Flutter', 8 | 'author': '3mrdev', 9 | 'website': 'https://3mr.dev', 10 | 'license': 'LGPL-3', 11 | 'data': [ 12 | 'views/view.xml', 13 | 'security/security.xml', 14 | 'security/ir.model.access.csv', 15 | ], 16 | # 'demo': ['data/demo.xml'], 17 | 'installable': True, 18 | 'application': True, 19 | 'auto_install': False 20 | } -------------------------------------------------------------------------------- /security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | 3 | 1e,books employee,model_flutter_book,odoo_flutter_backend.group_book_employee,1,1,1,0 4 | 2e,publishers employee,model_flutter_publisher,odoo_flutter_backend.group_book_employee,1,1,1,0 5 | 3e,authors employee,model_flutter_author,odoo_flutter_backend.group_book_employee,1,1,1,0 6 | 4e,categories employee,model_flutter_category,odoo_flutter_backend.group_book_employee,1,1,1,0 7 | 8 | 1m,books manager,model_flutter_book,odoo_flutter_backend.group_book_manager,1,1,1,1 9 | 2m,publishers manager,model_flutter_publisher,odoo_flutter_backend.group_book_manager,1,1,1,1 10 | 3m,authors manager,model_flutter_author,odoo_flutter_backend.group_book_manager,1,1,1,1 11 | 4m,categories manager,model_flutter_category,odoo_flutter_backend.group_book_manager,1,1,1,1 -------------------------------------------------------------------------------- /controllers/api.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from odoo import http 4 | from odoo.http import request 5 | 6 | 7 | class Api (http.Controller): 8 | 9 | @http.route(['/api/books'], type="http", auth="public", website=True, method=['POST'], csrf=False) 10 | def get_books(self): 11 | values = {} 12 | 13 | data = request.env['flutter.book'].sudo().search([]) 14 | 15 | if data: 16 | books = [] 17 | for book_data in data: 18 | book = { 19 | "name": str(book_data.name), 20 | "description": book_data.description, 21 | "state": book_data.state, 22 | "publish_date": str(book_data.publish_date), 23 | "language": book_data.language, 24 | "isbn": book_data.isbn, 25 | "price": book_data.price, 26 | "author": book_data.author.name, 27 | "publisher": book_data.publisher.name, 28 | } 29 | categories = [] 30 | for category in book_data.categories: 31 | categories.append(category.name) 32 | book["categories"] = categories 33 | books.append(book) 34 | 35 | values['success'] = True 36 | values['data'] = books 37 | else: 38 | values['success'] = False 39 | values['error_code'] = 1 40 | values['error_data'] = 'No data found!' 41 | 42 | return json.dumps(values) -------------------------------------------------------------------------------- /security/security.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Book Store 11 | 1 12 | 13 | 14 | 15 | 16 | 17 | 18 | Employee 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Manager 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Python template 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | pip-wheel-metadata/ 26 | share/python-wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | MANIFEST 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .nox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | .hypothesis/ 53 | .pytest_cache/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | .python-version 87 | 88 | # pipenv 89 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 90 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 91 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 92 | # install all needed dependencies. 93 | #Pipfile.lock 94 | 95 | # celery beat schedule file 96 | celerybeat-schedule 97 | 98 | # SageMath parsed files 99 | *.sage.py 100 | 101 | # Environments 102 | .env 103 | .venv 104 | env/ 105 | venv/ 106 | ENV/ 107 | env.bak/ 108 | venv.bak/ 109 | 110 | # Spyder project settings 111 | .spyderproject 112 | .spyproject 113 | 114 | # Rope project settings 115 | .ropeproject 116 | 117 | # mkdocs documentation 118 | /site 119 | 120 | # mypy 121 | .mypy_cache/ 122 | .dmypy.json 123 | dmypy.json 124 | 125 | # Pyre type checker 126 | .pyre/ 127 | 128 | -------------------------------------------------------------------------------- /views/view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Books 11 | flutter.book 12 | form 13 | tree,form 14 | 15 | 16 | 17 | 18 | Publishers 19 | flutter.publisher 20 | form 21 | tree,form 22 | 23 | 24 | 25 | 26 | Authors 27 | flutter.author 28 | form 29 | tree,form 30 | 31 | 32 | 33 | 34 | Categories 35 | flutter.category 36 | form 37 | tree,form 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Flutter Logo](https://github.com/3mrdevs/odoo_flutter_backend/blob/master/static/description/icon.png?raw=true) 2 | ![Odoo Logo](https://github.com/3mrdevs/odoo_flutter_backend/blob/master/static/description/odoo.png?raw=true) 3 | 4 |

Odoo Flutter Backend Example

5 | 6 | [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/3mrdevs/odoo_flutter_backend/graphs/commit-activity) 7 | [![GitHub issues](https://img.shields.io/github/issues/3mrdevs/odoo_flutter_backend)](https://github.com/3mrdevs/odoo_flutter_backend/issues) 8 | [![Hex.pm](https://img.shields.io/hexpm/l/plug)](https://github.com/3mrdevs/odoo_flutter_backend/blob/master/LICENSE) 9 | [![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/3mrdevs/odoo_flutter_backend?include_prereleases)](https://github.com/3mrdevs/odoo_flutter_backend/releases/tag/master) 10 | [![GitHub repo size](https://img.shields.io/github/repo-size/3mrdevs/odoo_flutter_backend)](https://github.com/3mrdevs/odoo_flutter_backend) 11 | 12 |

13 | This Odoo Flutter Backend is a simple example of a book store back-end with Odoo for a flutter app with an API controller. 14 |

15 | 16 | # Step by step commits so you can get aboard easily 17 | 18 |

Odoo Backend API

19 | 20 |

Books Route

21 | 22 | ```bash 23 | http://localhost:8080/api/books 24 | ``` 25 | 26 |

Books Route Output

27 | 28 | ```bash 29 | { 30 | "success":true, 31 | "data":[ 32 | { 33 | "name":"Book name", 34 | "description":"dfsdf", 35 | "state":"draft", 36 | "publish_date":"2020-05-18", 37 | "language":"en", 38 | "isbn":"23234324", 39 | "price":20.0, 40 | "author":"Ahmed", 41 | "publisher":"Dar", 42 | "categories":[ 43 | "Arabic / \u0627\u0644\u0652\u0639\u064e\u0631\u064e\u0628\u064a\u0651\u0629" 44 | ] 45 | } 46 | ] 47 | } 48 | ``` 49 | 50 |

Odoo Backend Screen shots

51 |

Books create example

52 | 53 | ![Books](https://github.com/3mrdevs/odoo_flutter_backend/blob/master/static/description/books_create.PNG?raw=true) 54 | 55 |

Books actions example

56 | 57 | ![Books](https://github.com/3mrdevs/odoo_flutter_backend/blob/master/static/description/books_actions.PNG?raw=true) 58 | 59 |

Books search example

60 | 61 | ![Books](https://github.com/3mrdevs/odoo_flutter_backend/blob/master/static/description/books_search.PNG?raw=true) 62 | 63 |

Authors (CRUD)

64 | 65 | ![Authors](https://github.com/3mrdevs/odoo_flutter_backend/blob/master/static/description/authors.PNG?raw=true) 66 | 67 |

Publishers (CRUD)

68 | 69 | ![Publishers](https://github.com/3mrdevs/odoo_flutter_backend/blob/master/static/description/publishers.PNG?raw=true) 70 | 71 |

Categories (CRUD)

72 | 73 | ![Categories](https://github.com/3mrdevs/odoo_flutter_backend/blob/master/static/description/categories.PNG?raw=true) 74 | -------------------------------------------------------------------------------- /models/models.py: -------------------------------------------------------------------------------- 1 | from odoo import fields, models, api 2 | 3 | # This python module imports: 4 | 5 | # ORM is Object relational mapping which Odoo uses to connect with postgres through psycopg2 lib 6 | # Odoo fields module to implement database columns with a pre-defined sql queries in the ORM module 7 | # Odoo models module to inherit the ORM methods that Odoo uses and create the columns and the behavior 8 | # Odoo api module to access the api annotations of the Odoo ORM methods which each one of them has a purpose, 9 | 10 | 11 | # Odoo fields attributes: 12 | 13 | # required : Setting the field as required for input raises an error if its not filled. 14 | # readonly : Setting the field as readonly which only displays thr field content. 15 | # translate : Adding the ability to translate this field content to other languages. (Amazing Feature) 16 | 17 | # Adding books model to store books data. 18 | class Books (models.Model): 19 | 20 | # Holds the name of the table in database 21 | _name = 'flutter.book' 22 | 23 | # Holds the description of the table in database 24 | _description = 'Model for storing books and do CRUD operations.' 25 | 26 | # Sorts the categories descending order with the time of creation. 27 | _order = "create_date desc" 28 | 29 | # Adding a filed (column) for the name of the book. Char is varchar or string with a small length. 30 | name = fields.Char(required=True,translate=True) 31 | 32 | # Adding a filed (column) for the activeness of the book which stores true or false to determine 33 | # if the book is still in stock for sale.. 34 | active = fields.Boolean(default=True) 35 | 36 | # Adding a filed (column) for the number of the book. Integer is a field for numbers. 37 | number = fields.Integer() 38 | 39 | # Adding a filed (column) for the description of the book which has more string length than char. 40 | description = fields.Text(required=True) 41 | 42 | # Adding a filed (column) for the image of the book which stores binary data for any file format. 43 | image = fields.Binary() 44 | 45 | # Adding a filed (column) for the status of the book which stores a string of the current state. 46 | state = fields.Selection([ 47 | ('draft','Draft'), 48 | ('waiting','Waiting approval'), 49 | ('reviewed','Reviewed'), 50 | ('published','Published'), 51 | ],default='draft',readonly=True) 52 | 53 | # Adding a filed (column) for the publish date of the book which stores string containing a 54 | # date format. 55 | publish_date = fields.Date() 56 | 57 | # Adding a filed (column) for the language of the book which stores string containing the key 58 | # of the selected option. 59 | language = fields.Selection([ 60 | ('ar','Arabic'), 61 | ('en','english') 62 | ],default='en') 63 | 64 | # Adding a filed (column) for the isbn of the book. Char is varchar or string with a 65 | # small length. You can use char to store numbers sometime which is more advanced. 66 | isbn = fields.Char("International Standard Book Number") 67 | 68 | # Adding a filed (column) for the price cost of the book which stores real number. 69 | price = fields.Float(required=True) 70 | 71 | # Adding a filed (column) for the relation of the author with the book which stores 72 | # the author id who wrote the book. 73 | author = fields.Many2one("flutter.author",required=True) 74 | 75 | # Adding a filed (column) for the relation of the publisher with the book which stores 76 | # the publisher id who published the book of the author. 77 | publisher = fields.Many2one("flutter.publisher",required=True) 78 | 79 | # Adding a filed (column) for the relation of the categories with the books which stores 80 | # the categories ids which the admin selected. Note: postgres stores then as ids but odoo 81 | # display them as lists and when you click on them you can choose what categories you want 82 | # for this book. 83 | categories = fields.Many2many("flutter.category") 84 | 85 | # Adding author model for book authors. 86 | class Author (models.Model): 87 | 88 | # Holds the name of the table in database 89 | _name = 'flutter.author' 90 | 91 | # Holds the description of the table in database 92 | _description = 'Model for storing authors of books and do CRUD operations.' 93 | 94 | # Sorts the authors descending order with the time of registration. 95 | _order = "create_date desc" 96 | 97 | # Adding a filed (column) for the name of the author. Char is varchar or string with a 98 | # small length. 99 | name = fields.Char(required=True,translate=True) 100 | 101 | # Adding a filed (column) for the image of the author which stores binary data for any 102 | # file format. 103 | image = fields.Binary() 104 | 105 | # Adding a filed (column) for the reverse relation of the publisher with the book which 106 | # stores all the books ids that the publisher had published. Note: postgres stores ids 107 | # but odoo displays them as a list of books records in his views which is nice. 108 | books = fields.One2many("flutter.book","author") 109 | 110 | # Adding a publisher model to store publishers info 111 | class Publisher (models.Model): 112 | 113 | # Holds the name of the table in database 114 | _name = 'flutter.publisher' 115 | 116 | # Holds the description of the table in database 117 | _description = 'Model for storing publishers of books and do CRUD operations.' 118 | 119 | # Sorts the publishers descending order with the time of registration. 120 | _order = "create_date desc" 121 | 122 | # Adding a filed (column) for the name of the publisher. Char is varchar or string with 123 | # a small length. 124 | name = fields.Char(required=True,translate=True) 125 | 126 | # Adding a filed (column) for the image of the publisher which stores binary data for any 127 | # file format. 128 | image = fields.Binary() 129 | 130 | # Adding a filed (column) for the reverse relation of the publisher with the book which 131 | # stores all the books ids that the publisher had published. Note: postgres stores ids but 132 | # odoo displays them as a list of books records in his views which is nice. 133 | books = fields.One2many("flutter.book", "publisher") 134 | 135 | # Adding a category model to store multiple categories of the published books. 136 | class Category (models.Model): 137 | 138 | # Holds the name of the table in database 139 | _name = 'flutter.category' 140 | 141 | # Holds the description of the table in database 142 | _description = 'Model for storing categories of the books and do CRUD operations.' 143 | 144 | # Sorts the categories descending order with the time of creation. 145 | _order = "create_date desc" 146 | 147 | # Adding a filed (column) for the name of the publisher. Char is varchar or string with 148 | # a small length. 149 | name = fields.Char(required=True,translate=True) 150 | 151 | # Adding a filed (column) for the reverse relation of the categories with the books which 152 | # stores the books ids which the admin selected for the book. Note: postgres stores then 153 | # as ids but odoo display them as lists and when you click on them you can choose what 154 | # books you want for this category. 155 | books = fields.Many2many("flutter.book") -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 59 | 60 | 61 | 62 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 1589680561264 90 | 94 | 95 | 1589699000520 96 | 101 | 102 | 1589699131446 103 | 108 | 109 | 1589700294056 110 | 115 | 116 | 1589700344663 117 | 122 | 123 | 1589700362280 124 | 129 | 130 | 1589703603596 131 | 136 | 137 | 1589703631484 138 | 143 | 144 | 1589703651380 145 | 150 | 151 | 1589703700112 152 | 157 | 158 | 1589703907384 159 | 164 | 165 | 1589704026976 166 | 171 | 172 | 1589704429967 173 | 178 | 179 | 1589704529393 180 | 185 | 186 | 1589704564420 187 | 192 | 193 | 1589704600399 194 | 199 | 200 | 1589704626865 201 | 206 | 207 | 1589704685709 208 | 213 | 214 | 1589704715063 215 | 220 | 221 | 1589704743562 222 | 227 | 228 | 1589704771580 229 | 234 | 235 | 1589704887553 236 | 241 | 242 | 1589705174228 243 | 248 | 249 | 1589705326713 250 | 255 | 256 | 1589705354079 257 | 262 | 263 | 1589705438092 264 | 269 | 270 | 1589705498157 271 | 276 | 277 | 1589705598589 278 | 283 | 284 | 1589706123920 285 | 290 | 291 | 1589706254177 292 | 297 | 298 | 1589706398700 299 | 304 | 305 | 1589706766558 306 | 311 | 312 | 1589706819095 313 | 318 | 319 | 1589706876179 320 | 325 | 326 | 1589706905050 327 | 332 | 333 | 1589707017805 334 | 339 | 340 | 1589707039377 341 | 346 | 347 | 1589707058241 348 | 353 | 354 | 1589707075289 355 | 360 | 361 | 1589707094901 362 | 367 | 368 | 1589707113759 369 | 374 | 375 | 1589707126971 376 | 381 | 382 | 1589707349551 383 | 388 | 389 | 1589707628972 390 | 395 | 396 | 1589709099421 397 | 402 | 403 | 1589709521793 404 | 409 | 410 | 1589710847837 411 | 416 | 417 | 1589711417369 418 | 423 | 424 | 1589711577057 425 | 430 | 431 | 1589712285244 432 | 437 | 440 | 441 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 481 | --------------------------------------------------------------------------------