diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/point_of_sale/static/src/xml | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/point_of_sale/static/src/xml')
71 files changed, 2628 insertions, 0 deletions
diff --git a/addons/point_of_sale/static/src/xml/Chrome.xml b/addons/point_of_sale/static/src/xml/Chrome.xml new file mode 100644 index 00000000..17593b2f --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Chrome.xml @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="Chrome" owl="1"> + <div class="pos" t-att-class="{ 'big-scrollbars': state.hasBigScrollBars }"> + <div class="pos-receipt-print"></div> + <div class="pos-topheader" t-att-class="{ oe_hidden: state.uiState !== 'READY' }"> + <div t-if="tempScreen.isShown" class="block-top-header" /> + <div class="pos-branding" t-if= "!env.isMobile"> + <img class="pos-logo" t-on-click="trigger('toggle-debug-widget')" + src="/point_of_sale/static/src/img/logo.png" alt="Logo" /> + <TicketButton isTicketScreenShown="isTicketScreenShown" /> + </div> + <div class="pos-rightheader"> + <TicketButton isTicketScreenShown="isTicketScreenShown" t-if="env.isMobile" /> + <div class="search-bar-portal" /> + <div class="status-buttons-portal" /> + </div> + </div> + <t t-if="state.uiState === 'READY'"> + <Portal target="'.pos .status-buttons-portal'"> + <div class="status-buttons"> + <t t-if="!env.isMobile"> + <CashierName /> + </t> + <OrderManagementButton t-if="env.pos.config.manage_orders" /> + <SaleDetailsButton t-if="env.pos.proxy.printer" /> + <ProxyStatus t-if="env.pos.config.use_proxy" /> + <ClientScreenButton t-if="clientScreenButtonIsShown" /> + <SyncNotification /> + <HeaderButton /> + </div> + </Portal> + <div class="pos-content"> + <div class="window"> + <div class="subwindow"> + <div class="subwindow-container"> + <div class="subwindow-container-fix screens"> + <t isShown="!tempScreen.isShown" t-component="mainScreen.component" + t-props="mainScreenProps" t-key="mainScreen.name" /> + <t t-if="tempScreen.isShown" t-component="tempScreen.component" + t-props="tempScreenProps" t-key="tempScreen.name" /> + </div> + </div> + </div> + </div> + <DebugWidget t-if="env.isDebug() and state.debugWidgetIsShown" + t-transition="fade" /> + </div> + </t> + + <div t-if="['LOADING', 'CLOSING'].includes(state.uiState)" class="loader" t-transition="swing"> + <div class="loader-feedback"> + <h1 class="message"> + <t t-esc="loading.message" /> + </h1> + <div class="progressbar"> + <div class="progress" t-ref="progressbar"></div> + </div> + <div t-if="loading.skipButtonIsShown" class="button skip" t-on-click="trigger('loading-skip-callback')"> + Skip + </div> + </div> + </div> + + <!-- Allow popups to be visible at any state of the ui. --> + <div t-if="popup.isShown" class="popups"> + <t t-component="popup.component" t-props="popupProps" + t-key="popup.name" /> + </div> + + <NotificationSound t-if="state.sound.src" sound="state.sound" /> + </div> + </t> + + <t t-name="CustomerFacingDisplayHead"> + <div class="resources"> + <base t-att-href="origin" /> + <link href="/point_of_sale/static/src/css/customer_facing_display.css" + rel="stylesheet" /> + <script type="text/javascript"> + // This function needs to be named that way, call it the foreign JS API + // The iotbox will execute it, with the behavior intended + function foreign_js() { + if ($('.pos-adv').hasClass('pos-hidden')) { + $('.pos-customer_facing_display').addClass('pos-js_no_ADV'); + } + $(window).on('resize', function () { + $('.pos-customer_facing_display').toggleClass('pos-js_no_ADV', $('.pos-adv').hasClass('pos-hidden')); + }).trigger('resize'); + }; + </script> + </div> + </t> + + <t t-name="CustomerFacingDisplayOrderLines"> + <t t-foreach="orderlines" t-as="orderline"> + <div class="pos_orderlines_item"> + <div> + <div t-attf-style="background-image:url(#{orderline.product.image_base64})" /> + </div> + <div> + <t t-esc="orderline.get_full_product_name()" /> + </div> + <div> + <t t-esc="orderline.get_quantity_str()" /> + </div> + <div> + <t t-esc="pos.format_currency(orderline.get_display_price())" /> + </div> + </div> + </t> + </t> + + <t t-name="CustomerFacingDisplayPaymentLines"> + <t t-foreach="order.get_paymentlines()" t-as="paymentline"> + <div> + <span> + <t t-esc="paymentline.name" /></span> + </div> + <div> + <span> + <t t-esc="pos.format_currency(paymentline.get_amount())" /></span> + </div> + </t> + <t t-if="order.get_paymentlines().length > 0"> + <div> + <span class="pos-change_title">Change:</span> + </div> + <div> + <span class="pos-change_amount"> + <t t-esc="pos.format_currency(order.get_change())" /></span> + </div> + </t> + </t> +</templates> diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/CashierName.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/CashierName.xml new file mode 100644 index 00000000..41b7ee69 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/CashierName.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="CashierName" owl="1"> + <div class="oe_status"> + <span class="username"> + <t t-esc="username" /> + </span> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/ClientScreenButton.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/ClientScreenButton.xml new file mode 100644 index 00000000..bbcb1167 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/ClientScreenButton.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ClientScreenButton" owl="1"> + <div class="oe_status" t-on-click="onClick"> + <span class="message"><t t-esc="message" /></span> + <div t-if="state.status === 'warning'" class="js_warning oe_icon oe_orange"> + <i class="fa fa-fw fa-desktop" role="img" aria-label="Client Screen Warning" title="Client Screen Warning"></i> + </div> + <div t-if="state.status === 'failure'" class="js_disconnected oe_icon oe_red"> + <i class="fa fa-fw fa-desktop" role="img" aria-label="Client Screen Disconnected" title="Client Screen Disconnected"></i> + </div> + <div t-if="state.status === 'success'" class="js_connected oe_icon oe_green"> + <i class="fa fa-fw fa-desktop" role="img" aria-label="Client Screen Connected" title="Client Screen Connected"></i> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/DebugWidget.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/DebugWidget.xml new file mode 100644 index 00000000..6e67512e --- /dev/null +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/DebugWidget.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="DebugWidget" owl="1"> + <Draggable limitArea="'.pos'"> + <div class="debug-widget"> + <header class="drag-handle"> + <h1>Debug Window</h1> + </header> + <div class="toggle" t-on-click="trigger('toggle-debug-widget')" title="Dismiss" + role="img" aria-label="Dismiss"><i class="fa fa-times" /></div> + <div class="content"> + <p class="category">Electronic Scale</p> + <ul> + <li> + <input t-model="state.weightInput" type="text" class="weight"></input> + </li> + <li class="button set_weight" t-on-click="setWeight">Set Weight</li> + <li class="button reset_weight" t-on-click="resetWeight">Reset</li> + </ul> + + <p class="category">Barcode Scanner</p> + <ul> + <li> + <input t-model="state.barcodeInput" type="text" class="ean"></input> + </li> + <li class="button barcode" t-on-click="barcodeScan">Scan</li> + <li class="button custom_ean" t-on-click="barcodeScanEAN">Scan EAN-13</li> + </ul> + + <p class="category">Orders</p> + + <ul> + <li class="button" t-on-click="deleteOrders"> + Delete Paid Orders + </li> + <li class="button" t-on-click="deleteUnpaidOrders"> + Delete Unpaid Orders + </li> + <li t-if="!state.isPaidOrdersReady" class="button" + t-on-click="preparePaidOrders"> + Export Paid Orders + </li> + <a t-else="" t-att-download="paidOrdersFilename" t-att-href="paidOrdersURL" + t-on-click="state.isPaidOrdersReady = !state.isPaidOrdersReady"> + <li class="button"> + Download Paid Orders + </li> + </a> + <li t-if="!state.isUnpaidOrdersReady" class="button" + t-on-click="prepareUnpaidOrders"> + Export Unpaid Orders + </li> + <a t-else="" t-att-download="unpaidOrdersFilename" + t-att-href="unpaidOrdersURL" + t-on-click="state.isUnpaidOrdersReady = !state.isUnpaidOrdersReady"> + <li class="button"> + Download Unpaid Orders + </li> + </a> + <li class="button import_orders" style="position:relative"> + Import Orders + <input t-on-change="importOrders" type="file" + style="opacity:0;position:absolute;top:0;left:0;right:0;bottom:0;margin:0;cursor:pointer" /> + </li> + </ul> + + <p class="category">Hardware Status</p> + <ul> + <li class="status weighing">Weighing</li> + <li class="button display_refresh" t-on-click="refreshDisplay"> + Refresh Display + </li> + </ul> + <p class="category">Hardware Events</p> + <ul> + <li class="event" t-ref="open_cashbox">Open Cashbox</li> + <li class="event" t-ref="print_receipt">Print Receipt</li> + <li class="event" t-ref="scale_read">Read Weighing Scale</li> + </ul> + <p class="category">Others</p> + <ul> + <li class="event"> + <span>Buffer: </span> + <t t-esc="bufferRepr" /> + </li> + </ul> + </div> + </div> + </Draggable> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/HeaderButton.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/HeaderButton.xml new file mode 100644 index 00000000..19d9c7c8 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/HeaderButton.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="HeaderButton" owl="1"> + <div class="header-button close_button" t-att-class="{ confirm: state.label === 'Confirm' }" + t-on-click="onClick"> + <t t-esc="translatedLabel" /> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/OrderManagementButton.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/OrderManagementButton.xml new file mode 100644 index 00000000..062e11c3 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/OrderManagementButton.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderManagementButton" owl="1"> + <div class="oe_status order-management" t-on-click="onClick"> + <div class="oe_icon oe_green"> + <i class="fa fa-fw fa-search" role="img" aria-label="Order Management Button" title="Order Management Button"></i> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/ProxyStatus.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/ProxyStatus.xml new file mode 100644 index 00000000..3bcbef6d --- /dev/null +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/ProxyStatus.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ProxyStatus" owl="1"> + <div class="oe_status js_proxy" t-on-click="onClick"> + <span t-if="state.msg and !env.isMobile" class="js_msg"> + <t t-esc="state.msg" /> + </span> + <span t-if="state.status === 'connected'" class="js_connected oe_green"> + <i class="fa fa-fw fa-sitemap" role="img" aria-label="Proxy Connected" + title="Proxy Connected"></i> + </span> + <span t-if="state.status === 'connecting'" class="js_connecting"> + <i class="fa fa-fw fa-spin fa-spinner" role="img" aria-label="Connecting to Proxy" + title="Connecting to Proxy"></i> + </span> + <span t-if="state.status === 'warning'" class="js_warning oe_orange"> + <i class="fa fa-fw fa-sitemap" role="img" aria-label="Proxy Warning" + title="Proxy Warning"></i> + </span> + <span t-if="state.status === 'disconnected'" class="js_disconnected oe_red"> + <i class="fa fa-fw fa-sitemap" role="img" aria-label="Proxy Disconnected" + title="Proxy Disconnected"></i> + </span> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/SaleDetailsButton.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/SaleDetailsButton.xml new file mode 100644 index 00000000..dc5ecc04 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/SaleDetailsButton.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="SaleDetailsButton" owl="1"> + <div class="oe_status"> + <div class="js_connected oe_icon"> + <i class="fa fa-fw fa-print" role="img" aria-label="Print" t-on-click="onClick" + title="Print a report with all the sales of the current PoS Session"></i> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/SyncNotification.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/SyncNotification.xml new file mode 100644 index 00000000..4a08c7ac --- /dev/null +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/SyncNotification.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="SyncNotification" owl="1"> + <div class="oe_status" t-on-click="onClick"> + <span t-if="state.msg" class="js_msg"> + <t t-esc="state.msg" /> + <span> </span> + </span> + <div t-if="state.status === 'connected'" class="js_connected oe_icon oe_green"> + <i class="fa fa-fw fa-wifi" role="img" aria-label="Synchronisation Connected" + title="Synchronisation Connected"></i> + </div> + <div t-if="state.status === 'connecting'" class="js_connecting oe_icon"> + <i class="fa fa-fw fa-spin fa-spinner" role="img" + aria-label="Synchronisation Connecting" title="Synchronisation Connecting"></i> + </div> + <div t-if="state.status === 'disconnected'" class="js_disconnected oe_icon oe_red"> + <i class="fa fa-fw fa-wifi" role="img" aria-label="Synchronisation Disconnected" + title="Synchronisation Disconnected"></i> + </div> + <div t-if="state.status === 'error'" class="js_error oe_icon oe_red"> + <i class="fa fa-fw fa-warning" role="img" aria-label="Synchronisation Error" + title="Synchronisation Error"></i> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/TicketButton.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/TicketButton.xml new file mode 100644 index 00000000..8a1a3a32 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/TicketButton.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="TicketButton" owl="1"> + <div class="ticket-button" t-att-class="{ highlight: props.isTicketScreenShown }" t-on-click="onClick"> + <div class="with-badge" t-att-badge="count"> + <i class="fa fa-ticket" aria-hidden="true"></i> + </div> + <div>Orders</div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Misc/Draggable.xml b/addons/point_of_sale/static/src/xml/Misc/Draggable.xml new file mode 100644 index 00000000..c0449381 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Misc/Draggable.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="Draggable" owl="1"> + <t t-slot="default"></t> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Misc/MobileOrderWidget.xml b/addons/point_of_sale/static/src/xml/Misc/MobileOrderWidget.xml new file mode 100644 index 00000000..883631a2 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Misc/MobileOrderWidget.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="MobileOrderWidget" owl="1"> + <div class="switchpane"> + <t t-if="pane === 'right'"> + <button class="btn-switchpane" t-on-click="trigger('click-pay')"> + <h1>Pay</h1> + <span><t t-esc="total" /></span> + </button> + <button class="btn-switchpane secondary" t-on-click="trigger('switchpane')"> + <h1>Review</h1> + <span><t t-esc="items_number"/> items</span> + </button> + </t> + <t t-if="pane === 'left'"> + <button class="btn-switchpane" t-on-click="trigger('switchpane')"><h1>Back</h1></button> + </t> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Misc/NotificationSound.xml b/addons/point_of_sale/static/src/xml/Misc/NotificationSound.xml new file mode 100644 index 00000000..6467e807 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Misc/NotificationSound.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="NotificationSound" owl="1"> + <audio t-att-src="props.sound.src" autoplay="true"></audio> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Misc/SearchBar.xml b/addons/point_of_sale/static/src/xml/Misc/SearchBar.xml new file mode 100644 index 00000000..a480f169 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Misc/SearchBar.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="point_of_sale.SearchBar" owl="1"> + <div class="pos-search-bar"> + <div class="search"> + <span class="search-icon"><i class="fa fa-search"></i></span> + <input class="radius-left" t-att-class="{ 'radius-right': !props.config.filter.show }" + t-model="state.searchInput" t-on-keydown="onKeydown" type="text" t-att-placeholder="placeholder" /> + <ul t-if="state.showSearchFields and state.searchInput" class="fields"> + <t t-foreach="config.searchFields" t-as="value" t-key="value_index"> + <li t-att-class="{ highlight: value_index == state.selectedFieldId }" + t-on-click="onClickSearchField(value_index)"> + <span class="field"> + <t t-esc="value"></t> + </span> + <span>: </span> + <span class="term"> + <t t-esc="state.searchInput"></t> + </span> + </li> + </t> + </ul> + </div> + <div t-if="props.config.filter.show" class="filter radius-right" + t-on-click.stop="state.showFilterOptions = !state.showFilterOptions"> + <span class="down-icon"> + <i class="fa fa-chevron-down" aria-hidden="true"></i> + </span> + <span> + <t t-esc="state.selectedFilter" /> + </span> + <ul t-if="state.showFilterOptions" class="options"> + <t t-foreach="config.filter.options" t-as="option" t-key="option"> + <li t-on-click="selectFilter(option)"> + <t t-esc="option"></t> + </li> + </t> + </ul> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/ConfirmPopup.xml b/addons/point_of_sale/static/src/xml/Popups/ConfirmPopup.xml new file mode 100644 index 00000000..f3b22b61 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/ConfirmPopup.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ConfirmPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <Draggable> + <div class="popup popup-confirm"> + <header class="title drag-handle"> + <t t-esc="props.title" /> + </header> + <main class="body"> + <t t-esc=" props.body" /> + </main> + <footer class="footer"> + <div class="button confirm" t-on-click="confirm"> + <t t-esc="props.confirmText" /> + </div> + <div class="button cancel" t-on-click="cancel"> + <t t-esc="props.cancelText" /> + </div> + </footer> + </div> + </Draggable> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/EditListInput.xml b/addons/point_of_sale/static/src/xml/Popups/EditListInput.xml new file mode 100644 index 00000000..b33a5161 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/EditListInput.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="EditListInput" owl="1"> + <div> + <input type="text" t-model="props.item.text" class="popup-input list-line-input" + placeholder="Serial/Lot Number" t-on-keyup="onKeyup" /> + <i class="oe_link_icon fa fa-trash-o" role="img" aria-label="Remove" title="Remove" + t-on-click="trigger('remove-item', props.item)"></i> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/EditListPopup.xml b/addons/point_of_sale/static/src/xml/Popups/EditListPopup.xml new file mode 100644 index 00000000..9b6d6354 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/EditListPopup.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="EditListPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <div class="popup popup-text"> + <header class="title"> + <t t-esc="props.title" /> + </header> + <main class="list-lines" t-on-remove-item="removeItem" + t-on-create-new-item="createNewItem"> + <t t-foreach="state.array" t-as="item" t-key="item._id"> + <EditListInput item="item" /> + </t> + </main> + <footer class="footer"> + <div class="button confirm" t-on-click="confirm"> + Ok + </div> + <div class="button cancel" t-on-click="cancel"> + Cancel + </div> + </footer> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/ErrorBarcodePopup.xml b/addons/point_of_sale/static/src/xml/Popups/ErrorBarcodePopup.xml new file mode 100644 index 00000000..6b455fca --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/ErrorBarcodePopup.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ErrorBarcodePopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <Draggable> + <div class="popup popup-barcode"> + <header class="title drag-handle"> + <span>Unknown Barcode</span> + <br /> + <span class="barcode"> + <t t-esc="props.code" /> + </span> + </header> + <main class="body"> + <t t-esc="translatedMessage" /> + </main> + <footer class="footer"> + <div class="button cancel" t-on-click="confirm"> + Ok + </div> + </footer> + </div> + </Draggable> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/ErrorPopup.xml b/addons/point_of_sale/static/src/xml/Popups/ErrorPopup.xml new file mode 100644 index 00000000..0f2e19e3 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/ErrorPopup.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ErrorPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <div class="popup popup-error"> + <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> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/ErrorTracebackPopup.xml b/addons/point_of_sale/static/src/xml/Popups/ErrorTracebackPopup.xml new file mode 100644 index 00000000..e7552c7c --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/ErrorTracebackPopup.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ErrorTracebackPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <div class="popup popup-error"> + <header class="title"> + <t t-esc="props.title" /> + </header> + <main class="body traceback"> + <t t-esc="props.body" /> + </main> + <footer class="footer"> + <div t-if="!props.exitButtonIsShown" class="button cancel" t-on-click="confirm"> + <t t-esc="props.confirmText" /> + </div> + <div t-if="props.exitButtonIsShown" class="button cancel" t-on-click="trigger(props.exitButtonTrigger)"> + <t t-esc="props.exitButtonText" /> + </div> + <a t-att-download="tracebackFilename" t-att-href="tracebackUrl"> + <div class="button icon download"> + <i class="fa fa-download" role="img" + aria-label="Download error traceback" + title="Download error traceback"></i> + </div> + </a> + <div class="button icon email" t-on-click="emailTraceback"> + <i class="fa fa-paper-plane" role="img" aria-label="Send by email" + title="Send by email"></i> + </div> + </footer> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/NumberPopup.xml b/addons/point_of_sale/static/src/xml/Popups/NumberPopup.xml new file mode 100644 index 00000000..41d37ee5 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/NumberPopup.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="NumberPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <Draggable> + <div class="popup popup-number" t-att-class="{ 'popup-password': props.isPassword }"> + <header class="title drag-handle"> + <t t-esc="props.title" /> + </header> + <div class="popup-input value active"> + <t t-esc="inputBuffer" /> + </div> + <div class="popup-numpad"> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('1')">1</button> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('2')">2</button> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('3')">3</button> + <t t-if="props.cheap"> + <button class="mode-button add" t-on-mousedown.prevent="sendInput('+1')">+1</button> + </t> + <t t-if="!props.cheap"> + <button class="mode-button add" t-on-mousedown.prevent="sendInput('+10')">+10</button> + </t> + <br /> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('4')">4</button> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('5')">5</button> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('6')">6</button> + <t t-if="props.cheap"> + <button class="mode-button add" t-on-mousedown.prevent="sendInput('+2')">+2</button> + </t> + <t t-if="!props.cheap"> + <button class="mode-button add" t-on-mousedown.prevent="sendInput('+20')">+20</button> + </t> + <br /> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('7')">7</button> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('8')">8</button> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('9')">9</button> + <button t-if="!props.isPassword" class="input-button number-char" t-on-mousedown.prevent="sendInput('-')">-</button> + <br /> + <button class="input-button numpad-char" t-on-mousedown.prevent="sendInput('Delete')">C</button> + <button class="input-button number-char" t-on-mousedown.prevent="sendInput('0')">0</button> + <button class="input-button number-char dot" t-on-mousedown.prevent="sendInput(decimalSeparator)"> + <t t-esc="decimalSeparator" /></button> + <button class="input-button numpad-backspace" t-on-mousedown.prevent="sendInput('Backspace')"> + <img style="pointer-events: none;" + src="/point_of_sale/static/src/img/backspace.png" width="24" + height="21" alt="Backspace" /> + </button> + <br /> + </div> + <footer class="footer centered"> + <div class="button cancel" t-on-mousedown.prevent="cancel"> + <t t-esc="props.cancelText" /> + </div> + <div class="button confirm" t-on-mousedown.prevent="confirm"> + <t t-esc="props.confirmText" /> + </div> + </footer> + </div> + </Draggable> + + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/OfflineErrorPopup.xml b/addons/point_of_sale/static/src/xml/Popups/OfflineErrorPopup.xml new file mode 100644 index 00000000..9950bc3d --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/OfflineErrorPopup.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OfflineErrorPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <Draggable> + <div class="popup popup-error"> + <header class="title drag-handle"> + <t t-esc="props.title" /> + </header> + <main class="body traceback"><t t-esc="props.body"/></main> + <footer class="footer"> + <div class="button cancel" t-on-click="cancel"> + Ok + </div> + <div class="button dont-show-again" t-on-click="dontShowAgain"> + Don't show again + </div> + </footer> + </div> + </Draggable> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/OrderImportPopup.xml b/addons/point_of_sale/static/src/xml/Popups/OrderImportPopup.xml new file mode 100644 index 00000000..b2f142b9 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/OrderImportPopup.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderImportPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <Draggable> + <div class="popup popup-import"> + <header class="title drag-handle"> + <span>Finished Importing Orders</span> + </header> + <ul class="body"> + <li>Successfully imported <b><t t-esc="props.report.paid or 0" /></b> paid orders</li> + <li>Successfully imported <b><t t-esc="props.report.unpaid or 0" /></b> unpaid orders</li> + <t t-if="unpaidSkipped"> + <li><b><t t-esc="unpaidSkipped"/></b> unpaid orders could not be imported + <ul> + <li><b><t t-esc="props.report.unpaid_skipped_existing or 0" /></b> were duplicates of existing orders</li> + <li><b><t t-esc="props.report.unpaid_skipped_session or 0" /></b> belong to another session: + <t t-if="props.report.unpaid_skipped_sessions"> + <ul> + <li>Session ids: <b><t t-esc="props.report.unpaid_skipped_sessions" /></b></li> + </ul> + </t> + </li> + </ul> + </li> + </t> + </ul> + <footer class="footer"> + <div class="button cancel" t-on-click="cancel"> + <t t-esc="props.confirmText" /> + </div> + </footer> + </div> + </Draggable> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/ProductConfiguratorPopup.xml b/addons/point_of_sale/static/src/xml/Popups/ProductConfiguratorPopup.xml new file mode 100644 index 00000000..fb863754 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/ProductConfiguratorPopup.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ProductConfiguratorPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <div class="popup popup-text popup-lg product-configurator-popup"> + <header class="title"> + <t t-esc="props.product.display_name" /> + </header> + + <main class="body product_configurator_attributes col-lg-4 col-md-6 col-sm-12"> + <div t-foreach="props.attributes" t-as="attribute" class="attribute"> + <div class="attribute_name" t-esc="attribute.name"/> + <RadioProductAttribute t-if="attribute.display_type === 'radio'" attribute="attribute"/> + <SelectProductAttribute t-elif="attribute.display_type === 'select'" attribute="attribute"/> + <ColorProductAttribute t-elif="attribute.display_type === 'color'" attribute="attribute"/> + </div> + </main> + + <footer class="footer"> + <div class="button highlight confirm" t-on-click="confirm"> + Add + </div> + <div class="button cancel" t-on-click="cancel"> + Cancel + </div> + </footer> + </div> + </div> + </t> + + <t t-name="RadioProductAttribute" owl="1"> + <div class="configurator_radio"> + <div t-foreach="values" t-as="value"> + <input type="radio" t-model="state.selected_value" t-att-name="attribute.id" + t-attf-id="{{ attribute.id }}_{{ value.id }}" t-att-value="value.id"/> + + <label t-attf-for="{{ attribute.id }}_{{ value.id }}"> + <div class="radio_attribute_label"> + <t t-esc="value.name"/> + <span t-if="value.price_extra" class="price_extra"> + + <t t-esc="env.pos.format_currency(value.price_extra)"/> + </span> + </div> + + <t t-if="value.id == state.selected_value && value.is_custom"> + <input class="custom_value" type="text" t-model="state.custom_value"/> + </t> + </label> + </div> + </div> + </t> + + <t t-name="SelectProductAttribute" owl="1"> + <div> + <t t-set="is_custom" t-value="false"/> + + <select class="configurator_select" t-model="state.selected_value"> + <option t-foreach="values" t-as="value" t-att-value="value.id"> + <t t-set="is_custom" t-value="is_custom || (value.is_custom && value.id == state.selected_value)"/> + <t t-esc="value.name"/> + <t t-if="value.price_extra"> + + <t t-esc="env.pos.format_currency(value.price_extra)"/> + </t> + </option> + </select> + + <input class="custom_value" t-if="is_custom" type="text" t-model="state.custom_value"/> + </div> + </t> + + <t t-name="ColorProductAttribute" owl="1"> + <div> + <t t-set="is_custom" t-value="false"/> + + <ul class="color_attribute_list"> + <li t-foreach="values" t-as="value" class="color_attribute_list_item"> + <t t-set="is_custom" t-value="is_custom || (value.is_custom && value.id == state.selected_value)"/> + <label t-attf-class="configurator_color {{ value.id == state.selected_value ? 'active' : '' }}" + t-attf-style="background-color: {{ value.html_color }};" t-att-data-color="value.name"> + <input type="radio" t-model="state.selected_value" t-att-value="value.id" t-att-name="attribute.id"/> + </label> + </li> + </ul> + + <input class="custom_value" t-if="is_custom" type="text" t-model="state.custom_value"/> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/SelectionPopup.xml b/addons/point_of_sale/static/src/xml/Popups/SelectionPopup.xml new file mode 100644 index 00000000..b9ca1bc7 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/SelectionPopup.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="SelectionPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <Draggable> + <div class="popup popup-selection"> + <header class="title drag-handle"> + <t t-esc="props.title" /> + </header> + <div class="selection scrollable-y"> + <t t-foreach="props.list" t-as="item" t-key="item.id"> + <div class="selection-item" t-att-class="{ selected: item.isSelected }" + t-on-click="selectItem(item.id)"> + <t t-esc="item.label" /> + </div> + </t> + </div> + <footer class="footer"> + <div class="button cancel" t-on-click="cancel"> + <t t-esc="props.cancelText" /> + </div> + </footer> + </div> + </Draggable> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/TextAreaPopup.xml b/addons/point_of_sale/static/src/xml/Popups/TextAreaPopup.xml new file mode 100644 index 00000000..a142c995 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/TextAreaPopup.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="TextAreaPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <Draggable> + <div class="popup popup-textarea"> + <header class="title drag-handle"> + <t t-esc="props.title" /> + </header> + <textarea t-model="state.inputValue" t-ref="input"></textarea> + <footer class="footer"> + <div class="button confirm" t-on-click="confirm"> + <t t-esc="props.confirmText" /> + </div> + <div class="button cancel" t-on-click="cancel"> + <t t-esc="props.cancelText" /> + </div> + </footer> + </div> + </Draggable> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Popups/TextInputPopup.xml b/addons/point_of_sale/static/src/xml/Popups/TextInputPopup.xml new file mode 100644 index 00000000..cc28d706 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Popups/TextInputPopup.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="TextInputPopup" owl="1"> + <div role="dialog" class="modal-dialog"> + <div class="popup popup-textinput"> + <header class="title"> + <t t-esc="props.title" /> + </header> + <div class="div"> + <p> + <t t-esc="props.body" /> + </p> + <input type="text" t-model="state.inputValue" t-ref="input" /> + </div> + <div class="footer"> + <div class="button confirm" t-on-click="confirm"> + <t t-esc="props.confirmText" /> + </div> + <div class="button cancel" t-on-click="cancel"> + <t t-esc="props.cancelText" /> + </div> + </div> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/SaleDetailsReport.xml b/addons/point_of_sale/static/src/xml/SaleDetailsReport.xml new file mode 100644 index 00000000..cce9616e --- /dev/null +++ b/addons/point_of_sale/static/src/xml/SaleDetailsReport.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="SaleDetailsReport" owl="1"> + <div class="pos-receipt"> + <t t-if="pos.company_logo_base64"> + <img class="pos-receipt-logo" t-att-src="pos.company_logo_base64" alt="Logo"/> + <br/> + </t> + <t t-if="!pos.company_logo_base64" class="pos-receipt-center-align"> + <h1 t-esc="pos.company.name" /> + <br/> + </t> + <br /><br /> + + <div class="orderlines"> + <t t-foreach="products" t-as="line" t-key="line.product_id"> + <div> + <t t-esc="line.product_name.substr(0,20)" /> + <span class="pos-receipt-right-align"> + <t t-esc="Math.round(line.quantity * Math.pow(10, pos.dp['Product Unit of Measure'])) / Math.pow(10, pos.dp['Product Unit of Measure'])" /> + <t t-if="line.uom !== 'Units'"> + <t t-esc="line.uom" /> + </t> + x + <t t-esc="pos.format_currency_no_symbol(line.price_unit)" /> + </span> + </div> + <t t-if="line.discount !== 0"> + <div class="pos-receipt-left-padding">Discount: <t t-esc="line.discount" />%</div> + </t> + </t> + </div> + + <br/> + <div>------------------------</div> + <br/> + + <div> + Payments: + </div> + <div t-foreach="payments" t-as="payment"> + <t t-esc="payment.name" /> + <span t-esc="pos.format_currency_no_symbol(payment.total)" class="pos-receipt-right-align"/> + </div> + + <br/> + <div>------------------------</div> + <br/> + + <div> + Taxes: + </div> + <div t-foreach="taxes" t-as="tax"> + <t t-esc="tax.name" /> + <span t-esc="pos.format_currency_no_symbol(tax.tax_amount)" class="pos-receipt-right-align"/> + </div> + + <br/> + <div>------------------------</div> + <br/> + + <div> + Total: + <span t-esc="pos.format_currency_no_symbol(total_paid)" class="pos-receipt-right-align"/> + </div> + + <br/> + <div class="pos-receipt-order-data"> + <div><t t-esc="date" /></div> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ClientListScreen/ClientDetailsEdit.xml b/addons/point_of_sale/static/src/xml/Screens/ClientListScreen/ClientDetailsEdit.xml new file mode 100644 index 00000000..5699dc64 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ClientListScreen/ClientDetailsEdit.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ClientDetailsEdit" owl="1"> + <section class="client-details edit"> + <div class="client-picture"> + <t t-if="partnerImageUrl"> + <img t-att-src="partnerImageUrl" alt="Partner" + style="width: 64px; height: 64px; object-fit: cover;" /> + </t> + <t t-else=""> + <i class="fa fa-camera" role="img" aria-label="Picture" title="Picture"></i> + </t> + <input type="file" class="image-uploader" t-on-change="uploadImage" /> + </div> + <input class="detail client-name" name="name" t-att-value="props.partner.name" + placeholder="Name" t-on-change="captureChange" /> + <div class="client-details-box clearfix"> + <div class="client-details-left"> + <div class="client-detail"> + <span class="label">Street</span> + <input class="detail client-address-street" name="street" + t-on-change="captureChange" t-att-value="props.partner.street || ''" + placeholder="Street" /> + </div> + <div class="client-detail"> + <span class="label">City</span> + <input class="detail client-address-city" name="city" + t-on-change="captureChange" t-att-value="props.partner.city || ''" + placeholder="City" /> + </div> + <div class="client-detail"> + <span class="label">Postcode</span> + <input class="detail client-address-zip" name="zip" + t-on-change="captureChange" t-att-value="props.partner.zip || ''" + placeholder="ZIP" /> + </div> + <div class="client-detail"> + <span class="label">State</span> + <select class="detail client-address-states needsclick" name="state_id" + t-on-change="captureChange"> + <option value="">None</option> + <t t-foreach="env.pos.states" t-as="state" t-key="state.id"> + <option t-if="props.partner.country_id[0] == state.country_id[0]" + t-att-value="state.id" + t-att-selected="props.partner.state_id ? ((state.id === props.partner.state_id[0]) ? true : undefined) : undefined"> + <t t-esc="state.name" /> + </option> + </t> + </select> + </div> + <div class="client-detail"> + <span class="label">Country</span> + <select class="detail client-address-country needsclick" name="country_id" + t-on-change="captureChange"> + <option value="">None</option> + <t t-foreach="env.pos.countries" t-as="country" t-key="country.id"> + <option t-att-value="country.id" + t-att-selected="props.partner.country_id ? ((country.id === props.partner.country_id[0]) ? true : undefined) : undefined"> + <t t-esc="country.name" /> + </option> + </t> + </select> + </div> + </div> + <div class="client-details-right"> + <div class="client-detail"> + <span class="label">Language</span> + <select class="detail client-lang needsclick" name="lang" + t-on-change="captureChange"> + <t t-foreach="env.pos.langs" t-as="lang" t-key="lang.id"> + <option t-att-value="lang.code" + t-att-selected="props.partner.lang ? ((lang.code === props.partner.lang) ? true : undefined) : lang.code === env.pos.user.lang? true : undefined"> + <t t-esc="lang.name" /> + </option> + </t> + </select> + </div> + <div class="client-detail"> + <span class="label">Email</span> + <input class="detail client-email" name="email" type="email" + t-on-change="captureChange" + t-att-value="props.partner.email || ''" /> + </div> + <div class="client-detail"> + <span class="label">Phone</span> + <input class="detail client-phone" name="phone" type="tel" + t-on-change="captureChange" + t-att-value="props.partner.phone || ''" /> + </div> + <div class="client-detail"> + <span class="label">Barcode</span> + <input class="detail barcode" name="barcode" t-on-change="captureChange" + t-att-value="props.partner.barcode || ''" /> + </div> + <div class="client-detail"> + <span class="label">Tax ID</span> + <input class="detail vat" name="vat" t-on-change="captureChange" + t-att-value="props.partner.vat || ''" /> + </div> + <div t-if="env.pos.pricelists.length gt 1" class="client-detail"> + <span class="label">Pricelist</span> + <select class="detail needsclick" name="property_product_pricelist" + t-on-change="captureChange"> + <t t-foreach="env.pos.pricelists" t-as="pricelist" + t-key="pricelist.id"> + <option t-att-value="pricelist.id" + t-att-selected="props.partner.property_product_pricelist ? (pricelist.id === props.partner.property_product_pricelist[0] ? true : false) : false"> + <t t-esc="pricelist.display_name" /> + </option> + </t> + </select> + </div> + </div> + </div> + </section> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ClientListScreen/ClientLine.xml b/addons/point_of_sale/static/src/xml/Screens/ClientListScreen/ClientLine.xml new file mode 100644 index 00000000..7693f08c --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ClientListScreen/ClientLine.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ClientLine" owl="1"> + <tr t-attf-class="client-line {{highlight}}" t-att-data-id="props.partner.id" + t-on-click="trigger('click-client', {client: props.partner})"> + <td> + <t t-esc="props.partner.name" /> + <span t-if="highlight"> + <br/><button class="edit-client-button" t-on-click.stop="trigger('click-edit')">EDIT</button> + </span> + </td> + <td t-if="!env.isMobile"> + <t t-esc="props.partner.address" /> + </td> + <td t-if="!env.isMobile" style="width: 130px;"> + <t t-esc="props.partner.phone || ''" /> + </td> + <td t-if="env.isMobile"> + <t t-esc="props.partner.zip or ''" /> + <span t-if="highlight"><br/></span> + </td> + <td> + <t t-esc="props.partner.email or ''" /> + <span t-if="highlight"><br/></span> + </td> + </tr> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ClientListScreen/ClientListScreen.xml b/addons/point_of_sale/static/src/xml/Screens/ClientListScreen/ClientListScreen.xml new file mode 100644 index 00000000..baefab13 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ClientListScreen/ClientListScreen.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ClientListScreen" owl="1"> + <div class="clientlist-screen screen" t-on-activate-edit-mode="activateEditMode"> + <div class="screen-content"> + <div class="top-content"> + <div t-if="!state.detailIsShown && !state.selectedClient" class="button new-customer" role="img" aria-label="Add a customer" + t-on-click="trigger('activate-edit-mode', { isNewClient: true })" + title="Add a customer"> + <t t-if="!env.isMobile"> + Create + </t> + <t t-else=""> + <i class="fa fa-plus"></i> + </t> + </div> + <div t-if="isNextButtonVisible" t-on-click="clickNext" + class="button next highlight"> + <t t-if="!env.isMobile"> + <t t-esc="nextButton.text" /> + </t> + <t t-else=""> + <i t-if="nextButton.command === 'deselect'" class="fa fa-trash"></i> + <i t-if="nextButton.command === 'set'" class="fa fa-check"></i> + </t> + </div> + <div class="button" t-if="state.detailIsShown" t-on-click="trigger('click-save')"> + <t t-if="!env.isMobile"> + <i class="fa fa-floppy-o"/> + <span> Save</span> + </t> + <t t-else=""> + <i class="fa fa-floppy-o"/> + </t> + </div> + <div class="button back" t-on-click="back"> + <t t-if="!env.isMobile">Discard</t> + <t t-else=""> + <i class="fa fa-undo"></i> + </t> + </div> + <div t-if="!state.detailIsShown" class="searchbox-client top-content-center"> + <input placeholder="Search Customers" size="1" t-on-keyup="updateClientList" /> + <span class="search-clear-client"></span> + </div> + </div> + <section class="full-content"> + <div class="client-window"> + <section class="subwindow collapsed"> + <div class="subwindow-container collapsed"> + <div t-if="state.detailIsShown" class="client-details-contents subwindow-container-fix"> + <ClientDetailsEdit t-props="state.editModeProps" + t-on-cancel-edit="cancelEdit"/> + </div> + </div> + </section> + <section class="subwindow list"> + <div class="subwindow-container"> + <div t-if="!state.detailIsShown" class="subwindow-container-fix scrollable-y"> + <table class="client-list"> + <thead> + <tr> + <th>Name</th> + <th t-if="!env.isMobile">Address</th> + <th t-if="!env.isMobile">Phone</th> + <th t-if="env.isMobile">ZIP</th> + <th>Email</th> + </tr> + </thead> + <tbody class="client-list-contents"> + <t t-foreach="clients" t-as="partner" + t-key="partner.id"> + <ClientLine partner="partner" + selectedClient="state.selectedClient" + detailIsShown="state.detailIsShown" + t-on-click-client="clickClient" /> + </t> + </tbody> + </table> + </div> + </div> + </section> + </div> + </section> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/ControlButtons/InvoiceButton.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/ControlButtons/InvoiceButton.xml new file mode 100644 index 00000000..72c85188 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/ControlButtons/InvoiceButton.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="InvoiceButton" owl="1"> + <div class="control-button" t-att-class="{ highlight: isHighlighted }"> + <i class="fa fa-file-pdf-o"></i> + <span> </span> + <span><t t-esc="commandName"></t></span> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/ControlButtons/ReprintReceiptButton.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/ControlButtons/ReprintReceiptButton.xml new file mode 100644 index 00000000..df3e4e06 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/ControlButtons/ReprintReceiptButton.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ReprintReceiptButton" owl="1"> + <div class="control-button"> + <i class="fa fa-print"></i> + <span> </span> + <span>Print Receipt</span> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/MobileOrderManagementScreen.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/MobileOrderManagementScreen.xml new file mode 100644 index 00000000..479b35a4 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/MobileOrderManagementScreen.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <div t-name="MobileOrderManagementScreen" class="screen-full-width" owl="1"> + <div t-if="mobileState.showDetails" class="leftpane"> + <OrderDetails order="orderManagementContext.selectedOrder" /> + <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="selectedClient" /> + <NumpadWidget /> + </div> + </div> + <div class="back-to-list" t-on-click="mobileState.showDetails = false"> + <span>Back to list</span> + </div> + </div> + <div t-else="" class="rightpane"> + <div class="flex-container"> + <OrderManagementControlPanel /> + <OrderList orders="orders" initHighlightedOrder="orderManagementContext.selectedOrder" /> + </div> + </div> + </div> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderDetails.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderDetails.xml new file mode 100644 index 00000000..87579d09 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderDetails.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderDetails" owl="1"> + <div class="order-container"> + <div t-ref="scrollable" class="order-scroller touch-scrollable"> + <div class="order"> + <t t-if="!props.order"> + <div class="order-empty"> + <i class="fa fa-shopping-cart" role="img" aria-label="Shopping cart" + title="Shopping cart" /> + <h1>Select an order</h1> + </div> + </t> + <t t-elif="orderlines.length === 0"> + <div class="order-empty"> + <i class="fa fa-shopping-cart" role="img" aria-label="Shopping cart" + title="Shopping cart" /> + <h1>Order is empty</h1> + </div> + </t> + <t t-else=""> + <ul class="orderlines"> + <t t-foreach="orderlines" t-as="orderline" t-key="orderline.id"> + <OrderlineDetails line="orderline" /> + </t> + </ul> + <OrderSummary total="total" tax="tax" /> + </t> + </div> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderList.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderList.xml new file mode 100644 index 00000000..865f609b --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderList.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderList" owl="1"> + <div class="orders"> + <div class="order-row header"> + <div class="header name">Order</div> + <div class="header date">Date</div> + <div class="header customer">Customer</div> + <div class="header total">Total</div> + </div> + <div class="order-list"> + <t t-foreach="props.orders" t-as="order" t-key="order.cid"> + <OrderRow order="order" highlightedOrder="highlightedOrder" /> + </t> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderManagementControlPanel.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderManagementControlPanel.xml new file mode 100644 index 00000000..3a294bfd --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderManagementControlPanel.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderManagementControlPanel" owl="1"> + <div class="control-panel"> + <div class="item button back" t-on-click="trigger('close-screen')"> + <i class="fa fa-angle-double-left"></i> + <span> Back</span> + </div> + <div class="item search-box"> + <span class="icon"> + <i class="fa fa-search" /> + </span> + <input type="text" t-model="orderManagementContext.searchString" t-on-keydown="onInputKeydown" placeholder="E.g. customer: Steward, date: 2020-05-09" /> + <span class="clear" t-on-click="trigger('clear-search')"> + <i class="fa fa-remove" /> + </span> + </div> + <div t-if="showPageControls" class="item"> + <div class="page-controls"> + <div class="previous" t-on-click="trigger('prev-page')"> + <i class="fa fa-fw fa-caret-left" role="img" aria-label="Previous Order List" title="Previous Order List"></i> + </div> + <div class="next" t-on-click="trigger('next-page')"> + <i class="fa fa-fw fa-caret-right" role="img" aria-label="Next Order List" title="Next Order List"></i> + </div> + </div> + <div class="page"> + <span><t t-esc="pageNumber" /></span> + </div> + </div> + <div t-else="" class="item"></div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderManagementScreen.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderManagementScreen.xml new file mode 100644 index 00000000..8992e2c8 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderManagementScreen.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderManagementScreen" owl="1"> + <div class="order-management-screen screen" t-att-class="{ oe_hidden: !props.isShown }"> + <div t-if="!env.isMobile" class="screen-full-width"> + <div class="leftpane"> + <OrderDetails order="orderManagementContext.selectedOrder" /> + <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="selectedClient" /> + <NumpadWidget /> + </div> + </div> + </div> + <div class="rightpane"> + <div class="flex-container"> + <OrderManagementControlPanel /> + <OrderList orders="orders" initHighlightedOrder="orderManagementContext.selectedOrder" /> + </div> + </div> + </div> + <MobileOrderManagementScreen t-else="" /> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderRow.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderRow.xml new file mode 100644 index 00000000..29b07cfe --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderRow.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderRow" owl="1"> + <div class="order-row" + t-att-class="{ highlight: highlighted, lighter: !props.order.locked }" + t-on-click="trigger('click-order', props.order)"> + <div class="item name"><t t-esc="name" /></div> + <div class="item date"><t t-esc="date" /></div> + <div class="item customer"><t t-esc="customer" /></div> + <div class="item total"><t t-esc="total" /></div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderlineDetails.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderlineDetails.xml new file mode 100644 index 00000000..2e6869e5 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/OrderlineDetails.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderlineDetails" owl="1"> + <li class="orderline"> + <span class="product-name"> + <t t-esc="productName" /> + </span> + <span class="price"> + <t t-esc="totalPrice" /> + </span> + <li class="info"> + <strong> + <t t-esc="quantity" /> + </strong> + <span><t t-esc="pricePerUnit" /></span> + </li> + </li> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/ReprintReceiptScreen.xml b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/ReprintReceiptScreen.xml new file mode 100644 index 00000000..0a80a0e0 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/OrderManagementScreen/ReprintReceiptScreen.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ReprintReceiptScreen" owl="1"> + <div class="receipt-screen screen"> + <div class="screen-content"> + <div class="top-content"> + <span class="button back" t-on-click="confirm"> + <i class="fa fa-angle-double-left"></i> + <span> </span> + <span>Back</span> + </span> + </div> + <div class="centered-content"> + <div class="button print" t-on-click="tryReprint"> + <i class="fa fa-print"></i> Print Receipt + </div> + <div class="pos-receipt-container"> + <OrderReceipt order="props.order" t-ref="order-receipt" /> + </div> + </div> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PSNumpadInputButton.xml b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PSNumpadInputButton.xml new file mode 100644 index 00000000..381cd88c --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PSNumpadInputButton.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="PSNumpadInputButton" owl="1"> + <button t-attf-class="{{ _class }}" + t-on-click="trigger('input-from-numpad', { key: props.value })"> + <t t-slot="default"> + <t t-if="props.text"> + <t t-esc="props.text" /> + </t> + <t t-else=""> + <t t-esc="props.value" /> + </t> + </t> + </button> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentMethodButton.xml b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentMethodButton.xml new file mode 100644 index 00000000..dacf7e96 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentMethodButton.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="PaymentMethodButton" owl="1"> + <div class="button paymentmethod" + t-on-click="trigger('new-payment-line', props.paymentMethod)"> + <div class="payment-name"> + <t t-esc="props.paymentMethod.name" /> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml new file mode 100644 index 00000000..d78128c9 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="PaymentScreen" owl="1"> + <div class="payment-screen screen" t-att-class="{ oe_hidden: !props.isShown }"> + <div class="screen-content"> + <t t-if="!env.isMobile"> + <div class="top-content"> + <div class="button back" + t-on-click="showScreen('ProductScreen')"> + <i class="fa fa-angle-double-left fa-fw"></i> + <span class="back_text">Back</span> + </div> + <div class="top-content-center"><h1>Payment</h1></div> + <div class="button next" t-att-class="{ highlight: currentOrder.is_paid() }" + t-on-click="validateOrder(false)"> + <span class="next_text">Validate</span> + <i class="fa fa-angle-double-right fa-fw"></i> + </div> + </div> + </t> + <div class="main-content"> + <div class="left-content"> + <t t-if="env.isMobile"> + <section class="paymentlines-container"> + <PaymentScreenStatus paymentLines="paymentLines" /> + </section> + </t> + <div class="paymentmethods-container"> + <PaymentScreenPaymentLines paymentLines="paymentLines" /> + <div class="paymentmethods"> + <t t-foreach="payment_methods_from_config" t-as="paymentMethod" + t-key="paymentMethod.id"> + <PaymentMethodButton paymentMethod="paymentMethod" /> + </t> + </div> + </div> + </div> + <div class="right-content"> + <t t-if="!env.isMobile"> + <section class="paymentlines-container"> + <PaymentScreenStatus paymentLines="paymentLines" /> + </section> + </t> + + <div class="payment-buttons-container"> + <section class="payment-numpad"> + <PaymentScreenNumpad /> + </section> + + <div class="payment-buttons"> + <div class="customer-button"> + <div class="button" t-on-click="selectClient"> + <i class="fa fa-user" role="img" aria-label="Customer" + title="Customer" /> + <span class="js_customer_name"> + <t t-if="env.pos.get_client()"> + <t t-esc="env.pos.get_client().name" /> + </t> + <t t-if="!env.pos.get_client()"> + Customer + </t> + </span> + </div> + </div> + <div class="payment-controls"> + <div t-if="env.pos.config.module_account" class="button js_invoice" + t-att-class="{ highlight: currentOrder.is_to_invoice() }" + t-on-click="toggleIsToInvoice"> + <i class="fa fa-file-text-o" /> Invoice + </div> + <div t-if="env.pos.config.tip_product_id" class="button js_tip" + t-on-click="addTip"> + <i class="fa fa-heart" /> Tip + </div> + <div t-if="env.pos.config.iface_cashdrawer" class="button js_cashdrawer" + t-on-click="openCashbox"> + <i class="fa fa-archive" /> Open Cashbox + </div> + </div> + </div> + </div> + </div> + </div> + <t t-if="env.isMobile"> + <div class="switchpane"> + <button class="btn-switchpane" t-att-class="{ secondary: !currentOrder.is_paid() }" t-on-click="validateOrder(false)"> + <h1>Validate</h1> + </button> + <button class="btn-switchpane secondary" t-on-click="showScreen('ProductScreen', {mobile_pane: 'left'})"> + <h1>Review</h1> + </button> + </div> + </t> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenElectronicPayment.xml b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenElectronicPayment.xml new file mode 100644 index 00000000..792c490c --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenElectronicPayment.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="PaymentScreenElectronicPayment" owl="1"> + <div class="paymentline electronic_payment"> + <t t-if="props.line.payment_status == 'pending'"> + <div> + Payment request pending + </div> + <div class="button send_payment_request highlight" title="Send Payment Request" t-on-click="trigger('send-payment-request', props.line)"> + Send + </div> + </t> + <t t-elif="props.line.payment_status == 'retry'"> + <div> + Transaction cancelled + </div> + <div class="button send_payment_request highlight" title="Send Payment Request" t-on-click="trigger('send-payment-request', props.line)"> + Retry + </div> + </t> + <t t-elif="props.line.payment_status == 'force_done'"> + <div> + Connection error + </div> + <div class="button send_force_done" title="Force Done" t-on-click="trigger('send-force-done', props.line)"> + Force done + </div> + </t> + <t t-elif="props.line.payment_status == 'waitingCard'"> + <div> + Waiting for card + </div> + <div class="button send_payment_cancel" title="Cancel Payment Request" t-on-click="trigger('send-payment-cancel', props.line)"> + Cancel + </div> + </t> + <t t-elif="['waiting', 'waitingCancel'].includes(props.line.payment_status)"> + <div> + Request sent + </div> + <div> + <i class="fa fa-spinner fa-spin" role="img" /> + </div> + </t> + <t t-elif="props.line.payment_status == 'reversing'"> + <div> + Reversal request sent to terminal + </div> + <div> + <i class="fa fa-spinner fa-spin" role="img" /> + </div> + </t> + <t t-elif="props.line.payment_status == 'done'"> + <div> + Payment Successful + </div> + <t t-if="props.line.can_be_reversed"> + <div class="button send_payment_reversal" title="Reverse Payment" t-on-click="trigger('send-payment-reverse', props.line)"> + Reverse + </div> + </t> + <t t-else=""> + <div></div> + </t> + </t> + <t t-elif="props.line.payment_status == 'reversed'"> + <div> + Payment reversed + </div> + <div></div> + </t> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenNumpad.xml b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenNumpad.xml new file mode 100644 index 00000000..d988ab5f --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenNumpad.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="PaymentScreenNumpad" owl="1"> + <div class="numpad"> + <PSNumpadInputButton value="'1'" /> + <PSNumpadInputButton value="'2'" /> + <PSNumpadInputButton value="'3'" /> + <PSNumpadInputButton value="'+10'" changeClassTo="'mode-button'" /> + <br /> + <PSNumpadInputButton value="'4'" /> + <PSNumpadInputButton value="'5'" /> + <PSNumpadInputButton value="'6'" /> + <PSNumpadInputButton value="'+20'" changeClassTo="'mode-button'" /> + <br /> + <PSNumpadInputButton value="'7'" /> + <PSNumpadInputButton value="'8'" /> + <PSNumpadInputButton value="'9'" /> + <PSNumpadInputButton value="'+50'" changeClassTo="'mode-button'" /> + <br /> + <PSNumpadInputButton value="'-'" text="'+/-'" /> + <PSNumpadInputButton value="'0'" /> + <PSNumpadInputButton value="decimalPoint" /> + <PSNumpadInputButton value="'Backspace'"> + <img src="/point_of_sale/static/src/img/backspace.png" width="24" height="21" + alt="Backspace" /> + </PSNumpadInputButton> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenPaymentLines.xml b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenPaymentLines.xml new file mode 100644 index 00000000..6816f300 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenPaymentLines.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="PaymentScreenPaymentLines" owl="1"> + <div class="paymentlines"> + <t t-foreach="props.paymentLines" t-as="line" t-key="line.cid"> + <t t-if="line.selected"> + <div class="paymentline selected" + t-att-class="selectedLineClass(line)" + t-on-click="trigger('select-payment-line', { cid: line.cid })"> + <div class="payment-name"> + <t t-esc="line.payment_method.name" /> + </div> + <div class="payment-amount"> + <t t-if="line and line.payment_status and ['done', 'waitingCard', 'waiting', 'reversing', 'reversed'].includes(line.payment_status)"> + <t t-esc="env.pos.format_currency_no_symbol(line.get_amount())" /> + </t> + <t t-else=""> + <t t-esc="formatLineAmount(line)" /> + </t> + </div> + <t t-if="!line.payment_status or !['done', 'reversed'].includes(line.payment_status)"> + <div class="delete-button" + t-on-click="trigger('delete-payment-line', { cid: line.cid })" + aria-label="Delete" title="Delete"> + <i class="fa fa-times-circle" /> + </div> + </t> + </div> + <t t-if="line and line.payment_status"> + <PaymentScreenElectronicPayment line="line" /> + </t> + </t> + <t t-else=""> + <div class="paymentline" + t-att-class="unselectedLineClass(line)" + t-on-click="trigger('select-payment-line', { cid: line.cid })"> + <div class="payment-name"> + <t t-esc="line.payment_method.name" /> + </div> + <div class="payment-amount"> + <t t-if="line and line.payment_status and ['done', 'waitingCard', 'waiting', 'reversing', 'reversed'].includes(line.payment_status)"> + <t t-esc="env.pos.format_currency_no_symbol(line.get_amount())" /> + </t> + <t t-else=""> + <t t-esc="formatLineAmount(line)" /> + </t> + </div> + <t t-if="!line.payment_status or !['done', 'reversed'].includes(line.payment_status)"> + <div class="delete-button" + t-on-click="trigger('delete-payment-line', { cid: line.cid })" + aria-label="Delete" title="Delete"> + <i class="fa fa-times-circle" /> + </div> + </t> + </div> + </t> + </t> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenStatus.xml b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenStatus.xml new file mode 100644 index 00000000..7c90c8a5 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/PaymentScreen/PaymentScreenStatus.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<t t-name="PaymentScreenStatus" owl="1"> + <div t-if="props.paymentLines.length === 0" class="paymentlines-empty"> + <div class="total"> + <t t-esc="totalDueText" /> + </div> + <div class="message"> + Please select a payment method. + </div> + </div> + + <div t-else=""> + <div class="payment-status-container"> + <div> + <div class="payment-status-remaining"> + <span class="label">Remaining</span> + <span class="amount" + t-att-class="{ highlight: currentOrder.get_due() > 0 }"> + <t t-esc="remainingText" /> + </span> + </div> + <div class="payment-status-total-due"> + <span class="label">Total Due</span> + <span> + <t t-esc="totalDueText" /> + </span> + </div> + </div> + <div> + <div class="payment-status-change"> + <span class="label">Change</span> + <span class="amount" + t-att-class="{ highlight: currentOrder.get_change() > 0 }"> + <t t-esc="changeText" /> + </span> + </div> + </div> + </div> + </div> +</t> +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ActionpadWidget.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ActionpadWidget.xml new file mode 100644 index 00000000..183912fd --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ActionpadWidget.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ActionpadWidget" owl="1"> + <div class="actionpad"> + <button class="button set-customer" t-att-class="{'decentered': isLongName}" + t-on-click="trigger('click-customer')"> + <t t-if="!env.isMobile"><i class="fa fa-user" role="img" aria-label="Customer" title="Customer" /></t> + <t t-if="client"> + <t t-esc="client.name" /> + </t> + <t t-else=""> + Customer + </t> + </button> + <button class="button pay" t-on-click="trigger('click-pay')"> + <div class="pay-circle"> + <i class="fa fa-chevron-right" role="img" aria-label="Pay" title="Pay" /> + </div> + Payment + </button> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CashBoxOpening.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CashBoxOpening.xml new file mode 100644 index 00000000..27193bf9 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CashBoxOpening.xml @@ -0,0 +1,28 @@ +<?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> + + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CategoryBreadcrumb.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CategoryBreadcrumb.xml new file mode 100644 index 00000000..0e9ba155 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CategoryBreadcrumb.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<templates id="template" xml:space="preserve"> + + <t t-name="CategoryBreadcrumb" owl="1"> + <span class="breadcrumb"> + <img src="/point_of_sale/static/src/img/bc-arrow-big.png" class="breadcrumb-arrow" + alt="Slash" /> + <span class="breadcrumb-button" + t-on-click="trigger('switch-category', props.category.id)"> + <t t-esc="props.category.name"></t> + </span> + </span> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CategoryButton.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CategoryButton.xml new file mode 100644 index 00000000..da829cba --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CategoryButton.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<templates id="template" xml:space="preserve"> + + <t t-name="CategoryButton" owl="1"> + <span class="category-button" t-on-click="trigger('switch-category', props.category.id)"> + <div class="category-img"> + <img t-att-src="imageUrl" alt="Category" /> + </div> + <div class="category-name"> + <t t-esc="props.category.name" /> + </div> + </span> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CategorySimpleButton.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CategorySimpleButton.xml new file mode 100644 index 00000000..de052e16 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/CategorySimpleButton.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<templates id="template" xml:space="preserve"> + + <t t-name="CategorySimpleButton" owl="1"> + <span class="category-simple-button" + t-on-click="trigger('switch-category', props.category.id)"> + <t t-esc="props.category.name" /> + </span> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ControlButtons/SetFiscalPositionButton.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ControlButtons/SetFiscalPositionButton.xml new file mode 100644 index 00000000..ab09f363 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ControlButtons/SetFiscalPositionButton.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="SetFiscalPositionButton" owl="1"> + <div class="control-button o_fiscal_position_button"> + <i class="fa fa-book" role="img" aria-label="Set fiscal position" + title="Set fiscal position" /> + <t t-esc='currentFiscalPositionName' /> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ControlButtons/SetPricelistButton.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ControlButtons/SetPricelistButton.xml new file mode 100644 index 00000000..ffe3e3ec --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ControlButtons/SetPricelistButton.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="SetPricelistButton" owl="1"> + <div class="control-button o_pricelist_button"> + <i class="fa fa-th-list" role="img" aria-label="Price list" title="Price list" /> + <t t-esc="currentPricelistName" /> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/HomeCategoryBreadcrumb.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/HomeCategoryBreadcrumb.xml new file mode 100644 index 00000000..2bfa426e --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/HomeCategoryBreadcrumb.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<templates id="template" xml:space="preserve"> + + <t t-name="HomeCategoryBreadcrumb" owl="1"> + <span class="breadcrumb"> + <span t-if="!env.isMobile" class="breadcrumb-button breadcrumb-home" + t-on-click="trigger('switch-category', 0)"> + <i class="fa fa-home" role="img" aria-label="Home" title="Home"></i> + </span> + <span t-if="env.isMobile" class="breadcrumb-button breadcrumb-home" + t-on-click="trigger('categ-popup', props.subcategories)"> + <t t-if="env.pos.get('selectedCategoryId') === 0"> + All + </t> + <t t-else=""> + <t t-esc="props.currentCat.name"/> + </t> + </span> + </span> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/NumpadWidget.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/NumpadWidget.xml new file mode 100644 index 00000000..4b9962c0 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/NumpadWidget.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="NumpadWidget" owl="1"> + <div class="numpad"> + <button class="input-button number-char" t-on-click="sendInput('1')">1</button> + <button class="input-button number-char" t-on-click="sendInput('2')">2</button> + <button class="input-button number-char" t-on-click="sendInput('3')">3</button> + <button class="mode-button" t-att-class="{'selected-mode': props.activeMode === 'quantity'}" + t-on-click="changeMode('quantity')">Qty</button> + <br /> + <button class="input-button number-char" t-on-click="sendInput('4')">4</button> + <button class="input-button number-char" t-on-click="sendInput('5')">5</button> + <button class="input-button number-char" t-on-click="sendInput('6')">6</button> + <button class="mode-button" t-att-class="{ + 'selected-mode': props.activeMode === 'discount', + 'disabled-mode': !hasManualDiscount + }" + t-att-disabled="!hasManualDiscount" + t-on-click="changeMode('discount')">Disc</button> + <br /> + <button class="input-button number-char" t-on-click="sendInput('7')">7</button> + <button class="input-button number-char" t-on-click="sendInput('8')">8</button> + <button class="input-button number-char" t-on-click="sendInput('9')">9</button> + <button class="mode-button" t-att-class="{ + 'selected-mode': props.activeMode === 'price', + 'disabled-mode': !hasPriceControlRights + }" t-att-disabled="!hasPriceControlRights" + t-on-click="changeMode('price')">Price</button> + <br /> + <button class="input-button numpad-minus" t-on-click="sendInput('-')">+/-</button> + <button class="input-button number-char" t-on-click="sendInput('0')">0</button> + <button class="input-button number-char" t-on-click="sendInput(decimalSeparator)"> + <t t-esc="decimalSeparator" /> + </button> + <button class="input-button numpad-backspace" 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> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/OrderSummary.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/OrderSummary.xml new file mode 100644 index 00000000..a229c53a --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/OrderSummary.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderSummary" owl="1"> + <div class="summary clearfix"> + <div class="line"> + <div class="entry total"> + <span class="badge">Total: </span> + <span class="value"> + <t t-esc="props.total" /> + </span> + <div t-if="props.tax" class="subentry"> + Taxes: + <span class="value"> + <t t-esc="props.tax" /> + </span> + </div> + </div> + </div> + </div> + </t> + +</templates>
\ No newline at end of file diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/OrderWidget.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/OrderWidget.xml new file mode 100644 index 00000000..532309dc --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/OrderWidget.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderWidget" owl="1"> + <div class="order-container" t-ref="scrollable"> + <div class="order"> + <t t-if="orderlinesArray.length === 0" > + <div class='order-empty'> + <i class='fa fa-shopping-cart' role="img" aria-label="Shopping cart" + title="Shopping cart"/> + <h1>This order is empty</h1> + </div> + </t> + <t t-else=""> + <ul class="orderlines"> + <t t-foreach="orderlinesArray" t-as="orderline" t-key="orderline.id"> + <Orderline line="orderline" /> + </t> + </ul> + <OrderSummary total="state.total" tax="state.tax" /> + </t> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/Orderline.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/Orderline.xml new file mode 100644 index 00000000..e4ede636 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/Orderline.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="Orderline" owl="1"> + <li t-on-click="selectLine" class="orderline" t-att-class="addedClasses"> + <span class="product-name"> + <t t-esc="props.line.get_full_product_name()"/> + <span> </span> + <t t-if="props.line.get_product().tracking!=='none' && (env.pos.picking_type.use_create_lots || env.pos.picking_type.use_existing_lots)"> + <t t-if="props.line.has_valid_product_lot()"> + <i t-on-click.stop="lotIconClicked" + class="oe_link_icon fa fa-list oe_icon line-lot-icon oe_green" + aria-label="Valid product lot" + role="img" + title="Valid product lot" + /> + </t> + <t t-else=""> + <i t-on-click.stop="lotIconClicked" + class="oe_link_icon fa fa-list oe_icon line-lot-icon oe_red" + aria-label="Invalid product lot" + role="img" + title="Invalid product lot" + /> + </t> + </t> + </span> + <span class="price"> + <t t-esc="env.pos.format_currency(props.line.get_display_price())"/> + </span> + <ul class="info-list"> + <t t-if="props.line.get_quantity_str() !== '1' || props.line.selected "> + <li class="info"> + <em> + <t t-esc="props.line.get_quantity_str()" /> + </em> + <span> </span><t t-esc="props.line.get_unit().name" /> + at + <t t-if="props.line.display_discount_policy() == 'without_discount' and + props.line.get_unit_display_price() < props.line.get_lst_price()"> + <s> + <t t-esc="env.pos.format_currency(props.line.get_fixed_lst_price(),'Product Price')" /> + </s> + <t t-esc="env.pos.format_currency(props.line.get_unit_display_price(),'Product Price')" /> + </t> + <t t-else=""> + <t t-esc="env.pos.format_currency(props.line.get_unit_display_price(),'Product Price')" /> + </t> + / + <t t-esc="props.line.get_unit().name" /> + </li> + </t> + <t t-if="props.line.get_discount_str() !== '0'"> + <li class="info"> + With a + <em> + <t t-esc="props.line.get_discount_str()" />% + </em> + discount + </li> + </t> + </ul> + <t t-if="props.line.get_lot_lines()"> + <ul class="info-list"> + <t t-foreach="props.line.get_lot_lines()" t-as="lot" t-key="lot.cid"> + <li> + SN <t t-esc="lot.attributes['lot_name']"/> + </li> + </t> + </ul> + </t> + </li> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductItem.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductItem.xml new file mode 100644 index 00000000..4825efaf --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductItem.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<templates id="template" xml:space="preserve"> + + <t t-name="ProductItem" owl="1"> + <article class="product" tabindex="0" t-on-keypress="spaceClickProduct" + t-on-click="trigger('click-product', props.product)" + t-att-data-product-id="props.product.id" + t-attf-aria-labelledby="article_product_{{props.product.id}}"> + <div class="product-img"> + <img t-att-src="imageUrl" t-att-alt="props.product.display_name" /> + <span class="price-tag"> + <t t-esc="price" /> + </span> + </div> + <div class="product-name" t-attf-id="article_product_{{props.product.id}}"> + <t t-esc="props.product.display_name" /> + </div> + </article> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductList.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductList.xml new file mode 100644 index 00000000..9e87ca95 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductList.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<templates id="template" xml:space="preserve"> + + <t t-name="ProductList" owl="1"> + <div class="product-list-container"> + <div t-if="props.products.length != 0" class="product-list"> + <t t-foreach="props.products" t-as="product" t-key="product.id"> + <ProductItem product="product" /> + </t> + </div> + <div t-else="" class="product-list-empty"> + <div class="product-list-empty"> + <t t-if="props.searchWord !== ''"> + <p> + No results found for " + <b t-esc="props.searchWord"></b> + ". + </p> + </t> + <t t-else=""> + <p>There are no products in this category.</p> + </t> + </div> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductScreen.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductScreen.xml new file mode 100644 index 00000000..6bef9281 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductScreen.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ProductScreen" owl="1"> + <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> + </div> + <t t-if="env.isMobile"> + <MobileOrderWidget pane="mobile_pane" t-on-switchpane="switchPane"/> + </t> + </t> + </div> + <div class="rightpane" t-if="!env.isMobile || mobile_pane === 'right'"> + <ProductsWidget t-if="!state.cashControl"/> + <t t-if="env.isMobile"> + <MobileOrderWidget pane="mobile_pane" t-on-switchpane="switchPane"/> + </t> + </div> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductsWidget.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductsWidget.xml new file mode 100644 index 00000000..3dfd5276 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductsWidget.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<templates id="template" xml:space="preserve"> + + <t t-name="ProductsWidget" owl="1"> + <div class="products-widget"> + <ProductsWidgetControlPanel breadcrumbs="breadcrumbs" subcategories="subcategories" hasNoCategories="hasNoCategories" /> + <ProductList products="productsToDisplay" searchWord="searchWord" /> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductsWidgetControlPanel.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductsWidgetControlPanel.xml new file mode 100644 index 00000000..2c7d7727 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ProductsWidgetControlPanel.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<templates id="template" xml:space="preserve"> + + <t t-name="ProductsWidgetControlPanel" owl="1"> + <div class="products-widget-control"> + <t t-if="!props.hasNoCategories"> + <div class="rightpane-header" t-att-class="{ + 'green-border-bottom': !env.pos.config.iface_display_categ_images, + 'grey-border-bottom': env.pos.config.iface_display_categ_images, + }"> + <!-- Breadcrumbs --> + <div class="breadcrumbs"> + <HomeCategoryBreadcrumb subcategories="props.subcategories" currentCat="props.breadcrumbs[props.breadcrumbs.length - 1]"/> + <t t-if="!env.isMobile"> + <t t-foreach="props.breadcrumbs" t-as="category" t-key="category.id"> + <CategoryBreadcrumb category="category" /> + </t> + </t> + </div> + <!-- Subcategories --> + <t t-if="props.subcategories.length > 0 and !env.pos.config.iface_display_categ_images and !env.isMobile"> + <t t-foreach="props.subcategories" t-as="category" t-key="category.id"> + <CategorySimpleButton category="category" /> + </t> + </t> + </div> + <t t-if="props.subcategories.length > 0 and env.pos.config.iface_display_categ_images and !env.isMobile"> + <div class="categories"> + <div class="category-list-scroller"> + <div class="category-list"> + <t t-foreach="props.subcategories" t-as="category" t-key="category.id"> + <CategoryButton category="category" /> + </t> + </div> + </div> + </div> + </t> + </t> + <Portal target="'.pos .search-bar-portal'"> + <div class="search-box"> + <span class="icon"><i class="fa fa-search"></i></span> + <span t-on-click="clearSearch" class="clear-icon"> + <i class="fa fa-times" aria-hidden="true"></i> + </span> + <input t-ref="search-word-input" type="text" placeholder="Search Products..." t-on-keyup="updateSearch" /> + </div> + </Portal> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml b/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml new file mode 100644 index 00000000..379b360d --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="OrderReceipt" owl="1"> + <div class="pos-receipt"> + <t t-if="receipt.company.logo"> + <img class="pos-receipt-logo" t-att-src="receipt.company.logo" alt="Logo"/> + <br/> + </t> + <t t-if="!receipt.company.logo"> + <h2 class="pos-receipt-center-align"> + <t t-esc="receipt.company.name" /> + </h2> + <br/> + </t> + <div class="pos-receipt-contact"> + <t t-if="receipt.company.contact_address"> + <div><t t-esc="receipt.company.contact_address" /></div> + </t> + <t t-if="receipt.company.phone"> + <div>Tel:<t t-esc="receipt.company.phone" /></div> + </t> + <t t-if="receipt.company.vat"> + <div><t t-esc="receipt.company.vat_label"/>:<t t-esc="receipt.company.vat" /></div> + </t> + <t t-if="receipt.company.email"> + <div><t t-esc="receipt.company.email" /></div> + </t> + <t t-if="receipt.company.website"> + <div><t t-esc="receipt.company.website" /></div> + </t> + <t t-if="receipt.header_html"> + <t t-raw="receipt.header_html" /> + </t> + <t t-if="!receipt.header_html and receipt.header"> + <div style="white-space:pre-line"><t t-esc="receipt.header" /></div> + </t> + <t t-if="receipt.cashier"> + <div class="cashier"> + <div>--------------------------------</div> + <div>Served by <t t-esc="receipt.cashier" /></div> + </div> + </t> + </div> + <br /><br /> + + <!-- Orderlines --> + + <div class="orderlines"> + <t t-foreach="receipt.orderlines" t-as="line" t-key="line.id"> + <t t-if="isSimple(line)"> + <div> + <t t-esc="line.product_name_wrapped[0]" /> + <span t-esc="env.pos.format_currency_no_symbol(line.price_display)" class="price_display pos-receipt-right-align"/> + </div> + <WrappedProductNameLines line="line" /> + </t> + <t t-else=""> + <div t-esc="line.product_name_wrapped[0]" /> + <WrappedProductNameLines line="line" /> + <t t-if="line.display_discount_policy == 'without_discount' and line.price != line.price_lst"> + <div class="pos-receipt-left-padding"> + <t t-esc="env.pos.format_currency_no_symbol(line.price_lst)" /> + -> + <t t-esc="env.pos.format_currency_no_symbol(line.price)" /> + </div> + </t> + <t t-elif="line.discount !== 0"> + <div class="pos-receipt-left-padding"> + <t t-if="env.pos.config.iface_tax_included === 'total'"> + <t t-esc="env.pos.format_currency_no_symbol(line.price_with_tax_before_discount)"/> + </t> + <t t-else=""> + <t t-esc="env.pos.format_currency_no_symbol(line.price)"/> + </t> + </div> + </t> + <t t-if="line.discount !== 0"> + <div class="pos-receipt-left-padding"> + Discount: <t t-esc="line.discount" />% + </div> + </t> + <div class="pos-receipt-left-padding"> + <t t-esc="Math.round(line.quantity * Math.pow(10, env.pos.dp['Product Unit of Measure'])) / Math.pow(10, env.pos.dp['Product Unit of Measure'])"/> + <t t-if="!line.is_in_unit" t-esc="line.unit_name" /> + x + <t t-esc="env.pos.format_currency_no_symbol(line.price_display_one)" /> + <span class="price_display pos-receipt-right-align"> + <t t-esc="env.pos.format_currency_no_symbol(line.price_display)" /> + </span> + </div> + </t> + <t t-if="line.pack_lot_lines"> + <div class="pos-receipt-left-padding"> + <ul> + <t t-foreach="line.pack_lot_lines" t-as="lot" t-key="lot.cid"> + <li> + SN <t t-esc="lot.attributes['lot_name']"/> + </li> + </t> + </ul> + </div> + </t> + </t> + </div> + + <!-- Subtotal --> + + <t t-if="!isTaxIncluded"> + <div class="pos-receipt-right-align">--------</div> + <br/> + <div>Subtotal<span t-esc="env.pos.format_currency(receipt.subtotal)" class="pos-receipt-right-align"/></div> + <t t-foreach="receipt.tax_details" t-as="tax" t-key="tax.name"> + <div> + <t t-esc="tax.name" /> + <span t-esc='env.pos.format_currency_no_symbol(tax.amount)' class="pos-receipt-right-align"/> + </div> + </t> + </t> + + <!-- Total --> + <div class="pos-receipt-right-align">--------</div> + <br/> + <div class="pos-receipt-amount"> + TOTAL + <span t-esc="env.pos.format_currency(receipt.total_with_tax)" class="pos-receipt-right-align"/> + </div> + <t t-if="receipt.total_rounded != receipt.total_with_tax"> + <div class="pos-receipt-amount"> + Rounding + <span t-esc='env.pos.format_currency(receipt.rounding_applied)' class="pos-receipt-right-align"/> + </div> + <div class="pos-receipt-amount"> + To Pay + <span t-esc='env.pos.format_currency(receipt.total_rounded)' class="pos-receipt-right-align"/> + </div> + </t> + <br/><br/> + + <!-- Payment Lines --> + + <t t-foreach="receipt.paymentlines" t-as="line" t-key="line.cid"> + <div> + <t t-esc="line.name" /> + <span t-esc="env.pos.format_currency_no_symbol(line.amount)" class="pos-receipt-right-align"/> + </div> + </t> + <br/> + + <div class="pos-receipt-amount receipt-change"> + CHANGE + <span t-esc="env.pos.format_currency(receipt.change)" class="pos-receipt-right-align"/> + </div> + <br/> + + <!-- Extra Payment Info --> + + <t t-if="receipt.total_discount"> + <div> + Discounts + <span t-esc="env.pos.format_currency(receipt.total_discount)" class="pos-receipt-right-align"/> + </div> + </t> + <t t-if="isTaxIncluded"> + <t t-foreach="receipt.tax_details" t-as="tax" t-key="tax.name"> + <div> + <t t-esc="tax.name" /> + <span t-esc="env.pos.format_currency_no_symbol(tax.amount)" class="pos-receipt-right-align"/> + </div> + </t> + <div> + Total Taxes + <span t-esc="env.pos.format_currency(receipt.total_tax)" class="pos-receipt-right-align"/> + </div> + </t> + + <div class="before-footer" /> + + <!-- Footer --> + <div t-if="receipt.footer_html" class="pos-receipt-center-align"> + <t t-raw="receipt.footer_html" /> + </div> + + <div t-if="!receipt.footer_html and receipt.footer" class="pos-receipt-center-align" style="white-space:pre-line"> + <br/> + <t t-esc="receipt.footer" /> + <br/> + <br/> + </div> + + <div class="after-footer"> + <t t-foreach="receipt.paymentlines" t-as="line"> + <t t-if="line.ticket"> + <br /> + <div class="pos-payment-terminal-receipt"> + <t t-raw="line.ticket" /> + </div> + </t> + </t> + </div> + + <br/> + <div class="pos-receipt-order-data"> + <div><t t-esc="receipt.name" /></div> + <div><t t-esc="receipt.date.localestring" /></div> + </div> + + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/ReceiptScreen.xml b/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/ReceiptScreen.xml new file mode 100644 index 00000000..8f0bd54a --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/ReceiptScreen.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="ReceiptScreen" owl="1"> + <div class="receipt-screen screen"> + <div class="screen-content"> + <div class="top-content"> + <div class="top-content-center"> + <h1 t-if="!env.isMobile"> + <t t-esc="orderAmountPlusTip" /> + </h1> + </div> + <div class="button next" t-att-class="{ highlight: !locked }" + t-on-click="orderDone"> + New Order <i class="fa fa-angle-double-right"></i> + </div> + </div> + <div class="default-view"> + <div class="pos-receipt-container"> + <OrderReceipt order="currentOrder" t-ref="order-receipt" /> + </div> + <div class="actions"> + <h1>How would you like to receive your receipt?</h1> + <div class="buttons"> + <div class="button print" t-on-click="printReceipt"> + <i class="fa fa-print"></i> Print Receipt + </div> + </div> + <form t-on-submit.prevent="onSendEmail" class="send-email"> + <div class="email-icon"><i class="fa fa-envelope-o" aria-hidden="true"></i></div> + <div class="input-email"> + <input type="email" placeholder="Email Receipt" t-model="orderUiState.inputEmail" /> + <button class="send" t-att-class="{ highlight: is_email(orderUiState.inputEmail) }" type="submit">Send</button> + </div> + </form> + <t t-if="orderUiState.emailSuccessful !== null"> + <div class="notice" t-attf-class="{{ orderUiState.emailSuccessful ? 'successful' : 'failed' }}"> + <t t-esc="orderUiState.emailNotice"></t> + </div> + </t> + </div> + </div> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/WrappedProductNameLines.xml b/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/WrappedProductNameLines.xml new file mode 100644 index 00000000..d49061a8 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/WrappedProductNameLines.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="WrappedProductNameLines" owl="1"> + <span> + <t t-foreach="props.line.product_name_wrapped.slice(1)" t-as="wrapped_line"><t t-esc="wrapped_line"/></t> + </span> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/Screens/ScaleScreen/ScaleScreen.xml b/addons/point_of_sale/static/src/xml/Screens/ScaleScreen/ScaleScreen.xml new file mode 100644 index 00000000..de21dcc3 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/ScaleScreen/ScaleScreen.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<templates id="template" xml:space="preserve"> + + <t t-name="ScaleScreen" owl="1"> + <div class="scale-screen screen"> + <div class="screen-content"> + <div class="top-content"> + <span class="button back" t-on-click="back"> + <i class="fa fa-angle-double-left"></i> + Back + </span> + <h1 class="product-name"> + <t t-esc="productName" /> + </h1> + </div> + <div class="centered-content"> + <div class="weight js-weight"> + <t t-esc="productWeightString" /> + </div> + <div class="product-price"> + <t + t-esc="env.pos.format_currency(productPrice) + '/' + productUom" /> + </div> + <div class="computed-price"> + <t t-esc="computedPriceString" /> + </div> + <div class="buy-product" t-on-click="confirm"> + Order + <i class="fa fa-angle-double-right"></i> + </div> + </div> + </div> + </div> + </t> + +</templates>
\ No newline at end of file diff --git a/addons/point_of_sale/static/src/xml/Screens/TicketScreen/TicketScreen.xml b/addons/point_of_sale/static/src/xml/Screens/TicketScreen/TicketScreen.xml new file mode 100644 index 00000000..40bfc501 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/Screens/TicketScreen/TicketScreen.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + + <t t-name="TicketScreen" owl="1"> + <div class="ticket-screen screen"> + <div class="screen-content"> + <div class="controls"> + <div class="buttons"> + <button t-if="showNewTicketButton" class="highlight" t-on-click="createNewOrder">New Order</button> + <button class="discard" t-on-click="trigger('close-screen')">Discard</button> + </div> + <t t-set="placeholder">Search Tickets...</t> + <SearchBar config="searchBarConfig" placeholder="placeholder" /> + </div> + <div class="orders"> + <div class="header-row"> + <div class="col start wide">Date</div> + <div class="col start wide">Receipt Number</div> + <div class="col start">Customer</div> + <div class="col start wide" t-if="showCardholderName()">Cardholder Name</div> + <div class="col start">Employee</div> + <div class="col end">Total</div> + <div class="col start narrow">Status</div> + <div class="col center very-narrow" name="delete"></div> + </div> + <t t-foreach="filteredOrderList" t-as="order" t-key="order.cid"> + <div class="order-row pointer" t-on-click="selectOrder(order)"> + <div class="col start wide"> + <t t-esc="getDate(order)"></t> + </div> + <div class="col start wide"> + <t t-esc="order.name"></t> + </div> + <div class="col start"> + <t t-esc="getCustomer(order)"></t> + </div> + <div t-if="showCardholderName()" class="col start"> + <t t-esc="getCardholderName(order)"></t> + </div> + <div class="col start"> + <t t-esc="getEmployee(order)"></t> + </div> + <div class="col end"> + <t t-esc="getTotal(order)"></t> + </div> + <div class="col start narrow"> + <t t-esc="getStatus(order)"></t> + </div> + <div t-if="!hideDeleteButton(order)" class="col center very-narrow delete-button" name="delete" t-on-click.stop="deleteOrder(order)"> + <i class="fa fa-trash" aria-hidden="true"></i> + </div> + <div t-else="" class="col center very-narrow delete-button"></div> + </div> + </t> + </div> + </div> + </div> + </t> + +</templates> diff --git a/addons/point_of_sale/static/src/xml/debug_manager.xml b/addons/point_of_sale/static/src/xml/debug_manager.xml new file mode 100644 index 00000000..7ecc7cc1 --- /dev/null +++ b/addons/point_of_sale/static/src/xml/debug_manager.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + +<t t-extend="WebClient.DebugManager.Backend"> + <t t-jquery="a[data-action='perform_click_everywhere_test']" t-operation="after"> + <a role="menuitem" href="#" data-action="perform_pos_js_tests" class="dropdown-item">Run Point of Sale JS Tests</a> + </t> +</t> + +</templates> |
