[POS] Einweisungen und Sicherheitsdaten über RPC geladen
- Erweiterung von get_access_list_grouped() um Sicherheitsdaten (Haftungsausschluss, ID, Geburtstag, RFID) - Rückgabe nun als dict mit access_by_area + user-Feldern - Anpassung der OWL-Komponente OwsMachineAccessList: - updateAccessList() lädt Sicherheitsdaten über jsonrpc - state enthält jetzt getrennte Felder für security_briefing, security_id etc. - Maschinenliste bleibt dauerhaft sichtbar - Fehlerbehandlung bei fehlendem ows.user integriert - alte load_fields()-Logik entfernt
This commit is contained in:
parent
3057f0cf80
commit
b7d98a999a
|
|
@ -23,6 +23,8 @@
|
|||
'open_workshop/static/src/css/pos.css',
|
||||
'open_workshop/static/src/js/ows_pos_customer_sidebar.js',
|
||||
'open_workshop/static/src/xml/ows_pos_customer_sidebar.xml',
|
||||
'open_workshop/static/src/js/ows_machine_access_list.js',
|
||||
'open_workshop/static/src/xml/ows_machine_access_list.xml',
|
||||
'open_workshop/static/src/xml/ows_product_screen.xml',
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -424,10 +424,10 @@ class OwsMachine(models.Model):
|
|||
|
||||
@api.model
|
||||
def get_access_list_grouped(self, partner_id):
|
||||
partner = self.env['res.partner'].browse(partner_id)
|
||||
areas = self.env['ows.machine.area'].search([], order="name")
|
||||
_logger.info("🔍 Maschinenbereiche: %s", areas.mapped('name'))
|
||||
_logger.info("🔍 Partner_id: %s", partner_id)
|
||||
res = []
|
||||
|
||||
access_by_area = []
|
||||
for area in areas:
|
||||
machines = self.search([('area_id', '=', area.id)], order="name")
|
||||
machine_list = []
|
||||
|
|
@ -440,12 +440,22 @@ class OwsMachine(models.Model):
|
|||
'name': machine.name,
|
||||
'has_access': has_access,
|
||||
})
|
||||
res.append({
|
||||
'area': area.name,
|
||||
'color_hex': area.color_hex or '#000000',
|
||||
'machines': machine_list
|
||||
})
|
||||
return res
|
||||
if machine_list:
|
||||
access_by_area.append({
|
||||
'area': area.name,
|
||||
'color_hex': area.color_hex or '#000000',
|
||||
'machines': machine_list
|
||||
})
|
||||
|
||||
user = partner.ows_user_id[:1]
|
||||
return {
|
||||
'access_by_area': access_by_area,
|
||||
'security_briefing': user.security_briefing if user else False,
|
||||
'security_id': user.security_id if user else '',
|
||||
'rfid_card': user.rfid_card if user else '',
|
||||
'birthday': user.birthday if user else '',
|
||||
}
|
||||
|
||||
|
||||
|
||||
class OwsMachineAccess(models.Model):
|
||||
|
|
|
|||
|
|
@ -1,132 +0,0 @@
|
|||
/* This file is based on the original code from the OrderWidget in Odoo Point of Sale module (screen.js).
|
||||
* It has been modified to create a sidebar that displays machine access information for the selected customer.*/
|
||||
|
||||
odoo.define('open_workshop.machine_access_sidebar', function (require) {
|
||||
"use strict";
|
||||
|
||||
const DUMMY_PARTNER = {
|
||||
id: 1,
|
||||
name: "AAAA Max Mustermann",
|
||||
security_briefing: false,
|
||||
security_id: null,
|
||||
create_date: null,
|
||||
};
|
||||
|
||||
var rpc = require('web.rpc');
|
||||
var screens = require('point_of_sale.screens');
|
||||
var chrome = require('point_of_sale.chrome');
|
||||
var core = require('web.core');
|
||||
var QWeb = core.qweb;
|
||||
|
||||
|
||||
|
||||
var MachineAccessSidebar = screens.ScreenWidget.extend({
|
||||
template: 'MachineAccessSidebar',
|
||||
|
||||
init: function(parent, options) {
|
||||
this._super(parent, options);
|
||||
this.partner = null;
|
||||
this.pos.bind('change:selectedOrder', this.bind_order_events, this);
|
||||
},
|
||||
|
||||
show: function() {
|
||||
this._super();
|
||||
this.render_access();
|
||||
},
|
||||
|
||||
update_machine_access: function(partner) {
|
||||
console.log("🔁 Sidebar aktualisiert Maschinenfreigaben für Partner:", partner);
|
||||
this.partner = partner;
|
||||
this.render_access();
|
||||
},
|
||||
|
||||
render_access: function() {
|
||||
var self = this;
|
||||
var partner = this.partner || DUMMY_PARTNER;
|
||||
|
||||
|
||||
|
||||
rpc.query({
|
||||
model: 'ows.machine',
|
||||
method: 'get_access_list_grouped',
|
||||
args: [partner.id],
|
||||
}).then(function (result) {
|
||||
partner.create_date = partner.create_date && partner.create_date.substring(0, 10);
|
||||
var html = QWeb.render('PartnerMachineAccessList', {
|
||||
areas: result || [],
|
||||
partner: partner,
|
||||
});
|
||||
self.$('.access-content').html(html);
|
||||
});
|
||||
},
|
||||
|
||||
bind_order_events: function () {
|
||||
var order = this.pos.get_order();
|
||||
if (!order) return;
|
||||
|
||||
/*order.unbind('change:client', this);
|
||||
order.bind('change:client', this, function () {
|
||||
this.update_machine_access(order.get_client());
|
||||
});*/
|
||||
|
||||
this.update_machine_access(order.get_client());
|
||||
}
|
||||
});
|
||||
|
||||
// Sidebar aktualisieren bei Klick im ClientListScreenWidget (Vorschau)
|
||||
screens.ClientListScreenWidget.include({
|
||||
show: function () {
|
||||
this._super();
|
||||
$('.order-selector').hide(); // ← wird hier versteckt
|
||||
},
|
||||
hide: function () {
|
||||
this._super();
|
||||
$('.order-selector').show(); // ← beim Verlassen wieder zeigen
|
||||
},
|
||||
display_client_details: function (visibility, partner, clickpos) {
|
||||
this._super(visibility, partner, clickpos);
|
||||
|
||||
try {
|
||||
if (partner && typeof partner === 'object' && 'id' in partner) {
|
||||
var sidebar = this.pos.chrome.sidebar_widget;
|
||||
if (sidebar) {
|
||||
console.log("👤 ClientListScreen: Vorschau für", partner.name);
|
||||
sidebar.update_machine_access(partner);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("⚠️ Fehler beim Update der Sidebar nach Kundenauswahl:", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
chrome.Chrome.include({
|
||||
build_widgets: function () {
|
||||
this._super();
|
||||
|
||||
var sidebar = new MachineAccessSidebar(this, {});
|
||||
this.sidebar_widget = sidebar;
|
||||
sidebar.appendTo(this.$el);
|
||||
|
||||
//this.pos.bind('change:selectedOrder', sidebar.bind_order_events, sidebar);
|
||||
|
||||
if (this.pos.get_order()) {
|
||||
sidebar.bind_order_events();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
odoo.define('open_workshop.models', function (require) {
|
||||
"use strict";
|
||||
var models = require('point_of_sale.models');
|
||||
var field_utils = require('web.field_utils');
|
||||
models.load_fields('res.partner', 'create_date');
|
||||
models.load_fields('res.partner', 'birthday');
|
||||
models.load_fields('res.partner', 'security_briefing');
|
||||
models.load_fields('res.partner', 'security_id');
|
||||
models.load_fields('res.partner', 'rfid_card');
|
||||
|
||||
|
||||
});
|
||||
63
static/src/js/ows_machine_access_list.js
Normal file
63
static/src/js/ows_machine_access_list.js
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
// @odoo-module
|
||||
|
||||
import { Component, useState, onMounted } from "@odoo/owl";
|
||||
import { useBus } from "@web/core/utils/hooks";
|
||||
import { usePos } from "@point_of_sale/app/store/pos_hook";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
|
||||
export class OwsMachineAccessList extends Component {
|
||||
static template = "open_workshop.OwsMachineAccessList";
|
||||
|
||||
setup() {
|
||||
this.pos = usePos();
|
||||
|
||||
this.state = useState({
|
||||
client: null,
|
||||
grouped_accesses: [],
|
||||
security_briefing: false,
|
||||
security_id: '',
|
||||
rfid_card: '',
|
||||
birthday: '',
|
||||
});
|
||||
|
||||
// Initialer Client bei Komponentenerstellung (z. B. bei Seiten-Refresh)
|
||||
const initial_order = this.pos.get_order?.();
|
||||
const initial_client = initial_order?.get_client?.() || null;
|
||||
this.state.client = initial_client;
|
||||
|
||||
// OWL-idiomatisch: Bus-Events mit useBus() registrieren
|
||||
useBus(this.env.bus, "order-changed", () => this.updateAccessList());
|
||||
useBus(this.env.bus, "client-selected", () => this.updateAccessList());
|
||||
|
||||
// Beim Initial-Render Zugriffsdaten laden
|
||||
onMounted(() => {
|
||||
this.updateAccessList();
|
||||
});
|
||||
}
|
||||
|
||||
async updateAccessList() {
|
||||
const partner = this.pos.get_order?.()?.get_client?.() || null;
|
||||
this.state.client = partner;
|
||||
|
||||
try {
|
||||
const data = await jsonrpc("/open_workshop/partner_access", {
|
||||
partner_id: partner?.id || 0,
|
||||
});
|
||||
|
||||
this.state.grouped_accesses = data.access_by_area || [];
|
||||
this.state.security_briefing = data.security_briefing;
|
||||
this.state.security_id = data.security_id;
|
||||
this.state.rfid_card = data.rfid_card;
|
||||
this.state.birthday = data.birthday;
|
||||
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Laden der Einweisungen:", error);
|
||||
this.state.grouped_accesses = [];
|
||||
this.state.security_briefing = false;
|
||||
this.state.security_id = '';
|
||||
this.state.rfid_card = '';
|
||||
this.state.birthday = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3,12 +3,14 @@
|
|||
import { ProductScreen } from "@point_of_sale/app/screens/product_screen/product_screen";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { OwsPosCustomerSidebar } from "@open_workshop/js/ows_pos_customer_sidebar";
|
||||
import { OwsMachineAccessList } from "@open_workshop/js/ows_machine_access_list";
|
||||
|
||||
export class OwsProductScreen extends ProductScreen {
|
||||
static template = "open_workshop.ProductScreen";
|
||||
static components = {
|
||||
...ProductScreen.components,
|
||||
OwsPosCustomerSidebar,
|
||||
OwsMachineAccessList,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
76
static/src/xml/ows_machine_access_list.xml
Normal file
76
static/src/xml/ows_machine_access_list.xml
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<t t-name="open_workshop.OwsMachineAccessList">
|
||||
<div class="client-details-grid p-2 small">
|
||||
|
||||
<!-- ✅ Sicherheitsbereich -->
|
||||
<t t-if="state.client">
|
||||
<div class="client-details-header">
|
||||
<ul>
|
||||
<li><span class="client-details-label">Einweisungen</span></li>
|
||||
</ul>
|
||||
|
||||
<div class="client-details-area border" t-att-style="'border: solid 3px #ffffff; margin: 5px;'">
|
||||
<ul>
|
||||
<li class="client-detail">
|
||||
<span class="detail client-details-vvow_briefing">✅</span>
|
||||
<span class="briefinglabel">Werkstatt</span>
|
||||
</li>
|
||||
|
||||
<li class="client-detail">
|
||||
<t t-if="!state.security_briefing">
|
||||
<span class="detail client-details-vvow_briefing_error">❌</span>
|
||||
</t>
|
||||
<t t-if="state.security_briefing">
|
||||
<span class="detail client-details-vvow_briefing">✅</span>
|
||||
</t>
|
||||
<span class="briefinglabel">Haftungsausschluss</span>
|
||||
</li>
|
||||
|
||||
<t t-if="!state.security_briefing">
|
||||
<li class="client-detail">
|
||||
<ul class="subpoints">
|
||||
<span class="detail client-details-vvow_sec_briefing_error">‼️Bitte Prüfen‼️</span>
|
||||
</ul>
|
||||
</li>
|
||||
</t>
|
||||
|
||||
<t t-if="state.security_briefing">
|
||||
<ul class="subpoints">
|
||||
<li class="client-detail">
|
||||
<span class="label">Id:</span>
|
||||
<span class="detail client-details-vvow_security_id">
|
||||
<t t-esc="state.security_id || 'N/A'" />
|
||||
</span>
|
||||
</li>
|
||||
<li class="client-detail">
|
||||
<span class="label">Geburtstag:</span>
|
||||
<span class="detail client-details-vvow_security_id">
|
||||
<t t-esc="state.birthday || 'N/A'" />
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- ✅ Maschinenliste: immer sichtbar, gefiltert -->
|
||||
<t t-foreach="state.grouped_accesses" t-as="area" t-key="area.area">
|
||||
<t t-if="area.machines.length > 0">
|
||||
<div class="client-details-area" t-att-style="'border: solid 3px ' + area.color_hex + '; margin: 5px;'">
|
||||
<ul>
|
||||
<t t-foreach="area.machines" t-as="machine" t-key="machine.name">
|
||||
<li class="client-detail">
|
||||
<span t-attf-class="detail {{ machine.has_access ? 'client-details-vvow_briefing' : 'client-details-vvow_briefing_error' }}">
|
||||
<t t-esc="machine.has_access ? '✅' : '❌'" />
|
||||
</span>
|
||||
<span class="briefinglabel"><t t-esc="machine.name"/></span>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="MachineAccessSidebar">
|
||||
<div class="machine-access-sidebar">
|
||||
<div class="access-content">
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="PartnerMachineAccessList">
|
||||
<div class="client-details-grid">
|
||||
<div class="client-details-header">
|
||||
<ul>
|
||||
<li><span class="client-details-label">Einweisungen</span></li>
|
||||
</ul>
|
||||
|
||||
<div class="client-details-area" t-att-style="'border: solid 3px #ffffff; margin: 5px;'">
|
||||
<ul>
|
||||
<li class="client-detail">
|
||||
<span class="detail client-details-vvow_briefing">✅</span>
|
||||
<span class="briefinglabel">Werkstatt</span>
|
||||
</li>
|
||||
|
||||
<li class="client-detail">
|
||||
<t t-if="!partner.security_briefing">
|
||||
<span class="detail client-details-vvow_briefing_error">❌</span>
|
||||
</t>
|
||||
<t t-if="partner.security_briefing">
|
||||
<span class="detail client-details-vvow_briefing">✅</span>
|
||||
</t>
|
||||
<span class="briefinglabel">Haftungsausschluss</span>
|
||||
</li>
|
||||
|
||||
|
||||
<t t-if="!partner.security_briefing">
|
||||
<li class="client-detail">
|
||||
<ul class="subpoints"><span class="detail client-details-vvow_sec_briefing_error">‼️Bitte Prüfen‼️</span></ul>
|
||||
</li>
|
||||
</t>
|
||||
|
||||
|
||||
<t t-if="partner.security_briefing">
|
||||
<ul class="subpoints">
|
||||
<li class="client-detail">
|
||||
<span class="label">Id:</span>
|
||||
<t t-if="partner.security_id">
|
||||
<span class="detail client-details-vvow_security_id"><t t-esc="partner.security_id"/></span>
|
||||
</t>
|
||||
<t t-if="!partner.security_id">
|
||||
<span class="detail client-details-vvow_security_id">N/A</span>
|
||||
</t>
|
||||
</li>
|
||||
<li class="client-detail">
|
||||
<span class="label">Erstellt:</span>
|
||||
<t t-if="partner.create_date">
|
||||
<span class="detail client-details-vvow_security_id"><t t-esc="partner.create_date"/></span>
|
||||
</t>
|
||||
<t t-if="!partner.create_date">
|
||||
<span class="detail client-vvow_birthday">N/A</span>
|
||||
</t>
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<t t-foreach="areas" t-as="area">
|
||||
<div class="client-details-area" t-att-style="'border: solid 3px ' + area.color_hex + '; margin: 5px;'">
|
||||
<ul>
|
||||
<t t-foreach="area.machines" t-as="machine">
|
||||
<li class="client-detail">
|
||||
<t t-if="!machine.has_access">
|
||||
<span class="detail client-details-vvow_briefing_error">❌</span>
|
||||
</t>
|
||||
<t t-if="machine.has_access">
|
||||
<span class="detail client-details-vvow_briefing">✅</span>
|
||||
</t>
|
||||
<span class="briefinglabel"><t t-esc="machine.name"/></span>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
<div class="product-screen d-flex h-100 bg-100" t-att-class="{ 'd-none': !props.isShown }">
|
||||
<div class="custompane d-flex flex-column border-end bg-200">
|
||||
<OwsPosCustomerSidebar />
|
||||
<OwsMachineAccessList />
|
||||
</div>
|
||||
|
||||
<div t-if="!ui.isSmall || pos.mobile_pane === 'left'"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user