feat(shopfloor): switch action-path RPCs to fpRpc + wire plant_overview/move_card (P6.3.5)
JobWorkspace, ShopfloorLanding, ManagerDashboard, and the embedded FpHoldComposer now call fpRpc() for write-path endpoints (start/finish step, hold create, sign-off, milestone advance, work-centre move, assign-worker, assign-tank, manager takeover). fpRpc auto-injects tablet_tech_id from the tech_store so the server can rebind env via env_for_tablet_tech() and credit the right user. Read-path RPCs (workspace/load, landing/kanban, manager/overview, manager/funnel, manager/approval_inbox, manager/at_risk, shopfloor/scan) stay as plain rpc() — no audit benefit, no need for the extra plumbing. Also wires tablet_tech_id into /fp/shopfloor/plant_overview/move_card which I missed in P6.3.3 — surfaced when grepping JS for write callers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1108,21 +1108,23 @@ class FpShopfloorController(http.Controller):
|
||||
@http.route('/fp/shopfloor/plant_overview/move_card',
|
||||
type='jsonrpc', auth='user')
|
||||
def plant_overview_move_card(self, card_id, source_model=None,
|
||||
target_workcenter_id=None):
|
||||
target_workcenter_id=None,
|
||||
tablet_tech_id=None):
|
||||
"""Move a step card to a different work centre (drag & drop).
|
||||
|
||||
`source_model` is accepted for backward compatibility but ignored —
|
||||
Plant Overview now only ever serves fp.job.step cards. A target
|
||||
of 0 / falsy clears the work centre.
|
||||
"""
|
||||
Step = request.env['fp.job.step']
|
||||
env = env_for_tablet_tech(request.env, tablet_tech_id)
|
||||
Step = env['fp.job.step']
|
||||
step = Step.browse(int(card_id))
|
||||
if not step.exists():
|
||||
return {'ok': False, 'error': f'Step {card_id} not found.'}
|
||||
|
||||
wc_id = int(target_workcenter_id) if target_workcenter_id else False
|
||||
if wc_id:
|
||||
wc = request.env['fp.work.centre'].browse(wc_id)
|
||||
wc = env['fp.work.centre'].browse(wc_id)
|
||||
if not wc.exists():
|
||||
return {'ok': False,
|
||||
'error': f'Work centre {target_workcenter_id} not found.'}
|
||||
@@ -1132,7 +1134,7 @@ class FpShopfloorController(http.Controller):
|
||||
_logger.info(
|
||||
'Plant Overview: moved step %s (%s) → WC %s by uid %s',
|
||||
step.id, step.name, wc_id or 'unassigned',
|
||||
request.env.uid,
|
||||
env.uid,
|
||||
)
|
||||
except Exception as exc:
|
||||
_logger.exception('Plant Overview move_card failed')
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
import { Component, useState } from "@odoo/owl";
|
||||
import { Dialog } from "@web/core/dialog/dialog";
|
||||
import { rpc } from "@web/core/network/rpc";
|
||||
import { fpRpc } from "../services/fp_rpc";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
// Hold reasons kept here so the picker doesn't need a server roundtrip.
|
||||
@@ -75,7 +75,7 @@ export class FpHoldComposer extends Component {
|
||||
}
|
||||
this.state.submitting = true;
|
||||
try {
|
||||
const res = await rpc("/fp/workspace/hold", {
|
||||
const res = await fpRpc("/fp/workspace/hold", {
|
||||
job_id: this.props.jobId,
|
||||
step_id: this.props.stepId || null,
|
||||
part_ref: this.props.partRef || "",
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import { Component, useState, onMounted, onWillUnmount } from "@odoo/owl";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { rpc } from "@web/core/network/rpc";
|
||||
import { fpRpc } from "./services/fp_rpc";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { WorkflowChip } from "./components/workflow_chip";
|
||||
import { GateViz } from "./components/gate_viz";
|
||||
@@ -116,7 +117,7 @@ export class FpJobWorkspace extends Component {
|
||||
// ---- Step actions ------------------------------------------------------
|
||||
async onStartStep(stepId) {
|
||||
try {
|
||||
const res = await rpc("/fp/shopfloor/start_wo", { workorder_id: stepId });
|
||||
const res = await fpRpc("/fp/shopfloor/start_wo", { workorder_id: stepId });
|
||||
if (res && res.ok) {
|
||||
this.notification.add("Step started.", { type: "success" });
|
||||
await this.refresh();
|
||||
@@ -135,7 +136,7 @@ export class FpJobWorkspace extends Component {
|
||||
contextLabel: `${this.state.data.job.display_wo_name} · Step ${step.sequence_display}: ${step.name}`,
|
||||
onSubmit: async (dataUri) => {
|
||||
try {
|
||||
const res = await rpc("/fp/workspace/sign_off", {
|
||||
const res = await fpRpc("/fp/workspace/sign_off", {
|
||||
step_id: step.id,
|
||||
signature_data_uri: dataUri,
|
||||
});
|
||||
@@ -154,7 +155,7 @@ export class FpJobWorkspace extends Component {
|
||||
}
|
||||
// Plain finish — no signature required
|
||||
try {
|
||||
const res = await rpc("/fp/shopfloor/stop_wo", {
|
||||
const res = await fpRpc("/fp/shopfloor/stop_wo", {
|
||||
workorder_id: step.id, finish: true,
|
||||
});
|
||||
if (res && res.ok) {
|
||||
@@ -201,7 +202,7 @@ export class FpJobWorkspace extends Component {
|
||||
|
||||
async onAdvanceMilestone() {
|
||||
try {
|
||||
const res = await rpc("/fp/workspace/advance_milestone", {
|
||||
const res = await fpRpc("/fp/workspace/advance_milestone", {
|
||||
job_id: this.state.jobId,
|
||||
});
|
||||
if (res && res.ok) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import { Component, useState, onMounted, onWillUnmount } from "@odoo/owl";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { rpc } from "@web/core/network/rpc";
|
||||
import { fpRpc } from "./services/fp_rpc";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { QrScanner } from "./qr_scanner";
|
||||
import { FpTabletLock } from "./tablet_lock";
|
||||
@@ -208,7 +209,7 @@ export class ManagerDashboard extends Component {
|
||||
async onAssignWorker(step, userIdRaw) {
|
||||
const userId = parseInt(userIdRaw) || null;
|
||||
try {
|
||||
const res = await rpc("/fp/manager/assign_worker", {
|
||||
const res = await fpRpc("/fp/manager/assign_worker", {
|
||||
step_id: step.id, user_id: userId,
|
||||
});
|
||||
if (res && res.ok) {
|
||||
@@ -226,7 +227,7 @@ export class ManagerDashboard extends Component {
|
||||
async onAssignTank(step, tankIdRaw) {
|
||||
const tankId = parseInt(tankIdRaw) || null;
|
||||
try {
|
||||
const res = await rpc("/fp/manager/assign_tank", {
|
||||
const res = await fpRpc("/fp/manager/assign_tank", {
|
||||
step_id: step.id, tank_id: tankId,
|
||||
});
|
||||
if (res && res.ok) {
|
||||
@@ -243,7 +244,7 @@ export class ManagerDashboard extends Component {
|
||||
|
||||
async onTakeOver(step) {
|
||||
try {
|
||||
const res = await rpc("/fp/manager/take_over", {
|
||||
const res = await fpRpc("/fp/manager/take_over", {
|
||||
step_id: step.id,
|
||||
});
|
||||
if (res && res.ok) {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import { Component, useState, onMounted, onWillUnmount } from "@odoo/owl";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { rpc } from "@web/core/network/rpc";
|
||||
import { fpRpc } from "./services/fp_rpc";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { QrScanner } from "./qr_scanner";
|
||||
import { FpKanbanCard } from "./components/kanban_card";
|
||||
@@ -254,7 +255,7 @@ export class FpShopfloorLanding extends Component {
|
||||
this._movesInFlight += 1;
|
||||
this._lastDropAt = Date.now();
|
||||
try {
|
||||
const res = await rpc("/fp/shopfloor/plant_overview/move_card", {
|
||||
const res = await fpRpc("/fp/shopfloor/plant_overview/move_card", {
|
||||
card_id: dragged.id,
|
||||
target_workcenter_id: col.work_center_id,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user