Odoo 18 POS – Display Only Combo Products with Total Price and Order Date on Receipt

In my Odoo 18 POS, I want to customize the receipt so that:

Only products of type “combo” are displayed.

The individual items included in the combo are not listed separately.

The displayed price is the total price of the combo, not the sum of the child products.

The receipt layout remains the default Odoo POS layout.

The order date should be displayed, not just the payment timestamp.

I have tried overriding OrderReceipt using a CustomOrderReceipt component, but I encounter errors such as OwlError or Cannot read properties of undefined when filtering lines or accessing paymentlines.

I am looking for an approach or working example to:

Filter order lines to show only combos.

Display the total price of the combo.

Show the order date.

Avoid Owl errors caused by missing data (e.g., payment_method undefined).

Any advice or working examples would be greatly appreciated.

My template
[text](

<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">

  <!-- Surcharge du template OrderReceipt -->
  <t t-name="pos_receipt_customisation.OrderReceipt" t-inherit="point_of_sale.OrderReceipt" t-inherit-mode="primary">

    <xpath expr="//OrderWidget" position="replace">

      <!-- Filtrer uniquement les lignes de type combo (exclure enfants) -->
      <t t-set="combo_lines" t-value="props.data.orderlines.filter(line => line.is_combo)"/>

      <div class="order-container d-flex flex-column flex-grow-1 overflow-y-auto text-start">
        <t t-foreach="combo_lines" t-as="line" t-key="line.id">
          <li class="orderline position-relative d-flex align-items-center p-2 lh-sm cursor-pointer px-0">
            <div class="product-order"></div>
            <div class="d-flex flex-column w-100 gap-1">
              <div class="d-flex justify-content-between">
                <div class="product-name d-inline-block flex-grow-1 fw-bolder pe-1 text-truncate">
                  <span class="text-wrap"><t t-esc="line.productName"/></span>
                </div>
                <div class="product-price price fw-bolder">
                  <t t-esc="line.price_total ? props.formatCurrency(line.price_total) : props.formatCurrency(line.price)"/>
                </div>
              </div>
              <ul class="info-list d-flex flex-column">
                <li class="price-per-unit">
                  <span class="qty px-1 border rounded text-bg-view fw-bolder me-1">
                    <t t-esc="line.qty"/> <t t-esc="line.unit || 'Unité(s)'"/>
                  </span>
                  x <t t-esc="line.price_total ? props.formatCurrency(line.price_total) : props.formatCurrency(line.price)"/> / <t t-esc="line.unit || 'Unité(s)'"/>
                </li>
              </ul>
            </div>
          </li>
        </t>
      </div>

      <!-- Montant total -->
      <div class="pos-receipt-amount receipt-total">
        TOTAL
        <span class="pos-receipt-right-align">
          <t t-esc="props.formatCurrency(props.data.amount_total)"/>
        </span>
      </div>

      <!-- Paiement -->
<div class="paymentlines text-start">
  <t t-foreach="props.data.paymentlines" t-as="line" t-key="line.id">
    <t t-if="line.payment_method">
      <t t-esc="line.payment_method.name"/> 
      <span class="pos-receipt-right-align">
        <t t-esc="props.formatCurrency(line.amount)"/>
      </span>
    </t>
    <t t-else="">
      <span>Autre</span>
      <span class="pos-receipt-right-align">
        <t t-esc="props.formatCurrency(line.amount)"/>
      </span>
    </t>
  </t>
</div>


    </xpath>
  </t>

  <!-- Surcharge ReceiptScreen -->
  <t t-name="pos_receipt_customisation.ReceiptScreen" t-inherit="point_of_sale.ReceiptScreen" t-inherit-mode="extension" owl="1">
    <xpath expr="//OrderReceipt" position="replace">
      <CustomOrderReceipt data="pos.orderExportForPrinting(pos.get_order())" formatCurrency="env.utils.formatCurrency"/>
    </xpath>
  </t>

</templates>

this is the Js:
/** @odoo-module **/

import { patch } from "@web/core/utils/patch";
import { ReceiptScreen } from "@point_of_sale/app/screens/receipt_screen/receipt_screen";
import { OrderReceipt } from "@point_of_sale/app/screens/receipt_screen/receipt/order_receipt";

export class CustomOrderReceipt extends OrderReceipt {
  static template = "pos_receipt_customisation.OrderReceipt";
}

patch(ReceiptScreen, {
  components: { ...ReceiptScreen.components, CustomOrderReceipt },
});

)

What I tried:

I tried to customize the Odoo 18 POS receipt by:

Creating a custom XML template that inherits from point_of_sale.OrderReceipt.

