Browse Source

[ADD] 'pos_order_load'

pull/9/head
Sylvain Calador 10 years ago
parent
commit
d7db6cc5ec
  1. 1
      pos_order_load/__init__.py
  2. 51
      pos_order_load/__openerp__.py
  3. 42
      pos_order_load/point_of_sale.py
  4. 51
      pos_order_load/static/src/css/pos_order_load.css
  5. 238
      pos_order_load/static/src/js/pos_order_load.js
  6. 68
      pos_order_load/static/src/xml/pos_order_load.xml
  7. 18
      pos_order_load/view/pos_order_load.xml

1
pos_order_load/__init__.py

@ -0,0 +1 @@
import point_of_sale

51
pos_order_load/__openerp__.py

@ -0,0 +1,51 @@
# -*- 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',
'version': '0.1',
'author': 'Akretion',
'category': 'Sales Management',
'depends': [
'base',
'decimal_precision',
'point_of_sale',
'product',
'web',
],
'demo': [],
'website': 'https://www.akretion.com',
'description': """
This module allows to load existing POS order
""",
'data': [
'view/pos_order_load.xml',
],
'qweb': [
'static/src/xml/pos_order_load.xml',
],
'test': [],
'installable': True,
'auto_install': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

42
pos_order_load/point_of_sale.py

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2014 Akretion (<http://www.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'
@api.model
def search_read_orders(self, query):
condition = [('pos_reference', 'ilike', query)]
fields = ['pos_reference', 'partner_id']
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 {
'partner_id': self.partner_id and self.partner_id.id or False,
'orderlines': orderlines
}

51
pos_order_load/static/src/css/pos_order_load.css

@ -0,0 +1,51 @@
.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;
}

238
pos_order_load/static/src/js/pos_order_load.js

@ -0,0 +1,238 @@
/******************************************************************************
* Point Of Sale - Product Template module for Odoo
* Copyright (C) 2014-Today Akretion (http://www.akretion.com)
* @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/>.
*****************************************************************************/
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;
module.LoadButtonWidget = module.PosBaseWidget.extend({
template: 'LoadButtonWidget',
init: function(parent, options){
options = options || {};
this._super(parent, options);
},
start: function() {
var self = this;
this.$el.click(function(){
var ss = self.pos.pos_widget.screen_selector;
ss.set_current_screen('orderlist');
});
},
show: function(){
this.$el.removeClass('oe_hidden');
},
hide: function(){
this.$el.addClass('oe_hidden');
}
});
module.PosWidget = module.PosWidget.extend({
build_widgets: function() {
this._super();
this.orderlist_screen = new module.OrderListScreenWidget(this, {});
this.orderlist_screen.appendTo(this.$('.screens'));
this.orderlist_screen.hide();
this.load_button = new module.LoadButtonWidget(this);
this.load_button.appendTo(this.$('li.orderline.empty'));
this.screen_selector.screen_set['orderlist'] =
this.orderlist_screen;
},
});
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')
);
}
}
});
module.OrderListScreenWidget = module.ScreenWidget.extend({
template: 'OrderListScreenWidget',
show_leftpane: true,
init: function(parent, options){
this._super(parent, options);
},
start: function() {
var self = this;
this._super();
this.$el.find('span.button.back').click(function(){
order = self.pos.get('selectedOrder');
order.set_client(undefined);
order.get('orderLines').reset();
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 ss = self.pos.pos_widget.screen_selector;
ss.set_current_screen('products');
});
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: function(order_id) {
var self = this;
var posOrderModel = new instance.web.Model('pos.order');
return posOrderModel.call('load_order', [order_id])
.then(function (result) {
var order = self.pos.get('selectedOrder');
order.get('orderLines').reset();
var partner = self.pos.db.get_partner_by_id(
result[0].partner_id);
order.set_client(partner || undefined);
var orderlines = result[0].orderlines || [];
for (var i=0, len=orderlines.length; i<len; i++) {
var orderline = orderlines[i];
var product_id = orderline.product_id[0];
var product = self.pos.db.get_product_by_id(product_id);
var options = {
quantity: orderline.qty,
price: orderline.price_unit,
discount: orderline.discount,
}
for (key in orderline) {
if (!key.indexOf('product__')) {
product = self.add_product_attribute(
product, key, orderline
);
}
}
order.addProduct(product, options);
last_orderline = order.getLastOrderline();
last_orderline = jQuery.extend(last_orderline, orderline);
}
}).fail(function (error, event){
if (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
});
}
console.error('Failed to load order:', order_id);
self.pos_widget.screen_selector.show_popup('error',{
message: 'Connection error',
comment: 'Can not execute this action because the POS \
is currently offline',
});
event.preventDefault();
});
},
load_orders: function(query) {
var self = this;
var posOrderModel = new instance.web.Model('pos.order');
return posOrderModel.call('search_read_orders', [query || ''])
.then(function (result) {
self.render_list(result);
}).fail(function (error, event){
if (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
}
);
}
console.error('Failed to load orders:', query);
self.pos_widget.screen_selector.show_popup('error',{
message: 'Connection error',
comment: '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.load_order(parseInt(this.dataset['orderId']));
});
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();
},
});
}

68
pos_order_load/static/src/xml/pos_order_load.xml

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<template>
<t t-name="LoadButtonWidget">
<button class="order-load">Load</button>
</t>
<t t-name="LoadOrderLine">
<tr class="order-line" t-att-data-order-id="order.id">
<td><t t-esc="order.pos_reference"/></td>
<td t-if="order.partner_id"><t t-esc="order.partner_id[1]"/></td>
<td t-if="!order.partner_id"></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>
</tr>
</thead>
<tbody class="order-list-contents">
</tbody>
</table>
</div>
</div>
</section>
</div>
</section>
</div>
</div>
</t>
</template>

18
pos_order_load/view/pos_order_load.xml

@ -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>
Loading…
Cancel
Save