diff --git a/pos_order_to_sale_order/README.rst b/pos_order_to_sale_order/README.rst new file mode 100644 index 00000000..03c108e3 --- /dev/null +++ b/pos_order_to_sale_order/README.rst @@ -0,0 +1,8 @@ +======================= +PoS Order To Sale Order +======================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/pos_order_to_sale_order/__init__.py b/pos_order_to_sale_order/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/pos_order_to_sale_order/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/pos_order_to_sale_order/__manifest__.py b/pos_order_to_sale_order/__manifest__.py new file mode 100644 index 00000000..26bb8aa2 --- /dev/null +++ b/pos_order_to_sale_order/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "PoS Order To Sale Order", + "version": "12.0.1.0.0", + "author": "GRAP,Odoo Community Association (OCA)", + "category": "Point Of Sale", + "license": "AGPL-3", + "depends": ["point_of_sale"], + "maintainers": ["legalsylvain"], + "development_status": "Production/Stable", + "website": "https://github.com/OCA/pos", + "data": [ + "views/view_pos_config.xml", + "views/assets.xml", + ], + "qweb": ["static/src/xml/pos_order_to_sale_order.xml"], +} diff --git a/pos_order_to_sale_order/i18n/fr.po b/pos_order_to_sale_order/i18n/fr.po new file mode 100644 index 00000000..782e0889 --- /dev/null +++ b/pos_order_to_sale_order/i18n/fr.po @@ -0,0 +1,164 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_order_to_sale_order +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-19 23:40+0000\n" +"PO-Revision-Date: 2020-01-19 23:40+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:15 +#, python-format +msgid "Back" +msgstr "Retour" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:148 +#, python-format +msgid "Check your internet connection and try again." +msgstr "Veuillez vérifier votre connexion internet et essayer de nouveau." + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:26 +#, python-format +msgid "Create Confirmed Sale Order" +msgstr "Créer une vente confirmée" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,field_description:pos_order_to_sale_order.field_pos_config__iface_create_confirmed_sale_order +msgid "Create Confirmed Sale Orders" +msgstr "Créer des ventes confirmées" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:29 +#, python-format +msgid "Create Delivered Sale Order" +msgstr "Créer une vente livrée" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,field_description:pos_order_to_sale_order.field_pos_config__iface_create_delivered_sale_order +msgid "Create Delivered Sale Orders" +msgstr "Créer des ventes livrées" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:23 +#, python-format +msgid "Create Draft Sale Order" +msgstr "Créer un devis" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,field_description:pos_order_to_sale_order.field_pos_config__iface_create_draft_sale_order +msgid "Create Draft Sale Orders" +msgstr "Créer des devis" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:6 +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:18 +#, python-format +msgid "Create Sale Order" +msgstr "Créer une vente" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:100 +#, python-format +msgid "Create Sale Order and discard the current PoS Order?" +msgstr "Créer une vente, et supprimer le ticket de caisse en cours ?" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,field_description:pos_order_to_sale_order.field_pos_config__iface_create_sale_order +msgid "Create Sale Orders" +msgstr "Créer des ventes" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,help:pos_order_to_sale_order.field_pos_config__iface_create_confirmed_sale_order +msgid "If checked, the cashier will have the possibility to create a confirmed Sale Order, based on the current draft PoS Order." +msgstr "En cochant la case, le caissier aura la possibilité de créer une vente confirmée, à partir du ticket de caisse en cours." + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,help:pos_order_to_sale_order.field_pos_config__iface_create_delivered_sale_order +msgid "If checked, the cashier will have the possibility to create a confirmed sale Order, based on the current draft PoS Order.\n" +" the according picking will be marked as delivered. Only invoices process will be possible." +msgstr "" +"En cochant la case, le caissier aura la possibilité de créer une vente " +"confirmée, à partir du ticket de caisse en cours.\n" +" Le bon de livraison correspondant sera marqué comme livré. Seul le " +"processus de facturation sera possible." + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,help:pos_order_to_sale_order.field_pos_config__iface_create_draft_sale_order +msgid "If checked, the cashier will have the possibility to create a draft Sale Order, based on the current draft PoS Order." +msgstr "" +"En cochant la case, le caissier aura la possibilité de créer une vente en " +"brouillon, à partir du ticket de caisse en cours." + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:29 +#, python-format +msgid "No customer defined" +msgstr "Pas de client défini" + +#. module: pos_order_to_sale_order +#: code:addons/pos_order_to_sale_order/models/sale_order.py:17 +#, python-format +msgid "Point of Sale %s" +msgstr "Point de vente %s" + +#. module: pos_order_to_sale_order +#: model:ir.model,name:pos_order_to_sale_order.model_pos_config +msgid "Point of Sale Configuration" +msgstr "Paramétrage du point de vente" + +#. module: pos_order_to_sale_order +#: model:ir.model,name:pos_order_to_sale_order.model_sale_order +msgid "Sale Order" +msgstr "Bon de commande" + +#. module: pos_order_to_sale_order +#: model_terms:ir.ui.view,arch_db:pos_order_to_sale_order.view_pos_config_form +msgid "Sale Order Creations" +msgstr "Créations de Vente" + +#. module: pos_order_to_sale_order +#: model:ir.model,name:pos_order_to_sale_order.model_sale_order_line +msgid "Sales Order Line" +msgstr "Ligne de bons de commande" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:147 +#, python-format +msgid "The order could not be sent" +msgstr "La commande n'a pas pu être envoyée" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:103 +#, python-format +msgid "This operation will permanently discard the current PoS Order and create a Sale Order, based on the current order lines." +msgstr "" +"Cette opération va supprimer définitivement le ticket de caisse en cours, et " +"créer une vente, en se basant sur les lignes du ticket en cours." + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:30 +#, python-format +msgid "You should select a customer in order to create a Sale Order." +msgstr "Vous devez sélectionner un client, afin de créer une vente." diff --git a/pos_order_to_sale_order/i18n/pos_order_to_sale_order.pot b/pos_order_to_sale_order/i18n/pos_order_to_sale_order.pot new file mode 100644 index 00000000..1ec9191c --- /dev/null +++ b/pos_order_to_sale_order/i18n/pos_order_to_sale_order.pot @@ -0,0 +1,156 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_order_to_sale_order +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-19 23:45+0000\n" +"PO-Revision-Date: 2020-01-19 23:45+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:15 +#, python-format +msgid "Back" +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:148 +#, python-format +msgid "Check your internet connection and try again." +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:26 +#, python-format +msgid "Create Confirmed Sale Order" +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,field_description:pos_order_to_sale_order.field_pos_config__iface_create_confirmed_sale_order +msgid "Create Confirmed Sale Orders" +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:29 +#, python-format +msgid "Create Delivered Sale Order" +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,field_description:pos_order_to_sale_order.field_pos_config__iface_create_delivered_sale_order +msgid "Create Delivered Sale Orders" +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:23 +#, python-format +msgid "Create Draft Sale Order" +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,field_description:pos_order_to_sale_order.field_pos_config__iface_create_draft_sale_order +msgid "Create Draft Sale Orders" +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:6 +#: code:addons/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml:18 +#, python-format +msgid "Create Sale Order" +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:100 +#, python-format +msgid "Create Sale Order and discard the current PoS Order?" +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,field_description:pos_order_to_sale_order.field_pos_config__iface_create_sale_order +msgid "Create Sale Orders" +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,help:pos_order_to_sale_order.field_pos_config__iface_create_confirmed_sale_order +msgid "If checked, the cashier will have the possibility to create a confirmed Sale Order, based on the current draft PoS Order." +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,help:pos_order_to_sale_order.field_pos_config__iface_create_delivered_sale_order +msgid "If checked, the cashier will have the possibility to create a confirmed sale Order, based on the current draft PoS Order.\n" +" the according picking will be marked as delivered. Only invoices process will be possible." +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model.fields,help:pos_order_to_sale_order.field_pos_config__iface_create_draft_sale_order +msgid "If checked, the cashier will have the possibility to create a draft Sale Order, based on the current draft PoS Order." +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:29 +#, python-format +msgid "No customer defined" +msgstr "" + +#. module: pos_order_to_sale_order +#: code:addons/pos_order_to_sale_order/models/sale_order.py:17 +#, python-format +msgid "Point of Sale %s" +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model,name:pos_order_to_sale_order.model_pos_config +msgid "Point of Sale Configuration" +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model,name:pos_order_to_sale_order.model_sale_order +msgid "Sale Order" +msgstr "" + +#. module: pos_order_to_sale_order +#: model_terms:ir.ui.view,arch_db:pos_order_to_sale_order.view_pos_config_form +msgid "Sale Order Creations" +msgstr "" + +#. module: pos_order_to_sale_order +#: model:ir.model,name:pos_order_to_sale_order.model_sale_order_line +msgid "Sales Order Line" +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:147 +#, python-format +msgid "The order could not be sent" +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:103 +#, python-format +msgid "This operation will permanently discard the current PoS Order and create a Sale Order, based on the current order lines." +msgstr "" + +#. module: pos_order_to_sale_order +#. openerp-web +#: code:addons/pos_order_to_sale_order/static/src/js/screens.js:30 +#, python-format +msgid "You should select a customer in order to create a Sale Order." +msgstr "" diff --git a/pos_order_to_sale_order/models/__init__.py b/pos_order_to_sale_order/models/__init__.py new file mode 100644 index 00000000..1109a47e --- /dev/null +++ b/pos_order_to_sale_order/models/__init__.py @@ -0,0 +1,3 @@ +from . import sale_order +from . import sale_order_line +from . import pos_config diff --git a/pos_order_to_sale_order/models/pos_config.py b/pos_order_to_sale_order/models/pos_config.py new file mode 100644 index 00000000..1b8c8841 --- /dev/null +++ b/pos_order_to_sale_order/models/pos_config.py @@ -0,0 +1,50 @@ +# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class PosConfig(models.Model): + _inherit = "pos.config" + + iface_create_sale_order = fields.Boolean( + string="Create Sale Orders", + compute="_compute_iface_create_sale_order", + store=True) + + iface_create_draft_sale_order = fields.Boolean( + string="Create Draft Sale Orders", + default=True, + help="If checked, the cashier will have the possibility to create" + " a draft Sale Order, based on the current draft PoS Order.", + ) + + iface_create_confirmed_sale_order = fields.Boolean( + string="Create Confirmed Sale Orders", + default=True, + help="If checked, the cashier will have the possibility to create" + " a confirmed Sale Order, based on the current draft PoS Order.", + ) + + iface_create_delivered_sale_order = fields.Boolean( + string="Create Delivered Sale Orders", + default=True, + help="If checked, the cashier will have the possibility to create" + " a confirmed sale Order, based on the current draft PoS Order.\n" + " the according picking will be marked as delivered. Only invoices" + " process will be possible.", + ) + + @api.depends( + "iface_create_draft_sale_order", + "iface_create_confirmed_sale_order", + "iface_create_delivered_sale_order", + ) + def _compute_iface_create_sale_order(self): + for config in self: + config.iface_create_sale_order = any([ + config.iface_create_draft_sale_order, + config.iface_create_confirmed_sale_order, + config.iface_create_delivered_sale_order, + ]) diff --git a/pos_order_to_sale_order/models/sale_order.py b/pos_order_to_sale_order/models/sale_order.py new file mode 100644 index 00000000..56e95731 --- /dev/null +++ b/pos_order_to_sale_order/models/sale_order.py @@ -0,0 +1,62 @@ +# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import _, api, models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + @api.model + def _prepare_from_pos(self, order_data): + PosSession = self.env["pos.session"] + session = PosSession.browse(order_data["pos_session_id"]) + return { + "partner_id": order_data["partner_id"], + "origin": _("Point of Sale %s") % (session.name), + "client_order_ref": order_data["name"], + "user_id": order_data["user_id"], + "pricelist_id": order_data["pricelist_id"], + "fiscal_position_id": order_data["fiscal_position_id"], + } + + @api.model + def create_order_from_pos(self, order_data, action): + SaleOrderLine = self.env["sale.order.line"] + + # Create Draft Sale order + order_vals = self._prepare_from_pos(order_data) + sale_order = self.create(order_vals.copy()) + sale_order.onchange_partner_id() + # we rewrite data, because onchange could alter some + # custom data (like pricelist) + sale_order.write(order_vals) + + # create Sale order lines + for order_line_data in order_data["lines"]: + # Create Sale order lines + order_line_vals = SaleOrderLine._prepare_from_pos( + sale_order, order_line_data[2]) + sale_order_line = SaleOrderLine.create( + order_line_vals.copy()) + sale_order_line.product_id_change() + # we rewrite data, because onchange could alter some + # data (like quantity, or price) + sale_order_line.write(order_line_vals) + + # Confirm Sale Order + if action in ["confirmed", "delivered"]: + sale_order.action_confirm() + + # mark picking as delivered + if action == "delivered": + # Mark all moves are delivered + for move in sale_order.mapped( + "picking_ids.move_ids_without_package"): + move.quantity_done = move.product_uom_qty + sale_order.mapped("picking_ids").button_validate() + + return { + "sale_order_id": sale_order.id, + } diff --git a/pos_order_to_sale_order/models/sale_order_line.py b/pos_order_to_sale_order/models/sale_order_line.py new file mode 100644 index 00000000..aa65e6c4 --- /dev/null +++ b/pos_order_to_sale_order/models/sale_order_line.py @@ -0,0 +1,23 @@ +# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, models + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + @api.model + def _prepare_from_pos(self, sale_order, order_line_data): + ProductProduct = self.env["product.product"] + product = ProductProduct.browse(order_line_data["product_id"]) + return { + "order_id": sale_order.id, + "product_id": order_line_data["product_id"], + "name": product.name, + "product_uom_qty": order_line_data["qty"], + "discount": order_line_data["discount"], + "price_unit": order_line_data["price_unit"], + "tax_id": order_line_data["tax_ids"], + } diff --git a/pos_order_to_sale_order/readme/CONFIGURE.rst b/pos_order_to_sale_order/readme/CONFIGURE.rst new file mode 100644 index 00000000..1b4c3c63 --- /dev/null +++ b/pos_order_to_sale_order/readme/CONFIGURE.rst @@ -0,0 +1,6 @@ +* Go to Point Of Sale / Configuration / Point of Sale +* Check the box 'Create Sale Orders' +* Select the desired default behaviour + +.. figure:: ../static/description/pos_config_form.png + :width: 800 px diff --git a/pos_order_to_sale_order/readme/CONTRIBUTORS.rst b/pos_order_to_sale_order/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..e1525ce0 --- /dev/null +++ b/pos_order_to_sale_order/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Sylvain LE GAL (https://www.twitter.com/legalsylvain) diff --git a/pos_order_to_sale_order/readme/DESCRIPTION.rst b/pos_order_to_sale_order/readme/DESCRIPTION.rst new file mode 100644 index 00000000..aca0573c --- /dev/null +++ b/pos_order_to_sale_order/readme/DESCRIPTION.rst @@ -0,0 +1,22 @@ +This module extends the functionality of point of sale to allow sale orders +creation from the Point of Sale. + +In the POS UI, button has been added to create a sale order and discard +the current POS order. + +This module is usefull in many cases, for exemple : + +* take orders with a very simple interface + +* if you have some customers that come every day in your shop, but want to + have a unique invoice at the end of the month. With that module, you can + create a sale order and deliver products every time to keep your stock value + correct, and to create a unique invoice, when you want. + +**Technical Notes** + +* Some hooks are defined in the JS file, to define custom behaviour after + having created the sale order. + +* Some prepare functions are available in the ``sale.order`` model and + ``sale.order.line`` models to overload the creation of the sale order. diff --git a/pos_order_to_sale_order/readme/USAGE.rst b/pos_order_to_sale_order/readme/USAGE.rst new file mode 100644 index 00000000..ef015587 --- /dev/null +++ b/pos_order_to_sale_order/readme/USAGE.rst @@ -0,0 +1,23 @@ +* Open your Point of sale +* create a new order and select products +* select a customer + +* then, click on the "Create Sale Order" button + +.. figure:: ../static/description/pos_frontend_order.png + :width: 800 px + +Three options are available: + +* **Create a draft Order** + A new sale order in a draft mode will be created that can be changed later. + +* **Create a Confirmed Order** + A new sale order will be created and confirmed. + +* **Create Delivered Picking** (by default) + A new sale order will be created and confirmed. the associated picking + will be marked as delivered. + +.. figure:: ../static/description/pos_frontend_buttons.png + :width: 800 px diff --git a/pos_order_to_sale_order/static/description/icon.png b/pos_order_to_sale_order/static/description/icon.png new file mode 100644 index 00000000..d547d9cb Binary files /dev/null and b/pos_order_to_sale_order/static/description/icon.png differ diff --git a/pos_order_to_sale_order/static/description/index.html b/pos_order_to_sale_order/static/description/index.html new file mode 100644 index 00000000..1c635449 --- /dev/null +++ b/pos_order_to_sale_order/static/description/index.html @@ -0,0 +1,496 @@ + + + + + + +PoS Order To Sale Order + + + +
+