Using an xpath to replace the OrderWidget section and filter only combo products (line.is_combo).

Displaying the combo product name, quantity, and total price, while excluding the products included in the combo.

Adding the total amount and payment lines using props.formatCurrency.

Creating a JavaScript class CustomOrderReceipt extending OrderReceipt and patching ReceiptScreen to include the custom component.

What I was expecting:

The receipt should only show combo products, not their child items.

Each combo should display its total price.

The receipt layout should remain the default Odoo POS style.

The total order amount and payment lines should display correctly.

Ideally, the receipt should also display the order date, not just the payment time.

Currently, instead of this expected behavior, I am getting Owl lifecycle errors and some combo prices or payment methods sometimes don’t display properly.

How can I remove the Error Overlay that obstructs Playwright E2E test assertions

I’m running Playwright E2E tests against a Next.js 15 project. When something goes wrong in dev, Next injects an error overlay (via the element) (see image as an example). That overlay is useful in development, but during Playwright runs it sometimes appears on top of the page and blocks my tests (screenshots, clicks, assertions).

enter image description here

What I want:

For E2E only, I’d like to hide or disable that overlay so tests can continue cleanly (often times these errors are unrelated to the tests i’d like to assert).

What I’ve tried:

I wrote a helper to hide the portal element after page.goto(), but overlays can appear later (after navigation or initial render) so it isn’t reliable, and seems very hacky.

Example test setup:

export async function hideNextJsPortal(page) {
  await page.evaluate(() => {
    const portal = document.querySelector('nextjs-portal');
    if (portal) portal.style.display = 'none';
  });
}

in test sample:

test.beforeEach(async ({ page }) => {
  await page.goto('/');
  await hideNextJsPortal(page);
});

Pressing enter doesn’t run JS function, separate button does work

I’m trying to make a website where a user can input a name, and get a webpage corresponding to that name (if it exists). I’ve got a simple function that when the user presses the submit button, the function works exactly as desired. However, when I’ve tried to update the code so that the user can also press the enter button for the same effect, the code doesn’t run properly, not pulling up the correct window, nor giving the incorrect site or a http error.

This is the js code:

       function showFrame(){
          //show frame
          document.getElementById("Frame").style.display = "flex";
          //set iframe to the name inputted
          var theRaw = document.getElementById("Hog").value;
          theProcessed = "https://chickendragon.neocities.org/Database/" + theRaw;
          document.getElementById("inFrame").src = theProcessed;
          document.getElementById("Database").style.display = "none";
       }

This is the html:

  <!-- Search Bar--> 
  <div class="content" id="Database">
  <form >
    <label for="Hog">Enter file name below:</label><br>
     <input type="text" id="Hog">
  </form>
  <button onclick="showFrame()">Submit</button> <!-- This works-->
  </div>

  <!-- File access-->
  <div class="content" id="Frame">
  <iframe id="inFrame" src= ""></iframe>
  </div>

I’ve tried putting an onsubmit=”showFrame()” but nowhere I slot it seems to work. Additionally, moving the code around to pass the input value into the function also gives similar results.

Javascript ctx.putImageData at an angle for unknown reason

I am writing a program to generate some orbital images. I decided to use js because I have a fair amount of experience with it and its fast to write for prototypes. The issue is that when I go to use ctx.putImageData it is rotated by a -45° angle and the image is stretched.
This is the actually important code:

  genImg(){
    let index = 0;
    for(let y = 0; y <= 400; y++){
      for(let x = 0; x <= 400; x++){
        let lx = (x - 200)*this.step;
        let ly = (200 - y)*this.step;
        this.points.push(this.value(Math.sqrt(Math.pow(lx, 2) + Math.pow(ly, 2)), this.t, Math.atan2(lx,ly))[0]);
      }
    }
    let sclFct = 1000/Math.max(...this.points);
    for(let i = 0; i<= 160000; i++){
      let val = Math.round(this.points[i]*sclFct);
      this.imgDataArr[index] = cmap[val*4]; // R value        
      this.imgDataArr[index + 1] = cmap[val*4 + 1]; // G value
      this.imgDataArr[index + 2] = cmap[val*4 + 2]; // B value
      this.imgDataArr[index + 3] = 255; // A value
      index += 4; 
    }
    let imgData = new ImageData(this.imgDataArr, 400, 400);
    ctx.putImageData(imgData, 0, 0);
  }

