diff --git a/README.md b/README.md index 0c6667bb6f2..a0158d919ee 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ # Odoo tutorials -This repository hosts the code for the bases and solutions of the -[official Odoo tutorials](https://www.odoo.com/documentation/16.0/developer/howtos.html). +This repository hosts the code for the bases of the modules used in the +[official Odoo tutorials](https://www.odoo.com/documentation/latest/developer/tutorials.html). -It has 2 branches for each Odoo version: one for the bases and one for -the solutions. For example, `16.0` and `16.0-solutions`. The first -contains the code of the modules that serve as base for the tutorials, -and the second contains the code of the same modules with the complete -solution. \ No newline at end of file +It has 3 branches for each Odoo version: one for the bases, one for the +[Discover the JS framework](https://www.odoo.com/documentation/latest/developer/tutorials/discover_js_framework.html) +tutorial's solutions, and one for the +[Master the Odoo web framework](https://www.odoo.com/documentation/latest/developer/tutorials/master_odoo_web_framework.html) +tutorial's solutions. For example, `17.0`, `17.0-discover-js-framework-solutions` and +`17.0-master-odoo-web-framework-solutions`. diff --git a/awesome_clicker/__init__.py b/awesome_clicker/__init__.py new file mode 100644 index 00000000000..40a96afc6ff --- /dev/null +++ b/awesome_clicker/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/awesome_clicker/__manifest__.py b/awesome_clicker/__manifest__.py new file mode 100644 index 00000000000..e57ef4d5bb0 --- /dev/null +++ b/awesome_clicker/__manifest__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Awesome Clicker", + + 'summary': """ + Starting module for "Master the Odoo web framework, chapter 1: Build a Clicker game" + """, + + 'description': """ + Starting module for "Master the Odoo web framework, chapter 1: Build a Clicker game" + """, + + 'author': "Odoo", + 'website': "https://www.odoo.com/", + 'category': 'Tutorials/AwesomeClicker', + 'version': '0.1', + 'application': True, + 'installable': True, + 'depends': ['base', 'web'], + + 'data': [], + 'assets': { + 'web.assets_backend': [ + 'awesome_clicker/static/src/**/*', + ], + + }, + 'license': 'AGPL-3' +} diff --git a/awesome_dashboard/__init__.py b/awesome_dashboard/__init__.py new file mode 100644 index 00000000000..b0f26a9a602 --- /dev/null +++ b/awesome_dashboard/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers diff --git a/awesome_dashboard/__manifest__.py b/awesome_dashboard/__manifest__.py new file mode 100644 index 00000000000..31406e8addb --- /dev/null +++ b/awesome_dashboard/__manifest__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Awesome Dashboard", + + 'summary': """ + Starting module for "Discover the JS framework, chapter 2: Build a dashboard" + """, + + 'description': """ + Starting module for "Discover the JS framework, chapter 2: Build a dashboard" + """, + + 'author': "Odoo", + 'website': "https://www.odoo.com/", + 'category': 'Tutorials/AwesomeDashboard', + 'version': '0.1', + 'application': True, + 'installable': True, + 'depends': ['base', 'web', 'mail', 'crm'], + + 'data': [ + 'views/views.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'awesome_dashboard/static/src/**/*', + ], + }, + 'license': 'AGPL-3' +} diff --git a/awesome_dashboard/controllers/__init__.py b/awesome_dashboard/controllers/__init__.py new file mode 100644 index 00000000000..457bae27e11 --- /dev/null +++ b/awesome_dashboard/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers \ No newline at end of file diff --git a/awesome_dashboard/controllers/controllers.py b/awesome_dashboard/controllers/controllers.py new file mode 100644 index 00000000000..56d4a051287 --- /dev/null +++ b/awesome_dashboard/controllers/controllers.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- + +import logging +import random + +from odoo import http +from odoo.http import request + +logger = logging.getLogger(__name__) + +class AwesomeDashboard(http.Controller): + @http.route('/awesome_dashboard/statistics', type='json', auth='user') + def get_statistics(self): + """ + Returns a dict of statistics about the orders: + 'average_quantity': the average number of t-shirts by order + 'average_time': the average time (in hours) elapsed between the + moment an order is created, and the moment is it sent + 'nb_cancelled_orders': the number of cancelled orders, this month + 'nb_new_orders': the number of new orders, this month + 'total_amount': the total amount of orders, this month + """ + + return { + 'average_quantity': random.randint(4, 12), + 'average_time': random.randint(4, 123), + 'nb_cancelled_orders': random.randint(0, 50), + 'nb_new_orders': random.randint(10, 200), + 'orders_by_size': { + 'm': random.randint(0, 150), + 's': random.randint(0, 150), + 'xl': random.randint(0, 150), + }, + 'total_amount': random.randint(100, 1000) + } + diff --git a/awesome_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js new file mode 100644 index 00000000000..637fa4bb972 --- /dev/null +++ b/awesome_dashboard/static/src/dashboard.js @@ -0,0 +1,10 @@ +/** @odoo-module **/ + +import { Component } from "@odoo/owl"; +import { registry } from "@web/core/registry"; + +class AwesomeDashboard extends Component { + static template = "awesome_dashboard.AwesomeDashboard"; +} + +registry.category("actions").add("awesome_dashboard.dashboard", AwesomeDashboard); diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard.xml new file mode 100644 index 00000000000..1a2ac9a2fed --- /dev/null +++ b/awesome_dashboard/static/src/dashboard.xml @@ -0,0 +1,8 @@ + + + + + hello dashboard + + + diff --git a/awesome_dashboard/views/views.xml b/awesome_dashboard/views/views.xml new file mode 100644 index 00000000000..47fb2b6f258 --- /dev/null +++ b/awesome_dashboard/views/views.xml @@ -0,0 +1,11 @@ + + + + Dashboard + awesome_dashboard.dashboard + + + + + + diff --git a/awesome_gallery/__init__.py b/awesome_gallery/__init__.py new file mode 100644 index 00000000000..a0fdc10fe11 --- /dev/null +++ b/awesome_gallery/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import models diff --git a/awesome_gallery/__manifest__.py b/awesome_gallery/__manifest__.py new file mode 100644 index 00000000000..624766dca89 --- /dev/null +++ b/awesome_gallery/__manifest__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Gallery View", + 'summary': """ + Starting module for "Master the Odoo web framework, chapter 3: Create a Gallery View" + """, + + 'description': """ + Starting module for "Master the Odoo web framework, chapter 3: Create a Gallery View" + """, + + 'version': '0.1', + 'application': True, + 'category': 'Tutorials/AwesomeGallery', + 'installable': True, + 'depends': ['web', 'contacts'], + 'data': [ + 'views/views.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'awesome_gallery/static/src/**/*', + ], + }, + 'license': 'AGPL-3' +} diff --git a/awesome_gallery/models/__init__.py b/awesome_gallery/models/__init__.py new file mode 100644 index 00000000000..7f0930ee744 --- /dev/null +++ b/awesome_gallery/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# import filename_python_file_within_folder_or_subfolder +from . import ir_action +from . import ir_ui_view diff --git a/awesome_gallery/models/ir_action.py b/awesome_gallery/models/ir_action.py new file mode 100644 index 00000000000..eae20acbf5c --- /dev/null +++ b/awesome_gallery/models/ir_action.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +from odoo import fields, models + + +class ActWindowView(models.Model): + _inherit = 'ir.actions.act_window.view' + + view_mode = fields.Selection(selection_add=[ + ('gallery', "Awesome Gallery") + ], ondelete={'gallery': 'cascade'}) diff --git a/awesome_gallery/models/ir_ui_view.py b/awesome_gallery/models/ir_ui_view.py new file mode 100644 index 00000000000..0c11b8298ac --- /dev/null +++ b/awesome_gallery/models/ir_ui_view.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +from odoo import fields, models + + +class View(models.Model): + _inherit = 'ir.ui.view' + + type = fields.Selection(selection_add=[('gallery', "Awesome Gallery")]) diff --git a/awesome_gallery/static/src/gallery_view.js b/awesome_gallery/static/src/gallery_view.js new file mode 100644 index 00000000000..db904d1f478 --- /dev/null +++ b/awesome_gallery/static/src/gallery_view.js @@ -0,0 +1,3 @@ +/** @odoo-module */ + +// TODO: Begin here! diff --git a/awesome_gallery/views/views.xml b/awesome_gallery/views/views.xml new file mode 100644 index 00000000000..56327365875 --- /dev/null +++ b/awesome_gallery/views/views.xml @@ -0,0 +1,19 @@ + + + + + Contacts + res.partner + kanban,tree,form,activity + + {'default_is_company': True} + +

