diff --git a/salesperson_in_pos/__init__.py b/salesperson_in_pos/__init__.py new file mode 100644 index 00000000000..d581b39cea7 --- /dev/null +++ b/salesperson_in_pos/__init__.py @@ -0,0 +1,2 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from . import models diff --git a/salesperson_in_pos/__manifest__.py b/salesperson_in_pos/__manifest__.py new file mode 100644 index 00000000000..5fed907e965 --- /dev/null +++ b/salesperson_in_pos/__manifest__.py @@ -0,0 +1,19 @@ +{ + 'name': "Salesperson_Pos", + 'version': "1.0", + 'summary': "Add salesperson field in POS app", + 'description': "This module adds a button in the POS dashboard to assign a salesperson to respective orders.", + 'author': "Priyansi Borda", + 'depends': ['base', 'point_of_sale', 'hr'], + 'data': [ + "views/pos_view.xml", + ], + 'assets': { + 'point_of_sale._assets_pos': [ + 'salesperson_in_pos/static/src/**/*', + ], + }, + 'application': False, + 'installable': True, + 'license': 'LGPL-3', +} diff --git a/salesperson_in_pos/models/__init__.py b/salesperson_in_pos/models/__init__.py new file mode 100644 index 00000000000..f0214ee0ae6 --- /dev/null +++ b/salesperson_in_pos/models/__init__.py @@ -0,0 +1,3 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from . import pos_order +from . import pos_session diff --git a/salesperson_in_pos/models/pos_order.py b/salesperson_in_pos/models/pos_order.py new file mode 100644 index 00000000000..0801e9d0e83 --- /dev/null +++ b/salesperson_in_pos/models/pos_order.py @@ -0,0 +1,7 @@ +from odoo import models, fields + + +class PosOrder(models.Model): + _inherit = "pos.order" + + salesperson_id = fields.Many2one('hr.employee', string='Salesperson', help='Salesperson who created the order') diff --git a/salesperson_in_pos/models/pos_session.py b/salesperson_in_pos/models/pos_session.py new file mode 100644 index 00000000000..7f1141200d0 --- /dev/null +++ b/salesperson_in_pos/models/pos_session.py @@ -0,0 +1,10 @@ +from odoo import models + + +class PosSession(models.Model): + _inherit = 'pos.session' + + def _load_pos_data_models(self, config_id): + data = super()._load_pos_data_models(config_id) + data.append("hr.employee") + return data diff --git a/salesperson_in_pos/static/src/control_button/control_button.js b/salesperson_in_pos/static/src/control_button/control_button.js new file mode 100644 index 00000000000..cdc706a7682 --- /dev/null +++ b/salesperson_in_pos/static/src/control_button/control_button.js @@ -0,0 +1,10 @@ +import { patch } from "@web/core/utils/patch"; +import { ControlButtons } from "@point_of_sale/app/screens/product_screen/control_buttons/control_buttons"; +import { SelectSalespersonButton } from "@salesperson_in_pos/salesperson_button/salesperson_button"; + +patch(ControlButtons, { + components: { + ...ControlButtons.components, + SelectSalespersonButton, + }, +}); diff --git a/salesperson_in_pos/static/src/control_button/control_button.xml b/salesperson_in_pos/static/src/control_button/control_button.xml new file mode 100644 index 00000000000..80b562f5762 --- /dev/null +++ b/salesperson_in_pos/static/src/control_button/control_button.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/salesperson_in_pos/static/src/models/pos_order.js b/salesperson_in_pos/static/src/models/pos_order.js new file mode 100644 index 00000000000..6bf24ce7c61 --- /dev/null +++ b/salesperson_in_pos/static/src/models/pos_order.js @@ -0,0 +1,11 @@ +import { patch } from "@web/core/utils/patch"; +import { PosOrder } from "@point_of_sale/app/models/pos_order"; + +patch(PosOrder.prototype, { + setSalesperson(sales_person) { + this.update({ salesperson: sales_person }); + }, + getSalesperson(){ + return this.salesperson; + }, +}); diff --git a/salesperson_in_pos/static/src/salesperson_button/salesperson_button.js b/salesperson_in_pos/static/src/salesperson_button/salesperson_button.js new file mode 100644 index 00000000000..b9c86e6819b --- /dev/null +++ b/salesperson_in_pos/static/src/salesperson_button/salesperson_button.js @@ -0,0 +1,40 @@ +import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/store/pos_hook"; +import { useService } from "@web/core/utils/hooks"; +import { _t } from "@web/core/l10n/translation"; +import { makeAwaitable } from "@point_of_sale/app/store/make_awaitable_dialog"; +import { SelectionPopup } from "@point_of_sale/app/utils/input_popups/selection_popup"; + +export class SelectSalespersonButton extends Component { + static template = "point_of_sale.SelectSalespersonButton"; + static props = ["salesperson?"] + setup() { + this.pos = usePos(); + this.dialog = useService("dialog"); + const salesperson = this.pos.get_order()?.getSalesperson(); + if (salesperson) { + this.props.salesperson = salesperson; + } + } + + async selectSalesperson(){ + const currentOrder = this.pos.get_order(); + if (!currentOrder) return; + const salesperson_list = this.pos.models['hr.employee'].map((sp) => { + return { + id: sp.id, + item: sp, + label: sp.name, + isSelected: currentOrder.getSalesperson()?.id === sp.id + } + }); + const selectedSalesperson = await makeAwaitable(this.dialog, SelectionPopup, { + title: _t("Select salesperson"), + list: salesperson_list, + }); + if (selectedSalesperson) return; + const same = currentOrder.getSalesperson()?.id === selected.id; + this.props.salesperson = same ? null : selected; + order.setSalesperson(same ? "" : selected); + } +} diff --git a/salesperson_in_pos/static/src/salesperson_button/salesperson_button.xml b/salesperson_in_pos/static/src/salesperson_button/salesperson_button.xml new file mode 100644 index 00000000000..6353ba4c9bd --- /dev/null +++ b/salesperson_in_pos/static/src/salesperson_button/salesperson_button.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/salesperson_in_pos/views/pos_view.xml b/salesperson_in_pos/views/pos_view.xml new file mode 100644 index 00000000000..840fb9e2ee4 --- /dev/null +++ b/salesperson_in_pos/views/pos_view.xml @@ -0,0 +1,22 @@ + + + pos.order.form + pos.order + + + + + + + + + pos.order.list + pos.order + + + + + + + + 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..439d09e6b72 --- /dev/null +++ b/website_airproof/__manifest__.py @@ -0,0 +1,49 @@ +{ + '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', + # Menu + 'data/menu.xml', + # Shapes + 'data/shapes.xml', + # Pages + 'data/pages/home.xml', + 'data/pages/contact.xml', + # Frontend + '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/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', + ], + }, +} 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..0a6a5d50a44 Binary files /dev/null and b/website_airproof/airproof-shop-page.jpg differ diff --git a/website_airproof/data/images.xml b/website_airproof/data/images.xml new file mode 100644 index 00000000000..08018dc2ccd --- /dev/null +++ b/website_airproof/data/images.xml @@ -0,0 +1,192 @@ + + + + + + + + + + + + + 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 + + + +