The Full code is here. Just off the bat I should mention this is all written in a class. The html is just a canvas element in the <main></main> area that is 400px by 400px. The CSS is just to center everything and give the canvas a border. The function this.value(r,t,p) takes the values r(radius), t(theta) and p(phi). Theta is a constant and radius and phi are calculated from (x,y) cords (see line 7 of the prior code).
enter image description here
In the image you can see where there is the diagonal. The black should be in the center with the other colors radiating out. So far I have tried a 45° rotation to the atan2 function, messing with the css and trying to add a rotation, and rotating the ctx element in code (i.e. using ctx.rotate(Math.PI/4)). This all is very strange to me because I have other projects where I have used the same method without issue. Any ideas would be wonderfull!

Javascript ctx.putImageData at an angle without saying to

I am writing a program to generate some orbital images. I decided to use js because I have a fair amount of experience with it and its fast to write for prototypes. The issue is that when I go to use ctx.putImageData it is rotated by a -45° angle and the image is stretched.
This is the actually important code:

  genImg(){
    let index = 0;
    for(let y = 0; y <= 400; y++){
      for(let x = 0; x <= 400; x++){
        let lx = (x - 200)*this.step;
        let ly = (200 - y)*this.step;
        this.points.push(this.value(Math.sqrt(Math.pow(lx, 2) + Math.pow(ly, 2)), this.t, Math.atan2(lx,ly))[0]);
      }
    }
    let sclFct = 1000/Math.max(...this.points);
    for(let i = 0; i<= 160000; i++){
      let val = Math.round(this.points[i]*sclFct);
      this.imgDataArr[index] = cmap[val*4]; // R value        
      this.imgDataArr[index + 1] = cmap[val*4 + 1]; // G value
      this.imgDataArr[index + 2] = cmap[val*4 + 2]; // B value
      this.imgDataArr[index + 3] = 255; // A value
      index += 4; 
    }
    let imgData = new ImageData(this.imgDataArr, 400, 400);
    ctx.putImageData(imgData, 0, 0);
  }

The Full code is here. Just off the bat I should mention this is all written in a class. The html is just a canvas element in the <main></main> area that is 400px by 400px. The CSS is just to center everything and give the canvas a border. The function this.value(r,t,p) takes the values r(radius), t(theta) and p(phi). Theta is a constant and radius and phi are calculated from (x,y) cords (see line 7 of the prior code).
enter image description here
In the image you can see where there is the diagonal. The black should be in the center with the other colors radiating out. So far I have tried a 45° rotation to the atan2 function, messing with the css and trying to add a rotation, and rotating the ctx element in code (i.e. using ctx.rotate(Math.PI/4)). This all is very strange to me because I have other projects where I have used the same method without issue. Any ideas would be wonderfull!

Publish to @google-cloud/pubsub topic from Firebase sdk is failing

With all nodejs packages updated, trying to publish message to topic ends on timeout with error:

GoogleError: Total timeout of API google.pubsub.v1.Publisher exceeded. Error: Getting metadata from plugin failed with error: fetchImpl is not a function.

Trying to publish from cloud function but fails as well from cli.

Example using storage trigger to reproduce (but any attmept to publish ends the same):

import {onObjectFinalized, StorageEvent} from 'firebase-functions/v2/storage';
import {logger} from 'firebase-functions/v2';
import {PubSub} from '@google-cloud/pubsub';

const pubSub = new PubSub();

export default onObjectFinalized({region: 'europe-west3'}, async (event: StorageEvent) => {
    logger.info('--- Storage Upload triggered', {data: event.data.name});

    const message = {uploadId: 'uploadId'};
    const topic = 'projects/---/topics/uploads';

    const pubRes = await pubSub.topic(topic).publishMessage({json: message});

    return pubRes;
});
  "dependencies": {
    "@google-cloud/pubsub": "^5.2.0",
    "firebase-admin": "^13.4.0",
    "firebase-functions": "^6.4.0",
    ...
  },

Never able to prevent the add to cart form submission

Here’s what I wrote to prevent add to cart form submission on product detail page, I intended to show a custom message or alert if some custom fields are empty, the strange thing is no matter what I tried, it still submits the form when clicking add to cart button, i don’t know what is wrong:

document.addEventListener('DOMContentLoaded', function () {
    const productForm = document.querySelector('form[action^="/cart/add"]');

    if (productForm) {
      productForm.addEventListener('submit', function (event) {
        event.preventDefault(); // Prevent form submission
        alert('Add to Cart submission prevented.');
      });
    }
  });

I use Danw. Can anyone help me? thanks

Nuxt 4: import aliases don’t work in test files

I have a vitest/Nuxt3 test setup that works fine and I’m trying to port it to Nuxt4 and I have import aliases issues.

The same imports that work from files in /app fail in my test file, which is located in /test/unit/.

/app/
    classes/
        Project.ts