+ Create a Contact in your address book +

+ Odoo helps you track all activities related to your contacts. +

+
+
+
+
diff --git a/awesome_kanban/__init__.py b/awesome_kanban/__init__.py new file mode 100644 index 00000000000..40a96afc6ff --- /dev/null +++ b/awesome_kanban/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/awesome_kanban/__manifest__.py b/awesome_kanban/__manifest__.py new file mode 100644 index 00000000000..affef78bb12 --- /dev/null +++ b/awesome_kanban/__manifest__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Awesome Kanban", + 'summary': """ + Starting module for "Master the Odoo web framework, chapter 4: Customize a kanban view" + """, + + 'description': """ + Starting module for "Master the Odoo web framework, chapter 4: Customize a kanban view. + """, + + 'version': '0.1', + 'application': True, + 'category': 'Tutorials/AwesomeKanban', + 'installable': True, + 'depends': ['web', 'crm'], + 'data': [ + 'views/views.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'awesome_kanban/static/src/**/*', + ], + }, + 'license': 'AGPL-3' +} diff --git a/awesome_kanban/static/src/awesome_kanban_view.js b/awesome_kanban/static/src/awesome_kanban_view.js new file mode 100644 index 00000000000..9f33fc1300b --- /dev/null +++ b/awesome_kanban/static/src/awesome_kanban_view.js @@ -0,0 +1,3 @@ +/** @odoo-module */ + +// TODO: Define here your AwesomeKanban view diff --git a/awesome_kanban/views/views.xml b/awesome_kanban/views/views.xml new file mode 100644 index 00000000000..548b2907b6e --- /dev/null +++ b/awesome_kanban/views/views.xml @@ -0,0 +1,15 @@ + + + + + crm.lead.kanban.lead.awesome_gallery + crm.lead + + + + awesome_kanban + + + + + diff --git a/awesome_owl/__init__.py b/awesome_owl/__init__.py new file mode 100644 index 00000000000..457bae27e11 --- /dev/null +++ b/awesome_owl/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers \ No newline at end of file diff --git a/awesome_owl/__manifest__.py b/awesome_owl/__manifest__.py new file mode 100644 index 00000000000..77abad510ef --- /dev/null +++ b/awesome_owl/__manifest__.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Awesome Owl", + + 'summary': """ + Starting module for "Discover the JS framework, chapter 1: Owl components" + """, + + 'description': """ + Starting module for "Discover the JS framework, chapter 1: Owl components" + """, + + 'author': "Odoo", + 'website': "https://www.odoo.com", + + # Categories can be used to filter modules in modules listing + # Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml + # for the full list + 'category': 'Tutorials/AwesomeOwl', + 'version': '0.1', + + # any module necessary for this one to work correctly + 'depends': ['base', 'web'], + 'application': True, + 'installable': True, + 'data': [ + 'views/templates.xml', + ], + 'assets': { + 'awesome_owl.assets_playground': [ + ('include', 'web._assets_helpers'), + 'web/static/src/scss/pre_variables.scss', + 'web/static/lib/bootstrap/scss/_variables.scss', + 'web/static/lib/bootstrap/scss/_maps.scss', + ('include', 'web._assets_bootstrap'), + ('include', 'web._assets_core'), + 'web/static/src/libs/fontawesome/css/font-awesome.css', + 'awesome_owl/static/src/**/*', + ], + }, + 'license': 'AGPL-3' +} diff --git a/awesome_owl/controllers/__init__.py b/awesome_owl/controllers/__init__.py new file mode 100644 index 00000000000..457bae27e11 --- /dev/null +++ b/awesome_owl/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers \ No newline at end of file diff --git a/awesome_owl/controllers/controllers.py b/awesome_owl/controllers/controllers.py new file mode 100644 index 00000000000..bccfd6fe283 --- /dev/null +++ b/awesome_owl/controllers/controllers.py @@ -0,0 +1,10 @@ +from odoo import http +from odoo.http import request, route + +class OwlPlayground(http.Controller): + @http.route(['/awesome_owl'], type='http', auth='public') + def show_playground(self): + """ + Renders the owl playground page + """ + return request.render('awesome_owl.playground') diff --git a/awesome_owl/static/src/main.js b/awesome_owl/static/src/main.js new file mode 100644 index 00000000000..1af6c827e0b --- /dev/null +++ b/awesome_owl/static/src/main.js @@ -0,0 +1,11 @@ +import { whenReady } from "@odoo/owl"; +import { mountComponent } from "@web/env"; +import { Playground } from "./playground"; + +const config = { + dev: true, + name: "Owl Tutorial", +}; + +// Mount the Playground component when the document.body is ready +whenReady(() => mountComponent(Playground, document.body, config)); diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js new file mode 100644 index 00000000000..657fb8b07bb --- /dev/null +++ b/awesome_owl/static/src/playground.js @@ -0,0 +1,7 @@ +/** @odoo-module **/ + +import { Component } from "@odoo/owl"; + +export class Playground extends Component { + static template = "awesome_owl.playground"; +} diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml new file mode 100644 index 00000000000..4fb905d59f9 --- /dev/null +++ b/awesome_owl/static/src/playground.xml @@ -0,0 +1,10 @@ + + + + +
+ hello world +
+
+ +
diff --git a/awesome_owl/views/templates.xml b/awesome_owl/views/templates.xml new file mode 100644 index 00000000000..aa54c1a7241 --- /dev/null +++ b/awesome_owl/views/templates.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/supplier_portal/__init__.py b/supplier_portal/__init__.py new file mode 100644 index 00000000000..e046e49fbe2 --- /dev/null +++ b/supplier_portal/__init__.py @@ -0,0 +1 @@ +from . import controllers diff --git a/supplier_portal/__manifest__.py b/supplier_portal/__manifest__.py new file mode 100644 index 00000000000..027dafdea98 --- /dev/null +++ b/supplier_portal/__manifest__.py @@ -0,0 +1,18 @@ +{ + 'name': "Supplier Portal", + + 'summary': """ + Portal for supplier to upload their bills" + """, + + 'description': """ + Portal for supplier to upload their bills" + """, + 'category': 'Accounting/Accounting', + 'version': '0.1', + 'depends': ['portal', 'account'], + 'application': True, + 'installable': True, + 'data': ["views/portal_template.xml"], + 'license': 'AGPL-3' +} diff --git a/supplier_portal/controllers/__init__.py b/supplier_portal/controllers/__init__.py new file mode 100644 index 00000000000..8c3feb6f562 --- /dev/null +++ b/supplier_portal/controllers/__init__.py @@ -0,0 +1 @@ +from . import portal diff --git a/supplier_portal/controllers/portal.py b/supplier_portal/controllers/portal.py new file mode 100644 index 00000000000..967330bdcf3 --- /dev/null +++ b/supplier_portal/controllers/portal.py @@ -0,0 +1,40 @@ +from odoo import http +from odoo.http import request +from odoo.addons.portal.controllers import portal +import base64 + + +class BillsPortal(portal.CustomerPortal): + @http.route(['/upload/bill', + ], type='http', auth='user', website=True, methods=['GET', 'POST']) + def portal_upload_bill(self): + values = {} + partner_id = request.env['res.users'].sudo().browse( + request.session.uid).partner_id + organization = partner_id.parent_id if partner_id else False + values.update({'organization': organization}) + if request.httprequest.method == 'POST': + AccountMove = request.env['account.move'] + IrAttachment = request.env['ir.attachment'] + pdf_file = request.httprequest.files.get('pdf') + xml_file = request.httprequest.files.get('xml') + if not ((pdf_file and pdf_file.filename) or (xml_file and xml_file.filename)): + values.update( + {'message_error': 'You must atleast upload pdf or xml file of your bill'}) + return request.render('supplier_portal.portal_my_bills_form', values) + bill_id = AccountMove.sudo().create( + {'partner_id': partner_id.id, 'move_type': 'in_invoice'}) + for file in request.httprequest.files.values(): + if not file.filename: + continue + IrAttachment.sudo().create({ + 'name': file.filename, + 'datas': base64.encodebytes(file.read()), + 'res_model': 'account.move', + 'res_id': bill_id.id, + 'type': 'binary', + }) + values.update( + {'message_success': 'You have Successfully Uploaded Your bill'}) + return request.render('supplier_portal.portal_my_bills_form', values) + return request.render('supplier_portal.portal_my_bills_form', values) diff --git a/supplier_portal/static/src/img/upload_logo.png b/supplier_portal/static/src/img/upload_logo.png new file mode 100644 index 00000000000..5fa09bc2256 Binary files /dev/null and b/supplier_portal/static/src/img/upload_logo.png differ diff --git a/supplier_portal/views/portal_template.xml b/supplier_portal/views/portal_template.xml new file mode 100644 index 00000000000..722d3ebaa3c --- /dev/null +++ b/supplier_portal/views/portal_template.xml @@ -0,0 +1,57 @@ + + + + + + + diff --git a/website_airproof/README.md b/website_airproof/README.md new file mode 100644 index 00000000000..6c6390b9424 --- /dev/null +++ b/website_airproof/README.md @@ -0,0 +1,18 @@ +# Odoo Tutorial : Build a website theme + +This branch contains the code necessary for the creation of the website for our Airproof example. +Example used to illustrate the exercises given in the Odoo tutorial: Build a website theme. + +Here is the final design of the 4 pages of Airproof that will be created throughout this tutorial. + +**Home** +![Airproof home page](airproof-home-page.jpg) + +**Contact page** +![Airproof contact page](airproof-contact-page.jpg) + +**Shop page** +![Airproof shop page](airproof-shop-page.jpg) + +**Product page** +![Airproof product page](airproof-product-page.jpg) diff --git a/website_airproof/__init__.py b/website_airproof/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/website_airproof/__manifest__.py b/website_airproof/__manifest__.py new file mode 100644 index 00000000000..f6cd9dc0d5e --- /dev/null +++ b/website_airproof/__manifest__.py @@ -0,0 +1,59 @@ +{ + 'name': 'Airproof Theme', + 'description': 'Airproof Theme - Drones, modelling, camera', + 'category': 'Website/Theme', + # 'version': '18.0.1.0', + 'author': 'PSBE Designers', + 'license': 'LGPL-3', + 'depends': ['website_sale', 'website_sale_wishlist', 'website_blog', 'website_mass_mailing'], + 'data': [ + # Options + 'data/presets.xml', + 'data/website.xml', + # Menu + 'data/menu.xml', + # Gradients + 'data/gradients.xml', + # Shapes + 'data/shapes.xml', + # Pages + 'data/pages/home.xml', + 'data/pages/contact.xml', + # Frontend + 'views/new_page_template_templates.xml', + 'views/website_templates.xml', + 'views/website_sale_templates.xml', + 'views/website_sale_wishlist_templates.xml', + # Snippets + 'views/snippets/options.xml', + 'views/snippets/s_airproof_carousel.xml', + # Images + 'data/images.xml', + ], + 'assets': { + 'web._assets_primary_variables': [ + 'website_airproof/static/src/scss/primary_variables.scss', + ], + 'web._assets_frontend_helpers': [ + ('prepend', 'website_airproof/static/src/scss/bootstrap_overridden.scss'), + ], + 'web.assets_frontend': [ + # SCSS + 'website_airproof/static/src/scss/font.scss', + 'website_airproof/static/src/scss/components/mouse_follower.scss', + 'website_airproof/static/src/scss/layout/header.scss', + 'website_airproof/static/src/scss/pages/product_page.scss', + 'website_airproof/static/src/scss/pages/shop.scss', + 'website_airproof/static/src/scss/snippets/caroussel.scss', + 'website_airproof/static/src/scss/snippets/newsletter.scss', + 'website_airproof/static/src/snippets/s_airproof_carousel/000.scss', + # JS + 'website_airproof/static/src/js/mouse_follower.js', + ], + }, + 'new_page_templates': { + 'airproof': { + 'services': ['s_parallax', 's_airproof_key_benefits_h2', 's_call_to_action', 's_airproof_carousel'] + } + }, +} diff --git a/website_airproof/airproof-contact-page.jpg b/website_airproof/airproof-contact-page.jpg new file mode 100644 index 00000000000..cc1008a28cb Binary files /dev/null and b/website_airproof/airproof-contact-page.jpg differ diff --git a/website_airproof/airproof-home-page.jpg b/website_airproof/airproof-home-page.jpg new file mode 100644 index 00000000000..53eb1d617b2 Binary files /dev/null and b/website_airproof/airproof-home-page.jpg differ diff --git a/website_airproof/airproof-product-page.jpg b/website_airproof/airproof-product-page.jpg new file mode 100644 index 00000000000..bf07f58651a Binary files /dev/null and b/website_airproof/airproof-product-page.jpg differ diff --git a/website_airproof/airproof-shop-page.jpg b/website_airproof/airproof-shop-page.jpg new file mode 100644 index 00000000000..c77e724d7f1 Binary files /dev/null and b/website_airproof/airproof-shop-page.jpg differ diff --git a/website_airproof/data/gradients.xml b/website_airproof/data/gradients.xml new file mode 100644 index 00000000000..fd68f07b17c --- /dev/null +++ b/website_airproof/data/gradients.xml @@ -0,0 +1,14 @@ + + + + website_airproof.colorpicker + Custom Gradients + qweb + + + + + + + + diff --git a/website_airproof/data/images.xml b/website_airproof/data/images.xml new file mode 100644 index 00000000000..e3c7414a4d0 --- /dev/null +++ b/website_airproof/data/images.xml @@ -0,0 +1,188 @@ + + + + + + + + + White arrow icon + + ir.ui.view + + + + Glasses icon + + ir.ui.view + + + + 4K icon + + ir.ui.view + + + + Hand with drone icon + + ir.ui.view + + + + Control icon + + ir.ui.view + + + + Shopping icon + + ir.ui.view + + + + Phone icon + + ir.ui.view + + + + Envelop icon + + ir.ui.view + + + + Arrow icon + + ir.ui.view + + + + Small arrow icon + + ir.ui.view + + + + Check icon + + ir.ui.view + + + + Black Phone icon + + ir.ui.view + + + + Black Envelop icon + + ir.ui.view + + + + + + Drone Airproof Mini + + ir.ui.view + + + + Drone Airproof Pro + + ir.ui.view + + + + Drone Airproof Robin + + ir.ui.view + + + + Drone Airproof Falcon + + ir.ui.view + + + + Drone Airproof Eagle + + ir.ui.view + + + + + + + Drone accessories picture + + ir.ui.view + + + + Drone Robin picture + + ir.ui.view + + + + Drone school picture + + ir.ui.view + + + + Drone flying picture + + ir.ui.view + + + + + + Fields topview + + ir.ui.view + + + + + + Highway topview + + ir.ui.view + + + + + + Drone with blue background picture + + ir.ui.view + + + + + + Sticker logo + + ir.ui.view + + + + Drone picture + + ir.ui.view + + + diff --git a/website_airproof/data/menu.xml b/website_airproof/data/menu.xml new file mode 100644 index 00000000000..ee0a9319f19 --- /dev/null +++ b/website_airproof/data/menu.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + Waterproof drones + + 1 + 10 + +
+ +
+
+
+ + + + About us + /about-us + 1 + + 20 + + + + + Blog + + 1 + 30 + + + Our latest news + /blog/our-latest-news-2 + 1 + + 31 + + + Tutorials + /blog/tutorials-3 + 1 + + 32 + + + + + Contact us + /contactus + 1 + + 40 + +
diff --git a/website_airproof/data/pages/contact.xml b/website_airproof/data/pages/contact.xml new file mode 100644 index 00000000000..f6a4502dc75 --- /dev/null +++ b/website_airproof/data/pages/contact.xml @@ -0,0 +1,156 @@ + + + + + + + + + Contact us + + website_airproof.page_contact + /contactus + + qweb + + + + + Contact us + + + +