diff --git a/pos_place/__manifest__.py b/pos_place/__manifest__.py
index 5f23953b27..c9872c1f4b 100644
--- a/pos_place/__manifest__.py
+++ b/pos_place/__manifest__.py
@@ -20,6 +20,14 @@
"views/view_pos_place.xml",
"views/view_pos_order.xml",
],
+ "assets": {
+ "point_of_sale.assets": [
+ "pos_place/static/src/js/models.esm.js",
+ "pos_place/static/src/xml/ChromeWidgets/PosPlaceName.xml",
+ "pos_place/static/src/xml/ChromeWidgets/PosPlaceName.js",
+ "pos_place/static/src/xml/Chrome.xml",
+ ],
+ },
# "qweb": [
# "static/src/xml/pos_place.xml",
# ],
diff --git a/pos_place/models/pos_session.py b/pos_place/models/pos_session.py
new file mode 100644
index 0000000000..e506c2c165
--- /dev/null
+++ b/pos_place/models/pos_session.py
@@ -0,0 +1,24 @@
+# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
+# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+from odoo import models
+
+
+class PosSession(models.Model):
+ _inherit = "pos.session"
+
+ def _pos_ui_models_to_load(self):
+ result = super()._pos_ui_models_to_load()
+ if self.env.user.has_group("pos_place.group_pos_place_user"):
+ result.append("pos.place")
+ return result
+
+ def _loader_params_pos_place(self):
+ return {
+ "search_params": {
+ "fields": ["code", "name"],
+ },
+ }
+
+ def _get_pos_ui_pos_place(self, params):
+ return self.env["pos.place"].search_read(**params["search_params"])
diff --git a/pos_place/static/src/js/models.esm.js b/pos_place/static/src/js/models.esm.js
new file mode 100644
index 0000000000..0be73e539d
--- /dev/null
+++ b/pos_place/static/src/js/models.esm.js
@@ -0,0 +1,141 @@
+/** @odoo-module **/
+
+import {Order, PosGlobalState} from "point_of_sale.models";
+import Registries from "point_of_sale.Registries";
+
+const OverloadPosGlobalState = (PosGlobalState) =>
+ class extends PosGlobalState {
+ async _processData(loadedData) {
+ await super._processData(...arguments);
+ if (this.config.module_pos_hr) {
+ this.employees = loadedData["hr.employee"];
+ this.employee_by_id = loadedData.employee_by_id;
+ this.reset_cashier();
+ }
+ }
+ async after_load_server_data() {
+ await super.after_load_server_data(...arguments);
+ if (this.config.module_pos_hr) {
+ this.hasLoggedIn = !this.config.module_pos_hr;
+ }
+ }
+ reset_cashier() {
+ this.cashier = {
+ name: null,
+ id: null,
+ barcode: null,
+ user_id: null,
+ pin: null,
+ role: null,
+ };
+ }
+ set_cashier(employee) {
+ this.cashier = employee;
+ const selectedOrder = this.get_order();
+ if (selectedOrder && !selectedOrder.get_orderlines().length) {
+ // Order without lines can be considered to be un-owned by any employee.
+ // We set the cashier on that order to the currently set employee.
+ selectedOrder.cashier = employee;
+ }
+ if (!this.cashierHasPriceControlRights() && this.numpadMode === "price") {
+ this.numpadMode = "quantity";
+ }
+ }
+
+ /** {name: null, id: null, barcode: null, user_id:null, pin:null}
+ * If pos_hr is activated, return {name: string, id: int, barcode: string, pin: string, user_id: int}
+ * @returns {null|*}
+ */
+ get_cashier() {
+ if (this.config.module_pos_hr) {
+ return this.cashier;
+ }
+ return super.get_cashier();
+ }
+ get_cashier_user_id() {
+ if (this.config.module_pos_hr) {
+ return this.cashier.user_id ? this.cashier.user_id : null;
+ }
+ return super.get_cashier_user_id();
+ }
+ };
+Registries.Model.extend(PosGlobalState, PosHrPosGlobalState);
+
+export const OverloadOrder = (OriginalOrder) =>
+ class extends OriginalOrder {
+ get_place() {
+ return this.current_place;
+ // || this.db.load("current_place")
+ }
+ set_place(place) {
+ this.current_place = place;
+ // This.db.save("current_place", place || null);
+ }
+
+ export_for_printing() {
+ var result = super.export_for_printing(...arguments);
+ result.place = this.get_place();
+ return res;
+ }
+
+ export_as_JSON() {
+ const json = super.export_as_JSON(...arguments);
+ /* Const place = this.pos.get_place();
+ json.place = place ? place.id : false;
+*/
+ json.place = this.get_place();
+ return json;
+ }
+
+ init_from_JSON(json) {
+ super.init_from_JSON(...arguments);
+ this.set_place(json.place);
+ }
+ };
+
+Registries.Model.extend(Order, OverloadOrder);
+
+/* Odoo.define("pos_place.models", function (require) {
+ "use strict";
+
+ var models = require("point_of_sale.models");
+ var _super_order = models.Order.prototype;
+
+ // Load pos.place model
+ models.load_models({
+ model: "pos.place",
+ loaded: function (self, places) {
+ self.places = [];
+ for (var i = 0; i < places.length; i++) {
+ self.places.push(places[i]);
+ }
+ },
+ });*/
+
+/* // Make place persistent in the session
+ models.PosModel = models.PosModel.extend({
+ get_place: function () {
+ return this.get("current_place") || this.db.load("current_place");
+ },
+ set_place: function (place) {
+ this.set("current_place", place);
+ this.db.save("current_place", place || null);
+ },
+ });
+*/
+/* models.Order = models.Order.extend({
+ export_for_printing: function () {
+ var result = super.export_for_printing(...arguments);
+ result.place = this.pos.get_place();
+ return res;
+ },
+
+ export_as_JSON: function () {
+ var json = _super_order.export_as_JSON.apply(this, arguments);
+ var place = this.pos.get_place();
+ json.place_id = place ? place.id : false;
+ return json;
+ },
+ });
+});
+*/
diff --git a/pos_place/static/src/js/models.js b/pos_place/static/src/js/models.js
deleted file mode 100644
index 4efc4cb471..0000000000
--- a/pos_place/static/src/js/models.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
-Copyright (C) 2015 - Today: GRAP (http://www.grap.coop)
-@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
-License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-**/
-
-odoo.define("pos_place.models", function (require) {
- "use strict";
-
- var models = require("point_of_sale.models");
- var _super_order = models.Order.prototype;
-
- // Load pos.place model
- models.load_models({
- model: "pos.place",
- loaded: function (self, places) {
- self.places = [];
- for (var i = 0; i < places.length; i++) {
- self.places.push(places[i]);
- }
- },
- });
-
- // Make place persistent in the session
- models.PosModel = models.PosModel.extend({
- get_place: function () {
- return this.get("current_place") || this.db.load("current_place");
- },
- set_place: function (place) {
- this.set("current_place", place);
- this.db.save("current_place", place || null);
- },
- });
-
- models.Order = models.Order.extend({
- export_for_printing: function () {
- var res = _super_order.export_for_printing.apply(this, arguments);
- res.place = this.pos.get_place();
- return res;
- },
-
- export_as_JSON: function () {
- var json = _super_order.export_as_JSON.apply(this, arguments);
- var place = this.pos.get_place();
- json.place_id = place ? place.id : false;
- return json;
- },
- });
-});
diff --git a/pos_place/static/src/xml/Chrome.xml b/pos_place/static/src/xml/Chrome.xml
new file mode 100644
index 0000000000..186be46887
--- /dev/null
+++ b/pos_place/static/src/xml/Chrome.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/pos_place/static/src/xml/ChromeWidgets/PosPlaceName.js b/pos_place/static/src/xml/ChromeWidgets/PosPlaceName.js
new file mode 100644
index 0000000000..5475e47893
--- /dev/null
+++ b/pos_place/static/src/xml/ChromeWidgets/PosPlaceName.js
@@ -0,0 +1,61 @@
+odoo.define("pos_place.PosPlaceName", function (require) {
+ "use strict";
+
+ const PosComponent = require("point_of_sale.PosComponent");
+ const Registries = require("point_of_sale.Registries");
+
+ // Previously UsernameWidget
+ class PosPlaceName extends PosComponent {
+ /**
+ * Select a place, the returning value will either be an object or nothing (undefined)
+ */
+ async selectPosPlace() {
+ if (this.env.pos.config.module_pos_hr) {
+ const employeesList = this.env.pos.employees
+ .filter((employee) => employee.id !== this.env.pos.get_cashier().id)
+ .map((employee) => {
+ return {
+ id: employee.id,
+ item: employee,
+ label: employee.name,
+ isSelected: false,
+ };
+ });
+ let {confirmed, payload: employee} = await this.showPopup(
+ "SelectionPopup",
+ {
+ title: this.env._t("Change Cashier"),
+ list: employeesList,
+ }
+ );
+
+ if (!confirmed) {
+ return;
+ }
+
+ if (employee && employee.pin) {
+ employee = await this.askPin(employee);
+ }
+ if (employee) {
+ this.env.pos.set_cashier(employee);
+ }
+ return employee;
+ }
+ }
+
+ get username() {
+ const {name} = this.env.pos.get_cashier();
+ return name ? name : "";
+ }
+ get avatar() {
+ const user_id = this.env.pos.get_cashier_user_id();
+ const id = user_id ? user_id : -1;
+ return `/web/image/res.users/${id}/avatar_128`;
+ }
+ }
+ PosPlaceName.template = "PosPlaceName";
+
+ Registries.Component.add(PosPlaceName);
+
+ return PosPlaceName;
+});
diff --git a/pos_place/static/src/xml/ChromeWidgets/PosPlaceName.xml b/pos_place/static/src/xml/ChromeWidgets/PosPlaceName.xml
new file mode 100644
index 0000000000..cf9b26cf31
--- /dev/null
+++ b/pos_place/static/src/xml/ChromeWidgets/PosPlaceName.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ BOB
+
+
+
+
+
diff --git a/pos_place/static/src/xml/PosPlaceName.xml b/pos_place/static/src/xml/PosPlaceName.xml
new file mode 100644
index 0000000000..2531d23f81
--- /dev/null
+++ b/pos_place/static/src/xml/PosPlaceName.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+