Sylvain LE GAL
9 years ago
10 changed files with 833 additions and 0 deletions
-
38pos_order_load/README.rst
-
2pos_order_load/__init__.py
-
38pos_order_load/__openerp__.py
-
145pos_order_load/i18n/fr.po
-
2pos_order_load/models/__init__.py
-
97pos_order_load/models/pos_order.py
-
54pos_order_load/static/src/css/pos_order_load.css
-
363pos_order_load/static/src/js/pos_order_load.js
-
76pos_order_load/static/src/xml/pos_order_load.xml
-
18pos_order_load/view/pos_order_load.xml
@ -0,0 +1,38 @@ |
|||||
|
POS Order Load and Save |
||||
|
======================= |
||||
|
|
||||
|
This module allows to load existing POS order. |
||||
|
In this version, when the loaded order |
||||
|
is validated in the POS, a new one is created. |
||||
|
|
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues <https://github.com/OCA/pos/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 |
||||
|
`here <https://github.com/OCA/pos/issues/new?body=module:%20pos_order_load%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Sylvain Calador <sylvain.calador@akretion.com> |
||||
|
* Sylvain Le Gal (https://twitter.com/legalsylvain) |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: http://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: http://odoo-community.org |
||||
|
|
||||
|
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. |
||||
|
|
||||
|
To contribute to this module, please visit http://odoo-community.org. |
||||
|
|
@ -0,0 +1,2 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
import models |
@ -0,0 +1,38 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# Copyright (C) 2014-TODAY Akretion (<http://www.akretion.com>). |
||||
|
# Copyright (C) 2014 Sylvain Calador (sylvain.calador@akretion.com). |
||||
|
# |
||||
|
# 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 <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
{ |
||||
|
'name': 'POS Order Load and Save', |
||||
|
'version': '0.2', |
||||
|
'author': 'Akretion,GRAP,Odoo Community Association (OCA)', |
||||
|
'category': 'Point Of Sale', |
||||
|
'depends': [ |
||||
|
'point_of_sale', |
||||
|
], |
||||
|
'website': 'https://www.akretion.com', |
||||
|
'data': [ |
||||
|
'view/pos_order_load.xml', |
||||
|
], |
||||
|
'qweb': [ |
||||
|
'static/src/xml/pos_order_load.xml', |
||||
|
], |
||||
|
} |
@ -0,0 +1,145 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * pos_order_load |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 8.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2015-07-27 17:43+0000\n" |
||||
|
"PO-Revision-Date: 2015-07-27 17:43+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_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:291 |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:317 |
||||
|
#, python-format |
||||
|
msgid "Can not execute this action because the POS is currently offline" |
||||
|
msgstr "Impossible d'exécuter cette action car le Point de vente est actuellement hors ligne" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:182 |
||||
|
#, python-format |
||||
|
msgid "Can not load the Selected Order because the POS is currently offline" |
||||
|
msgstr "Impossible de charger la vente sélectionnée car le Point de vente est actuellement hors ligne" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/xml/pos_order_load.xml:28 |
||||
|
#, python-format |
||||
|
msgid "Cancel" |
||||
|
msgstr "Annuler" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:181 |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:290 |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:316 |
||||
|
#, python-format |
||||
|
msgid "Connection error" |
||||
|
msgstr "Erreur de connection" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/xml/pos_order_load.xml:60 |
||||
|
#, python-format |
||||
|
msgid "Customer" |
||||
|
msgstr "Client" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/xml/pos_order_load.xml:5 |
||||
|
#, python-format |
||||
|
msgid "Load Draft Order" |
||||
|
msgstr "Charger la vente en brouillon" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/xml/pos_order_load.xml:59 |
||||
|
#, python-format |
||||
|
msgid "Order" |
||||
|
msgstr "Vente" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#: model:ir.model,name:pos_order_load.model_pos_order |
||||
|
msgid "Point of Sale" |
||||
|
msgstr "Point de Vente" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/xml/pos_order_load.xml:10 |
||||
|
#, python-format |
||||
|
msgid "Save Current Order" |
||||
|
msgstr "Sauvegarder la vente" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:71 |
||||
|
#, python-format |
||||
|
msgid "Save The current Order ?" |
||||
|
msgstr "Sauvegarder la vente en cours ?" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/xml/pos_order_load.xml:36 |
||||
|
#, python-format |
||||
|
msgid "Search Orders" |
||||
|
msgstr "Chercher des ventes" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/xml/pos_order_load.xml:40 |
||||
|
#, python-format |
||||
|
msgid "Select Order" |
||||
|
msgstr "Choisir une vente" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:72 |
||||
|
#, python-format |
||||
|
msgid "This operation will save the current order in a draft state. You'll have to mark it as paid after." |
||||
|
msgstr "Cette opération va sauvegarder la vente en cours à l'état de brouillon. Vous devrez la marquer comme payée ultérieurement" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/xml/pos_order_load.xml:61 |
||||
|
#, python-format |
||||
|
msgid "Total Amount" |
||||
|
msgstr "Montant Total" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:269 |
||||
|
#, python-format |
||||
|
msgid "Unable to load some order lines because the products are not available in the POS cache.\n" |
||||
|
"\n" |
||||
|
"Please check that lines :\n" |
||||
|
"\n" |
||||
|
" * " |
||||
|
msgstr "Impossible de charger certaines lignes de ventes parce que les produits ne sont pas disponibles dans le cache du point de vente.\n" |
||||
|
"\n" |
||||
|
"Veuillez vérifier ces lignes :\n" |
||||
|
"\n" |
||||
|
" * " |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/js/pos_order_load.js:268 |
||||
|
#, python-format |
||||
|
msgid "Unknown Products" |
||||
|
msgstr "Produits Iconnu" |
||||
|
|
||||
|
#. module: pos_order_load |
||||
|
#. openerp-web |
||||
|
#: code:addons/pos_order_load/static/src/xml/pos_order_load.xml:32 |
||||
|
#, python-format |
||||
|
msgid "Validate" |
||||
|
msgstr "Valider" |
||||
|
|
@ -0,0 +1,2 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
import pos_order |
@ -0,0 +1,97 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# Copyright (C) 2014 Akretion (<http://www.akretion.com>). |
||||
|
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) |
||||
|
# @author Sylvain Calador (sylvain.calador@akretion.com). |
||||
|
# |
||||
|
# 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 <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
|
||||
|
from openerp import models, api |
||||
|
|
||||
|
|
||||
|
class PosOrder(models.Model): |
||||
|
_inherit = 'pos.order' |
||||
|
|
||||
|
# Overload Section |
||||
|
@api.model |
||||
|
def _order_fields(self, ui_order): |
||||
|
res = super(PosOrder, self)._order_fields(ui_order) |
||||
|
if 'order_id' in ui_order: |
||||
|
res['order_id'] = ui_order['order_id'] |
||||
|
return res |
||||
|
|
||||
|
@api.model |
||||
|
def create_from_ui(self, orders): |
||||
|
""" |
||||
|
Remove from the 'orders' list all orders where amount_return is < 0 |
||||
|
(because that means they are not paid, but just in draft state). |
||||
|
* call a specific function for the draft orders list |
||||
|
* call the parent create_from_ui() for the remaining orders""" |
||||
|
draft_orders = [] |
||||
|
for tmp_order in orders: |
||||
|
if tmp_order['data']['amount_return'] < 0\ |
||||
|
and abs(tmp_order['data']['amount_return']) > 0.000001: |
||||
|
draft_orders.append(tmp_order) |
||||
|
orders.remove(tmp_order) |
||||
|
|
||||
|
# Save Draft Orders |
||||
|
self._create_draft_order_from_ui(draft_orders) |
||||
|
|
||||
|
# Save Paid Orders |
||||
|
return super(PosOrder, self).create_from_ui(orders) |
||||
|
|
||||
|
|
||||
|
# Custom Section |
||||
|
@api.model |
||||
|
def search_read_orders(self, query): |
||||
|
condition = [ |
||||
|
('state', '=', 'draft'), |
||||
|
('statement_ids', '=', False), |
||||
|
'|', |
||||
|
('name', 'ilike', query), |
||||
|
('partner_id', 'ilike', query) |
||||
|
] |
||||
|
fields = ['name', 'partner_id', 'amount_total'] |
||||
|
return self.search_read(condition, fields, limit=10) |
||||
|
|
||||
|
@api.one |
||||
|
def load_order(self): |
||||
|
condition = [('order_id', '=', self.id)] |
||||
|
fields = ['product_id', 'price_unit', 'qty', 'discount'] |
||||
|
orderlines = self.lines.search_read(condition, fields) |
||||
|
return { |
||||
|
'id': self.id, |
||||
|
'name': self.pos_reference, |
||||
|
'partner_id': self.partner_id and self.partner_id.id or False, |
||||
|
'orderlines': orderlines |
||||
|
} |
||||
|
|
||||
|
@api.model |
||||
|
def _create_draft_order_from_ui(self, orders): |
||||
|
for order_tmp in orders: |
||||
|
order_data = order_tmp['data'] |
||||
|
statements_data = order_data['statement_ids'] |
||||
|
order_data.pop('statement_ids') |
||||
|
|
||||
|
# create Order |
||||
|
order = self.create(self._order_fields(order_data)) |
||||
|
|
||||
|
# Create payment |
||||
|
for statement_data in statements_data: |
||||
|
self.add_payment( |
||||
|
order.id, self._payment_fields(statement_data[2])) |
@ -0,0 +1,54 @@ |
|||||
|
.screen .top-content .button.validate { |
||||
|
left: 0px; |
||||
|
margin-left: 150px; |
||||
|
} |
||||
|
|
||||
|
.pos .orderlist-screen .order-list{ |
||||
|
font-size: 16px; |
||||
|
width: 100%; |
||||
|
line-height: 40px; |
||||
|
} |
||||
|
.pos .orderlist-screen .order-list th, |
||||
|
.pos .orderlist-screen .order-list td { |
||||
|
padding: 0px 8px; |
||||
|
} |
||||
|
.pos .orderlist-screen .order-list tr{ |
||||
|
transition: all 150ms linear; |
||||
|
background: rgb(230,230,230); |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.pos .orderlist-screen .order-list thead > tr, |
||||
|
.pos .orderlist-screen .order-list tr:nth-child(even) { |
||||
|
background: rgb(247,247,247); |
||||
|
} |
||||
|
.pos .orderlist-screen .order-list tr.highlight{ |
||||
|
transition: all 150ms linear; |
||||
|
background: rgb(110,200,155) !important; |
||||
|
color: white; |
||||
|
} |
||||
|
.pos .orderlist-screen .order-list tr.lowlight{ |
||||
|
transition: all 150ms linear; |
||||
|
background: rgb(216, 238, 227); |
||||
|
} |
||||
|
.pos .orderlist-screen .order-list tr.lowlight:nth-child(even){ |
||||
|
transition: all 150ms linear; |
||||
|
background: rgb(227, 246, 237); |
||||
|
} |
||||
|
.pos .orderlist-screen .order-details{ |
||||
|
padding: 16px; |
||||
|
border-bottom: solid 5px rgb(110,200,155); |
||||
|
} |
||||
|
|
||||
|
.pos .orderlist-screen .searchbox{ |
||||
|
right: auto; |
||||
|
margin-left: -90px; |
||||
|
margin-top:8px; |
||||
|
left: 50%; |
||||
|
} |
||||
|
.pos .orderlist-screen .searchbox input{ |
||||
|
width: 120px; |
||||
|
} |
||||
|
|
||||
|
.pos .order-line .total { |
||||
|
text-align: right; |
||||
|
} |
@ -0,0 +1,363 @@ |
|||||
|
/****************************************************************************** |
||||
|
* Point Of Sale - Product Template module for Odoo |
||||
|
* Copyright (C) 2014-Today Akretion (http://www.akretion.com)
|
||||
|
* @author Sylvain Calador (sylvain.calador@akretion.com) |
||||
|
* @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 <http://www.gnu.org/licenses/>.
|
||||
|
*****************************************************************************/ |
||||
|
|
||||
|
openerp.pos_order_load = function(instance, local) { |
||||
|
module = instance.point_of_sale; |
||||
|
var QWeb = instance.web.qweb; |
||||
|
var _t = instance.web._t; |
||||
|
var round_pr = instance.web.round_precision; |
||||
|
|
||||
|
/************************************************************************* |
||||
|
Extend Model Order: |
||||
|
* Add getter and setter function for field 'order_id'; |
||||
|
*/ |
||||
|
module.Order = module.Order.extend({ |
||||
|
|
||||
|
set_order_id: function(id) { |
||||
|
this.set({ |
||||
|
order_id: id, |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
get_order_id: function() { |
||||
|
return this.get('order_id'); |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
/************************************************************************* |
||||
|
New Widget LoadButtonWidget: |
||||
|
* On click, display a new screen to select draft orders; |
||||
|
*/ |
||||
|
module.LoadButtonWidget = module.PosBaseWidget.extend({ |
||||
|
template: 'LoadButtonWidget', |
||||
|
|
||||
|
renderElement: function() { |
||||
|
var self = this; |
||||
|
this._super(); |
||||
|
this.$el.click(function(){ |
||||
|
var ss = self.pos.pos_widget.screen_selector; |
||||
|
ss.set_current_screen('orderlist'); |
||||
|
}); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
/************************************************************************* |
||||
|
New Widget SaveButtonWidget: |
||||
|
* On click, backup the current draft order; |
||||
|
*/ |
||||
|
module.SaveButtonWidget = module.PosBaseWidget.extend({ |
||||
|
template: 'SaveButtonWidget', |
||||
|
|
||||
|
renderElement: function() { |
||||
|
var self = this; |
||||
|
this._super(); |
||||
|
this.$el.click(function(){ |
||||
|
self.pos.pos_widget.screen_selector.show_popup('confirm',{ |
||||
|
message: _t('Save The current Order ?'), |
||||
|
comment: _t('This operation will save the current order in a draft state. You\'ll have to mark it as paid after.'), |
||||
|
confirm: function(){ |
||||
|
var currentOrder = this.pos.get('selectedOrder'); |
||||
|
this.pos.push_order(currentOrder); |
||||
|
self.pos.get('selectedOrder').destroy(); |
||||
|
}, |
||||
|
}); |
||||
|
}); |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
/************************************************************************* |
||||
|
Extend PosWidget: |
||||
|
* Create new screen; |
||||
|
* Add load and save button; |
||||
|
*/ |
||||
|
module.PosWidget = module.PosWidget.extend({ |
||||
|
build_widgets: function() { |
||||
|
this._super(); |
||||
|
|
||||
|
// New Screen to select Draft Orders
|
||||
|
this.orderlist_screen = new module.OrderListScreenWidget(this, {}); |
||||
|
this.orderlist_screen.appendTo(this.$('.screens')); |
||||
|
this.orderlist_screen.hide(); |
||||
|
|
||||
|
this.screen_selector.screen_set['orderlist'] = |
||||
|
this.orderlist_screen; |
||||
|
|
||||
|
// Add buttons
|
||||
|
this.load_button = new module.LoadButtonWidget(this,{}); |
||||
|
this.load_button.appendTo(this.pos_widget.$('li.orderline.empty')); |
||||
|
|
||||
|
this.save_button = new module.SaveButtonWidget(this,{}); |
||||
|
|
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
/************************************************************************* |
||||
|
Extend OrderWidget: |
||||
|
*/ |
||||
|
module.OrderWidget = module.OrderWidget.extend({ |
||||
|
renderElement: function(scrollbottom){ |
||||
|
this._super(scrollbottom); |
||||
|
if (this.pos_widget.load_button) { |
||||
|
this.pos_widget.load_button.appendTo( |
||||
|
this.pos_widget.$('li.orderline.empty') |
||||
|
); |
||||
|
} |
||||
|
if (this.pos_widget.save_button && (this.pos.get('selectedOrder').get('orderLines').length > 0)) { |
||||
|
this.pos_widget.save_button.appendTo( |
||||
|
this.pos_widget.$('div.summary') |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
/************************************************************************* |
||||
|
New ScreenWidget OrderListScreenWidget: |
||||
|
* On show, display all draft orders; |
||||
|
* on click on an order, display the content; |
||||
|
* on click on 'validate', allow to use this POS Order; |
||||
|
* on click on 'cancel', display the preview screen; |
||||
|
*/ |
||||
|
module.OrderListScreenWidget = module.ScreenWidget.extend({ |
||||
|
template: 'OrderListScreenWidget', |
||||
|
show_leftpane: true, |
||||
|
model: 'pos.order', |
||||
|
current_order_id: 0, |
||||
|
|
||||
|
init: function(parent, options){ |
||||
|
this._super(parent, options); |
||||
|
}, |
||||
|
|
||||
|
reset_order: function(order) { |
||||
|
order.set_client(undefined); |
||||
|
order.set_order_id(undefined); |
||||
|
order.get('orderLines').reset(); |
||||
|
return order; |
||||
|
}, |
||||
|
|
||||
|
start: function() { |
||||
|
var self = this; |
||||
|
this._super(); |
||||
|
this.$el.find('span.button.back').click(function(){ |
||||
|
order = self.pos.get('selectedOrder'); |
||||
|
self.reset_order(order); |
||||
|
self.pos_widget.order_widget.change_selected_order(); |
||||
|
var ss = self.pos.pos_widget.screen_selector; |
||||
|
ss.set_current_screen('products'); |
||||
|
}); |
||||
|
this.$el.find('span.button.validate').click(function(){ |
||||
|
var orderModel = new instance.web.Model('pos.order'); |
||||
|
return orderModel.call('unlink', [[self.current_order_id]]) |
||||
|
.then(function (result) { |
||||
|
var ss = self.pos.pos_widget.screen_selector; |
||||
|
ss.set_current_screen('products'); |
||||
|
}).fail(function (error, event){ |
||||
|
if (parseInt(error.code) === 200) { |
||||
|
// Business Logic Error, not a connection problem
|
||||
|
self.pos_widget.screen_selector.show_popup( |
||||
|
'error-traceback', { |
||||
|
message: error.data.message, |
||||
|
comment: error.data.debug |
||||
|
}); |
||||
|
} |
||||
|
else{ |
||||
|
self.pos_widget.screen_selector.show_popup('error',{ |
||||
|
message: _t('Connection error'), |
||||
|
comment: _t('Can not load the Selected Order because the POS is currently offline'), |
||||
|
}); |
||||
|
} |
||||
|
event.preventDefault(); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
var search_timeout = null; |
||||
|
|
||||
|
this.$('.searchbox input').on('keyup',function(event){ |
||||
|
clearTimeout(search_timeout); |
||||
|
|
||||
|
var query = this.value; |
||||
|
|
||||
|
search_timeout = setTimeout(function(){ |
||||
|
self.perform_search(query); |
||||
|
},70); |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
this.$('.searchbox .search-clear').click(function(){ |
||||
|
self.clear_search(); |
||||
|
}); |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
// to override if necessary
|
||||
|
add_product_attribute: function(product, key, orderline){ |
||||
|
return product; |
||||
|
}, |
||||
|
|
||||
|
load_order_fields: function(order, fields) { |
||||
|
order.set_order_id(fields.id); |
||||
|
var partner = this.pos.db.get_partner_by_id( |
||||
|
fields.partner_id); |
||||
|
order.set_client(partner || undefined); |
||||
|
return order; |
||||
|
}, |
||||
|
|
||||
|
prepare_orderline_options: function(orderline) { |
||||
|
return { |
||||
|
quantity: orderline.qty, |
||||
|
price: orderline.price_unit, |
||||
|
discount: orderline.discount, |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
load_order: function(order_id) { |
||||
|
var self = this; |
||||
|
var orderModel = new instance.web.Model(this.model); |
||||
|
return orderModel.call('load_order', [order_id]) |
||||
|
.then(function (result) { |
||||
|
var order = self.pos.get('selectedOrder'); |
||||
|
var result = result[0]; |
||||
|
order = self.load_order_fields(order, result); |
||||
|
order.get('orderLines').reset(); |
||||
|
var orderlines = result.orderlines || []; |
||||
|
var unknown_products = []; |
||||
|
for (var i=0, len=orderlines.length; i<len; i++) { |
||||
|
var orderline = orderlines[i]; |
||||
|
var product_id = orderline.product_id[0]; |
||||
|
var product_name = orderline.product_id[1]; |
||||
|
var product = self.pos.db.get_product_by_id(product_id); |
||||
|
if (_.isUndefined(product)) { |
||||
|
unknown_products.push(product_name); |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
for (key in orderline) { |
||||
|
if (!key.indexOf('product__')) { |
||||
|
product = self.add_product_attribute( |
||||
|
product, key, orderline |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
order.addProduct(product, |
||||
|
self.prepare_orderline_options(orderline) |
||||
|
); |
||||
|
last_orderline = order.getLastOrderline(); |
||||
|
last_orderline = jQuery.extend(last_orderline, orderline); |
||||
|
} |
||||
|
// Forbid POS Order loading if some products are unknown
|
||||
|
if (unknown_products.length > 0){ |
||||
|
self.pos_widget.screen_selector.show_popup( |
||||
|
'error-traceback', { |
||||
|
message: _t('Unknown Products'), |
||||
|
comment: _t('Unable to load some order lines because the ' + |
||||
|
'products are not available in the POS cache.\n\n' + |
||||
|
'Please check that lines :\n\n * ') + unknown_products.join("; \n *") |
||||
|
}); |
||||
|
self.$el.find('span.button.validate').hide(); |
||||
|
} |
||||
|
else{ |
||||
|
self.$el.find('span.button.validate').show(); |
||||
|
} |
||||
|
|
||||
|
}).fail(function (error, event){ |
||||
|
if (parseInt(error.code) === 200) { |
||||
|
// Business Logic Error, not a connection problem
|
||||
|
self.pos_widget.screen_selector.show_popup( |
||||
|
'error-traceback', { |
||||
|
message: error.data.message, |
||||
|
comment: error.data.debug |
||||
|
}); |
||||
|
} |
||||
|
else{ |
||||
|
self.pos_widget.screen_selector.show_popup('error',{ |
||||
|
message: _t('Connection error'), |
||||
|
comment: _t('Can not execute this action because the POS is currently offline'), |
||||
|
}); |
||||
|
} |
||||
|
event.preventDefault(); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
load_orders: function(query) { |
||||
|
var self = this; |
||||
|
var orderModel = new instance.web.Model(this.model); |
||||
|
return orderModel.call('search_read_orders', [query || '']) |
||||
|
.then(function (result) { |
||||
|
self.render_list(result); |
||||
|
}).fail(function (error, event){ |
||||
|
if (parseInt(error.code) === 200) { |
||||
|
// Business Logic Error, not a connection problem
|
||||
|
self.pos_widget.screen_selector.show_popup( |
||||
|
'error-traceback', { |
||||
|
message: error.data.message, |
||||
|
comment: error.data.debug |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
else{ |
||||
|
self.pos_widget.screen_selector.show_popup('error',{ |
||||
|
message: _t('Connection error'), |
||||
|
comment: _t('Can not execute this action because the POS is currently offline'), |
||||
|
}); |
||||
|
} |
||||
|
event.preventDefault(); |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
show: function() { |
||||
|
this._super(); |
||||
|
var ss = this.pos.pos_widget.screen_selector; |
||||
|
if (ss.get_current_screen() == 'orderlist') { |
||||
|
this.load_orders(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
render_list: function(orders){ |
||||
|
var self = this; |
||||
|
var contents = this.$el[0].querySelector('.order-list-contents'); |
||||
|
contents.innerHTML = ""; |
||||
|
for (var i = 0, len = orders.length; i < len; i++){ |
||||
|
var order = orders[i]; |
||||
|
var orderline_html = QWeb.render('LoadOrderLine', |
||||
|
{widget: this, order:orders[i]}); |
||||
|
var orderline = document.createElement('tbody'); |
||||
|
orderline.innerHTML = orderline_html; |
||||
|
orderline = orderline.childNodes[1]; |
||||
|
orderline.addEventListener('click', function() { |
||||
|
self.current_order_id = parseInt(this.dataset['orderId']); |
||||
|
self.load_order(self.current_order_id); |
||||
|
}); |
||||
|
contents.appendChild(orderline); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
perform_search: function(query){ |
||||
|
this.load_orders(query) |
||||
|
}, |
||||
|
|
||||
|
clear_search: function(){ |
||||
|
this.load_orders(); |
||||
|
this.$('.searchbox input')[0].value = ''; |
||||
|
this.$('.searchbox input').focus(); |
||||
|
}, |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
} |
@ -0,0 +1,76 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<template> |
||||
|
|
||||
|
<t t-name="LoadButtonWidget"> |
||||
|
<button class="order-load">Load Draft Order</button> |
||||
|
</t> |
||||
|
|
||||
|
<t t-name="SaveButtonWidget"> |
||||
|
<li class="orderline"> |
||||
|
<button class="order-save">Save Current Order</button> |
||||
|
</li> |
||||
|
</t> |
||||
|
|
||||
|
<t t-name="LoadOrderLine"> |
||||
|
<tr class="order-line" t-att-data-order-id="order.id"> |
||||
|
<td><t t-esc="order.name"/></td> |
||||
|
<td t-if="order.partner_id"><t t-esc="order.partner_id[1]"/></td> |
||||
|
<td t-if="!order.partner_id"></td> |
||||
|
<td class="total"><t t-esc="widget.format_currency(order.amount_total)"/></td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
|
||||
|
<t t-name="OrderListScreenWidget"> |
||||
|
<div class="orderlist-screen screen"> |
||||
|
<div class="screen-content"> |
||||
|
<section class="top-content"> |
||||
|
<span class="button back"> |
||||
|
<i class="fa fa-angle-double-left"></i> |
||||
|
Cancel |
||||
|
</span> |
||||
|
<span class="button validate"> |
||||
|
<i class="fa fa-angle-double-left"></i> |
||||
|
Validate |
||||
|
</span> |
||||
|
<span class="searchbox"> |
||||
|
<input placeholder="Search Orders" /> |
||||
|
<span class="search-clear"></span> |
||||
|
</span> |
||||
|
<span class="searchbox"></span> |
||||
|
<span class="button next oe_hidden highlight"> |
||||
|
Select Order |
||||
|
<i class="fa fa-angle-double-right"></i> |
||||
|
</span> |
||||
|
</section> |
||||
|
<section class="full-content"> |
||||
|
<div class="window"> |
||||
|
<section class="subwindow collapsed"> |
||||
|
<div class="subwindow-container"> |
||||
|
<div class="subwindow-container-fix order-details-contents"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<section class="subwindow"> |
||||
|
<div class="subwindow-container"> |
||||
|
<div class="subwindow-container-fix touch-scrollable scrollable-y"> |
||||
|
<table class="order-list"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th>Order</th> |
||||
|
<th>Customer</th> |
||||
|
<th>Total Amount</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody class="order-list-contents"> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
</div> |
||||
|
</section> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
|
||||
|
</template> |
@ -0,0 +1,18 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- vim:fdn=3: |
||||
|
--> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<template id="assets_backend" name="pos_order_load assets" inherit_id="web.assets_backend"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<script type="text/javascript" src="/pos_order_load/static/src/js/pos_order_load.js"></script> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
<template id="index_pos_order_load" name="POS Index Order Load" inherit_id="point_of_sale.index"> |
||||
|
<xpath expr="//head" position="inside"> |
||||
|
<link rel="stylesheet" href="/pos_order_load/static/src/css/pos_order_load.css"/> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</data> |
||||
|
</openerp> |
||||
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue