[IMP] point_of_sale: cashbox opening popup.
Move the cashbox opening control from the left panel of the product screen widget to a popup that is raised at the opening of the session if its state is: opening_control. task-id: 2321973
This commit is contained in:
committed by
Pierre Masereel
parent
9d6f107b1c
commit
396918d638
@@ -3413,19 +3413,6 @@ td {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cashbox-input {
|
||||
margin: auto;
|
||||
line-height: 74px;
|
||||
font-size: 16px;
|
||||
border: solid 1px rgb(202, 202, 202);
|
||||
border-top-width: 0px;
|
||||
cursor: pointer;
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
flex-grow: 1;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.currencyCashBox {
|
||||
font-size: 30px;
|
||||
}
|
||||
@@ -3541,3 +3528,46 @@ td {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.pos .cashbox-button {
|
||||
height: 54px;
|
||||
width: 54px;
|
||||
font-weight: bold;
|
||||
vertical-align: middle;
|
||||
color: #555555;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-right: 1px solid;
|
||||
border-bottom: 1px solid;
|
||||
border-color: #bfbfbf;
|
||||
transition: all 150ms linear;
|
||||
}
|
||||
|
||||
.pos .cashbox-input {
|
||||
line-height: 74px;
|
||||
border: solid 1px rgb(202, 202, 202);
|
||||
border-top-width: 0px;
|
||||
cursor: pointer;
|
||||
background: white;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.cashbox-input .input-title {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
font-weight: bold;
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
.cashbox-input .input-amount {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.cashbox-notes {
|
||||
font-style: italic;
|
||||
font-weight: 350;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
@@ -1,42 +1,71 @@
|
||||
odoo.define('point_of_sale.CashBoxOpening', function(require) {
|
||||
odoo.define('point_of_sale.CashOpeningPopup', function(require) {
|
||||
'use strict';
|
||||
|
||||
const { useState, useRef} = owl.hooks;
|
||||
const { useListener } = require('web.custom_hooks');
|
||||
const NumberBuffer = require('point_of_sale.NumberBuffer');
|
||||
const PosComponent = require('point_of_sale.PosComponent');
|
||||
const AbstractAwaitablePopup = require('point_of_sale.AbstractAwaitablePopup');
|
||||
const Registries = require('point_of_sale.Registries');
|
||||
const { Gui } = require('point_of_sale.Gui');
|
||||
|
||||
class CashBoxOpening extends PosComponent {
|
||||
|
||||
class CashOpeningPopup extends AbstractAwaitablePopup {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.changes = {};
|
||||
this.defaultValue = this.env.pos.bank_statement.balance_start || 0;
|
||||
this.symbol = this.env.pos.currency.symbol;
|
||||
}
|
||||
captureChange(event) {
|
||||
this.changes[event.target.name] = event.target.value;
|
||||
this.cashBoxValue = this.env.pos.bank_statement.balance_start || 0;;
|
||||
this.currency = this.env.pos.currency;
|
||||
this.state = useState({
|
||||
notes: "",
|
||||
});
|
||||
useListener('numpad-click-input', this._updateCashAmount);
|
||||
useListener('update-cash', this._updateCashAmount);
|
||||
this.inputRef = useRef('input');
|
||||
NumberBuffer.use({
|
||||
nonKeyboardInputEvent: 'numpad-click-input',
|
||||
triggerAtInput: 'update-cash',
|
||||
useWithBarcode: false,
|
||||
});
|
||||
}
|
||||
|
||||
startSession() {
|
||||
let cashOpening = this.changes.cashBoxValue? this.changes.cashBoxValue: this.defaultValue;
|
||||
if(isNaN(cashOpening)) {
|
||||
Gui.showPopup('ErrorPopup',{
|
||||
'title': 'Wrong value',
|
||||
'body': 'Please insert a correct value.',
|
||||
});
|
||||
if(!parseFloat(this.cashBoxValue))
|
||||
return;
|
||||
}
|
||||
this.env.pos.bank_statement.balance_start = cashOpening;
|
||||
this.env.pos.bank_statement.balance_start = parseFloat(this.cashBoxValue);
|
||||
this.env.pos.pos_session.state = 'opened';
|
||||
this.props.cashControl.cashControl = false;
|
||||
this.rpc({
|
||||
model: 'pos.session',
|
||||
model: 'pos.session',
|
||||
method: 'set_cashbox_pos',
|
||||
args: [this.env.pos.pos_session.id, cashOpening, this.changes.notes],
|
||||
args: [this.env.pos.pos_session.id, parseFloat(this.cashBoxValue), this.state.notes],
|
||||
});
|
||||
this.trigger('close-popup');
|
||||
}
|
||||
|
||||
sendInput(value) {
|
||||
this.trigger('numpad-click-input', { value });
|
||||
}
|
||||
|
||||
async _updateCashAmount(event) {
|
||||
let value = event.detail.value ? event.detail.value : event.detail.key
|
||||
if(value !== "Backspace") {
|
||||
if(this.cashBoxValue === 0) {
|
||||
this.cashBoxValue = value !== "."? value: this.cashBoxValue + value;
|
||||
} else {
|
||||
this.cashBoxValue += value;
|
||||
}
|
||||
} else {
|
||||
if(this.cashBoxValue.length > 1) {
|
||||
this.cashBoxValue = this.cashBoxValue.substring(0, this.cashBoxValue.length -1)
|
||||
} else {
|
||||
this.cashBoxValue = 0;
|
||||
}
|
||||
}
|
||||
this.render();
|
||||
}
|
||||
|
||||
}
|
||||
CashBoxOpening.template = 'CashBoxOpening';
|
||||
|
||||
Registries.Component.add(CashBoxOpening);
|
||||
CashOpeningPopup.template = 'CashOpeningPopup';
|
||||
Registries.Component.add(CashOpeningPopup);
|
||||
|
||||
return CashBoxOpening;
|
||||
return CashOpeningPopup;
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ odoo.define('point_of_sale.ProductScreen', function(require) {
|
||||
const { useListener } = require('web.custom_hooks');
|
||||
const Registries = require('point_of_sale.Registries');
|
||||
const { onChangeOrder, useBarcodeReader } = require('point_of_sale.custom_hooks');
|
||||
const { Gui } = require('point_of_sale.Gui');
|
||||
const { useState } = owl.hooks;
|
||||
|
||||
class ProductScreen extends ControlButtonsMixin(PosComponent) {
|
||||
@@ -32,11 +33,13 @@ odoo.define('point_of_sale.ProductScreen', function(require) {
|
||||
triggerAtInput: 'update-selected-orderline',
|
||||
useWithBarcode: true,
|
||||
});
|
||||
let status = this.showCashBoxOpening()
|
||||
this.state = useState({ cashControl: status, numpadMode: 'quantity' });
|
||||
this.state = useState({ numpadMode: 'quantity' });
|
||||
this.mobile_pane = this.props.mobile_pane || 'right';
|
||||
}
|
||||
mounted() {
|
||||
if(this.env.pos.config.cash_control && this.env.pos.pos_session.state == 'opening_control') {
|
||||
Gui.showPopup('CashOpeningPopup');
|
||||
}
|
||||
this.env.pos.on('change:selectedClient', this.render, this);
|
||||
}
|
||||
willUnmount() {
|
||||
@@ -56,11 +59,6 @@ odoo.define('point_of_sale.ProductScreen', function(require) {
|
||||
get currentOrder() {
|
||||
return this.env.pos.get_order();
|
||||
}
|
||||
showCashBoxOpening() {
|
||||
if(this.env.pos.config.cash_control && this.env.pos.pos_session.state == 'opening_control')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
async _clickProduct(event) {
|
||||
if (!this.currentOrder) {
|
||||
this.env.pos.add_new_order();
|
||||
|
||||
@@ -1,27 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
|
||||
<t t-name="CashBoxOpening" owl="1">
|
||||
<div style="margin-top: -20px;">
|
||||
<br/>
|
||||
<h1>
|
||||
<span>
|
||||
Pos closed.
|
||||
</span><br/>
|
||||
<span>
|
||||
Set a cash opening
|
||||
</span>
|
||||
|
||||
</h1>
|
||||
<h1>Opening amount:</h1>
|
||||
<input name="cashBoxValue" class="cashbox-input" t-on-change="captureChange" t-att-value="defaultValue"/>
|
||||
<span class="currencyCashBox" t-esc="symbol"/>
|
||||
|
||||
<h1>Notes:</h1>
|
||||
<textarea name="notes" style="width: 51%" t-on-change="captureChange"/><br/><br/>
|
||||
|
||||
<span class="control-button" t-on-click="startSession()">Open</span>
|
||||
<t t-name="CashOpeningPopup" owl="1">
|
||||
<div role="dialog" class="modal-dialog">
|
||||
<div class="popup popup-confirm">
|
||||
<header class="title drag-handle">
|
||||
Start Cash Drawer
|
||||
</header>
|
||||
<main class="body">
|
||||
<div class="cashbox-input">
|
||||
<span class="input-title">
|
||||
Starting Cash
|
||||
</span>
|
||||
|
||||
<span class="input-amount">
|
||||
<span t-if="currency.position === 'before'">
|
||||
<t t-esc="currency.symbol"/><span> </span>
|
||||
</span>
|
||||
<t t-esc="cashBoxValue"/>
|
||||
<span t-if="currency.position === 'after'">
|
||||
<span> </span><t t-esc="currency.symbol"/>
|
||||
</span>
|
||||
</span>
|
||||
</div><br/>
|
||||
<textarea style="line-height: 20px;" rows="3"
|
||||
placeholder="Notes" class="cashbox-input cashbox-notes"
|
||||
t-model="state.notes" t-ref="input"/><br/><br/>
|
||||
<div>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('1')">1</button>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('2')">2</button>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('3')">3</button>
|
||||
<br/>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('4')">4</button>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('5')">5</button>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('6')">6</button>
|
||||
<br />
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('7')">7</button>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('8')">8</button>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('9')">9</button>
|
||||
<br/>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('.')">.</button>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('0')">0</button>
|
||||
<button class="input-button number-char cashbox-button" t-on-click="sendInput('Backspace')">
|
||||
<img style="pointer-events: none;" src="/point_of_sale/static/src/img/backspace.png"
|
||||
width="24" height="21" alt="Backspace" />
|
||||
</button>
|
||||
</div><br/>
|
||||
</main>
|
||||
<footer class="footer">
|
||||
<button style="height: 50px; margin: 22px 22px 22px 0px" t-model="state.notes" class="button cashbox-button" t-on-click="startSession()">Start Drawer</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -5,29 +5,24 @@
|
||||
<div class="product-screen screen" t-att-class="{ oe_hidden: !props.isShown }">
|
||||
<div class="screen-full-width">
|
||||
<div class="leftpane" t-if="!env.isMobile || mobile_pane === 'left'">
|
||||
<t t-if="state.cashControl">
|
||||
<CashBoxOpening cashControl="state"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<OrderWidget/>
|
||||
<div class="pads">
|
||||
<div class="control-buttons">
|
||||
<t t-foreach="controlButtons" t-as="cb" t-key="cb.name">
|
||||
<t t-component="cb.component" t-key="cb.name" />
|
||||
</t>
|
||||
</div>
|
||||
<div class="subpads">
|
||||
<ActionpadWidget client="client"/>
|
||||
<NumpadWidget activeMode="state.numpadMode" />
|
||||
</div>
|
||||
<OrderWidget/>
|
||||
<div class="pads">
|
||||
<div class="control-buttons">
|
||||
<t t-foreach="controlButtons" t-as="cb" t-key="cb.name">
|
||||
<t t-component="cb.component" t-key="cb.name" />
|
||||
</t>
|
||||
</div>
|
||||
<t t-if="env.isMobile">
|
||||
<MobileOrderWidget pane="mobile_pane" t-on-switchpane="switchPane"/>
|
||||
</t>
|
||||
<div class="subpads">
|
||||
<ActionpadWidget client="client"/>
|
||||
<NumpadWidget activeMode="state.numpadMode" />
|
||||
</div>
|
||||
</div>
|
||||
<t t-if="env.isMobile">
|
||||
<MobileOrderWidget pane="mobile_pane" t-on-switchpane="switchPane"/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="rightpane" t-if="!env.isMobile || mobile_pane === 'right'">
|
||||
<ProductsWidget t-if="!state.cashControl"/>
|
||||
<ProductsWidget/>
|
||||
<t t-if="env.isMobile">
|
||||
<MobileOrderWidget pane="mobile_pane" t-on-switchpane="switchPane"/>
|
||||
</t>
|
||||
|
||||
Reference in New Issue
Block a user