Skip to content

Commit

Permalink
[IMP] pos: Improve UI and access controls across features
Browse files Browse the repository at this point in the history
- Implemented employee login and update form placeholders for basic and advanced rights in the edit dashboard.
- Enforced primary payment method after order placement in pos_restaurant.
- Restricted basic user rights from creating products.
- Swapped positions of Lock and Print buttons, added a lock icon for clarity.
- Adjusted floor plan corner selector size.
- Hid zero dollar price for combos in the cart.
Task ID: 3916835

closes odoo#168651

Signed-off-by: Joseph Caburnay (jcb) <[email protected]>
  • Loading branch information
nesma-neha committed Jun 10, 2024
1 parent 264f4b8 commit 7226734
Show file tree
Hide file tree
Showing 16 changed files with 111 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
<t t-slot="product-name"/>
</div>
<div class="product-price d-inline-block text-end price fw-bolder">
<t t-if="line.price === 'free'">Free</t>
<t t-else="" t-esc="line.price"/>
<t t-esc="line.price"/>
</div>
</div>
<ul class="info-list" t-attf-class="{{props.infoListClasses}}">
Expand Down
15 changes: 11 additions & 4 deletions addons/point_of_sale/static/src/app/models/pos_order_line.js
Original file line number Diff line number Diff line change
Expand Up @@ -611,13 +611,20 @@ export class PosOrderline extends Base {
);
}

getPriceString() {
return this.get_discount_str() === "100"
? // free if the discount is 100
_t("Free")
: this.combo_line_ids.length > 0
? // empty string if it is a combo parent line
""
: formatCurrency(this.get_display_price(), this.currency);
}

getDisplayData() {
return {
productName: this.get_full_product_name(),
price:
this.get_discount_str() === "100"
? "free"
: formatCurrency(this.get_display_price(), this.currency),
price: this.getPriceString(),
qty: this.get_quantity_str(),
unit: this.product_id.uom_id ? this.product_id.uom_id.name : "",
unitPrice: formatCurrency(this.get_unit_display_price(), this.currency),
Expand Down
13 changes: 12 additions & 1 deletion addons/point_of_sale/static/src/app/navbar/navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { useService } from "@web/core/utils/hooks";

import { CashierName } from "@point_of_sale/app/navbar/cashier_name/cashier_name";
import { ProxyStatus } from "@point_of_sale/app/navbar/proxy_status/proxy_status";
import { SaleDetailsButton } from "@point_of_sale/app/navbar/sale_details_button/sale_details_button";
import {
SaleDetailsButton,
handleSaleDetails,
} from "@point_of_sale/app/navbar/sale_details_button/sale_details_button";
import { SyncNotification } from "@point_of_sale/app/navbar/sync_notification/sync_notification";
import { CashMovePopup } from "@point_of_sale/app/navbar/cash_move_popup/cash_move_popup";
import { TicketScreen } from "@point_of_sale/app/screens/ticket_screen/ticket_screen";
Expand Down Expand Up @@ -130,4 +133,12 @@ export class Navbar extends Component {
});
}
}

get showCreateProductButton() {
return this.isSystemUser;
}

async showSaleDetails() {
await handleSaleDetails(this.pos, this.hardwareProxy, this.dialog);
}
}
6 changes: 4 additions & 2 deletions addons/point_of_sale/static/src/app/navbar/navbar.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
debounceMillis="500"
t-if="pos.showSearchButton()" />
<CashierName />
<SaleDetailsButton t-if="hardwareProxy.printer" isHeaderButton="true"/>
<ProxyStatus t-if="pos.config.use_proxy" />
<button t-if="pos.config.customer_display_type !== 'none'" t-on-click="openCustomerDisplay" class="btn btn-light fa fa-fw fa-desktop text-success pe-4" title="Customer Display" />
<SyncNotification />
Expand All @@ -39,9 +38,12 @@
<DropdownItem t-if="showToggleProductView" onSelected="() => this.toggleProductView()">
Switch Product View
</DropdownItem>
<DropdownItem t-if="this.isSystemUser" onSelected="() => this.pos.editProduct()">
<DropdownItem t-if="showCreateProductButton" onSelected="() => this.pos.editProduct()">
Create Product
</DropdownItem>
<DropdownItem t-if="hardwareProxy.printer" onSelected="() => this.showSaleDetails()">
Print Report
</DropdownItem>
<DropdownItem onSelected="() => pos.closePos()">
Backend
</DropdownItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@ import { AlertDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
import { Component } from "@odoo/owl";
import { usePos } from "@point_of_sale/app/store/pos_hook";

export async function handleSaleDetails(pos, hardwareProxy, dialog) {
const saleDetails = await pos.data.call(
"report.point_of_sale.report_saledetails",
"get_sale_details",
[false, false, false, [pos.session.id]]
);
const report = renderToElement(
"point_of_sale.SaleDetailsReport",
Object.assign({}, saleDetails, {
date: new Date().toLocaleString(),
pos: pos,
formatCurrency: pos.env.utils.formatCurrency,
})
);
const { successful, message } = await hardwareProxy.printer.printReceipt(report);
if (!successful) {
dialog.add(AlertDialog, {
title: message.title,
body: message.body,
});
}
}
export class SaleDetailsButton extends Component {
static template = "point_of_sale.SaleDetailsButton";
static props = {
Expand All @@ -17,28 +39,6 @@ export class SaleDetailsButton extends Component {
}

async onClick() {
// IMPROVEMENT: Perhaps put this logic in a parent component
// so that for unit testing, we can check if this simple
// component correctly triggers an event.
const saleDetails = await this.pos.data.call(
"report.point_of_sale.report_saledetails",
"get_sale_details",
[false, false, false, [this.pos.session.id]]
);
const report = renderToElement(
"point_of_sale.SaleDetailsReport",
Object.assign({}, saleDetails, {
date: new Date().toLocaleString(),
pos: this.pos,
formatCurrency: this.env.utils.formatCurrency,
})
);
const { successful, message } = await this.hardwareProxy.printer.printReceipt(report);
if (!successful) {
this.dialog.add(AlertDialog, {
title: message.title,
body: message.body,
});
}
await handleSaleDetails(this.pos, this.hardwareProxy, this.dialog);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class ActionpadWidget extends Component {
get isLongName() {
return this.props.partner && this.props.partner.name.length > 10;
}

getMainButtonClasses() {
return "button btn d-flex flex-column flex-fill align-items-center justify-content-center fw-bolder btn-lg rounded-0";
}
Expand Down
17 changes: 17 additions & 0 deletions addons/pos_hr/static/src/overrides/components/navbar/navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,21 @@ patch(Navbar.prototype, {
this.pos.reset_cashier();
this.pos.showScreen("LoginScreen");
},
get showCreateProductButton() {
if (!this.pos.config.module_pos_hr || this.employeeIsAdmin()) {
return super.showCreateProductButton;
} else {
return false;
}
},
get showEditPlanButton() {
if (
this.pos.config.module_pos_restaurant &&
(!this.pos.config.module_pos_hr || this.employeeIsAdmin())
) {
return super.showEditPlanButton;
} else {
return false;
}
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@
!pos.config.module_pos_hr or employeeIsAdmin()
</attribute>
</xpath>
<xpath expr="//DropdownItem[contains(text(), 'Backend')]" position="after">
<DropdownItem t-if="pos.config.module_pos_hr" onSelected="() => this.showLoginScreen()">
Lock
</DropdownItem>
</xpath>
<xpath expr="//DropdownItem[contains(text(), 'Close Register')]" position="attributes">
<attribute name="t-if">
!pos.config.module_pos_hr or employeeIsAdmin()
</attribute>
</xpath>
<xpath expr="//CashierName" position="after">
<button t-if="pos.config.module_pos_hr" class="btn btn-light fa fa-lg fa-lock text-success px-3" title="Lock" t-on-click="showLoginScreen"/>
</xpath>
</t>

</templates>
4 changes: 2 additions & 2 deletions addons/pos_hr/static/tests/tours/pos_hr_tour.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ registry.category("web_tour.tours").add("PosHrTour", {
PosHr.clickCashierName(),
SelectionPopup.has("Mitchell Admin", { run: "click" }),
PosHr.cashierNameIs("Mitchell Admin"),
Chrome.clickMenuOption("Lock"),
PosHr.clickLockButton(),
PosHr.clickLoginButton(),
SelectionPopup.has("Pos Employee2", { run: "click" }),
NumberPopup.enterValue("12"),
Expand All @@ -57,7 +57,7 @@ registry.category("web_tour.tours").add("PosHrTour", {
TicketScreen.nthRowContains(2, "Pos Employee2", false),

// order for employee 1
Chrome.clickMenuOption("Lock"),
PosHr.clickLockButton(),
PosHr.login("Pos Employee1", "2580"),
TicketScreen.clickNewTicket(),
ProductScreen.addOrderline("Desk Pad", "1", "4"),
Expand Down
7 changes: 7 additions & 0 deletions addons/pos_hr/static/tests/tours/utils/pos_hr_helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,10 @@ export function login(name, pin) {
Dialog.confirm(),
]);
}
export function clickLockButton() {
return {
content: "Click on the menu button",
trigger: ".pos-rightheader button.fa-lock",
run: "click",
};
}
4 changes: 2 additions & 2 deletions addons/pos_hr/views/pos_config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
<field name="company_id" invisible="1" />
<div class="row">
<label for="basic_employee_ids" string="Basic rights" class="col-lg-4 o_light_label" />
<field name="basic_employee_ids" widget="many2many_tags" domain="[('company_id', '=', company_id)]" />
<field name="basic_employee_ids" widget="many2many_tags" placeholder="All Employees" domain="[('company_id', '=', company_id)]" />
</div>
<div class="row">
<label for="advanced_employee_ids" string="Advanced rights" class="col-lg-4 o_light_label" />
<field name="advanced_employee_ids" widget="many2many_tags" domain="[('company_id', '=', company_id)]" />
<field name="advanced_employee_ids" widget="many2many_tags" placeholder="Select Employee(s)" domain="[('company_id', '=', company_id)]" />
</div>
</xpath>
</field>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Navbar } from "@point_of_sale/app/navbar/navbar";
import { patch } from "@web/core/utils/patch";

patch(Navbar.prototype, {
get showEditPlanButton() {
if (
this.pos.config.module_pos_restaurant &&
(!this.pos.config.module_pos_hr || this.employeeIsAdmin())
) {
return super.showEditPlanButton;
} else {
return false;
}
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
.table-handle {
padding: 0px;
position: absolute;
width: 24px;
height: 24px;
border-radius: 12px;
width: 20px;
height: 20px;
border-radius: 10px;
background: white;
box-shadow: 0px 2px 3px rgba(0,0,0,0.2);
/* See o-grab-cursor mixin */
Expand Down
4 changes: 2 additions & 2 deletions addons/pos_restaurant/static/src/app/floor_screen/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ export class Table extends Component {
*/
computeHandleStyle(handleName) {
const table = this.props.table;
// 12 is half the handle's width
let offset = -12;
// 15 is half the handle's width on hovering
let offset = -15;
if (table.shape === "round") {
// min(width/2, height/2) is the real border radius
// 0.2929 is (1 - cos(45°)) to get in the middle of the border's arc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,7 @@ patch(Navbar.prototype, {
},
});
},
get showEditPlanButton() {
return true;
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
<templates id="template" xml:space="preserve">
<t t-name="pos_restaurant.Navbar" t-inherit="point_of_sale.Navbar" t-inherit-mode="extension">
<xpath expr="//DropdownItem[contains(text(), 'Backend')]" position="before">
<DropdownItem t-if="pos.mainScreen.component.name == 'FloorScreen'" onSelected="() => this.pos.toggleEditMode()">
Edit Plan
</DropdownItem>
<t t-if="pos.mainScreen.component.name == 'FloorScreen'">
<DropdownItem t-if="showEditPlanButton" onSelected="() => this.pos.toggleEditMode()">
Edit Plan
</DropdownItem>
</t>
<DropdownItem t-if="pos.mainScreen.component.name == 'FloorScreen'" onSelected="() => this.onSwitchButtonClick()">
Switch Floor View
</DropdownItem>
Expand Down

0 comments on commit 7226734

Please sign in to comment.