-
+
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
diff --git a/pos_order_return_traceability/README.rst b/pos_order_return_traceability/README.rst
new file mode 100644
index 00000000..817c1d17
--- /dev/null
+++ b/pos_order_return_traceability/README.rst
@@ -0,0 +1,83 @@
+================================
+POS frontend return traceability
+================================
+
+.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
+ :target: https://odoo-community.org/page/development-status
+ :alt: Beta
+.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github
+ :target: https://github.com/OCA/pos/tree/12.0/pos_order_return_traceability
+ :alt: OCA/pos
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+ :target: https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_order_return_traceability
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
+ :target: https://runbot.odoo-community.org/runbot/184/12.0
+ :alt: Try me on Runbot
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
+
+This module adds full return traceability to POS frontend
+
+**Table of contents**
+
+.. contents::
+ :local:
+
+Known issues / Roadmap
+======================
+
+* When a partially returned order is selected, every line is loaded to be
+ returned, even the fully returned ones (with 0 quantity). These lines should
+ be skipped, since this module will forbid any return quantity for them.
+* When an order is fully returned, during the same session can be still
+ selected from order list within because of caching issues. Anyway, the order
+ cannot be returned again.
+
+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
+~~~~~~~
+
+* Solvos
+
+Contributors
+~~~~~~~~~~~~
+
+* David Alonso
+
+Maintainers
+~~~~~~~~~~~
+
+This module is maintained by the OCA.
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+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.
+
+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_return_traceability/__init__.py b/pos_order_return_traceability/__init__.py
new file mode 100644
index 00000000..a9e33722
--- /dev/null
+++ b/pos_order_return_traceability/__init__.py
@@ -0,0 +1,2 @@
+
+from . import models
diff --git a/pos_order_return_traceability/__manifest__.py b/pos_order_return_traceability/__manifest__.py
new file mode 100644
index 00000000..2432c021
--- /dev/null
+++ b/pos_order_return_traceability/__manifest__.py
@@ -0,0 +1,23 @@
+# © 2020 Solvos Consultoría Informática ()
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+{
+ "name": "POS frontend return traceability",
+ "summary": "Adds full return traceability to POS frontend",
+ "version": "12.0.1.0.0",
+ "author": "Odoo Community Association (OCA), Solvos",
+ "website": "http://www.github.com/OCA/pos",
+ "license": "AGPL-3",
+ "category": "Point Of Sale",
+ "depends": [
+ 'pos_order_mgmt',
+ 'pos_order_return',
+ ],
+ 'data': [
+ "views/pos_templates.xml",
+ ],
+ "qweb": [
+ 'static/src/xml/pos.xml',
+ ],
+ 'installable': True,
+}
diff --git a/pos_order_return_traceability/i18n/pos_order_return_traceability.pot b/pos_order_return_traceability/i18n/pos_order_return_traceability.pot
new file mode 100644
index 00000000..51ef30a8
--- /dev/null
+++ b/pos_order_return_traceability/i18n/pos_order_return_traceability.pot
@@ -0,0 +1,62 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * pos_order_return_traceability
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-02-07 15:37+0000\n"
+"PO-Revision-Date: 2020-02-07 15:37+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_return_traceability
+#. openerp-web
+#: code:addons/pos_order_return_traceability/static/src/js/widgets.js:62
+#, python-format
+msgid "* Invalid quantity line(s): "
+msgstr ""
+
+#. module: pos_order_return_traceability
+#. openerp-web
+#: code:addons/pos_order_return_traceability/static/src/js/widgets.js:67
+#, python-format
+msgid "* Non-returnable line(s): "
+msgstr ""
+
+#. module: pos_order_return_traceability
+#: model:ir.model.fields,field_description:pos_order_return_traceability.field_pos_order__is_returnable
+msgid "Is Returnable"
+msgstr ""
+
+#. module: pos_order_return_traceability
+#. openerp-web
+#: code:addons/pos_order_return_traceability/static/src/js/widgets.js:59
+#, python-format
+msgid "Please check the following line(s):"
+msgstr ""
+
+#. module: pos_order_return_traceability
+#: model:ir.model,name:pos_order_return_traceability.model_pos_order
+msgid "Point of Sale Orders"
+msgstr ""
+
+#. module: pos_order_return_traceability
+#. openerp-web
+#: code:addons/pos_order_return_traceability/static/src/js/widgets.js:72
+#, python-format
+msgid "Return lines error(s)"
+msgstr ""
+
+#. module: pos_order_return_traceability
+#. openerp-web
+#: code:addons/pos_order_return_traceability/static/src/xml/pos.xml:6
+#, python-format
+msgid "widget.pos.config.iface_return_done_order and order.is_returnable"
+msgstr ""
+
diff --git a/pos_order_return_traceability/models/__init__.py b/pos_order_return_traceability/models/__init__.py
new file mode 100644
index 00000000..97c35351
--- /dev/null
+++ b/pos_order_return_traceability/models/__init__.py
@@ -0,0 +1,2 @@
+
+from . import pos_order
diff --git a/pos_order_return_traceability/models/pos_order.py b/pos_order_return_traceability/models/pos_order.py
new file mode 100644
index 00000000..e13c5ae4
--- /dev/null
+++ b/pos_order_return_traceability/models/pos_order.py
@@ -0,0 +1,31 @@
+# © 2020 Solvos Consultoría Informática ()
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import api, fields, models
+
+
+class PosOrder(models.Model):
+ _inherit = 'pos.order'
+
+ is_returnable = fields.Boolean(
+ compute='_compute_is_returnable',
+ )
+
+ def _compute_is_returnable(self):
+ for order in self:
+ order.is_returnable = \
+ order.amount_total >= 0 and \
+ sum([l.max_returnable_qty(ignored_line_ids=[])
+ for l in order.lines]) > 0
+
+ @api.model
+ def _prepare_fields_for_pos_list(self):
+ return super()._prepare_fields_for_pos_list() + ['is_returnable']
+
+ def _prepare_done_order_line_for_pos(self, order_line):
+ line = super()._prepare_done_order_line_for_pos(order_line)
+ return {
+ **line,
+ 'id': order_line.id,
+ 'qty_returnable': order_line.max_returnable_qty(ignored_line_ids=[])
+ }
diff --git a/pos_order_return_traceability/readme/CONTRIBUTORS.rst b/pos_order_return_traceability/readme/CONTRIBUTORS.rst
new file mode 100644
index 00000000..423455df
--- /dev/null
+++ b/pos_order_return_traceability/readme/CONTRIBUTORS.rst
@@ -0,0 +1 @@
+* David Alonso
diff --git a/pos_order_return_traceability/readme/DESCRIPTION.rst b/pos_order_return_traceability/readme/DESCRIPTION.rst
new file mode 100644
index 00000000..a110badb
--- /dev/null
+++ b/pos_order_return_traceability/readme/DESCRIPTION.rst
@@ -0,0 +1 @@
+This module adds full return traceability to POS frontend
diff --git a/pos_order_return_traceability/readme/ROADMAP.rst b/pos_order_return_traceability/readme/ROADMAP.rst
new file mode 100644
index 00000000..9349d582
--- /dev/null
+++ b/pos_order_return_traceability/readme/ROADMAP.rst
@@ -0,0 +1,6 @@
+* When a partially returned order is selected, every line is loaded to be
+ returned, even the fully returned ones (with 0 quantity). These lines should
+ be skipped, since this module will forbid any return quantity for them.
+* When an order is fully returned, during the same session can be still
+ selected from order list within because of caching issues. Anyway, the order
+ cannot be returned again.
diff --git a/pos_order_return_traceability/static/description/index.html b/pos_order_return_traceability/static/description/index.html
new file mode 100644
index 00000000..ab2a0a92
--- /dev/null
+++ b/pos_order_return_traceability/static/description/index.html
@@ -0,0 +1,431 @@
+
+
+
+
+
+
+POS frontend return traceability
+
+
+
+
+
POS frontend return traceability
+
+
+
+
This module adds full return traceability to POS frontend
+
Table of contents
+
+
+
+
+- When a partially returned order is selected, every line is loaded to be
+returned, even the fully returned ones (with 0 quantity). These lines should
+be skipped, since this module will forbid any return quantity for them.
+- When an order is fully returned, during the same session can be still
+selected from order list within because of caching issues. Anyway, the order
+cannot be returned again.
+
+
+
+
+
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.
+
+
+
+
+
+
+
+
This module is maintained by the OCA.
+
+
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.
+
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_return_traceability/static/src/js/models.js b/pos_order_return_traceability/static/src/js/models.js
new file mode 100644
index 00000000..5d9d3b47
--- /dev/null
+++ b/pos_order_return_traceability/static/src/js/models.js
@@ -0,0 +1,31 @@
+/* Copyright 2020 Solvos Consultoría Informática
+ License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+*/
+
+
+odoo.define('pos_order_return_traceability.models', function (require) {
+ 'use strict';
+
+ var models = require('point_of_sale.models');
+
+ models.load_fields("product.product", ['pos_allow_negative_qty']);
+
+ var orderline_super = models.Orderline.prototype;
+
+ models.Orderline = models.Orderline.extend({
+
+ initialize: function(){
+ orderline_super.initialize.apply(this, arguments);
+ this.returned_line_id = false;
+ this.quantity_returnable = this.get_quantity();
+ },
+
+ export_as_JSON: function () {
+ var res = orderline_super.export_as_JSON.apply(this, arguments);
+ res.returned_line_id = this.returned_line_id;
+ return res;
+ }
+
+ });
+
+});
diff --git a/pos_order_return_traceability/static/src/js/widgets.js b/pos_order_return_traceability/static/src/js/widgets.js
new file mode 100644
index 00000000..dadf255b
--- /dev/null
+++ b/pos_order_return_traceability/static/src/js/widgets.js
@@ -0,0 +1,106 @@
+/* Copyright 2020 Solvos Consultoría Informática
+ License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+*/
+
+odoo.define('pos_order_return_traceability.widgets', function (require) {
+ "use strict";
+
+ var core = require('web.core');
+ var screens = require('point_of_sale.screens');
+ var order_mgmt_widgets = require('pos_order_mgmt.widgets');
+
+ var QWeb = core.qweb;
+
+ screens.ActionpadWidget.include({
+
+ renderElement: function() {
+ var self = this;
+ this._super();
+
+ var button_pay_click_handler = $._data(
+ this.$el.find('.pay')[0], 'events').click[0].handler;
+ var button_pay = this.$('.pay');
+ button_pay.off('click');
+ button_pay.click(function(){
+ var order = self.pos.get_order();
+ if (self.check_return_order(order)) {
+ button_pay_click_handler();
+ }
+ });
+
+ },
+
+ check_return_order: function (order) {
+ var self = this;
+ if (!order.returned_order_id) {
+ return true;
+ }
+
+ var lines = order.get_orderlines();
+ var qty_incorrect_lines = [], no_return_lines = [];
+ for (var i = 0; i < lines.length; i++) {
+ var qty_line = lines[i].get_quantity();
+ var product = lines[i].get_product();
+ if (!lines[i].returned_line_id && (qty_line < 0) &&
+ !product.pos_allow_negative_qty) {
+ // Prevent new lines without return associated
+ no_return_lines.push(product.display_name);
+ } else if (lines[i].returned_line_id && (
+ (qty_line > 0) ||
+ ((-1)*lines[i].quantity_returnable > qty_line)
+ )) {
+ // Maximum quantity allowed exceeded
+ qty_incorrect_lines.push(product.display_name + ': ' +
+ lines[i].get_quantity_str() + ' < ' +
+ (-1)*lines[i].quantity_returnable);
+ }
+ }
+
+ if ((qty_incorrect_lines.length + no_return_lines.length) > 0) {
+ var error_message = _t('Please check the following line(s):');
+ if (qty_incorrect_lines.length > 0) {
+ error_message += "\n\n";
+ error_message += _t('* Invalid quantity line(s): ') +
+ qty_incorrect_lines.join(', ');
+ }
+ if (no_return_lines.length > 0) {
+ error_message += "\n\n";
+ error_message += _t('* Non-returnable line(s): ') +
+ no_return_lines.join(', ');
+ }
+ self.gui.show_popup(
+ 'error-traceback', {
+ 'title': _t('Return lines error(s)'),
+ 'body': error_message,
+ });
+ return false;
+ }
+
+ return true;
+ }
+
+ });
+
+ order_mgmt_widgets.OrderListScreenWidget.include({
+
+ _prepare_product_options_from_orderline_data: function (
+ order, line, action) {
+
+ var self = this;
+ var ret = this._super(order, line, action);
+
+ if (['return'].indexOf(action) !== -1) {
+ ret.quantity = (-1) * line.qty_returnable;
+ ret.extras = {
+ returned_line_id: line.id,
+ quantity_returnable: line.qty_returnable,
+ }
+ }
+
+ return ret;
+
+ },
+
+ });
+
+});
diff --git a/pos_order_return_traceability/static/src/xml/pos.xml b/pos_order_return_traceability/static/src/xml/pos.xml
new file mode 100644
index 00000000..3eea007f
--- /dev/null
+++ b/pos_order_return_traceability/static/src/xml/pos.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ widget.pos.config.iface_return_done_order and order.is_returnable
+
+
+
+
diff --git a/pos_order_return_traceability/tests/__init__.py b/pos_order_return_traceability/tests/__init__.py
new file mode 100644
index 00000000..d9b96c4f
--- /dev/null
+++ b/pos_order_return_traceability/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_module
diff --git a/pos_order_return_traceability/tests/test_module.py b/pos_order_return_traceability/tests/test_module.py
new file mode 100644
index 00000000..c7538730
--- /dev/null
+++ b/pos_order_return_traceability/tests/test_module.py
@@ -0,0 +1,83 @@
+# © 2020 Solvos Consultoría Informática ()
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import fields
+from odoo.tests.common import TransactionCase
+
+
+class TestModule(TransactionCase):
+
+ def setUp(self):
+ super(TestModule, self).setUp()
+
+ # Get Registry
+ self.PosOrder = self.env['pos.order']
+ self.AccountPayment = self.env['account.payment']
+
+ # Get Object
+ self.pos_product = self.env.ref('point_of_sale.whiteboard_pen')
+ self.pricelist = self.env.ref('product.list0')
+ self.partner = self.env.ref('base.res_partner_12')
+
+ # Create a new pos config and open it
+ self.pos_config = self.env.ref('point_of_sale.pos_config_main').copy()
+ self.pos_config.open_session_cb()
+
+ def test_return_traceability(self):
+ order = self._create_order()
+ order_line = order.lines[0]
+
+ self.assertTrue(order.is_returnable)
+ prepared_line = order._prepare_done_order_line_for_pos(order_line)
+ self.assertEqual(prepared_line['id'], order_line.id)
+ self.assertEqual(prepared_line['qty_returnable'], order_line.qty)
+
+ res_refund = order.refund()
+ order_refund = self.PosOrder.browse(res_refund['res_id'])
+ self.assertFalse(order.is_returnable)
+ self.assertFalse(order_refund.is_returnable)
+ prepared_line = order._prepare_done_order_line_for_pos(order_line)
+ self.assertEqual(prepared_line['qty_returnable'], 0)
+
+ self.assertTrue('is_returnable' in
+ self.PosOrder._prepare_fields_for_pos_list())
+
+ def _create_order(self):
+ order_data = {
+ 'id': u'0006-001-0010',
+ 'to_invoice': True,
+ 'data': {
+ 'pricelist_id': self.pricelist.id,
+ 'user_id': 1,
+ 'name': 'Order 0006-001-0010',
+ 'partner_id': self.partner.id,
+ 'amount_paid': 0.9,
+ 'pos_session_id': self.pos_config.current_session_id.id,
+ 'lines': [[0, 0, {
+ 'product_id': self.pos_product.id,
+ 'price_unit': 0.9,
+ 'qty': 1,
+ 'price_subtotal': 0.9,
+ 'price_subtotal_incl': 0.9,
+ }]],
+ 'statement_ids': [[0, 0, {
+ 'journal_id': self.pos_config.journal_ids[0].id,
+ 'amount': 0.9,
+ 'name': fields.Datetime.now(),
+ 'account_id':
+ self.env.user.partner_id.property_account_receivable_id.id,
+ 'statement_id':
+ self.pos_config.current_session_id.statement_ids[0].id,
+ }]],
+ 'creation_date': u'2018-09-27 15:51:03',
+ 'amount_tax': 0,
+ 'fiscal_position_id': False,
+ 'uid': u'00001-001-0001',
+ 'amount_return': 0,
+ 'sequence_number': 1,
+ 'amount_total': 0.9,
+ }}
+
+ result = self.PosOrder.create_from_ui([order_data])
+ order = self.PosOrder.browse(result[0])
+ return order
diff --git a/pos_order_return_traceability/views/pos_templates.xml b/pos_order_return_traceability/views/pos_templates.xml
new file mode 100644
index 00000000..f9873e9b
--- /dev/null
+++ b/pos_order_return_traceability/views/pos_templates.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+