Merge lp:~sylvain-legal/openerp-pos/7.0_pos_select_customer into lp:openerp-pos

Proposed by Sylvain LE GAL (GRAP)
Status: Needs review
Proposed branch: lp:~sylvain-legal/openerp-pos/7.0_pos_select_customer
Merge into: lp:openerp-pos
Prerequisite: lp:~sylvain-legal/openerp-pos/7.0_pos_second_header
Diff against target: 791 lines (+752/-0)
6 files modified
pos_select_customer/__init__.py (+22/-0)
pos_select_customer/__openerp__.py (+76/-0)
pos_select_customer/i18n/fr.po (+74/-0)
pos_select_customer/static/src/css/psc.css (+168/-0)
pos_select_customer/static/src/js/psc.js (+309/-0)
pos_select_customer/static/src/xml/psc.xml (+103/-0)
To merge this branch: bzr merge lp:~sylvain-legal/openerp-pos/7.0_pos_select_customer
Reviewer Review Type Date Requested Status
Cristian Salamea (community) Approve
Pedro Manuel Baeza code review and test Approve
Leonardo Pistone Needs Fixing
Review via email: mp+228826@code.launchpad.net

Commit message

[ADD] Add new module to select customers in Front End Point Of Sale

Description of the change

Add a module to select a customer in point of sale (front end view) module.
This module load all customers when POS is started (as product behaviour).

Nota:
- Flake8: OK.
- This module doesn't cover for the time being some extra-feature. (pricelist, invoicing). Plz read __openerp__.py manifest for more information;

Thanks for your reviews.

To post a comment you must log in.
Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

Hi, Sylvain, I have tried your module, and it works good, but it has the same flaw as the 8.0 version: when you select a customer with a different pricelist, prices are not adapted.

Can you modify this?

Regards.

review: Needs Fixing (code review and test)
Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

Hi. Yes this is notified in the manifest __openerp__.py file. ("Non covered feature" section). It would very interesting but it is a big work and i didn't planned to work on that immediately.
I dont understand the need fixing. It's not a bug. It is just a non covered case. (As many thinks in openerp PoS
)
Regards.

Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

Well, I see this as a blocking feature, because you will expect that each customer has its pricelist applied, that's why my needs fixing. It's very difficult to do?

Regards.

Revision history for this message
Leonardo Pistone (lepistone) wrote :

In __openerp__.py there are some """'s that should be removed.

Thanks

review: Needs Fixing
Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

Hi pedro,

Yes, it is quite a big job to realize. We have to load all the pricelist behaviour and write the algorithm in Javascript. Pricelist is a big algorithm depending of quantity, date and other pricelist recursively. I think this is why it's not managed in Odoo by default.

For that, I wrote 'pos_backup_draft_orders' and 'fix_pos_change_pricelist' to realize that.
but of course it's not optimized.

Regards.

Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

Maybe this feature doesnt' have to be offline. We can see if POS is online, and get prices in this case, and on contrary, take standar price. What do you think?

Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

Hi Pedro,

And about the online requirement, I'm not agree with that.
My PoV is:

Point Of Sale - Front-End is a module that HAS TO work OFFLINE. If not it's not possible to use it.
Try to say to a customer: Hey ! I have a software but you can't sell if you have a problem with your Internet Provider!

So my module realize the selection of the customer, and when Odoo will compute the correct price, depending of pricelist, it will works in all case.
For me it's not a lake of that module, it is a bug in Odoo.
Ref:
https://github.com/odoo/odoo/issues/2297#issuecomment-55262887

What do you think ?

Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

Hi, I'm not saying to forbid the use offline, but to use online capabilities to bring pricelists. If that not possible (you're offline), you can warn user that priceslists are ignored, but continue working as previously.

You can check also this comment in an issue that points that Odoo is not going to do this in a short term (nor v8 and probably not v9):

https://github.com/odoo/odoo/issues/2297#issuecomment-55262887

Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

Fully agree with you!
But out of the scope of this module.
If you use this module, pricelist will not work; OK.
But if you dont use this module, pricelist will not work either!
The defaultprice list doesn't work as said in my link (and in your link too. ;-) )

My PoV: It's not a problem of pos_select_customer.

So:
Solution 1: Odoo implements pricelist computation (offline / online) in the trunk;
Solution 2: OCA developps an extra module to compute pricelist (offline / online) in a POS module;

Do you agree ?

Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

Yeah, let's continue including a warning about pricelists in this module, and see if we can organize an OCA code sprint for POS pricelists. I see your post in the mailing list, but I can't send any mail... it returns me an error.

review: Approve (code review and test)
Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

@lpistone:

I Just saw your comment. I'm not sure to understand why there is extra """. Are you talking about L79 of the Merge proposal for exemple ? If yes:

print ("""aaa"""
""" bbb""")
>> aaa bbb

print (""" aaa
 bbb""")
>> aaa
>> bbb

In that case, the first behaviour is wanted because the sentence is not finished.

Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

I have made a comment inline.

Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

As said to @lpistone, this will change the display of the description. Doesn't it ?

Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

That's true, but for module description it's not important, because it's parsed by an RST compiler, which interprets correctly this line breaks and join them in a correct way. In dashes, it's important to indent second line a bit more for the compiler recognise it as a continuation line.

Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

How. Thank you for that information.
I did'nt know how RST compiler works.
I'll change that.
Regards.

Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

Hi again !

I did the changes, writing the first part instead of the second part. The result is not the same in the part 1. That breaks the display of the description. Are you sure about what you said ? Please see the screenshot in the links.
Regards.

(TEST 1) -> http://hpics.li/d8c3c94
Possible improvements and fix:
------------------------------
    * This module displays all the customers. That can be long to display
 if there are a lot of customers in database; Display only 80 could be a
 solution;
    * Images of customers are loaded each time; Similar behaviour as
 products image management (with cache) could be developped;

(TEST 2) -> http://hpics.li/b9043e0
Possible improvements and fix:
------------------------------
    * This module displays all the customers. That can be long to display"""
    """ if there are a lot of customers in database; Display only 80"""
    """ could be a solution;
    * Images of customers are loaded each time; Similar behaviour as"""
    """ products image management (with cache) could be developped;

Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

You have missed the spoken indentation. Try this:

Possible improvements and fix:
------------------------------
    * This module displays all the customers. That can be long to display
      if there are a lot of customers in database; Display only 80 could be a
      solution;
    * Images of customers are loaded each time; Similar behaviour as
      products image management (with cache) could be developped;

2. By Sylvain LE GAL (GRAP)

[FIX] remove useless quote in __openerp__ description.

Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

OK !
Done.
thank you for your patience.

Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

Hi Leonardo,

I commit the fix about comment. Can you update your status if all is ok for you now ?

Regards.

Revision history for this message
Cristian Salamea (ovnicraft) wrote :

Any news from this ?
I read the log and code, aparently bug is fixed.

review: Approve
Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

Project has moved into github.
https://github.com/odoo-pos/odoo-pos/tree/7.0

review: Disapprove (obsolete)

Unmerged revisions

2. By Sylvain LE GAL (GRAP)

[FIX] remove useless quote in __openerp__ description.

1. By Sylvain LE GAL (GRAP)