/shared/
    types/
        project/
            project.ts

/test/
    unit/
        project.test.ts
        project.json

The types file is nested to avoid auto-imports.

In Project.ts, I can do

import type { Project } from '#shared/types/project/project'

This doesn’t work in project.test.ts.

Also, in project.test.ts, I can’t import my Project class. This fails.

import WorkProject from '@/classes/Project'

I have to use manual paths:

import type { Project } from '../../shared/types/project/project'
import WorkProject from '../../classes/Project'

My guess is that since Nuxt 4, the tsconfig is split in multiple files, each with its scope (app, node, server, shared) and there is none for the test folder.

Is that it? What should I do about it?

I could live with ../../paths but it sucks not to be able to write test files consistently with tested code.

How to keep .nuxt/imports.d.ts synchronized?

The magic in Nuxt auto-imports relies on .nuxt/imports.d.ts, which is automatically generated.

While trying to understand the auto-import feature, I’ve been moving a types file e.g. from /shared/types to /shared/types/subdir and back, to see how it impacts lint errors, etc. and I had strange results because .nuxt/imports.d.ts did not reflect those changes.

npm run dev does refresh .nuxt/imports.d.ts but it has to be run everytime those files change.

Is there a command that should be run so that auto-imports directories are watched to keep .nuxt/imports.d.ts synced?

Is this expected behaviour, acceptable because those type files are not meant to change so often?

(Using Nuxt 4, if that matters.)

Displaying Javascript array as HTML list with multiple elements within the same list item [closed]

I have this code

function pojeden() {

    const arrayClone = array.slice()

    let arrayLength = array.length

    let newArray = []

    for (let i = 0; i < 30; i++) {
        let arr = arrayClone[Math.floor(Math.random() * arrayLength)]

        arrayLength--

        let index = arrayClone.indexOf(arr)

        arrayClone.splice(index, 1)

        newArray.push(arr)
     }

const spacja = `${newArray.map(newArray =>
            `<li>${newArray}</li>`).join('')}`;

document.getElementById("miesiac").innerHTML = spacja
}

It creates a HTML list with 30 unique, non-repeating list items taken from the elements of an array.

That’s all good, but what if I want a list with the same amount of list items but TWICE or THRICE the elements from the array?

I do NOT mean a list with 60 or 90 list items. I mean a list with 30 items but each bullet has 2 or 3 array elements each instead of only 1.

Basically, the code above creates a list that looks like this:

  • banana
  • apple
  • orange

When I want a list that would look like this:

  • banana, apple
  • orange, berry
  • kiwi, peach

Or even:

  • banana, apple, orange
  • berry, kiwi, peach
  • pear, grape, pineapple

Same amount of list items (bullets) but under each there is more than one element (listed next to each other).

How to achieve this?

I assume array.join() and forEach() wouldn’t work with this so instead I have tried playing around with loops, appendChild and using modulo for it but I am very much a beginner so I didn’t manage to utilize this for my mini project and eventually gave up until I decided to pick it up again. I suppose this method would most likely work but because I am too inexperienced I couldn’t make it work for myself

Z-index and modal backdrop [closed]

I created a modal using the <dialog> tag. It works fine, but I also created a notification toasts with a higher z-index. Here is a code sample:

.notification {
  z-index: 1090;
  position: absolute;
  top: 0;
  right: 0;
  background-color: #afa;
}

.modal {
  z-index: 1055;
  background-color: #aaf;
  height: fit-content;
}

.modal::backdrop {
  background-color: #0000008f;
  backdrop-filter: blur(0.375rem);
}
<div class="notification">
  This notification should be on top of the modal backdrop.
</div>

<dialog id="modal" class="modal">
  <div class="modal-content">
    <div>Modal Content</div>
  </div>
</dialog>

I would like the notification to be over the modal backdrop. But I understood that even with a z-index of 9999, the notification will not be over the backdrop. I already read these answers :

I don’t want to implement my own backdrop + modal layering. Is there another clean solution?

Here is a JSFidle: https://jsfiddle.net/uhw4mj85/2/

Implementation of an actual asynchronous function in javascript? [closed]

I’m relatively new to javascript, and I’ve just now started deepening my knowledge of how javascript handles asynchronous tasks.

However, I feel like I miss something, because if I think of all the asynchronous things (callbacks, promises, async/await), none of them actually stop the execution of code to delegate an asynchronous task to some other agent.

I’ll be a bit more specific taking the example of the fs library. At which point does the code actually stops and waits for the file to be loaded from the disk? and how? Furthermore, does that operation require a new thread?

Displaying Javascript array as HTML list with multiple elements within the same list item