PoS Order To Sale Order

+ + +

Production/Stable License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runbot

+

This module extends the functionality of point of sale to allow sale orders +creation from the Point of Sale.

+

In the POS UI, buttons has been added to create a sale order and discard +the current POS order.

+

This module is usefull in many cases, for exemple :

+ +

Three options are available:

+ +
+https://raw.githubusercontent.com/OCA/pos/8.0/pos_order_to_sale_order/static/description/pos_create_picking_option_1.png +
+ +
+https://raw.githubusercontent.com/OCA/pos/8.0/pos_order_to_sale_order/static/description/pos_create_picking_option_2.png +
+ +
+https://raw.githubusercontent.com/OCA/pos/8.0/pos_order_to_sale_order/static/description/pos_create_picking_option_3.png +
+

Technical Notes

+ +

Table of contents

+
+ +
+
+

Configuration

+

To configure this module, you need to:

+ +
+https://raw.githubusercontent.com/OCA/pos/8.0/pos_order_to_sale_order/static/description/pos_config_form.png +
+
+
+

Known issues / Roadmap

+ +

Note that this problem is fixed if pos_pricelist is installed. +(same repository) In that cases, the pricelist, the unit prices and the taxes +will be the same in the order, as in the displayed bill.

+
+https://raw.githubusercontent.com/OCA/pos/8.0/pos_order_to_sale_order/static/description/pos_create_picking_confirm.png +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • GRAP
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

