[IMP] point_of_sale: usability of ClosePosPopup
In this commit we modify the ClosePosPopup so that we make it more usable. For this reason we expose less info in order to keep it simple for the user and we rename the footer buttons respecting the Odoo standards. Finally, since we want to make it more obvious to the user and avoid unwanted acceptance of the payment difference, we show ConfirmPopup with the relevant information. task-2755384 subtask of task-2669747 Part-of: odoo/odoo#88006
This commit is contained in:
@@ -8,38 +8,39 @@
|
||||
padding: 15px 50px;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .session-overview {
|
||||
.pos .close-pos-popup header {
|
||||
display: flex;
|
||||
margin-bottom: 30px;
|
||||
justify-content: space-between;
|
||||
width: auto;
|
||||
height: 65px;
|
||||
background-color: rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .overview-info {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
.pos .close-pos-popup .title {
|
||||
height: inherit;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .overview-info .info-value {
|
||||
margin-left: 50px;
|
||||
.pos .close-pos-popup .total-orders {
|
||||
height: inherit;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .overview-info span {
|
||||
margin-bottom: 10px;
|
||||
.pos .close-pos-popup .total-orders .amount {
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .column-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .session-overview .opening-note {
|
||||
margin-left: 70px;
|
||||
.pos .close-pos-popup .opening-note {
|
||||
color: darkgrey;
|
||||
text-align: left;
|
||||
font-size: 16px;
|
||||
width: 250px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
max-height: 90px;
|
||||
padding-left: 10px;
|
||||
padding: 5px 10px;
|
||||
margin-bottom: 10px;
|
||||
border-left: solid 3px darkgrey;
|
||||
overflow-y: auto;
|
||||
word-break: break-word;
|
||||
@@ -63,8 +64,16 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .right-align {
|
||||
text-align: right;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .payment-methods-overview table .pos-input {
|
||||
width: 85px;
|
||||
width: 110px;
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .payment-methods-overview table .warning {
|
||||
@@ -75,6 +84,7 @@
|
||||
.pos .close-pos-popup .body .button.icon {
|
||||
margin: 0;
|
||||
float: unset;
|
||||
margin-right: 0 20px 0 20px;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .payment-methods-overview table .cash-sign {
|
||||
@@ -100,31 +110,23 @@
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .accept-closing {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .accept-closing label, #accept {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .accept-closing label.disabled {
|
||||
cursor: default;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup #accept {
|
||||
all: revert;
|
||||
margin-right: 10px;
|
||||
.pos .close-pos-popup .footer {
|
||||
box-sizing: border-box;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .accept-closing .warning {
|
||||
color: red;
|
||||
font-style: italic;
|
||||
.pos .close-pos-popup .footer .button {
|
||||
float: left;
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
@@ -149,8 +151,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .footer .button {
|
||||
width: 150px;
|
||||
.pos .close-pos-popup .footer .small.button {
|
||||
float: right;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.pos .close-pos-popup .footer .button.disabled {
|
||||
|
||||
@@ -8,7 +8,7 @@ odoo.define('point_of_sale.HeaderButton', function(require) {
|
||||
// This is the close session button
|
||||
class HeaderButton extends PosComponent {
|
||||
onClick() {
|
||||
this.showPopup('ClosePosPopup');
|
||||
this.showPopup('ClosePosPopup', { keepBehind: true });
|
||||
}
|
||||
}
|
||||
HeaderButton.template = 'HeaderButton';
|
||||
|
||||
@@ -40,7 +40,7 @@ odoo.define('point_of_sale.ClosePosPopup', function(require) {
|
||||
this.amountAuthorizedDiff = closingData.amount_authorized_diff;
|
||||
|
||||
// component state and refs definition
|
||||
const state = {notes: '', acceptClosing: false, payments: {}};
|
||||
const state = {notes: '', payments: {}};
|
||||
if (this.cashControl) {
|
||||
state.payments[this.defaultCashDetails.id] = {counted: 0, difference: -this.defaultCashDetails.amount, number: 0};
|
||||
}
|
||||
@@ -84,7 +84,6 @@ odoo.define('point_of_sale.ClosePosPopup', function(require) {
|
||||
}
|
||||
this.state.payments[paymentId].difference =
|
||||
this.env.pos.round_decimals_currency(this.state.payments[paymentId].counted - expectedAmount);
|
||||
this.state.acceptClosing = false;
|
||||
}
|
||||
updateCountedCash({ total, moneyDetailsNotes, moneyDetails }) {
|
||||
this.state.payments[this.defaultCashDetails.id].counted = total;
|
||||
@@ -95,7 +94,6 @@ odoo.define('point_of_sale.ClosePosPopup', function(require) {
|
||||
}
|
||||
this.manualInputCashCount = false;
|
||||
this.moneyDetails = moneyDetails;
|
||||
this.state.acceptClosing = false;
|
||||
this.closeDetailsPopup();
|
||||
}
|
||||
hasDifference() {
|
||||
@@ -105,8 +103,28 @@ odoo.define('point_of_sale.ClosePosPopup', function(require) {
|
||||
const absDifferences = Object.entries(this.state.payments).map(pm => Math.abs(pm[1].difference));
|
||||
return this.isManager || this.amountAuthorizedDiff == null || Math.max(...absDifferences) <= this.amountAuthorizedDiff;
|
||||
}
|
||||
canCloseSession() {
|
||||
return !this.cashControl || !this.hasDifference() || this.state.acceptClosing;
|
||||
async onCloseSession() {
|
||||
if (!this.cashControl || !this.hasDifference()) {
|
||||
this.closeSession();
|
||||
} else if (this.hasUserAuthority()) {
|
||||
const { confirmed } = await this.showPopup('ConfirmPopup', {
|
||||
title: this.env._t('Payments Difference'),
|
||||
body: this.env._t('Do you want to accept payments difference and post a profit/loss journal entry?'),
|
||||
});
|
||||
if (confirmed) {
|
||||
this.closeSession();
|
||||
}
|
||||
} else {
|
||||
await this.showPopup('ConfirmPopup', {
|
||||
title: this.env._t('Payments Difference'),
|
||||
body: _.str.sprintf(
|
||||
this.env._t('The maximum difference allowed is %s.\n\
|
||||
Please contact your manager to accept the closing difference.'),
|
||||
this.env.pos.format_currency(this.amountAuthorizedDiff)
|
||||
),
|
||||
confirmText: this.env._t('OK'),
|
||||
})
|
||||
}
|
||||
}
|
||||
canCancel() {
|
||||
return true;
|
||||
@@ -120,7 +138,7 @@ odoo.define('point_of_sale.ClosePosPopup', function(require) {
|
||||
this.trigger('close-pos');
|
||||
}
|
||||
async closeSession() {
|
||||
if (this.canCloseSession() && !this.closeSessionClicked) {
|
||||
if (!this.closeSessionClicked) {
|
||||
this.closeSessionClicked = true;
|
||||
let response;
|
||||
if (this.cashControl) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<textarea placeholder="Notes" class="opening-cash-notes" t-model="state.notes"/>
|
||||
<textarea placeholder="Add an opening note..." class="opening-cash-notes" t-model="state.notes"/>
|
||||
</main>
|
||||
<footer class="footer">
|
||||
<div class="button" t-on-click="startSession">Open session</div>
|
||||
|
||||
@@ -3,33 +3,23 @@
|
||||
|
||||
<t t-name="ClosePosPopup" owl="1">
|
||||
<div class="popup close-pos-popup">
|
||||
<header class="title">
|
||||
CLOSING CONTROL
|
||||
<header>
|
||||
<div class="title">Closing Session</div>
|
||||
<div class="total-orders">
|
||||
Total <t t-esc="ordersDetails.quantity"/> orders:
|
||||
<span class="amount" t-esc="env.pos.format_currency(ordersDetails.amount)"/>
|
||||
</div>
|
||||
</header>
|
||||
<main class="body">
|
||||
<div class="session-overview">
|
||||
<div class="overview-info">
|
||||
<div class="info-title column-left">
|
||||
<span>Total <t t-esc="ordersDetails.quantity"/> orders</span>
|
||||
<span>Payments</span>
|
||||
<span>Customer Account</span>
|
||||
</div>
|
||||
<div class="info-value column-left">
|
||||
<span t-esc="env.pos.format_currency(ordersDetails.amount)"/>
|
||||
<span t-esc="env.pos.format_currency(paymentsAmount)"/>
|
||||
<span t-esc="env.pos.format_currency(payLaterAmount)"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="openingNotes" class="opening-note">
|
||||
<t t-esc="openingNotes"/>
|
||||
</div>
|
||||
<div t-if="openingNotes" class="opening-note">
|
||||
<t t-esc="openingNotes"/>
|
||||
</div>
|
||||
<div class="payment-methods-overview">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Payment Method</th>
|
||||
<th>Expected</th>
|
||||
<th class="right-align">Expected</th>
|
||||
<th style="width: 25%">Counted</th>
|
||||
<th style="width: 20%">Difference</th>
|
||||
</tr>
|
||||
@@ -38,7 +28,7 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td t-esc="defaultCashDetails.name"/>
|
||||
<td t-esc="env.pos.format_currency(defaultCashDetails.amount)"/>
|
||||
<td t-esc="env.pos.format_currency(defaultCashDetails.amount)" class="right-align"/>
|
||||
<td class="flex" t-on-input="() => this.handleInputChange(defaultCashDetails.id)">
|
||||
<input class="pos-input" type="number" t-model.number="state.payments[defaultCashDetails.id].counted"/>
|
||||
<div class="button icon" t-on-click="openDetailsPopup">
|
||||
@@ -51,7 +41,7 @@
|
||||
<tbody class="cash-overview">
|
||||
<tr>
|
||||
<td>Opening</td>
|
||||
<td t-esc="env.pos.format_currency(defaultCashDetails.opening)"/>
|
||||
<td t-esc="env.pos.format_currency(defaultCashDetails.opening)" class="right-align"/>
|
||||
</tr>
|
||||
<tr t-foreach="defaultCashDetails.moves" t-as="move" t-key="move.name">
|
||||
<td>
|
||||
@@ -60,7 +50,7 @@
|
||||
<t t-esc="move.name"/>
|
||||
</div>
|
||||
</td>
|
||||
<td t-esc="env.pos.format_currency(Math.abs(move.amount))" />
|
||||
<td t-esc="env.pos.format_currency(Math.abs(move.amount))" class="right-align"/>
|
||||
</tr>
|
||||
<tr t-if="defaultCashDetails.payment_amount">
|
||||
<td>
|
||||
@@ -69,14 +59,14 @@
|
||||
Payments in <t t-esc="defaultCashDetails.name"/>
|
||||
</div>
|
||||
</td>
|
||||
<td t-esc="env.pos.format_currency(Math.abs(defaultCashDetails.payment_amount))"/>
|
||||
<td t-esc="env.pos.format_currency(Math.abs(defaultCashDetails.payment_amount))" class="right-align"/>
|
||||
</tr>
|
||||
</tbody>
|
||||
</t>
|
||||
<tbody t-if="otherPaymentMethods.length > 0">
|
||||
<tr t-foreach="otherPaymentMethods" t-as="pm" t-key="pm.id">
|
||||
<td t-esc="pm.name"/>
|
||||
<td t-esc="env.pos.format_currency(pm.amount)"/>
|
||||
<td t-esc="env.pos.format_currency(pm.amount)" class="right-align"/>
|
||||
<t t-set="_showDiff" t-value="_getShowDiff(pm)" />
|
||||
<td t-if="_showDiff" t-on-input="() => this.handleInputChange(pm.id)"><input class="pos-input" type="number" t-model.number="state.payments[pm.id].counted"/></td>
|
||||
<td t-if="_showDiff" t-esc="env.pos.format_currency(state.payments[pm.id].difference)" t-att-class="{'warning': state.payments[pm.id].difference}"/>
|
||||
@@ -84,18 +74,14 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<textarea placeholder="Notes" class="closing-notes" t-model="state.notes"/>
|
||||
<div class="accept-closing" t-att-class="{invisible: !hasDifference()}">
|
||||
<t t-set="_hasUserAuthority" t-value="hasUserAuthority()" />
|
||||
<input t-att-disabled="!_hasUserAuthority" type="checkbox" id="accept" t-model="state.acceptClosing"/>
|
||||
<label t-att-class="{disabled: !_hasUserAuthority}" for="accept">Accept payments difference and post a profit/loss journal entry</label>
|
||||
<div class="warning" t-att-class="{invisible: _hasUserAuthority}">The maximum difference allowed is <t t-esc="env.pos.format_currency(amountAuthorizedDiff)"/>. Please contact your manager to accept the closing difference.</div>
|
||||
</div>
|
||||
<textarea placeholder="Add a closing note..." class="closing-notes" t-model="state.notes"/>
|
||||
</main>
|
||||
<footer class="footer">
|
||||
<div class="button" t-att-class="{'disabled': !canCancel()}" t-on-click="cancelPopup">Continue Selling</div>
|
||||
<div class="button" t-on-click="closePos">Keep Session Open</div>
|
||||
<div class="button" t-att-class="{'disabled': !canCloseSession()}" t-on-click="closeSession">Close Session</div>
|
||||
<div class="button highlight" t-on-click="onCloseSession">Close Session</div>
|
||||
<div class="button" t-on-click="closePos" title="Visit the Backend but keep session open">Backend</div>
|
||||
<div class="button" t-att-class="{'disabled': !canCancel()}" t-on-click="cancelPopup">Discard</div>
|
||||
<div class="small button icon"><i class="fa fa-print" role="img" title="Print the report"/></div>
|
||||
<div class="small button icon"><i class="fa fa-file-pdf-o" role="img" title="Download the report as PDF"/></div>
|
||||
</footer>
|
||||
</div>
|
||||
<MoneyDetailsPopup
|
||||
|
||||
@@ -399,7 +399,7 @@ odoo.define('point_of_sale.tour.acceptance', function (require) {
|
||||
trigger: ".header-button",
|
||||
}, {
|
||||
content: "close the Point of Sale frontend",
|
||||
trigger: ".close-pos-popup .button:contains('Continue Selling')",
|
||||
trigger: ".close-pos-popup .button:contains('Discard')",
|
||||
run: function() {}, //it's a check,
|
||||
}]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user