I have this code

function pojeden() {

    const arrayClone = array.slice()

    let arrayLength = array.length

    let newArray = []

    for (let i = 0; i < 30; i++) {
        let arr = arrayClone[Math.floor(Math.random() * arrayLength)]

        arrayLength--

        let index = arrayClone.indexOf(arr)

        arrayClone.splice(index, 1)

        newArray.push(arr)
     }

const spacja = `${newArray.map(newArray =>
            `<li>${newArray}</li>`).join('')}`;

document.getElementById("miesiac").innerHTML = spacja
}

It creates a HTML list with 30 unique, non-repeating list items taken from the elements of an array.

That’s all good, but what if I want a list with the same amount of list items but TWICE or THRICE the elements from the array?

I do NOT mean a list with 60 or 90 list items. I mean a list with 30 items but each bullet has 2 or 3 array elements each instead of only 1.

Basically, the code above creates a list that looks like this:

  • banana
  • apple
  • orange

When I want a list that would look like this:

  • banana, apple
  • orange, berry
  • kiwi, peach

Or even:

  • banana, apple, orange
  • berry, kiwi, peach
  • pear, grape, pineapple

Same amount of list items (bullets) but under each there is more than one element (listed next to each other).

How to achieve this?

I assume array.join() and forEach() wouldn’t work with this so instead I have tried playing around with loops, appendChild and using modulo for it but I am very much a beginner so I didn’t manage to utilize this for my mini project and eventually gave up until I decided to pick it up again. I suppose this method would most likely work but because I am too inexperienced I couldn’t make it work for myself

Z-index and modal backdrop

I created a modal using the <dialog> tag. It works fine, but I also created a notification toasts with a higher z-index. Here is a code sample:

<div class="notification">
  This notification should be on top of the modal backdrop.
</div>

<dialog id="modal" class="modal">
  <div class="modal-content">
    <div>Modal Content</div>
  </div>
</dialog>

Here is the associated CSS:

.notification {  
  z-index: 1090;  
  position: absolute;
  top: 0;
  right: 0;
  background-color: #afa;
}

.modal {
  z-index: 1055;  
  background-color: #aaf;
  height: fit-content;  
}

.modal::backdrop {
  background-color: #0000008f;
  backdrop-filter: blur(0.375rem);
}

I would like the notification to be over the modal backdrop. But I understood that even with a z-index of 9999, the notification will not be over the backdrop. I already read these answers :

I don’t want to implement my own backdrop + modal layering. Is there another clean solution?

Here is a JSFidle: https://jsfiddle.net/uhw4mj85/2/

How to restore a nested object type after type narrowing?

I am using web workers for my heavy computations. Passing data to the worker is implicitly done by serializing the objects, so their types are narrowed down to simple objects, meaning that an object Foo defined like this:

class Foo {
  name: string
  child: Bar

  constructor(name: string, child: Bar) {
    this.name = name
    this.child = child
  }
}

class Bar {
  name: string

  constructor(name: string) {
    this.name = name
  }

  sayHello() {
    console.log("Hello!")
  }
}

is narrowed down to an object like this:

{ name: "foo", child: { name: "bar" } }

So to use the method sayHello, the actual type has to be restored in the worker, e.g. by using the constructor:

const newFoo = new Foo(other.name, new Bar(other.child.name)

Which, as you can see, can become very verbose and a likely source of errors.

You could also define copy constructors in the actual constructors or static methods like:

class Foo {
  // ...
  static from(other: Foo) {
    const child = Bar.from(other.child)
    return new Foo(other.name, child)
  }
}

class Bar {
  // ...
  static from(other: Bar) {
    return new Bar(other.name)
  }
}

This might be possible, but is also very verbose and prone to errors.

Therefore I have created a copy function, that creates a new class instance from the prototype and copies the properties:

function copy<T>(obj: any, prototype: T): T {
    if (!obj) return obj

    const clone = Object.create(prototype)
    Reflect.ownKeys(obj).forEach((key) => {
        const desc = Object.getOwnPropertyDescriptor(obj as T, key)
        if (desc) {
            Object.defineProperty(clone, key, desc)
        }
    })
    return clone as T
}

This works well for flat classes, but nested types are still narrowed to plain objects, meaning the function sayHello in Bar is missing, when calling:

const fooFromObj = copy({ name: "foo", child: { name: "bar" } }, Foo.prototype)

because this creates this object:

Foo { name: "foo", child: { name: "bar" } }
// instead of:
Foo { name: "foo", child: Bar { name: "bar" } }

Can I get the type of a nested class from the parent type to recursively restore the nested types?