Commit d5d1ac39 by Damien Moulard

Merge branch 'ticket_2630' into 'dev_cooperatic'

#2630: Add pos automatic reload after product prices change

See merge request !37
parents cc93f522 9d0f4ac7
......@@ -35,6 +35,7 @@
# be careful : called sequently (exterenal ID must be put before)
#'security/ir.model.access.csv',
#'templates.xml',
"views/view_pos_config.xml",
'static/src/xml/templates.xml',
],
'installable': True,
......
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * lacagette_custom_pos
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-15 08:00+0000\n"
"PO-Revision-Date: 2022-04-15 08:00+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: lacagette_custom_pos
#: model:ir.model.fields,field_description:lacagette_custom_pos.field_pos_config__reload_on_prices_change
msgid "Reload on prices change"
msgstr "Rechargement si des prix changent"
#. module: lacagette_custom_pos
#. openerp-web
#: code:lacagette_addons/lacagette_custom_pos/static/src/js/screens.js:73
#, python-format
msgid "POS data must been refreshed"
msgstr "Des données doivent être rafraichies."
#. module: lacagette_custom_pos
#. openerp-web
#: code:lacagette_addons/lacagette_custom_pos/static/src/js/screens.js:73
#, python-format
msgid "Some product prices have been changed, page will be refreshed"
msgstr "Des prix d'articles ont changé, la page va être rechargée."
from . import pos_config
\ No newline at end of file
from openerp import fields, models
class PosConfig(models.Model):
_inherit = 'pos.config'
reload_on_prices_change = fields.Boolean(
string="Reload on prices change",
default=False)
\ No newline at end of file
odoo.define("lacagette_custom_pos.screens", function (require) {
"use strict";
var screens = require("point_of_sale.screens");
var models = require('point_of_sale.models');
var core = require('web.core');
var dataModel = require('web.DataModel');
var lacagette_products = new dataModel('lacagette.products');
var _t = core._t;
const interval = 1 * 60 * 1000; // used for last_price_change call
var reload_on_prices_change = false;
models.load_fields("pos.config", ['reload_on_prices_change']);
const update_last_price_change_data = async function () {
/*
Ask odoo server data about last prices change
According to response, pos_session variables will be set
in order to make decision about reloading or not pos data
*/
lacagette_products.call('get_last_price_change')
.then(
function(received) {
if (typeof received.data !== "undefined" && received.data.length > 0) {
if (typeof posmodel.pos_session.last_price_update != "undefined") {
posmodel.pos_session.previous_price_update = posmodel.pos_session.last_price_update
}
posmodel.pos_session.last_price_update = received.data[0].write_date
posmodel.pos_session.last_price_update_load = Date.now();
if (posmodel.pos_session.last_price_update != posmodel.pos_session.previous_price_update)
posmodel.pos_session.needs_reload = true;
}
}
)
.fail(function(result, ev){
// Store event date. Used to make the "reloading" decision
posmodel.pos_session.last_network_failure = Date.now();
ev.preventDefault();
})
}
screens.ClientListScreenWidget.include({
init: function(parent, options) {
this._super(parent, options);
reload_on_prices_change = this.pos.config.reload_on_prices_change;
if (reload_on_prices_change) {
posmodel.pos_session.load_at = Date.now();
posmodel.pos_session.needs_reload = false;
const confirmRefresh = event => {
// Called when unload is unsafe
event.preventDefault();
const message = _t("Are you sure you want to refresh the page?")
(event || window.event).returnValue = confirmationMessage; //Gecko + IE
return message; //Gecko + Webkit, Safari, Chrome etc.
};
const checkUnload = event => {
try {
if (window.navigator.onLine == true) {
return undefined;
} else {
return confirmRefresh(event);
}
} catch(err) {
return confirmRefresh(event);
}
}
window.addEventListener("beforeunload", checkUnload, { capture: true });
// Let's init a perpetual regular call to prices update data
setInterval(() => {
// catch all the errors.
update_last_price_change_data().catch(console.log);
}, interval);
}
},
show: function(){
if (typeof posmodel.pos_session.previous_price_update != "undefined"
&& posmodel.pos_session.needs_reload == true) {
/*
At least one product price has been changed since pos session has been started
We can't reload page without having a look to network state
If page reload is called while network is down, the browser will show a blank page
and there will be no way to show POS screens again.
A smarter way to refresh products data would be to process products data retrieve,
in ajax mode, without having to reload whole page code.
It could be the next improve step for this module.
*/
const now = Date.now();
let can_reload_page = false;
if (typeof posmodel.pos_session.last_network_failure == "undefined") {
/*
no network failure while retreiving price change data.
It doesn't mean that network is now available,
since it could be shutdown after last call
Let reload available
only if wifi icon is green is better
but not safe at all !
beforeunload event capture will ask user for confirmation if network has gone
*/
if ($('.js_connected.oe_icon.oe_green').length > 0)
can_reload_page = true;
} else {
// one network failure occured
if (posmodel.pos_session.last_price_update_load > posmodel.pos_session.last_network_failure) {
can_reload_page = true;
}
}
if (can_reload_page === true) {
this.gui.show_popup("alert", {
'title': _t("POS data must been refreshed"),
'body': _t("Some product prices have been changed, page will be refreshed")
});
setTimeout(function(){
window.location.reload();
}, 3000);
} else {
this._super();
}
} else {
this._super();
}
}
});
});
\ No newline at end of file
......@@ -5,6 +5,7 @@
<template id="assets" name="lacagette_pos_sales_assets" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<script type="text/javascript" src="/lacagette_custom_pos/static/src/js/backend.js"></script>
<script type="text/javascript" src="/lacagette_custom_pos/static/src/js/screens.js"></script>
</xpath>
<xpath expr="//link[@id='pos-stylesheet']" position="after">
<link rel="stylesheet" href="/lacagette_custom_pos/static/src/css/lacagette_custom_pos.css" />
......
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_custom_pos_config_form" model="ir.ui.view">
<field name="name">lacagette.custom.pos.config.form</field>
<field name="model">pos.config</field>
<field name="inherit_id" ref="point_of_sale.view_pos_config_form"/>
<field name="arch" type="xml">
<field name="cash_control" position="after">
<field name="reload_on_prices_change"/>
</field>
</field>
</record>
</data>
</openerp>
\ No newline at end of file
<?xml version="1.0"?>
<odoo>
<odoo noupdate="1">
<record id="nb_past_days_to_compute_sales_average" model="ir.config_parameter">
<field name="key">lacagette_products.nb_past_days_to_compute_sales_average</field>
<field name="value">100</field>
......
......@@ -7,6 +7,22 @@ import numpy
class LaCagetteProducts(models.Model):
_name = "lacagette.products"
@api.model
def get_last_price_change(self):
res = {}
try:
sql = """
SELECT
write_date, product_id
FROM product_price_history
ORDER BY write_date DESC LIMIT 1
"""
self.env.cr.execute(sql)
res['data'] = self.env.cr.dictfetchall()
except Exception as e:
res['error'] = str(e)
return res
def get_uoms(self):
res = {}
try:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment