Skip to content

Commit

Permalink
[IMP] pos: display cart item quantity on product card
Browse files Browse the repository at this point in the history
Before this commit:
- The product card did not show the number of items in the cart.

After this commit:
- Added quantity display on the product card which indicates how many of
  each product is in the cart.

closes odoo#188736

Task: 4244560
X-original-commit: 3fa1deb
Signed-off-by: David Monnom (moda) <[email protected]>
Signed-off-by: Parthkumar Patel (parp) <[email protected]>
  • Loading branch information
parp-odoo committed Nov 27, 2024
1 parent 7f860b4 commit bf5ccd6
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class ProductCard extends Component {
onClick: { type: Function, optional: true },
onProductInfoClick: { type: Function, optional: true },
showWarning: { type: Boolean, optional: true },
productCartQty: { type: [Number, undefined], optional: true },
};
static defaultProps = {
onClick: () => {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@
<div t-if="props.imageUrl" class="product-img rounded-top rounded-3">
<img class="w-100 bg-100" t-att-src="props.imageUrl" t-att-alt="props.name" />
</div>
<div class="product-content d-flex flex-column justify-content-between p-2 rounded-bottom rounded-3 flex-shrink-1">
<div class="overflow-hidden lh-sm product-name"
<div class="product-content d-flex flex-row px-2 justify-content-between rounded-bottom rounded-3 flex-shrink-1" t-att-class="{'h-100' : !props.imageUrl}">
<div class="overflow-hidden lh-sm product-name my-2"
t-att-class="{'no-image d-flex justify-content-center align-items-center text-center fs-4': !props.imageUrl}"
t-attf-id="article_product_{{props.productId}}"
t-esc="props.name" />
<h1 t-if="props.productCartQty"
t-out="props.productCartQty"
class="product-cart-qty text-muted display-6 fw-bolder m-0 mt-auto" />
</div>
</article>
</t>
Expand Down
4 changes: 4 additions & 0 deletions addons/point_of_sale/static/src/app/models/pos_order.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ export class PosOrder extends Base {
return this.state !== "draft";
}

get totalQuantity() {
return this.lines.reduce((sum, line) => sum + line.getQuantity(), 0);
}

get isUnsyncedPaid() {
return this.finalized && typeof this.id === "string";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useService } from "@web/core/utils/hooks";
import { useBarcodeReader } from "@point_of_sale/app/hooks/barcode_reader_hook";
import { _t } from "@web/core/l10n/translation";
import { usePos } from "@point_of_sale/app/hooks/pos_hook";
import { Component, onMounted, useState, reactive, onWillRender } from "@odoo/owl";
import { Component, onMounted, useEffect, useState, reactive, onWillRender } from "@odoo/owl";
import { CategorySelector } from "@point_of_sale/app/components/category_selector/category_selector";
import { Input } from "@point_of_sale/app/components/inputs/input/input";
import {
Expand Down Expand Up @@ -52,6 +52,7 @@ export class ProductScreen extends Component {
this.state = useState({
previousSearchWord: "",
currentOffset: 0,
quantityByProductTmplId: {},
});
onMounted(() => {
this.pos.openOpeningControl();
Expand Down Expand Up @@ -84,6 +85,18 @@ export class ProductScreen extends Component {
this.numberBuffer.use({
useWithBarcode: true,
});

useEffect(
() => {
this.state.quantityByProductTmplId = this.currentOrder?.lines?.reduce((acc, ol) => {
acc[ol.product_id.product_tmpl_id.id]
? (acc[ol.product_id.product_tmpl_id.id] += ol.qty)
: (acc[ol.product_id.product_tmpl_id.id] = ol.qty);
return acc;
}, {});
},
() => [this.currentOrder.totalQuantity]
);
}

getNumpadButtons() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
imageUrl="pos.config.show_product_images and this.getProductImage(product)"
onClick.bind="() => this.addProductToOrder(product)"
productInfo="true"
productCartQty="this.state.quantityByProductTmplId[product.id]"
onProductInfoClick.bind="() => this.onProductInfoClick(product)" />
</div>
<div t-else="" class="flex-grow-1 text-center mt-5">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ registry.category("web_tour.tours").add("ProductScreenTour", {
...ProductScreen.selectedOrderlineHasDirect("Desk Organizer", "123.0", "627.3"),
...[".", "5"].map(Numpad.click),
...ProductScreen.selectedOrderlineHasDirect("Desk Organizer", "123.5", "629.85"),
]),
// Check effects of numpad on product card quantity
ProductScreen.productCardQtyIs("Desk Organizer", "123.5"),
inLeftSide([
// Re-select the order line after switching to the product screen
{ ...ProductScreen.clickLine("Desk Organizer", "123.5")[0], isActive: ["mobile"] },
Numpad.click("Price"),
Numpad.isActive("Price"),
Numpad.click("1"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ export function clickDisplayedProduct(
if (isCheckNeed) {
step.push(...selectedOrderlineHas(name, nextQuantity, nextPrice));
}
if (isCheckNeed && nextQuantity) {
step.push(...productCardQtyIs(name, nextQuantity));
}

return step;
}
Expand Down Expand Up @@ -461,6 +464,16 @@ export function cashDifferenceIs(val) {
},
];
}
export function productCardQtyIs(productName, qty) {
qty = `${Number.parseFloat(Number.parseFloat(qty).toFixed(2))}`;
return [
{
content: `'${productName}' should have '${qty}' quantity`,
trigger: `article.product .product-content:has(.product-name:contains("${productName}")):has(.product-cart-qty:contains("${qty}"))`,
},
];
}

// Temporarily put it here. It should be in the utility methods for the backend views.
export function lastClosingCashIs(val) {
return [
Expand Down

0 comments on commit bf5ccd6

Please sign in to comment.