[IMP] point_of_sale: display rescue session

- Add link to see rescue session on each `pos_config`
- Change error popup by a alert popup when closing a pos.

Before the user wasn't notified when a rescue session isn't closed.
The popup isn't an error but a notification that inform the user that the session is already closed and a rescue session was created.

closes odoo/odoo#107000

Taskid: 2817110
Related: odoo/upgrade#4111
Signed-off-by: Trinh Jacky (trj) <trj@odoo.com>
This commit is contained in:
David Monnom (moda)
2023-01-10 12:34:59 +01:00
parent 2587f31912
commit 9644ca52ff
6 changed files with 94 additions and 20 deletions
+9 -8
View File
@@ -106,7 +106,7 @@ class PosConfig(models.Model):
session_ids = fields.One2many('pos.session', 'config_id', string='Sessions')
current_session_id = fields.Many2one('pos.session', compute='_compute_current_session', string="Current Session")
current_session_state = fields.Char(compute='_compute_current_session')
number_of_opened_session = fields.Integer(string="Number of Opened Session", compute='_compute_current_session')
number_of_rescue_session = fields.Integer(string="Number of Rescue Session", compute='_compute_current_session')
last_session_closing_cash = fields.Float(compute='_compute_last_session')
last_session_closing_date = fields.Date(compute='_compute_last_session')
pos_session_username = fields.Char(compute='_compute_current_session_user')
@@ -213,13 +213,14 @@ class PosConfig(models.Model):
"""If there is an open session, store it to current_session_id / current_session_State.
"""
for pos_config in self:
opened_sessions = pos_config.session_ids.filtered(lambda s: not s.state == 'closed')
session = pos_config.session_ids.filtered(lambda s: not s.state == 'closed' and not s.rescue)
opened_sessions = pos_config.session_ids.filtered(lambda s: s.state != 'closed')
rescue_sessions = opened_sessions.filtered('rescue')
session = pos_config.session_ids.filtered(lambda s: s.state != 'closed' and not s.rescue)
# sessions ordered by id desc
pos_config.number_of_opened_session = len(opened_sessions)
pos_config.has_active_session = opened_sessions and True or False
pos_config.current_session_id = session and session[0].id or False
pos_config.current_session_state = session and session[0].state or False
pos_config.number_of_rescue_session = len(rescue_sessions)
@api.depends('session_ids')
def _compute_last_session(self):
@@ -543,13 +544,13 @@ class PosConfig(models.Model):
'type': 'ir.actions.act_window',
}
def open_opened_session_list(self):
def open_opened_rescue_session_form(self):
self.ensure_one()
return {
'name': _('Opened Sessions'),
'res_model': 'pos.session',
'view_mode': 'tree,kanban,form',
'view_mode': 'form',
'res_id': self.session_ids.filtered(lambda s: s.state != 'closed' and s.rescue).id,
'type': 'ir.actions.act_window',
'domain': [('state', '!=', 'closed'), ('config_id', '=', self.id)]
}
# All following methods are made to create data needed in POS, when a localisation
+10 -1
View File
@@ -494,7 +494,16 @@ class PosSession(models.Model):
if any(order.state == 'draft' for order in self.order_ids):
return {'successful': False, 'message': _("You cannot close the POS when orders are still in draft"), 'redirect': False}
if self.state == 'closed':
return {'successful': False, 'message': _("This session is already closed."), 'redirect': True}
return {
'successful': False,
'type': 'alert',
'title': 'Session already closed',
'message': _("The session has been already closed by another User. "
"All sales completed in the meantime have been saved in a "
"Rescue Session, which can be reviewed anytime and posted "
"to Accounting from Point of Sale's dashboard."),
'redirect': True
}
if bank_payment_method_diffs:
no_loss_account = self.env['account.journal']
no_profit_account = self.env['account.journal']
@@ -0,0 +1,17 @@
/** @odoo-module */
import AbstractAwaitablePopup from "@point_of_sale/js/Popups/AbstractAwaitablePopup";
import Registries from "@point_of_sale/js/Registries";
import { _lt } from "@web/core/l10n/translation";
export class AlertPopup extends AbstractAwaitablePopup {}
AlertPopup.template = "AlertPopup";
AlertPopup.defaultProps = {
confirmText: _lt("Ok"),
title: "",
body: "",
cancelKey: false,
};
Registries.Component.add(AlertPopup);
@@ -132,11 +132,26 @@ class ClosePosPopup extends AbstractAwaitablePopup {
return this.handleClosingError(response);
}
}
await this.rpc({
model: "pos.session",
method: "update_closing_control_state_session",
args: [this.env.pos.pos_session.id, this.state.notes],
});
try {
await this.rpc({
model: "pos.session",
method: "update_closing_control_state_session",
args: [this.env.pos.pos_session.id, this.state.notes],
});
} catch (error) {
// We have to handle the error manually otherwise the validation check stops the script.
// In case of "rescue session", we want to display the next popup with "handleClosingError".
// FIXME
if (
!error.message &&
!error.message.data &&
error.message.data.message !== "This session is already closed."
) {
throw error;
}
}
try {
const bankPaymentMethodDiffPairs = this.otherPaymentMethods
.filter((pm) => pm.type == "bank")
@@ -170,11 +185,23 @@ class ClosePosPopup extends AbstractAwaitablePopup {
window.location = "/web#action=point_of_sale.action_client_pos_menu";
}
}
this.closeSessionClicked = false;
}
this.closeSessionClicked = false;
}
async handleClosingError(response) {
await this.showPopup("ErrorPopup", { title: "Error", body: response.message });
let popupType = "";
let title = "";
if (response.type == "alert") {
popupType = "AlertPopup";
title = response.title ? response.title : "";
} else {
popupType = "ErrorPopup";
title = "Error";
}
await this.showPopup(popupType, { title: title, body: response.message });
if (response.redirect) {
window.location = "/web#action=point_of_sale.action_client_pos_menu";
}
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="AlertPopup" owl="1">
<div class="popup">
<p class="title">
<t t-esc="props.title" />
</p>
<p class="body">
<t t-esc="props.body" />
</p>
<div class="footer">
<div class="button cancel" t-on-click="confirm">
<t t-esc="props.confirmText" />
</div>
</div>
</div>
</t>
</templates>
@@ -60,7 +60,7 @@
<field name="pos_session_state"/>
<field name="pos_session_duration"/>
<field name="currency_id"/>
<field name="number_of_opened_session"/>
<field name="number_of_rescue_session"/>
<templates>
<t t-name="kanban-menu">
<div class="container">
@@ -149,9 +149,11 @@
</div>
</div>
<button t-if="record.number_of_opened_session.value &gt; 1" class="btn btn-link" style="padding-left:0; text-decoration: underline" name="open_opened_session_list" type="object">
There are <t t-esc="record.number_of_opened_session.value"/> open sessions
</button>
<div>
<a t-if="record.number_of_rescue_session.value &gt; 0" class="oe_kanban_action oe_kanban_action_a col-12" name="open_opened_rescue_session_form" type="object">
<t t-esc="record.number_of_rescue_session.value" /> outstanding rescue session
</a>
</div>
</div>
</div>
<div style="text-align:right;">