[ADD] Add new module to select customers in Front End Point Of Sale

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'pos_select_customer'
2=== added file 'pos_select_customer/__init__.py'
3--- pos_select_customer/__init__.py 1970-01-01 00:00:00 +0000
4+++ pos_select_customer/__init__.py 2014-09-12 08:56:09 +0000
5@@ -0,0 +1,22 @@
6+# -*- encoding: utf-8 -*-
7+##############################################################################
8+#
9+# Point Of Sale - Select Customer module for OpenERP
10+# Copyright (C) 2013-2014 GRAP (http://www.grap.coop)
11+# @author Julien WESTE
12+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
13+#
14+# This program is free software: you can redistribute it and/or modify
15+# it under the terms of the GNU Affero General Public License as
16+# published by the Free Software Foundation, either version 3 of the
17+# License, or (at your option) any later version.
18+#
19+# This program is distributed in the hope that it will be useful,
20+# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+# GNU Affero General Public License for more details.
23+#
24+# You should have received a copy of the GNU Affero General Public License
25+# along with this program. If not, see <http://www.gnu.org/licenses/>.
26+#
27+##############################################################################
28
29=== added file 'pos_select_customer/__openerp__.py'
30--- pos_select_customer/__openerp__.py 1970-01-01 00:00:00 +0000
31+++ pos_select_customer/__openerp__.py 2014-09-12 08:56:09 +0000
32@@ -0,0 +1,76 @@
33+# -*- encoding: utf-8 -*-
34+##############################################################################
35+#
36+# Point Of Sale - Select Customer module for OpenERP
37+# Copyright (C) 2014 GRAP (http://www.grap.coop)
38+# @author Julien WESTE
39+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
40+#
41+# This program is free software: you can redistribute it and/or modify
42+# it under the terms of the GNU Affero General Public License as
43+# published by the Free Software Foundation, either version 3 of the
44+# License, or (at your option) any later version.
45+#
46+# This program is distributed in the hope that it will be useful,
47+# but WITHOUT ANY WARRANTY; without even the implied warranty of
48+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49+# GNU Affero General Public License for more details.
50+#
51+# You should have received a copy of the GNU Affero General Public License
52+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53+#
54+##############################################################################
55+
56+{
57+ 'name': 'Point Of Sale - Select Customers',
58+ 'summary': 'Allow users to select a customer in Front End Point Of Sale',
59+ 'version': '0.1',
60+ 'category': 'sale',
61+ 'description': """
62+Allow users to select a customer in Front End Point Of Sale
63+===========================================================
64+
65+Functionality:
66+--------------
67+ * Allow user to set a customer to a pos order in front end views;
68+
69+Possible improvements and fix:
70+------------------------------
71+ * This module displays all the customers. That can be long to display
72+ if there are a lot of customers in database; Display only 80 could be a
73+ solution;
74+ * Images of customers are loaded each time; Similar behaviour as
75+ products image management (with cache) could be developped;
76+
77+NON Covered features:
78+---------------------
79+ * Possibility to create customers in front end views;
80+ * Possibility to change price if customer has a list price different as
81+ the default list price; (Big stuff);
82+ * Possibility to see if the partner has not the default price list;
83+ * Possibility to invoice in front-end views;
84+
85+Copyright, Authors and Licence:
86+-------------------------------
87+ * Copyright: 2014, GRAP: Groupement Régional Alimentaire de Proximité;
88+ * Author:
89+ * Julien WESTE;
90+ * Sylvain LE GAL (https://twitter.com/legalsylvain);
91+ * Licence: AGPL-3 (http://www.gnu.org/licenses/);""",
92+ 'author': 'GRAP',
93+ 'website': 'http://www.grap.coop',
94+ 'license': 'AGPL-3',
95+ 'depends': [
96+ 'point_of_sale',
97+ 'pos_second_header',
98+ ],
99+ 'qweb': [
100+ 'static/src/xml/psc.xml',
101+ ],
102+ 'js': [
103+ 'static/src/js/psc.js',
104+ ],
105+ 'css': [
106+ 'static/src/css/psc.css',
107+ ],
108+}
109
110=== added directory 'pos_select_customer/i18n'
111=== added file 'pos_select_customer/i18n/fr.po'
112--- pos_select_customer/i18n/fr.po 1970-01-01 00:00:00 +0000
113+++ pos_select_customer/i18n/fr.po 2014-09-12 08:56:09 +0000
114@@ -0,0 +1,74 @@
115+# -*- encoding: utf-8 -*-
116+##############################################################################
117+#
118+# Point Of Sale - Select Customer module for OpenERP
119+# Copyright (C) 2013-2014 GRAP (http://www.grap.coop)
120+# @author Julien WESTE
121+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
122+#
123+# This program is free software: you can redistribute it and/or modify
124+# it under the terms of the GNU Affero General Public License as
125+# published by the Free Software Foundation, either version 3 of the
126+# License, or (at your option) any later version.
127+#
128+# This program is distributed in the hope that it will be useful,
129+# but WITHOUT ANY WARRANTY; without even the implied warranty of
130+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
131+# GNU Affero General Public License for more details.
132+#
133+# You should have received a copy of the GNU Affero General Public License
134+# along with this program. If not, see <http://www.gnu.org/licenses/>.
135+#
136+##############################################################################
137+# Translation of OpenERP Server.
138+# This file contains the translation of the following modules:
139+# * pos_select_customer
140+#
141+msgid ""
142+msgstr ""
143+"Project-Id-Version: OpenERP Server 7.0\n"
144+"Report-Msgid-Bugs-To: \n"
145+"POT-Creation-Date: 2014-04-16 16:31+0000\n"
146+"PO-Revision-Date: 2014-04-16 16:31+0000\n"
147+"Last-Translator: <>\n"
148+"Language-Team: \n"
149+"MIME-Version: 1.0\n"
150+"Content-Type: text/plain; charset=UTF-8\n"
151+"Content-Transfer-Encoding: \n"
152+"Plural-Forms: \n"
153+
154+#. module: pos_select_customer
155+#. openerp-web
156+#: code:addons/pos_select_customer/static/src/xml/psc.xml:48
157+#, python-format
158+msgid "Cancel"
159+msgstr "Annuler"
160+
161+#. module: pos_select_customer
162+#. openerp-web
163+#: code:addons/pos_select_customer/static/src/js/psc.js:57
164+#, python-format
165+msgid "Customer"
166+msgstr "Client"
167+
168+#. module: pos_select_customer
169+#. openerp-web
170+#: code:addons/pos_select_customer/static/src/xml/psc.xml:41
171+#, python-format
172+msgid "Customer Selection"
173+msgstr "Sélection d'un client"
174+
175+#. module: pos_select_customer
176+#. openerp-web
177+#: code:addons/pos_select_customer/static/src/js/psc.js:68
178+#, python-format
179+msgid "Del."
180+msgstr "Suppr."
181+
182+#. module: pos_select_customer
183+#. openerp-web
184+#: code:addons/pos_select_customer/static/src/xml/psc.xml:45
185+#, python-format
186+msgid "Search Customers"
187+msgstr "Rechercher des clients"
188+
189
190=== added directory 'pos_select_customer/static'
191=== added directory 'pos_select_customer/static/src'
192=== added directory 'pos_select_customer/static/src/css'
193=== added file 'pos_select_customer/static/src/css/psc.css'
194--- pos_select_customer/static/src/css/psc.css 1970-01-01 00:00:00 +0000
195+++ pos_select_customer/static/src/css/psc.css 2014-09-12 08:56:09 +0000
196@@ -0,0 +1,168 @@
197+/******************************************************************************
198+ Point Of Sale - Select Customer module for OpenERP
199+ Copyright (C) 2014 GRAP (http://www.grap.coop)
200+ @author Julien WESTE
201+ @author Sylvain LE GAL (https://twitter.com/legalsylvain)
202+
203+ This program is free software: you can redistribute it and/or modify
204+ it under the terms of the GNU Affero General Public License as
205+ published by the Free Software Foundation, either version 3 of the
206+ License, or (at your option) any later version.
207+
208+ This program is distributed in the hope that it will be useful,
209+ but WITHOUT ANY WARRANTY; without even the implied warranty of
210+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
211+ GNU Affero General Public License for more details.
212+
213+ You should have received a copy of the GNU Affero General Public License
214+ along with this program. If not, see <http://www.gnu.org/licenses/>.
215+******************************************************************************/
216+
217+/* ********* Current customer name ********* */
218+
219+.point-of-sale #rightheader #customer-name{
220+ width:200px;
221+}
222+.point-of-sale #rightheader #remove-customer-button{
223+ width:80px;
224+}
225+
226+/* ********* Customer PopUp ********* */
227+.point-of-sale .modal-dialog .popup-select-customer{
228+ margin-left:0;
229+ margin-top:0;
230+ left:5%;
231+ width: 90%;
232+ top:5%;
233+ height:90%;
234+}
235+.point-of-sale .modal-dialog .popup-select-customer .customer-header{
236+ height:65px;
237+}
238+
239+.point-of-sale .modal-dialog .popup-select-customer #customer-title{
240+/* text-align:left;*/
241+}
242+.point-of-sale .modal-dialog .popup-select-customer .customer-searchbox{
243+ float:left;
244+ top: 20px;
245+ position: absolute;
246+ left: 10px;
247+}
248+.point-of-sale .modal-dialog .popup-select-customer #customer-cancel{
249+ top: 0px;
250+ position: absolute;
251+ right: 10px;
252+}
253+/* ********* Customer List ********* */
254+
255+.point-of-sale .customer-list {
256+ padding:10px !important;
257+}
258+
259+.point-of-sale .customer-list-container {
260+ position:absolute;
261+ top:70px;
262+ bottom:0px;
263+ left:0px;
264+ right:0px;
265+}
266+
267+.point-of-sale .customer-list-scroller{
268+ -webkit-box-sizing: border-box;
269+ -moz-box-sizing: border-box;
270+ -ms-box-sizing: border-box;
271+ box-sizing: border-box;
272+ width:100%;
273+ height:100%;
274+ overflow: hidden;
275+}
276+
277+/* ********* Customer Scrollbar ********* */
278+/* Fix incorrect display of buttons.*/
279+/* TODO: found why it is necessary and remove top,bottom and left values*/
280+.point-of-sale .customer-list-container .scrollbar .up-button{
281+ top: -10px;
282+ left: -5px;
283+}
284+.point-of-sale .customer-list-container .scrollbar .down-button {
285+ left: -5px;
286+ bottom: -5px;
287+}
288+
289+/* ********* Customer Item ********* */
290+
291+.point-of-sale .customer {
292+ position:relative;
293+ vertical-align: top;
294+ display: inline-block;
295+ font-size: 11px;
296+ margin: 5px !important;
297+ width: 200px;
298+ height:110px;
299+ background:#fff;
300+ border: 1px solid #fff;
301+ border-radius: 3px;
302+ overflow: hidden;
303+ -webkit-box-shadow: 0px 2px 0px #dad8e4, 0px 1px 8px #636480;
304+ -moz-box-shadow: 0px 2px 0px #dad8e4, 0px 1px 8px #636480;
305+ box-shadow: 0px 2px 0px #dad8e4, 0px 1px 8px #636480;
306+}
307+
308+.point-of-sale .customer .customer-name,
309+ .point-of-sale .customer .customer-email,
310+ .point-of-sale .customer .customer-address,
311+ .point-of-sale .customer .customer-phone,
312+ .point-of-sale .customer .customer-mobile{
313+ position: absolute;
314+ -webkit-box-sizing: border-box;
315+ -moz-box-sizing: border-box;
316+ -ms-box-sizing: border-box;
317+ box-sizing: border-box;
318+
319+ text-align:left;
320+ overflow: hidden;
321+ text-overflow: ellipsis;
322+ background: -webkit-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
323+ background: -moz-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
324+ background: -ms-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
325+ padding: 3px;
326+}
327+.point-of-sale .customer .customer-name{
328+ font-size: 13px;
329+ width:100%;
330+ top:0px;
331+ height: 20px;
332+}
333+.point-of-sale .customer .customer-email{
334+ width:100%;
335+ top:24px;
336+ height: 16px;
337+}
338+.point-of-sale .customer .customer-img {
339+ position: absolute;
340+ top: 44px;
341+ left: 0px;
342+ width: 64px;
343+ height: 64px;
344+ background: white;
345+ text-align: center;
346+}
347+.point-of-sale .customer .customer-address{
348+ width:135px;
349+ top:44px;
350+ left: 65px;
351+ height: 32px;
352+}
353+.point-of-sale .customer .customer-phone{
354+ width:135px;
355+ top:76px;
356+ left: 65px;
357+ height: 16px;
358+}
359+.point-of-sale .customer .customer-mobile{
360+ width:135px;
361+ top:92px;
362+ left: 65px;
363+ height: 16px;
364+}
365
366=== added directory 'pos_select_customer/static/src/img'
367=== added file 'pos_select_customer/static/src/img/icon.png'
368Binary files pos_select_customer/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and pos_select_customer/static/src/img/icon.png 2014-09-12 08:56:09 +0000 differ
369=== added directory 'pos_select_customer/static/src/js'
370=== added file 'pos_select_customer/static/src/js/psc.js'
371--- pos_select_customer/static/src/js/psc.js 1970-01-01 00:00:00 +0000
372+++ pos_select_customer/static/src/js/psc.js 2014-09-12 08:56:09 +0000
373@@ -0,0 +1,309 @@
374+/******************************************************************************
375+ Point Of Sale - Select Customer module for OpenERP
376+ Copyright (C) 2014 GRAP (http://www.grap.coop)
377+ @author Julien WESTE
378+ @author Sylvain LE GAL (https://twitter.com/legalsylvain)
379+
380+ This program is free software: you can redistribute it and/or modify
381+ it under the terms of the GNU Affero General Public License as
382+ published by the Free Software Foundation, either version 3 of the
383+ License, or (at your option) any later version.
384+
385+ This program is distributed in the hope that it will be useful,
386+ but WITHOUT ANY WARRANTY; without even the implied warranty of
387+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
388+ GNU Affero General Public License for more details.
389+
390+ You should have received a copy of the GNU Affero General Public License
391+ along with this program. If not, see <http://www.gnu.org/licenses/>.
392+******************************************************************************/
393+
394+openerp.pos_select_customer = function (instance) {
395+ module = instance.point_of_sale;
396+ _t = instance.web._t;
397+
398+ /*************************************************************************
399+ Define : CustomerOrderWidget that display the name of the customer
400+ of the current pos order and display button to select of remove it.
401+ */
402+ module.CustomerOrderWidget = module.PosBaseWidget.extend({
403+ template: 'CustomerOrderWidget',
404+
405+ /* Overload Section */
406+ init: function(parent, options){
407+ this._super(parent,options);
408+ this.pos.bind('change:selectedOrder', this.refresh, this);
409+ },
410+
411+ start: function(){
412+ this._super();
413+ this._build_widgets();
414+ },
415+
416+ /* Custom Section */
417+ refresh: function(){
418+ this.renderElement();
419+ this._build_widgets();
420+ },
421+
422+ _build_widgets: function(){
423+ // Create a button to open the customer popup
424+ this.select_customer_button = new module.HeaderButtonWidget(this,{
425+ label:_t('Customer'),
426+ action: function(){
427+ self.screen_selector.show_popup('select-customer');
428+ },
429+ });
430+ this.select_customer_button.replace($('.placeholder-SelectCustomerButton'));
431+ this.select_customer_button.renderElement();
432+
433+ if (this.get_name() !== ''){
434+ // Create a button to remove the current customer
435+ this.remove_customer_button = new module.HeaderButtonWidget(this,{
436+ label:_t('Del.'),
437+ action: function(){
438+ this.pos.get('selectedOrder').set_client(undefined);
439+ this.pos_widget.customer_order.refresh();
440+ this.hide();
441+ },
442+ });
443+ this.remove_customer_button.replace($('.placeholder-RemoveCustomerButton'));
444+ this.remove_customer_button.renderElement();
445+ }
446+ },
447+
448+ get_name: function(){
449+ customer = this.pos.get('selectedOrder').get_client();
450+ if(customer){
451+ return customer.name;
452+ }else{
453+ return "";
454+ }
455+ },
456+ });
457+
458+ /*************************************************************************
459+ Define : CustomerWidget that display a customer
460+ */
461+ module.CustomerWidget = module.PosBaseWidget.extend({
462+ template: 'CustomerWidget',
463+
464+ /* Overload Section */
465+ init: function(parent, options) {
466+ this._super(parent,options);
467+ this.model = options.model;
468+ },
469+
470+ renderElement: function() {
471+ this._super();
472+ this.$('img').replaceWith(this.pos_widget.image_cache.get_image(this.model.get_image_small_url()));
473+ var self = this;
474+ $("a", this.$el).click(function(e){
475+ self.pos.get('selectedOrder').set_client(self.model.toJSON());
476+ self.pos_widget.customer_order.refresh();
477+ self.pos_widget.screen_selector.set_current_screen('products');
478+ });
479+ },
480+ });
481+
482+ /*************************************************************************
483+ Define : CustomerListScreenWidget that display a list of customers.
484+ */
485+ module.CustomerListScreenWidget = module.ScreenWidget.extend({
486+ template:'CustomerListScreenWidget',
487+
488+ init: function(parent, options) {
489+ this._super(parent,options);
490+ this.customer_list = [];
491+ },
492+
493+ start: function() {
494+ this._super();
495+ var self = this;
496+ },
497+
498+ renderElement: function() {
499+ this._super();
500+ var self = this;
501+ // Delete old customers widget and display refreshed customers list
502+ for(var i = 0, len = this.customer_list.length; i < len; i++){
503+ this.customer_list[i].destroy();
504+ }
505+ this.customer_list = [];
506+ var customers = this.pos.get('customer_list_filter') || [];
507+ for(var i = 0, len = customers.models.length; i < len; i++){
508+ var customer = new module.CustomerWidget(this, {
509+ model: customers.models[i],
510+ click_product_action: this.click_product_action,
511+ });
512+ this.customer_list.push(customer);
513+ customer.appendTo(this.$('.customer-list'));
514+ }
515+
516+ // Delete old scrollbar widget and display refreshed scrollbar
517+ if(this.scrollbar){
518+ this.scrollbar.destroy();
519+ }
520+ this.scrollbar = new module.ScrollbarWidget(this,{
521+ target_widget: this,
522+ target_selector: '.customer-list-scroller',
523+ on_show: function(){
524+ self.$('.customer-list-scroller').css({'padding-right':'62px'},100);
525+ },
526+ on_hide: function(){
527+ self.$('.customer-list-scroller').css({'padding-right':'0px'},100);
528+ },
529+ });
530+ this.scrollbar.replace(this.$('.placeholder-ScrollbarWidget'));
531+ },
532+ }),
533+
534+ /*************************************************************************
535+ Define : SelectCustomerPopupWidget that display a pop up to search
536+ and select customers.
537+ */
538+ module.SelectCustomerPopupWidget = module.PopUpWidget.extend({
539+ template:'SelectCustomerPopupWidget',
540+
541+ start: function(){
542+ this._super();
543+ var self = this;
544+ this.customer_list_widget = new module.CustomerListScreenWidget(this,{});
545+ },
546+
547+ show: function(){
548+ this._super();
549+ var self = this;
550+ this.reset_customers();
551+ this.customer_list_widget.replace($('.placeholder-CustomerListScreenWidget'));
552+ this.$('#customer-cancel').off('click').click(function(){
553+ self.pos_widget.screen_selector.set_current_screen('products');
554+ });
555+ // filter customers according to the search string
556+ this.$('.customer-searchbox input').keyup(function(event){
557+ pattern = $(this).val().toLowerCase();
558+ if(pattern){
559+ var customers = self.pos.get('customer_list').search_customer(pattern);
560+ self.pos.set({'customer_list_filter' : customers});
561+ self.$('.customer-search-clear').fadeIn();
562+ self.customer_list_widget.renderElement();
563+ }
564+ else{
565+ self.reset_customers();
566+ }
567+ });
568+ //reset the search when clicking on reset
569+ this.$('.customer-search-clear').click(function(){
570+ self.reset_customers();
571+ });
572+ },
573+
574+ reset_customers: function(){
575+ this.pos.set({'customer_list_filter' : this.pos.get('customer_list')});
576+ this.$('.customer-search-clear').fadeOut();
577+ this.customer_list_widget.renderElement();
578+ this.$('.customer-searchbox input').val('').focus();
579+ },
580+
581+ });
582+
583+
584+ /*************************************************************************
585+ Overload : PosWidget to include button in PosOrderHeaderWidget widget
586+ to select or unselect customers
587+ */
588+ module.PosWidget = module.PosWidget.extend({
589+
590+ build_widgets: function(){
591+ this._super();
592+ var self = this;
593+
594+ // Add a widget to manage customer
595+ this.customer_order = new module.CustomerOrderWidget(this,{});
596+ this.customer_order.appendTo(this.$('#pos_order_header'));
597+
598+ // create a pop up 'select-customer' to search and select customers
599+ this.select_customer_popup = new module.SelectCustomerPopupWidget(this, {});
600+ this.select_customer_popup.appendTo($('.point-of-sale'));
601+ this.select_customer_popup.hide();
602+ this.screen_selector.popup_set['select-customer'] = this.select_customer_popup;
603+
604+ },
605+ });
606+
607+ /*************************************************************************
608+ Define : New Model 'Customer'
609+ */
610+ module.Customer = Backbone.Model.extend({
611+ get_image_small_url: function(){
612+ return instance.session.url('/web/binary/image', {model: 'res.partner', field: 'image_small', id: this.get('id')});
613+ },
614+ });
615+
616+ module.CustomerCollection = Backbone.Collection.extend({
617+ model: module.Customer,
618+
619+ search_customer: function(pattern){
620+ res = new module.CustomerCollection();
621+ var reg = RegExp(pattern,"i");
622+ for(var i = 0, len = this.models.length; i < len; i++){
623+ res_reg = reg.exec(this.models[i].attributes.name);
624+ if (res_reg){
625+ res.push(this.models[i]);
626+ }
627+ }
628+ return res;
629+ },
630+ });
631+
632+ /*
633+ Overload: PosModel.initialize() to define two new lists.
634+ 'customer_list' are the list of all customers available;
635+ 'customer_list_filter' are a sub-list according to the current filter
636+ selection.
637+ */
638+ var _initialize_ = module.PosModel.prototype.initialize;
639+ module.PosModel.prototype.initialize = function(session, attributes){
640+ _initialize_.call(this, session, attributes);
641+ this.set({
642+ 'customer_list': new module.CustomerCollection(),
643+ 'customer_list_filter': new module.CustomerCollection(),
644+ });
645+ };
646+
647+ /*
648+ Overload: PosModel.load_server_data() function to get in memory
649+ customers.
650+ The function will load all usefull informations even if any
651+ informations won't be used in this module, to allow further modules
652+ to use them.
653+ */
654+ var _load_server_data_ = module.PosModel.prototype.load_server_data;
655+ module.PosModel.prototype.load_server_data = function(){
656+ var self = this;
657+ var load_def = _load_server_data_.call(self).done(self.load_customers_data());
658+ return load_def;
659+ },
660+
661+ module.PosModel = module.PosModel.extend({
662+ load_customers_data: function(){
663+ var self = this;
664+ var loaded = self.fetch(
665+ 'res.partner',
666+ ['name','display_name','title','function','type',
667+ 'parent_id','is_company',
668+ 'lang','company_id','ean13','color',
669+ 'contact_address','street','street2','city','zip','state_id','country_id',
670+ 'property_product_pricelist','vat','debit_limit','credit_limit',
671+ 'email','website','fax','phone','mobile',],
672+ [['customer', '=', true]])
673+ .then(function(customers){
674+ console.log(customers);
675+ self.set({'customer_list' : new module.CustomerCollection(customers)});
676+ self.set({'customer_list_filter' : new module.CustomerCollection(customers)});
677+ });
678+ return loaded;
679+ },
680+ });
681+};
682+
683
684=== added directory 'pos_select_customer/static/src/xml'
685=== added file 'pos_select_customer/static/src/xml/psc.xml'
686--- pos_select_customer/static/src/xml/psc.xml 1970-01-01 00:00:00 +0000
687+++ pos_select_customer/static/src/xml/psc.xml 2014-09-12 08:56:09 +0000
688@@ -0,0 +1,103 @@
689+<?xml version="1.0" encoding="UTF-8"?>
690+<!-- ********************************************************************** -->
691+<!--Point Of Sale - Select Customer module for OpenERP -->
692+<!--Copyright (C) 2014 GRAP (http://www.grap.coop) -->
693+<!--@author Julien WESTE -->
694+<!--@author Sylvain LE GAL (https://twitter.com/legalsylvain) -->
695+
696+<!--This program is free software: you can redistribute it and/or modify -->
697+<!--it under the terms of the GNU Affero General Public License as -->
698+<!--published by the Free Software Foundation, either version 3 of the -->
699+<!--License, or (at your option) any later version. -->
700+
701+<!--This program is distributed in the hope that it will be useful, -->
702+<!--but WITHOUT ANY WARRANTY; without even the implied warranty of -->
703+<!--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
704+<!--GNU Affero General Public License for more details. -->
705+
706+<!--You should have received a copy of the GNU Affero General Public License-->
707+<!--along with this program. If not, see <http://www.gnu.org/licenses/>. -->
708+<!-- ********************************************************************** -->
709+<templates id="template" xml:space="preserve">
710+
711+ <t t-name="CustomerOrderWidget">
712+ <div class="extra-label">
713+ <span class="placeholder-SelectCustomerButton" />
714+ </div>
715+ <div id="customer-name" class="extra-label">
716+ <div class="extra-text">
717+ <t t-esc="widget.get_name()" />
718+ </div>
719+ </div>
720+ <div id="remove-customer-button" class="extra-label">
721+ <span class="placeholder-RemoveCustomerButton" />
722+ </div>
723+ </t>
724+
725+ <t t-name="SelectCustomerPopupWidget">
726+ <div class="modal-dialog">
727+ <div class="popup popup-select-customer">
728+ <div class="customer-header">
729+ <div id="customer-title">
730+ Customer Selection
731+ </div>
732+ <div class="customer-searchbox">
733+ <input placeholder="Search Customers" />
734+ <img class="customer-search-clear" src="/point_of_sale/static/src/img/search_reset.gif" />
735+ </div>
736+ <div id="customer-cancel" class="button">
737+ Cancel
738+ </div>
739+ </div>
740+ <div class="content-container">
741+ <span class="placeholder-CustomerListScreenWidget" />
742+ </div>
743+ </div>
744+ </div>
745+ </t>
746+
747+ <t t-name="CustomerListScreenWidget">
748+ <div class='customer-list-container'>
749+ <div class="customer-list-scroller">
750+ <ol id="customer-screen-ol" class="customer-list">
751+ </ol>
752+ </div>
753+ <div class="shadow-top"></div>
754+ <span class="placeholder-ScrollbarWidget" />
755+ </div>
756+ </t>
757+
758+ <t t-name="CustomerWidget">
759+ <li class='customer'>
760+ <a href="#">
761+ <div class="customer-img">
762+ <img sr='' />
763+ </div>
764+ <div class="customer-name">
765+ <t t-esc="widget.model.get('name')"/>
766+ </div>
767+ <div class="customer-email">
768+ <t t-if="widget.model.get('email')">
769+ <t t-esc="widget.model.get('email')"/>
770+ </t>
771+ </div>
772+ <div class="customer-address">
773+ <t t-if="widget.model.get('contact_address')">
774+ <t t-esc="widget.model.get('contact_address')"/>
775+ </t>
776+ </div>
777+ <div class="customer-phone">
778+ <t t-if="widget.model.get('phone')">
779+ <t t-esc="widget.model.get('phone')"/>
780+ </t>
781+ </div>
782+ <div class="customer-mobile">
783+ <t t-if="widget.model.get('mobile')">
784+ <t t-esc="widget.model.get('mobile')"/>
785+ </t>
786+ </div>
787+ </a>
788+ </li>
789+ </t>
790+
791+</templates>

Subscribers

People subscribed via source and target branches