diff --git a/pos_backup_draft_orders/__init__.py b/pos_backup_draft_orders/__init__.py
new file mode 100644
index 00000000..d780e648
--- /dev/null
+++ b/pos_backup_draft_orders/__init__.py
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Point Of Sale - Backup Draft Orders module for OpenERP
+# Copyright (C) 2013-2014 GRAP (http://www.grap.coop)
+# @author Julien WESTE
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from . import model
diff --git a/pos_backup_draft_orders/__openerp__.py b/pos_backup_draft_orders/__openerp__.py
new file mode 100644
index 00000000..a50e44a0
--- /dev/null
+++ b/pos_backup_draft_orders/__openerp__.py
@@ -0,0 +1,58 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Point Of Sale - Backup Draft Orders module for OpenERP
+# Copyright (C) 2014 GRAP (http://www.grap.coop)
+# @author Julien WESTE
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+{
+ 'name': 'Point Of Sale - Backup Draft Orders',
+ 'summary': """Allow users to backup draft orders"""
+ """in Point Of Sale (Front end)""",
+ 'version': '0.1',
+ 'category': 'Point Of Sale',
+ 'description': """
+Allow users to backup draft orders in Point Of Sale (Front end)
+===============================================================
+
+Functionality:
+--------------
+ * Allow user to backup in the backoffice side orders selected in front-end;
+
+Copyright, Authors and Licence:
+-------------------------------
+ * Copyright: 2014, GRAP: Groupement Régional Alimentaire de Proximité;
+ * Author:
+ * Julien WESTE;
+ * Sylvain LE GAL (https://twitter.com/legalsylvain);
+ * Licence: AGPL-3 (http://www.gnu.org/licenses/);""",
+ 'author': 'GRAP',
+ 'website': 'http://www.grap.coop',
+ 'license': 'AGPL-3',
+ 'depends': [
+ 'point_of_sale',
+ 'pos_second_header',
+ ],
+ 'js': [
+ 'static/src/js/pbdo.js',
+ ],
+ 'css': [
+ 'static/src/css/pbdo.css',
+ ],
+}
diff --git a/pos_backup_draft_orders/i18n/fr.po b/pos_backup_draft_orders/i18n/fr.po
new file mode 100644
index 00000000..1e0d3c7b
--- /dev/null
+++ b/pos_backup_draft_orders/i18n/fr.po
@@ -0,0 +1,45 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Point Of Sale - Backup Draft Orders module for OpenERP
+# Copyright (C) 2013-2014 GRAP (http://www.grap.coop)
+# @author Julien WESTE
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+# * pos_backup_draft_orders
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-04-16 17:38+0000\n"
+"PO-Revision-Date: 2014-04-16 17:38+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_backup_draft_orders
+#. openerp-web
+#: code:addons/pos_backup_draft_orders/static/src/js/pbdo.js:50
+#, python-format
+msgid "Keep in Draft"
+msgstr "Sauvegarder"
diff --git a/pos_backup_draft_orders/i18n/pos_backup_draft_orders.pot b/pos_backup_draft_orders/i18n/pos_backup_draft_orders.pot
new file mode 100644
index 00000000..94771bcf
--- /dev/null
+++ b/pos_backup_draft_orders/i18n/pos_backup_draft_orders.pot
@@ -0,0 +1,31 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+# * pos_backup_draft_orders
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-11-16 02:09+0000\n"
+"PO-Revision-Date: 2014-11-16 02:09+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_backup_draft_orders
+#. openerp-web
+#: code:addons/pos_backup_draft_orders/static/src/js/pbdo.js:50
+#, python-format
+msgid "Keep in Draft"
+msgstr ""
+
+#. module: pos_backup_draft_orders
+#: code:_description:0
+#: model:ir.model,name:pos_backup_draft_orders.model_pos_order
+#, python-format
+msgid "Point of Sale"
+msgstr ""
+
diff --git a/pos_backup_draft_orders/model/__init__.py b/pos_backup_draft_orders/model/__init__.py
new file mode 100644
index 00000000..26e841dc
--- /dev/null
+++ b/pos_backup_draft_orders/model/__init__.py
@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Point Of Sale - Backup Draft Orders module for OpenERP
+# Copyright (C) 2013-2014 GRAP (http://www.grap.coop)
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from . import pos_order
diff --git a/pos_backup_draft_orders/model/pos_order.py b/pos_backup_draft_orders/model/pos_order.py
new file mode 100644
index 00000000..e980e43c
--- /dev/null
+++ b/pos_backup_draft_orders/model/pos_order.py
@@ -0,0 +1,73 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Point Of Sale - Backup Draft Orders module for OpenERP
+# Copyright (C) 2013-2014 GRAP (http://www.grap.coop)
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from openerp.osv.orm import Model
+
+
+class pos_order(Model):
+ _inherit = 'pos.order'
+
+ # custom function
+ def _create_draft_from_ui(self, cr, uid, orders, context=None):
+ order_ids = []
+ for tmp_order in orders:
+ order = tmp_order['data']
+ order_id = self.create(cr, uid, {
+ 'name': order['name'],
+ 'user_id': order['user_id'] or False,
+ 'session_id': order['pos_session_id'],
+ 'lines': order['lines'],
+ 'pos_reference': order['name'],
+ 'partner_id': order.get('partner_id', False)
+ }, context)
+ for payments in order['statement_ids']:
+ payment = payments[2]
+ self.add_payment(cr, uid, order_id, {
+ 'amount': payment['amount'] or 0.0,
+ 'payment_date': payment['name'],
+ 'statement_id': payment['statement_id'],
+ 'payment_name': payment.get('note', False),
+ 'journal': payment['journal_id']
+ }, context=context)
+ order_ids.append(order_id)
+ return order_ids
+
+ # Overload section
+ def create_from_ui(self, cr, uid, orders, context=None):
+ """
+ - remove from the 'orders' list all orders where amount_return is < 0
+ (because that means they are not paid, but just saved) and put them
+ in a 'saved_orders' list
+ - call a specific function for the 'saved_orders' list
+ - call the parent create_from_ui() for the remaining orders"""
+ saved_orders = []
+ for tmp_order in orders:
+ if tmp_order['data']['amount_return'] < 0\
+ and abs(tmp_order['data']['amount_return']) > 0.000001:
+ saved_orders.append(tmp_order)
+ orders.remove(tmp_order)
+
+ self._create_draft_from_ui(
+ cr, uid, saved_orders, context=context)
+
+ return super(pos_order, self).create_from_ui(
+ cr, uid, orders, context=context)
diff --git a/pos_backup_draft_orders/static/src/img/icon.png b/pos_backup_draft_orders/static/src/img/icon.png
new file mode 100644
index 00000000..74ed9c99
Binary files /dev/null and b/pos_backup_draft_orders/static/src/img/icon.png differ
diff --git a/pos_backup_draft_orders/static/src/js/pbdo.js b/pos_backup_draft_orders/static/src/js/pbdo.js
new file mode 100644
index 00000000..1f59fb83
--- /dev/null
+++ b/pos_backup_draft_orders/static/src/js/pbdo.js
@@ -0,0 +1,81 @@
+/******************************************************************************
+ Point Of Sale - Backup Draft Orders module for OpenERP
+ Copyright (C) 2014 GRAP (http://www.grap.coop)
+ @author Julien WESTE
+ @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+******************************************************************************/
+
+openerp.pos_backup_draft_orders = function (instance) {
+ module = instance.point_of_sale;
+ _t = instance.web._t;
+
+ /*************************************************************************
+ Overload : PosWidget to include button in PosOrderHeaderWidget widget
+ to backup draft orders
+ */
+ module.PosWidget = module.PosWidget.extend({
+
+ displayBackupButton: function(){
+ if (this.backup_order_button){
+ var order = this.pos.get('selectedOrder');
+ if (((order.get('orderLines').length + order.get('paymentLines').length) > 0) &&
+ (order.getChange()<0 && (Math.abs(order.getChange()) > 0.000001))){
+ this.backup_order_button.$el.fadeIn();
+ }
+ else{
+ this.backup_order_button.$el.fadeOut();
+ }
+ }
+ },
+
+ build_widgets: function(){
+ this._super();
+ var self = this;
+
+ // Create a button to backup the current order
+ this.backup_order_button = new module.HeaderButtonWidget(this,{
+ label:_t('Keep in Draft'),
+ action: function(){ self.backup_order(); },
+ });
+ this.backup_order_button.appendTo(this.$('#pos_order_header'));
+ this.pos.bind('change:selectedOrder', this.displayBackupButton, this);
+ this.backup_order_button.$el.fadeOut();
+ },
+
+ backup_order: function() {
+ var order = this.pos.get('selectedOrder');
+ this.pos.push_order(order.exportAsJSON());
+ this.pos.get('selectedOrder').destroy();
+ },
+
+ });
+
+ module.OrderWidget = module.OrderWidget.extend({
+ renderElement: function(){
+ this.pos_widget.displayBackupButton();
+ this._super();
+ },
+ });
+
+ module.PaymentScreenWidget = module.PaymentScreenWidget.extend({
+ updatePaymentSummary: function(){
+ this.pos_widget.displayBackupButton();
+ this._super();
+ },
+ });
+
+};
+
diff --git a/pos_backup_draft_orders/tests/__init__.py b/pos_backup_draft_orders/tests/__init__.py
new file mode 100644
index 00000000..878868f8
--- /dev/null
+++ b/pos_backup_draft_orders/tests/__init__.py
@@ -0,0 +1,28 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Point Of Sale - Backup Draft Orders module for OpenERP
+# Copyright (C) 2013-2014 GRAP (http://www.grap.coop)
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+
+from . import test_pos_backup_draft_orders
+
+fast_suite = [
+ test_pos_backup_draft_orders,
+]
diff --git a/pos_backup_draft_orders/tests/test_pos_backup_draft_orders.py b/pos_backup_draft_orders/tests/test_pos_backup_draft_orders.py
new file mode 100644
index 00000000..2d335e57
--- /dev/null
+++ b/pos_backup_draft_orders/tests/test_pos_backup_draft_orders.py
@@ -0,0 +1,117 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# Point Of Sale - Backup Draft Orders module for OpenERP
+# Copyright (C) 2013-2014 GRAP (http://www.grap.coop)
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+# from openerp.osv import osv
+from openerp.tests.common import TransactionCase
+
+
+class TestPosBackupDraftOrders(TransactionCase):
+ """Tests for 'Point Of Sale - Backup Draft Orders' Module"""
+
+ def setUp(self):
+ super(TestPosBackupDraftOrders, self).setUp()
+ cr, uid = self.cr, self.uid
+ self.imd_obj = self.registry('ir.model.data')
+ self.po_obj = self.registry('pos.order')
+ self.ps_obj = self.registry('pos.session')
+ self.abs_obj = self.registry('account.bank.statement')
+ pc_id = self.imd_obj.get_object_reference(
+ cr, uid, 'point_of_sale', 'pos_config_main')[1]
+ self.session_id = self.ps_obj.create(cr, uid, {
+ 'config_id': pc_id,
+ })
+ self.evian_product_id = self.imd_obj.get_object_reference(
+ cr, uid, 'point_of_sale', 'evian_2l')[1]
+ self.cash_journal_id = self.imd_obj.get_object_reference(
+ cr, uid, 'account', 'cash_journal')[1]
+ self.statement_id = self.abs_obj.search(cr, uid, [
+ ('journal_id', '=', self.cash_journal_id),
+ ('state', '=', 'open')])[0]
+
+ # Test Section
+ def test_01_create_paid_order(self):
+ """[Non regression] Test if the behaviour when the POS order is
+ paid works."""
+ cr, uid = self.cr, self.uid
+ po_ids = self.po_obj.search(cr, uid, [])
+ data = [{'data': {
+ 'user_id': uid,
+ 'name': 'ORDER NAME TEST 01',
+ 'pos_session_id': self.session_id,
+ 'lines': [[0, 0, {
+ 'product_id': self.evian_product_id,
+ 'discount': 0,
+ 'price_unit': 1.26,
+ 'qty': 5}]],
+ 'statement_ids': [[0, 0, {
+ 'journal_id': self.cash_journal_id,
+ 'amount': 10,
+ 'name': '2015-01-01 00:00:00',
+ 'statement_id': self.statement_id,
+ }]],
+ 'amount_paid': 10,
+ 'amount_tax': 0,
+ 'amount_return': 3.7,
+ 'amount_total': 6.3},
+ }]
+ self.po_obj.create_from_ui(cr, uid, data)
+ po = self.po_obj.browse(
+ cr, uid, self.po_obj.search(
+ cr, uid, [('id', 'not in', po_ids)])[0])
+ self.assertEqual(
+ po.state, 'paid',
+ "Pay an Order In Front Office must create a paid"
+ " order in back office")
+
+ def test_02_create_draft_order(self):
+ """[Feature] Test if the behaviour when the POS order is
+ unpaid works."""
+ cr, uid = self.cr, self.uid
+ po_ids = self.po_obj.search(cr, uid, [])
+ data = [{'data': {
+ 'user_id': uid,
+ 'name': 'ORDER NAME TEST 02',
+ 'pos_session_id': self.session_id,
+ 'lines': [[0, 0, {
+ 'product_id': self.evian_product_id,
+ 'discount': 0,
+ 'price_unit': 1.26,
+ 'qty': 5}]],
+ 'statement_ids': [[0, 0, {
+ 'journal_id': self.cash_journal_id,
+ 'amount': 2,
+ 'name': '2015-01-01 00:00:00',
+ 'statement_id': self.statement_id,
+ }]],
+ 'amount_paid': 2,
+ 'amount_tax': 0,
+ 'amount_return': -4.3,
+ 'amount_total': 6.3},
+ }]
+ self.po_obj.create_from_ui(cr, uid, data)
+ po = self.po_obj.browse(
+ cr, uid, self.po_obj.search(
+ cr, uid, [('id', 'not in', po_ids)])[0])
+ self.assertEqual(
+ po.state, 'draft',
+ "An unpaid or partial paid Order In Front Office must create a"
+ "draft order in back office.")