Compare commits

...

82 Commits

Author SHA1 Message Date
Denis Mudarisov 8399842311 🍒 module name change 4 years ago
Ivan Yelizariev ed2047d570 💚 pre-commit run --all 4 years ago
Ivan Yelizariev 7e49c47129 📖 new support mail 4 years ago
Ivan Yelizariev 0a7f7da0cd 📖 Distribute under MIT license 4 years ago
i18n-bot 256c439dee 👽 Update pos_keyboard.pot 4 years ago
Ivan Yelizariev f2e287fc0e 💚 pre-commit: auto cleanups 4 years ago
Ivan Yelizariev 60c0416547 💚 pre-commit: auto cleanups 4 years ago
Ivan Yelizariev ebfdf17ad2 💚 pos_keyboard/ 4 years ago
Ivan Yelizariev 5472cca160 💚 eslint --fix 4 years ago
Ivan Yelizariev 16129ba1cb 💚 pre-commit: auto cleanups 4 years ago
i18n-bot 79b0b95e0c 👽 Update pos_keyboard.pot 5 years ago
i18n-bot 4f55c10cb0 👽 Update pos_keyboard.pot 5 years ago
i18n-bot 1bb7839325 👽 Update pos_keyboard.pot 5 years ago
i18n-bot c240827934 👽 Update pos_keyboard.pot 5 years ago
fedoranvar a604f007d8 🛡️ JS-tour for connect-disconnect keyboard 5 years ago
fedoranvar bb8368f1e3 🛡️ JS-tour for connect-disconnect keyboard 5 years ago
Raul Ovalle 572c9907f5 🚑 Function 'disconnect' not working in expected way 5 years ago
Santiago J. Said e96361dce7 🚑 Duplicated event listener 5 years ago
fedoranvar 604b7c945a ⬆️1️⃣2️⃣ Fixed js-tour 5 years ago
Raul Ovalle 555b565825 🚑 Function 'disconnect' not working in expected way 5 years ago
Santiago J. Said 78304c9c3e 🚑 Duplicated event listener 5 years ago
KolushovAlexandr 33b228f7e3 💚 Redefining built-in "id", Delete index.html~ 5 years ago
i18n-bot 637c654432 [UPD] Update pos_keyboard.pot 5 years ago
KolushovAlexandr 1245bf9a5d 🚑 enter did not work for some popups 5 years ago
KolushovAlexandr 33376310de 🚑 enter did not work for some popups 5 years ago
KolushovAlexandr 4bae082f87 🛡️ pos_keyboard tests 5 years ago
KolushovAlexandr 57835656a1 🚑 clicking numbers and enter in selection popups 5 years ago
KolushovAlexandr 62f6d69ada 📖 pos_keyboard 5 years ago
Mirgalimova 42a4372f77 📖 keyboard documentation updated (#981) 5 years ago
KolushovAlexandr 777c6e132b 🚑 Incorrect input data on password pop-up if the first clicked button was `backspace 5 years ago
KolushovAlexandr 0fd4bef4f2 ⬆️1️⃣1️⃣ pos_keyboard 5 years ago
KolushovAlexandr 6a241b97a8 ability to use keyboard for password popup close #411 5 years ago
rusllan 63def2b3a7 🌈 all the __openerp__.py files renamed in __manifest__.py 6 years ago
rusllan b79ec55220 🌈fixed some lint errors 6 years ago
rusllan 042344170b 📖 adding changelog.rst and index.rst in modules where they were not 6 years ago
rusllan b2f54c0600 📖 changing email address 6 years ago
GabbasovDinar 19131ddfb1 [LINT] fix lints errors 6 years ago
GabbasovDinar ceea2e97f3 [LINT] fix lint errors 6 years ago
Dinar f7de17559d [PORT] mark unported modules as non-installable (#468) 7 years ago
ilmir 4d7cccd48f [DOC] pos_keyboard: new price 7 years ago
Ivan Yelizariev 64aeef4802 [DOC] add support email 7 years ago
manawi 786d36fb7d [FIX]Duplicate implicit target name: "changelog" 8 years ago
manawi 44e6a19f30 [FIX] 8.0 fix flake (#155) 8 years ago
x620 7abdb0d87b [REF] Fix lint errors 8 years ago
Ivan Yelizariev ad0bd90e5e [DOC] update price 8 years ago
ufaks 0c4a4efb26 fix merge conflict 8 years ago
ufaks c2add4b584 fix 8 years ago
ufaks 862275f61e update changelog 8 years ago
ufaks 811c9b4388 dummy commit 8 years ago
ufaks 50eefac7b7 fix repeat last symbol when press other key 8 years ago
ufaks 0dce7bbfbd fix minor issues: journal sequence, __openerp__.py 8 years ago
ufaks fc9185cb7e port to 9 8 years ago
ufaks 5b3267efb1 fix bugs 8 years ago
ufaks f57dd2febf REF 8 years ago
ufaks 67dd3946de add summary 8 years ago
ufaks 7227361088 fix authors 8 years ago
ufaks 8a004c0b23 fix readme 8 years ago
ufaks 0b2fabe06e fix 8 years ago
ufaks 132d5b1971 add pic 8 years ago
ufaks b550159b3d [fix] scanner bug 8 years ago
Ivan Yelizariev 23f8a054ef Revert "update license to GPL-3" 9 years ago
Ivan Yelizariev 5f0ef1e691 update license to GPL-3 9 years ago
Ivan Yelizariev 523e1858a2 [DOC] add license tag 9 years ago
Ivan Yelizariev 1bba12dc3d mark unported modules as non-installable 9 years ago
Ivan Yelizariev 336321692d [DOC] add IT-Projects LLC to authors 9 years ago
Ivan Yelizariev 0625ceaa60 [DOC] add icon 9 years ago
igallyamov 584e1b0711 Update README.rst 9 years ago
Ilnur Gallyamov 7630868bff fix README.rst; added the correct revision 9 years ago
igallyamov cca71b0770 add revision 9 years ago
igallyamov 4bea19b1f0 changed the name of the module 9 years ago
igallyamov 618cf29e0a Update README.rst 9 years ago
igallyamov ffac458383 update README.rst 9 years ago
Ilnur Gallyamov 718e3c76ad add "+/-" info key in README.rst file 9 years ago
Ilnur Gallyamov d830383f75 README.rst style fix 9 years ago
Ilnur Gallyamov a10f970072 README.rst style fix 9 years ago
Ilnur Gallyamov 07df647f3f README.rst style fix 9 years ago
Ilnur Gallyamov 87eb21024a README.rst style fix 9 years ago
Ilnur Gallyamov fdbf9ff335 fix style README.rst 9 years ago
Ilnur Gallyamov 81be37e990 fix style README.rst 9 years ago
Ilnur Gallyamov 8e88b33a71 description displaced in the README file 9 years ago
Ilnur Gallyamov b18f45cd3e 1. added support for basic keyboard 9 years ago
Ilnur Gallyamov b34425baf5 usb keyboard for Point of Sale v1.0.0 9 years ago
  1. 45
      pos_keyboard/README.rst
  2. 1
      pos_keyboard/__init__.py
  3. 43
      pos_keyboard/__manifest__.py
  4. 20
      pos_keyboard/data.xml
  5. 35
      pos_keyboard/doc/changelog.rst
  6. 60
      pos_keyboard/doc/index.rst
  7. 35
      pos_keyboard/i18n/pos_keyboard.pot
  8. BIN
      pos_keyboard/images/keyboard.png
  9. BIN
      pos_keyboard/static/description/icon.png
  10. 87
      pos_keyboard/static/description/index.html
  11. BIN
      pos_keyboard/static/description/keyboard_1.png
  12. BIN
      pos_keyboard/static/description/keyboard_2.png
  13. 313
      pos_keyboard/static/src/js/pos.js
  14. 147
      pos_keyboard/static/src/js/test_pos_keyboard.js
  15. 3
      pos_keyboard/tests/__init__.py
  16. 19
      pos_keyboard/tests/test_pos_keyboard.py
  17. 248
      to use usual keyboard (not virtual one) in Point of Sale',
  18. 3874
      upport in Point Of Sale",

45
pos_keyboard/README.rst

@ -0,0 +1,45 @@
.. image:: https://img.shields.io/badge/license-MIT-blue.svg
:target: https://opensource.org/licenses/MIT
:alt: License: MIT
==============
POS Keyboard
==============
The module allows to apply the usual keyboard (not the virtual one) in the Point of Sale.
Credits
=======
Contributors
------------
* `Ivan Yelizariev <https://it-projects.info/team/yelizariev>`__
* `Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>`__
* `Anvar Kildebekov <https://it-projects.info/team/fedoranvar>`__
Sponsors
--------
* `IT-Projects LLC <https://it-projects.info>`__
Maintainers
-----------
* `IT-Projects LLC <https://it-projects.info>`__
To get a guaranteed support you are kindly requested to purchase the module at `odoo apps store <https://apps.odoo.com/apps/modules/12.0/pos_keyboard/>`__.
Thank you for understanding!
`IT-Projects Team <https://www.it-projects.info/team>`__
Further information
===================
Demo: http://runbot.it-projects.info/demo/pos-addons/12.0
HTML Description: https://apps.odoo.com/apps/modules/12.0/pos_keyboard/
Usage instructions: `<doc/index.rst>`_
Changelog: `<doc/changelog.rst>`_
Tested on Odoo 12.0 d177e8f53b01f5e09c9b49c945781b69baac7009

1
pos_keyboard/__init__.py

@ -0,0 +1 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

43
pos_keyboard/__manifest__.py

@ -0,0 +1,43 @@
# Copyright 2015 igallyamov <https://github.com/igallyamov>
# Copyright 2016 ufaks <https://github.com/ufaks>
# Copyright 2016-2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
# Copyright 2018 Ruslan Ronzhin <https://it-projects.info/team/rusllan>
# Copyright 2019 Kolushov Alexandr <https://it-projects.info/team/kolushovalexandr>
# Copyright 2019 Anvar Kildebekov https://it-projects.info/team/fedoranvar>
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
{
"name": """POS Keyboard""",
"summary": """Module allows to use usual keyboard (not virtual one) in Point of Sale""",
"category": "Point Of Sale",
# "live_test_url": "http://apps.it-projects.info/shop/product/DEMO-URL?version={ODOO_BRANCH}",
"images": ["images/keyboard.png"],
"version": "12.0.1.1.5",
"application": False,
"author": "IT-Projects LLC, Ivan Yelizariev",
"support": "apps@itpp.dev",
"website": "https://it-projects.info/team/yelizariev",
"license": "LGPL-3",
"price": 15.00,
"currency": "EUR",
"depends": ["point_of_sale"],
"external_dependencies": {"python": [], "bin": []},
"data": ["data.xml"],
"demo": [],
"qweb": [],
"post_load": None,
"pre_init_hook": None,
"post_init_hook": None,
"uninstall_hook": None,
"auto_install": False,
"installable": True,
# "demo_title": "{MODULE_NAME}",
# "demo_addons": [
# ],
# "demo_addons_hidden": [
# ],
# "demo_url": "DEMO-URL",
# "demo_summary": "{SHORT_DESCRIPTION_OF_THE_MODULE}",
# "demo_images": [
# "images/MAIN_IMAGE",
# ]
}

20
pos_keyboard/data.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--Copyright 2015 igallyamov <https://github.com/igallyamov>
Copyright 2016 ufaks <https://github.com/ufaks>
Copyright 2019 Kolushov Alexandr <https://it-projects.info/team/kolushovalexandr>
License MIT (https://opensource.org/licenses/MIT). -->
<openerp>
<template id="assets" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<script type="text/javascript" src="/pos_keyboard/static/src/js/pos.js" />
</xpath>
</template>
<template id="demo_assets_backend" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script
type="text/javascript"
src="/pos_keyboard/static/src/js/test_pos_keyboard.js"
/>
</xpath>
</template>
</openerp>

35
pos_keyboard/doc/changelog.rst

@ -0,0 +1,35 @@
`1.1.4`
-------
**Fix:** Incompatibility with some modules led to the action duplicating
`1.1.3`
-------
**Fix:** Enter did not work for some pop-ups
`1.1.2`
-------
**Fix:** Error on clicking numbers and enter in selection popups
`1.1.1`
-------
**Fix:** Incorrect input data on password pop-up if the first clicked button was `backspace`
`1.1.0`
-------
**New:** Added popup handling
`1.0.2`
-------
- Fix bug: Repeat last keystroke when press non-number key or non-shortcut key after keypress on the number or shortcut key (i.e. q15jj ended up as quantity 1555)
`1.0.1`
-------
- Fix barcode scanner bug

60
pos_keyboard/doc/index.rst

@ -0,0 +1,60 @@
==============
POS Keyboard
==============
Installation
============
* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way
Usage
=====
Using hotkeys below switch to mode you need. Qty mode is used by default.
Then use keys with numbers to enter quantity, price or discount.
If you want to reset the amount of product to zero or delete them you can use ``Backspace`` .
=========== ===================== =================
Type Numpad Extra keys
=========== ===================== =================
mode qty ``/`` ``q``
----------- --------------------- -----------------
mode disc ``-`` ``d``
----------- --------------------- -----------------
mode price ``*`` ``p``
----------- --------------------- -----------------
+/- ``+`` ``s``
=========== ===================== =================
Also inside the Pop-ups windows you can use ``Enter``, ``Backspace`` and ``Esc`` keys in order to speed up the process of interaction with the System.
=========== ===================== ==================
Key Pop-up Action
=========== ===================== ==================
Backspace ``<-`` delete symbol
----------- --------------------- ------------------
Enter ``Ok`` confirmation
----------- --------------------- ------------------
Esc ``Cancel`` close Pop-up
=========== ===================== ==================
User Scenario
-------------
* Open menu ``[[ Users ]]``
* Choose a User with PIN code
* Enter PIN code with the keyboard
* You can use ``Backspace`` if you want to delete symbol
* You can use ``Enter`` if you want to confirm PIN code
* You can use ``Esc`` if you want to close the Pop-up keyboard
* Work in your own account using hotkeys for each mode on the Numpad or just press Extra keys. Then enter numbers.
* You can use ``/`` or ``q`` in case of Qrt mode
* You can use ``-`` or ``d`` in case of Disc mode
* You can use ``*`` or ``p`` in case of Price mode
* You can use ``+`` or ``s`` in case of +/-
RESULT: In opened POS Keyboard support is invoked instantly and available for further work without any extra action.

35
pos_keyboard/i18n/pos_keyboard.pot

@ -0,0 +1,35 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_keyboard
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \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_keyboard
#. openerp-web
#: code:addons/pos_keyboard/static/src/js/test_pos_keyboard.js:22
#, python-format
msgid "<p>Click to start the point of sale interface. It <b>runs on tablets</b>, laptops, or industrial hardware.</p><p>Once the session launched, the system continues to run without an internet connection.</p>"
msgstr ""
#. module: pos_keyboard
#. openerp-web
#: code:addons/pos_keyboard/static/src/js/test_pos_keyboard.js:18
#, python-format
msgid "Ready to launch your <b>point of sale</b>? <i>Click here</i>."
msgstr ""
#. module: pos_keyboard
#. openerp-web
#: code:addons/pos_keyboard/static/src/js/test_pos_keyboard.js:14
#, python-format
msgid "Show Apps Menu"
msgstr ""

BIN
pos_keyboard/images/keyboard.png

After

Width: 750  |  Height: 400  |  Size: 476 KiB

BIN
pos_keyboard/static/description/icon.png

After

Width: 100  |  Height: 100  |  Size: 1.9 KiB

87
pos_keyboard/static/description/index.html

@ -0,0 +1,87 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan" style="color:#875A7B;">POS Keyboard</h2>
<h3 class="oe_slogan">The module allows to apply the usual keyboard (not the virtual one) in the Point of Sale.</h3>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">How It Works</h3>
<div class="oe_span12 text-center">
<p class="oe_mt32">
<font style="font-size: 120%;">
<p> Users can take advantage of a regular keyboard to process pop-up actions, for example, enter a PIN on cashier changing.</p>
</font>
</p>
</div>
<div class="oe_screenshot" align="center">
<img style="max-width: 40%" src="keyboard_2.png"/>
</div>
<div class="oe_span12 text-center">
<p class="oe_mt32">
<font style="font-size: 120%;">
<p> In the Sale process cashiers can operate with the hotkeys for each of <i> Qty, Price, Disc, +/- modes </i> by using Numpad/Extra keys and after which they can enter necessary numbers.</p>
</font>
</p>
</div>
<div class="oe_screenshot" align="center">
<img style="max-width: 60%" src="keyboard_1.png"/>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span8">
<h2>Need our service?</h2>
<p class="oe_mt32">Contact us by <a href="mailto:apps@it-projects.info">email</a> or fill out <a href="https://www.it-projects.info/page/website.contactus " target="_blank">request form</a></p>
<ul>
<li><a href="mailto:apps@it-projects.info">apps@it-projects.info <i class="fa fa-envelope-o"></i></a></li>
<li><a href="https://www.it-projects.info/page/website.contactus " target="_blank">https://www.it-projects.info/page/website.contactus <i class="fa fa-list-alt"></i></a></li>
<li><a href="https://m.me/itprojectsllc" target="_blank">https://m.me/itprojectsllc <i class="fa fa-facebook-square"></i></a></li>
<li>skype@it-projects.info <i class="fa fa-skype"></i></li>
</ul>
</div>
<div class="oe_span4">
<div class="stamp" style="width:200px;">
<div style="margin-top: 15px;
position: relative;
font-family:'Vollkorn', serif;
font-size: 16px;
line-height: 25px;
text-transform: uppercase;
font-weight: bold;
color: #75526b;
border: 3px dashed #75526b;
float: left;
padding: 4px 12px;
-webkit-transform: rotate(8deg);
-o-transform: rotate(8deg);
-moz-transform: rotate(8deg);
-ms-transform: rotate(8deg);">
Tested on Odoo<br/>12.0 community
</div>
<!--<div style="margin-top: 15px;
position: relative;
font-family:'Vollkorn', serif;
font-size: 16px;
line-height: 25px;
text-transform: uppercase;
font-weight: bold;
color: #75526b;
border: 3px dashed #75526b;
float: left;
padding: 4px 12px;
-webkit-transform: rotate(6deg);
-o-transform: rotate(6deg);
-moz-transform: rotate(6deg);
-ms-transform: rotate(6deg);">
Tested on Odoo<br/>10.0 enterprise
</div>-->
</div>
</div>
</div>
</section>

BIN
pos_keyboard/static/description/keyboard_1.png

After

Width: 1308  |  Height: 826  |  Size: 121 KiB

BIN
pos_keyboard/static/description/keyboard_2.png

After

Width: 377  |  Height: 338  |  Size: 21 KiB

313
pos_keyboard/static/src/js/pos.js

@ -0,0 +1,313 @@
/* Copyright 2015 igallyamov <https://github.com/igallyamov>
Copyright 2016 ufaks <https://github.com/ufaks>
Copyright 2016 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
Copyright 2019 Kolushov Alexandr <https://it-projects.info/team/kolushovalexandr>
Copyright 2019 ssaid <https://github.com/ssaid>
Copyright 2019 raulovallet <https://github.com/raulovallet>
License MIT (https://opensource.org/licenses/MIT). */
/* eslint-disable complexity */
odoo.define("pos_keyboard.pos", function(require) {
"use strict";
var core = require("web.core");
var gui = require("point_of_sale.gui");
var models = require("point_of_sale.models");
var screens = require("point_of_sale.screens");
var PopupWidget = require("point_of_sale.popups");
gui.Gui.prototype.popup_classes
.filter(function(c) {
return c.name === "password";
})[0]
.widget.include({
init: function(parent, args) {
this._super(parent, args);
this.popup_type = "password";
},
});
PopupWidget.include({
keypad_action: function(data) {
var type = this.pos.keypad.type;
if (data.type === type.numchar) {
this.click_keyboard(data.val);
} else if (data.type === type.backspace) {
this.click_keyboard("BACKSPACE");
} else if (data.type === type.enter) {
// Some pop-ups might throw an error due to lack of some income data
try {
return this.click_confirm();
} catch (error) {
return;
}
} else if (data.type === type.escape) {
this.click_cancel();
}
},
click_keyboard: function(value) {
if (typeof this.inputbuffer === "undefined") {
return;
}
var newbuf = this.gui.numpad_input(this.inputbuffer, value, {
firstinput: this.firstinput,
});
this.firstinput = newbuf.length === 0;
var $value = this.$(".value");
if (newbuf !== this.inputbuffer) {
this.inputbuffer = newbuf;
$value.text(this.inputbuffer);
}
if (this.popup_type === "password" && newbuf) {
$value.text($value.text().replace(/./g, "•"));
}
},
show: function(options) {
this._super(options);
this.$("input,textarea").focus();
},
});
screens.NumpadWidget.include({
keypad_action: function(data) {
var type = this.pos.keypad.type;
if (data.type === type.numchar) {
this.state.appendNewChar(data.val);
} else if (data.type === type.bmode) {
this.state.changeMode(data.val);
} else if (data.type === type.sign) {
this.clickSwitchSign();
} else if (data.type === type.backspace) {
this.clickDeleteLastChar();
}
},
});
screens.PaymentScreenWidget.include({
show: function() {
this._super();
this.pos.keypad.disconnect();
},
hide: function() {
this._super();
this.pos.keypad.connect();
},
});
// This module mimics a keypad-only cash register. Use connect() and
// disconnect() to activate and deactivate it.
var Keypad = core.Class.extend({
init: function(attributes) {
this.pos = attributes.pos;
/* This.pos_widget = this.pos.pos_widget;*/
this.type = {
numchar: "number, dot",
bmode: "quantity, discount, price",
sign: "+, -",
backspace: "backspace",
enter: "enter",
escape: "escape",
};
this.data = {
// Type: undefined,
// val: undefined
};
delete this.action_callback;
this.active = false;
},
save_callback: function() {
this.saved_callback_stack.push(this.action_callback);
},
restore_callback: function() {
if (this.saved_callback_stack.length > 0) {
this.action_callback = this.saved_callback_stack.pop();
}
},
set_action_callback: function(callback) {
this.action_callback = callback;
},
// Remove action callback
reset_action_callback: function() {
delete this.action_callback;
},
// Starts catching keyboard events and tries to interpret keystrokes,
// calling the callback when needed.
connect: function() {
var self = this;
if (self.active) {
return;
}
// --- additional keyboard ---//
// KeyCode: + or - (Keypad '+')
var KC_PLU = 107;
// KeyCode: Quantity (Keypad '/')
var KC_QTY = 111;
// KeyCode: Price (Keypad '*')
var KC_AMT = 106;
// KeyCode: Discount Percentage [0..100] (Keypad '-')
var KC_DISC = 109;
// --- basic keyboard --- //
// KeyCode: sign + or - (Keypad 's')
var KC_PLU_1 = 83;
// KeyCode: Quantity (Keypad 'q')
var KC_QTY_1 = 81;
// KeyCode: Price (Keypad 'p')
var KC_AMT_1 = 80;
// KeyCode: Discount Percentage [0..100] (Keypad 'd')
var KC_DISC_1 = 68;
// KeyCode: Backspace (Keypad 'backspace')
var KC_BACKSPACE = 8;
// KeyCode: Enter (Keypad 'enter')
var KC_ENTER = 13;
// KeyCode: Escape (Keypad 'esc')
var KC_ESCAPE = 27;
var kc_lookup = {
48: "0",
49: "1",
50: "2",
51: "3",
52: "4",
53: "5",
54: "6",
55: "7",
56: "8",
57: "9",
80: "p",
83: "s",
68: "d",
190: ".",
81: "q",
96: "0",
97: "1",
98: "2",
99: "3",
100: "4",
101: "5",
102: "6",
103: "7",
104: "8",
105: "9",
106: "*",
107: "+",
109: "-",
110: ".",
111: "/",
};
// Usb keyboard keyup event
var rx = /INPUT|SELECT|TEXTAREA/i;
var ok = false;
var timeStamp = 0;
$("body").on("keyup", "", function(e) {
var statusHandler =
!rx.test(e.target.tagName) ||
e.target.disabled ||
e.target.readOnly;
if (statusHandler) {
var is_number = false;
var type = self.type;
var buttonMode = {
qty: "quantity",
disc: "discount",
price: "price",
};
var token = e.keyCode;
if (
(token >= 96 && token <= 105) ||
token === 110 ||
(token >= 48 && token <= 57) || token === 190
) {
self.data.type = type.numchar;
self.data.val = kc_lookup[token];
is_number = true;
ok = true;
} else if (token === KC_PLU || token === KC_PLU_1) {
self.data.type = type.sign;
ok = true;
} else if (token === KC_QTY || token === KC_QTY_1) {
self.data.type = type.bmode;
self.data.val = buttonMode.qty;
ok = true;
} else if (token === KC_AMT || token === KC_AMT_1) {
self.data.type = type.bmode;
self.data.val = buttonMode.price;
ok = true;
} else if (token === KC_DISC || token === KC_DISC_1) {
self.data.type = type.bmode;
self.data.val = buttonMode.disc;
ok = true;
} else if (token === KC_BACKSPACE) {
self.data.type = type.backspace;
ok = true;
} else if (token === KC_ENTER) {
self.data.type = type.enter;
ok = true;
} else if (token === KC_ESCAPE) {
self.data.type = type.escape;
ok = true;
} else {
delete self.data.type;
delete self.data.val;
ok = false;
}
if (is_number) {
if (timeStamp + 50 > new Date().getTime()) {
ok = false;
}
}
timeStamp = new Date().getTime();
setTimeout(function() {
if (ok) {
self.action_callback(self.data);
}
}, 50);
}
});
self.active = true;
},
// Stops catching keyboard events
disconnect: function() {
$("body").off("keyup", "");
this.active = false;
},
});
var _super_posmodel = models.PosModel.prototype;
models.PosModel = models.PosModel.extend({
initialize: function(session, attributes) {
var self = this;
this.keypad = new Keypad({pos: this});
_super_posmodel.initialize.call(this, session, attributes);
this.ready.then(function() {
self.keypad.set_action_callback(function(data) {
var current_screen = self.gui.current_screen;
var current_popup = self.gui.current_popup;
if (current_popup) {
current_popup.keypad_action(data);
} else if (
current_screen.numpad &&
current_screen.numpad.keypad_action
) {
current_screen.numpad.keypad_action(data);
}
});
});
},
});
return {
Keypad: Keypad,
};
});

147
pos_keyboard/static/src/js/test_pos_keyboard.js

@ -0,0 +1,147 @@
/* Copyright 2019 Kolushov Alexandr <https://it-projects.info/team/kolushovalexandr>
Copyright 2019 Anvar Kildebekov <https://it-projects.info/team/fedoranvar>
License MIT (https://opensource.org/licenses/MIT). */
odoo.define("pos_keyboard.tour", function(require) {
"use strict";
var tour = require("web_tour.tour");
var core = require("web.core");
var _t = core._t;
function open_pos_neworder() {
return [
{
trigger: "ul.o_menu_apps li.dropdown a.full",
content: _t("Show Apps Menu"),
position: "bottom",
},
{
trigger:
'.o_app[data-menu-xmlid="point_of_sale.menu_point_root"], .oe_menu_toggler[data-menu-xmlid="point_of_sale.menu_point_root"]',
content: _t(
"Ready to launch your <b>point of sale</b>? <i>Click here</i>."
),
position: "bottom",
},
{
trigger: ".o_pos_kanban button.oe_kanban_action_button",
content: _t(
"<p>Click to start the point of sale interface. It <b>runs on tablets</b>, laptops, or industrial hardware.</p><p>Once the session launched, the system continues to run without an internet connection.</p>"
),
position: "bottom",
},
{
content: "Switch to table or make dummy action",
trigger:
".table:not(.oe_invisible .neworder-button), .order-button.selected",
position: "bottom",
timeout: 30000,
},
{
content: "waiting for loading to finish",
trigger: ".order-button.neworder-button",
},
];
}
function add_product_to_order(product_name) {
return [
{
content: "buy " + product_name,
trigger: '.product-list .product-name:contains("' + product_name + '")',
},
{
content: "the " + product_name + " have been added to the order",
trigger: '.order .product-name:contains("' + product_name + '")',
},
];
}
function simulate_keyup_event(number) {
var event = $.Event("keyup");
event.which = number;
event.keyCode = number;
$("body").trigger(event);
}
function update_qty_for_product(qty) {
return [
{
content: "Make dummy action and update product qty",
trigger: ".order-button.selected",
run: function() {
simulate_keyup_event(96 + qty);
},
},
{
content: "Check the qty",
trigger: ".orderline.selected .info em:contains(" + qty + ")",
},
];
}
function connect_disconnect_keyboard() {
var stps = [
{
content: "Open Payment-Screen",
trigger: ".pay-circle",
},
];
if (odoo._modules.indexOf("pos_cashier_select") !== -1) {
stps = stps.concat([
{
trigger: '.modal-dialog.cashier .selection-item:contains("Admin")',
content: "select first cashier",
},
]);
}
stps = stps.concat([
{
content: "Close Payment-Screen",
trigger: ".button:contains(Back)",
},
]);
return stps;
}
function open_cashier_popup_and_close_it() {
return [
{
content: "Open cashier selection popup",
trigger: ".username",
},
{
content: "Make dummy action and simulate escape button clicking",
trigger: '.modal-dialog:not(".oe_hidden")',
run: function() {
simulate_keyup_event(27);
setTimeout(function() {
if ($('.modal-dialog:not(".oe_hidden")').length) {
console.log("error");
} else {
console.log("ok");
}
}, 50);
},
},
{
content:
"Make dummy action in order to properly pass the check for closed popups",
trigger: ".order-button.selected",
},
];
}
var steps = [];
var quantity = 3;
steps = steps.concat(open_pos_neworder());
steps = steps.concat(add_product_to_order("Miscellaneous"));
steps = steps.concat(update_qty_for_product(quantity));
steps = steps.concat(connect_disconnect_keyboard());
steps = steps.concat(update_qty_for_product(quantity + 1));
steps = steps.concat(open_cashier_popup_and_close_it());
tour.register("pos_keyboard_tour", {test: true, url: "/web"}, steps);
});

3
pos_keyboard/tests/__init__.py

@ -0,0 +1,3 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from . import test_pos_keyboard

19
pos_keyboard/tests/test_pos_keyboard.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2019 Kolushov Alexandr <https://it-projects.info/team/kolushovalexandr>
# License MIT (https://opensource.org/licenses/MIT).
import odoo.tests
@odoo.tests.common.at_install(True)
@odoo.tests.common.post_install(True)
class TestUi(odoo.tests.HttpCase):
def test_pos_keyboard(self):
# without a delay there might be problems on the steps whilst opening a POS
# caused by a not yet loaded button's action
self.phantom_js(
"/web",
"odoo.__DEBUG__.services['web_tour.tour'].run('pos_keyboard_tour', 500)",
"odoo.__DEBUG__.services['web_tour.tour'].tours.pos_keyboard_tour.ready",
login="admin",
)

248
to use usual keyboard (not virtual one) in Point of Sale',

@ -0,0 +1,248 @@
SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS
Commands marked with * may be preceded by a number, _N.
Notes in parentheses indicate the behavior if _N is given.
A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
h H Display this help.
q :q Q :Q ZZ Exit.
---------------------------------------------------------------------------
MMOOVVIINNGG
e ^E j ^N CR * Forward one line (or _N lines).
y ^Y k ^K ^P * Backward one line (or _N lines).
f ^F ^V SPACE * Forward one window (or _N lines).
b ^B ESC-v * Backward one window (or _N lines).
z * Forward one window (and set window to _N).
w * Backward one window (and set window to _N).
ESC-SPACE * Forward one window, but don't stop at end-of-file.
d ^D * Forward one half-window (and set half-window to _N).
u ^U * Backward one half-window (and set half-window to _N).
ESC-) RightArrow * Right one half screen width (or _N positions).
ESC-( LeftArrow * Left one half screen width (or _N positions).
ESC-} ^RightArrow Right to last column displayed.
ESC-{ ^LeftArrow Left to first column.
F Forward forever; like "tail -f".
ESC-F Like F but stop when search pattern is found.
r ^R ^L Repaint screen.
R Repaint screen, discarding buffered input.
---------------------------------------------------
Default "window" is the screen height.
Default "half-window" is half of the screen height.
---------------------------------------------------------------------------
SSEEAARRCCHHIINNGG
/_p_a_t_t_e_r_n * Search forward for (_N-th) matching line.
?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line.
n * Repeat previous search (for _N-th occurrence).
N * Repeat previous search in reverse direction.
ESC-n * Repeat previous search, spanning files.
ESC-N * Repeat previous search, reverse dir. & spanning files.
ESC-u Undo (toggle) search highlighting.
&_p_a_t_t_e_r_n * Display only matching lines
---------------------------------------------------
A search pattern may begin with one or more of:
^N or ! Search for NON-matching lines.
^E or * Search multiple files (pass thru END OF FILE).
^F or @ Start search at FIRST file (for /) or last file (for ?).
^K Highlight matches, but don't move (KEEP position).
^R Don't use REGULAR EXPRESSIONS.
---------------------------------------------------------------------------
JJUUMMPPIINNGG
g < ESC-< * Go to first line in file (or line _N).
G > ESC-> * Go to last line in file (or line _N).
p % * Go to beginning of file (or _N percent into file).
t * Go to the (_N-th) next tag.
T * Go to the (_N-th) previous tag.
{ ( [ * Find close bracket } ) ].
} ) ] * Find open bracket { ( [.
ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>.
ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>
---------------------------------------------------
Each "find close bracket" command goes forward to the close bracket
matching the (_N-th) open bracket in the top line.
Each "find open bracket" command goes backward to the open bracket
matching the (_N-th) close bracket in the bottom line.
m_<_l_e_t_t_e_r_> Mark the current top line with <letter>.
M_<_l_e_t_t_e_r_> Mark the current bottom line with <letter>.
'_<_l_e_t_t_e_r_> Go to a previously marked position.
'' Go to the previous position.
^X^X Same as '.
ESC-M_<_l_e_t_t_e_r_> Clear a mark.
---------------------------------------------------
A mark is any upper-case or lower-case letter.
Certain marks are predefined:
^ means beginning of the file
$ means end of the file
---------------------------------------------------------------------------
CCHHAANNGGIINNGG FFIILLEESS
:e [_f_i_l_e] Examine a new file.
^X^V Same as :e.
:n * Examine the (_N-th) next file from the command line.
:p * Examine the (_N-th) previous file from the command line.
:x * Examine the first (or _N-th) file from the command line.
:d Delete the current file from the command line list.
= ^G :f Print current file name.
---------------------------------------------------------------------------
MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS
-_<_f_l_a_g_> Toggle a command line option [see OPTIONS below].
--_<_n_a_m_e_> Toggle a command line option, by name.
__<_f_l_a_g_> Display the setting of a command line option.
___<_n_a_m_e_> Display the setting of an option, by name.
+_c_m_d Execute the less cmd each time a new file is examined.
!_c_o_m_m_a_n_d Execute the shell command with $SHELL.
|XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command.
s _f_i_l_e Save input to a file.
v Edit the current file with $VISUAL or $EDITOR.
V Print version number of "less".
---------------------------------------------------------------------------
OOPPTTIIOONNSS
Most options may be changed either on the command line,
or from within less by using the - or -- command.
Options may be given in one of two forms: either a single
character preceded by a -, or a name preceded by --.
-? ........ --help
Display help (from command line).
-a ........ --search-skip-screen
Search skips current screen.
-A ........ --SEARCH-SKIP-SCREEN
Search starts just after target line.
-b [_N] .... --buffers=[_N]
Number of buffers.
-B ........ --auto-buffers
Don't automatically allocate buffers for pipes.
-c ........ --clear-screen
Repaint by clearing rather than scrolling.
-d ........ --dumb
Dumb terminal.
-D [_x_n_._n] . --color=_x_n_._n
Set screen colors. (MS-DOS only)
-e -E .... --quit-at-eof --QUIT-AT-EOF
Quit at end of file.
-f ........ --force
Force open non-regular files.
-F ........ --quit-if-one-screen
Quit if entire file fits on first screen.
-g ........ --hilite-search
Highlight only last match for searches.
-G ........ --HILITE-SEARCH
Don't highlight any matches for searches.
-h [_N] .... --max-back-scroll=[_N]
Backward scroll limit.
-i ........ --ignore-case
Ignore case in searches that do not contain uppercase.
-I ........ --IGNORE-CASE
Ignore case in all searches.
-j [_N] .... --jump-target=[_N]
Screen position of target lines.
-J ........ --status-column
Display a status column at left edge of screen.
-k [_f_i_l_e] . --lesskey-file=[_f_i_l_e]
Use a lesskey file.
-K ........ --quit-on-intr
Exit less in response to ctrl-C.
-L ........ --no-lessopen
Ignore the LESSOPEN environment variable.
-m -M .... --long-prompt --LONG-PROMPT
Set prompt style.
-n -N .... --line-numbers --LINE-NUMBERS
Don't use line numbers.
-o [_f_i_l_e] . --log-file=[_f_i_l_e]
Copy to log file (standard input only).
-O [_f_i_l_e] . --LOG-FILE=[_f_i_l_e]
Copy to log file (unconditionally overwrite).
-p [_p_a_t_t_e_r_n] --pattern=[_p_a_t_t_e_r_n]
Start at pattern (from command line).
-P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t]
Define new prompt.
-q -Q .... --quiet --QUIET --silent --SILENT
Quiet the terminal bell.
-r -R .... --raw-control-chars --RAW-CONTROL-CHARS
Output "raw" control characters.
-s ........ --squeeze-blank-lines
Squeeze multiple blank lines.
-S ........ --chop-long-lines
Chop (truncate) long lines rather than wrapping.
-t [_t_a_g] .. --tag=[_t_a_g]
Find a tag.
-T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e]
Use an alternate tags file.
-u -U .... --underline-special --UNDERLINE-SPECIAL
Change handling of backspaces.
-V ........ --version
Display the version number of "less".
-w ........ --hilite-unread
Highlight first new line after forward-screen.
-W ........ --HILITE-UNREAD
Highlight first new line after any forward movement.
-x [_N[,...]] --tabs=[_N[,...]]
Set tab stops.
-X ........ --no-init
Don't use termcap init/deinit strings.
-y [_N] .... --max-forw-scroll=[_N]
Forward scroll limit.
-z [_N] .... --window=[_N]
Set size of window.
-" [_c[_c]] . --quotes=[_c[_c]]
Set shell quote characters.
-~ ........ --tilde
Don't display tildes after end of file.
-# [_N] .... --shift=[_N]
Horizontal scroll amount (0 = one half screen width)
--follow-name
The F command changes files if the input file is renamed.
--mouse
Enable mouse input.
--no-keypad
Don't send termcap keypad init/deinit strings.
--no-histdups
Remove duplicates from command history.
--rscroll=C
Set the character used to mark truncated lines.
--save-marks
Retain marks across invocations of less.
--use-backslash
Subsequent options use backslash as escape char.
--wheel-lines=N
Each click of the mouse wheel moves N lines.
---------------------------------------------------------------------------
LLIINNEE EEDDIITTIINNGG
These keys can be used to edit text being entered
on the "command line" at the bottom of the screen.
RightArrow ..................... ESC-l ... Move cursor right one character.
LeftArrow ...................... ESC-h ... Move cursor left one character.
ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word.
ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word.
HOME ........................... ESC-0 ... Move cursor to start of line.
END ............................ ESC-$ ... Move cursor to end of line.
BACKSPACE ................................ Delete char to left of cursor.
DELETE ......................... ESC-x ... Delete char under cursor.
ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor.
ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
UpArrow ........................ ESC-k ... Retrieve previous command line.
DownArrow ...................... ESC-j ... Retrieve next command line.
TAB ...................................... Complete filename & cycle.
SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle.
ctrl-L ................................... Complete filename, list all.

3874
upport in Point Of Sale",
File diff suppressed because it is too large
View File

Loading…
Cancel
Save