legalsylvain

+

This module is part of the OCA/pos project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/pos_order_to_sale_order/static/description/pos_config_form.png b/pos_order_to_sale_order/static/description/pos_config_form.png new file mode 100644 index 00000000..c108942f Binary files /dev/null and b/pos_order_to_sale_order/static/description/pos_config_form.png differ diff --git a/pos_order_to_sale_order/static/description/pos_frontend_buttons.png b/pos_order_to_sale_order/static/description/pos_frontend_buttons.png new file mode 100644 index 00000000..fa0d9f08 Binary files /dev/null and b/pos_order_to_sale_order/static/description/pos_frontend_buttons.png differ diff --git a/pos_order_to_sale_order/static/description/pos_frontend_order.png b/pos_order_to_sale_order/static/description/pos_frontend_order.png new file mode 100644 index 00000000..fdbe05a8 Binary files /dev/null and b/pos_order_to_sale_order/static/description/pos_frontend_order.png differ diff --git a/pos_order_to_sale_order/static/src/js/screens.js b/pos_order_to_sale_order/static/src/js/screens.js new file mode 100644 index 00000000..98b84fa6 --- /dev/null +++ b/pos_order_to_sale_order/static/src/js/screens.js @@ -0,0 +1,161 @@ +/** *************************************************************************** + Copyright (C) 2017 - Today: GRAP (http://www.grap.coop) + @author: Sylvain LE GAL (https://twitter.com/legalsylvain) + License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +******************************************************************************/ + +odoo.define('pos_order_to_sale_order.screens', function (require) { + "use strict"; + + var screens = require('point_of_sale.screens'); + var gui = require('point_of_sale.gui'); + var core = require('web.core'); + var framework = require('web.framework'); + var rpc = require('web.rpc'); + var _t = core._t; + + /** ********************************************************************** + New Widget CreateSaleOrderButtonWidget: + * On click, display a new screen to select the action to do + */ + var CreateSaleOrderButtonWidget = screens.ActionButtonWidget.extend({ + template: 'CreateSaleOrderButtonWidget', + + button_click: function () { + if (this.pos.get_order().get_client()) { + this.gui.show_screen('create_sale_order'); + } else { + this.gui.show_popup('error', { + 'title': _t('No customer defined'), + 'body': _t( + 'You should select a customer in order to create' + + ' a Sale Order.'), + }); + } + }, + + is_visible: function () { + return this.pos.get_order().orderlines.length > 0; + }, + + }); + + screens.define_action_button({ + 'name': 'create_sale_order', + 'widget': CreateSaleOrderButtonWidget, + 'condition': function () { + return this.pos.config.iface_create_sale_order; + }, + }); + + screens.OrderWidget.include({ + update_summary: function () { + this._super(); + if (this.getParent().action_buttons && + this.getParent().action_buttons.create_sale_order) { + this.getParent().action_buttons.create_sale_order.renderElement(); + } + }, + }); + + /** ********************************************************************** + New ScreenWidget CreateSaleOrderScreenWidget: + * On show, display all buttons, depending on the pos configuration + */ + var CreateSaleOrderScreenWidget = screens.ScreenWidget.extend({ + template: 'CreateSaleOrderScreenWidget', + auto_back: true, + + + show: function(){ + var self = this; + this._super(); + + this.renderElement(); + + this.$('.back').click(function(){ + self.gui.back(); + }); + + if (!this.pos.config.iface_create_draft_sale_order) { + this.$('#button-create-draft-order').addClass('oe_hidden'); + } + if (!this.pos.config.iface_create_confirmed_sale_order) { + this.$('#button-create-confirmed-order').addClass('oe_hidden'); + } + if (!this.pos.config.iface_create_delivered_sale_order) { + this.$('#button-create-delivered-order').addClass('oe_hidden'); + } + + this.$('.paymentmethod').click(function(event){ + self.click_sale_order_button(event.currentTarget.attributes.action.nodeValue); + }); + }, + + click_sale_order_button: function(action) { + var self = this; + this.gui.show_popup('confirm', { + 'title': _t( + 'Create Sale Order and discard the current' + + ' PoS Order?'), + 'body': _t( + "This operation will permanently discard the current PoS" + + " Order and create a Sale Order, based on the" + + " current order lines."), + confirm: function(){ + framework.blockUI(); + rpc.query({ + model: 'sale.order', + method: 'create_order_from_pos', + args: [self.pos.get('selectedOrder').export_as_JSON(), action], + }).then(function (result) { + self.hook_create_sale_order_success(result); + }).fail(function (error, event) { + self.hook_create_sale_order_error(error, event); + }); + }, + }); + }, + + /** + * Overloadable function to make custom action after Sale order + * Creation succeeded + */ + hook_create_sale_order_success: function (result) { + framework.unblockUI(); + this.pos.get('selectedOrder').destroy(); + }, + + /** + * Overloadable function to make custom action after Sale order + * Creation failed + */ + hook_create_sale_order_error: function (error, event) { + framework.unblockUI(); + event.preventDefault(); + if (error.code === 200) { + // Business Logic Error, not a connection problem + this.gui.show_popup('error-traceback', { + 'title': error.data.message, + 'body': error.data.debug, + }); + } else { + // Connexion problem + this.gui.show_popup('error', { + 'title': _t('The order could not be sent'), + 'body': _t('Check your internet connection and try again.'), + }); + } + }, + + }); + + gui.define_screen({ + 'name': 'create_sale_order', + 'widget': CreateSaleOrderScreenWidget, + 'condition': function () { + return this.pos.config.iface_create_sale_order; + }, + }); + +}); diff --git a/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml b/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml new file mode 100644 index 00000000..72493d7e --- /dev/null +++ b/pos_order_to_sale_order/static/src/xml/pos_order_to_sale_order.xml @@ -0,0 +1,37 @@ + + diff --git a/pos_order_to_sale_order/views/assets.xml b/pos_order_to_sale_order/views/assets.xml new file mode 100644 index 00000000..c8420256 --- /dev/null +++ b/pos_order_to_sale_order/views/assets.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/pos_order_to_sale_order/views/view_pos_config.xml b/pos_order_to_sale_order/views/view_pos_config.xml new file mode 100644 index 00000000..da0dfdeb --- /dev/null +++ b/pos_order_to_sale_order/views/view_pos_config.xml @@ -0,0 +1,43 @@ + + + + + pos.config + + + + + +

Sale Order Creations

+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+