Merged in hotfix/2026-04-28 (pull request #3204)

hotfix/2026-04-28 - Add Label, fix exported
This commit is contained in:
Dave Richer
2026-04-28 17:52:28 +00:00
6 changed files with 194 additions and 1 deletions

View File

@@ -1786,6 +1786,7 @@
},
"jobs": {
"actions": {
"addpayer": "Add Payer",
"addDocuments": "Add Job Documents",
"addNote": "Add Note",
"addtopartsqueue": "Add to Parts Queue",

View File

@@ -1780,6 +1780,7 @@
},
"jobs": {
"actions": {
"addpayer": "",
"addDocuments": "Agregar documentos de trabajo",
"addNote": "Añadir la nota",
"addtopartsqueue": "",

View File

@@ -1780,6 +1780,7 @@
},
"jobs": {
"actions": {
"addpayer": "",
"addDocuments": "Ajouter des documents de travail",
"addNote": "Ajouter une note",
"addtopartsqueue": "",

View File

@@ -1164,6 +1164,7 @@
- notification_followers
- state
- md_order_statuses
- md_ro_statuses
retry_conf:
interval_sec: 10
num_retries: 0
@@ -1184,7 +1185,8 @@
"new": {
"id": {{$body.event.data.new.id}},
"shopname": {{$body.event.data.new.shopname}},
"md_order_statuses": {{$body.event.data.new.md_order_statuses}}
"md_order_statuses": {{$body.event.data.new.md_order_statuses}},
"md_ro_statuses": {{$body.event.data.new.md_ro_statuses}}
}
},
"op": {{$body.event.op}},

View File

@@ -2956,6 +2956,7 @@ exports.GET_BODYSHOP_BY_ID = `
query GET_BODYSHOP_BY_ID($id: uuid!) {
bodyshops_by_pk(id: $id) {
id
md_ro_statuses
md_order_statuses
shopname
imexshopid

View File

@@ -0,0 +1,187 @@
import { afterEach, describe, expect, it } from "vitest";
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const mock = require("mock-require");
const graphqlRequestModuleId = require.resolve("graphql-request");
const queriesModuleId = require.resolve("../graphql-client/queries");
const rrLoggerModuleId = require.resolve("./rr-logger-event");
const rrExportLogsModuleId = require.resolve("./rr-export-logs");
const loadExportLogs = ({ requests }) => {
mock.stopAll();
mock(graphqlRequestModuleId, {
GraphQLClient: class MockGraphQLClient {
constructor(endpoint) {
this.endpoint = endpoint;
this.headers = {};
}
setHeaders(headers) {
this.headers = headers;
return this;
}
async request(query, variables) {
requests.push({
endpoint: this.endpoint,
headers: this.headers,
query,
variables
});
return {};
}
}
});
mock(queriesModuleId, {
INSERT_EXPORT_LOG: "INSERT_EXPORT_LOG",
MARK_JOB_EXPORTED: "MARK_JOB_EXPORTED"
});
mock(rrLoggerModuleId, () => {});
delete require.cache[rrExportLogsModuleId];
return require(rrExportLogsModuleId);
};
const socket = {
data: { authToken: "socket-token" },
user: { email: "tech@example.com" }
};
const job = {
id: "job-1",
bodyshop: {
id: "bodyshop-1",
md_ro_statuses: {
default_exported: "Exported"
}
}
};
describe("server/rr/rr-export-logs", () => {
const originalEndpoint = process.env.GRAPHQL_ENDPOINT;
afterEach(() => {
mock.stopAll();
delete require.cache[rrExportLogsModuleId];
process.env.GRAPHQL_ENDPOINT = originalEndpoint;
});
it("marks Reynolds full exports as exported using the shared DMS export mutation", async () => {
process.env.GRAPHQL_ENDPOINT = "https://graphql.example.test/v1/graphql";
const requests = [];
const { markRRExportSuccess } = loadExportLogs({ requests });
await markRRExportSuccess({
socket,
jobId: job.id,
job,
bodyshop: job.bodyshop,
result: {
success: true,
roStatus: {
status: "SUCCESS",
statusCode: "0",
message: "Finalized"
}
}
});
expect(requests).toHaveLength(1);
expect(requests[0]).toMatchObject({
endpoint: "https://graphql.example.test/v1/graphql",
headers: { Authorization: "Bearer socket-token" },
query: "MARK_JOB_EXPORTED",
variables: {
jobId: "job-1",
job: {
status: "Exported",
date_exported: expect.any(Date)
},
log: {
bodyshopid: "bodyshop-1",
jobid: "job-1",
successful: true,
useremail: "tech@example.com"
},
bill: {
exported: true,
exported_at: expect.any(Date)
}
}
});
});
it("uses the separately loaded bodyshop statuses when job.bodyshop is missing", async () => {
process.env.GRAPHQL_ENDPOINT = "https://graphql.example.test/v1/graphql";
const requests = [];
const { markRRExportSuccess } = loadExportLogs({ requests });
await markRRExportSuccess({
socket,
jobId: job.id,
job: { id: job.id },
bodyshop: job.bodyshop,
result: {
success: true,
roStatus: {
status: "SUCCESS",
statusCode: "0",
message: "Finalized"
}
}
});
expect(requests).toHaveLength(1);
expect(requests[0]).toMatchObject({
query: "MARK_JOB_EXPORTED",
variables: {
jobId: "job-1",
job: {
status: "Exported",
date_exported: expect.any(Date)
},
log: {
bodyshopid: "bodyshop-1",
jobid: "job-1",
successful: true,
useremail: "tech@example.com"
}
}
});
});
it("does not mark Reynolds early RO creation as exported", async () => {
process.env.GRAPHQL_ENDPOINT = "https://graphql.example.test/v1/graphql";
const requests = [];
const { markRRExportSuccess } = loadExportLogs({ requests });
await markRRExportSuccess({
socket,
jobId: job.id,
job,
bodyshop: job.bodyshop,
result: { success: true },
isEarlyRo: true
});
expect(requests).toHaveLength(1);
expect(requests[0]).toMatchObject({
query: "INSERT_EXPORT_LOG",
variables: {
logs: [
{
bodyshopid: "bodyshop-1",
jobid: "job-1",
successful: true,
useremail: "tech@example.com"
}
]
}
});
});
});