91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
import type { DatabaseContext } from "../db/database";
|
|
import { canEditOrderItems } from "./order-status";
|
|
import { appendAuditEvent, findOrderDetail, findOrderItemRecord, updateOrderItemQuantity, updateOrderNotes as saveOrderNotes, updateOrderTimestamp } from "./order-repository";
|
|
|
|
export async function changeOrderItemQuantity(
|
|
context: DatabaseContext,
|
|
input: {
|
|
orderId: string;
|
|
itemId: string;
|
|
quantity: number;
|
|
actor: string;
|
|
}
|
|
) {
|
|
const row = await findOrderItemRecord(context, input.orderId, input.itemId);
|
|
|
|
if (!row) {
|
|
return { statusCode: 404, message: "Order item not found." } as const;
|
|
}
|
|
|
|
if (!canEditOrderItems(row.order.status as never)) {
|
|
return { statusCode: 400, message: "Order items cannot be changed for this order status." } as const;
|
|
}
|
|
|
|
if (input.quantity < 1 || input.quantity > 10) {
|
|
return { statusCode: 400, message: "Quantity must be between 1 and 10." } as const;
|
|
}
|
|
|
|
const available = (row.inventory?.availableQuantity ?? 0) + row.item.quantity;
|
|
|
|
if (input.quantity > available) {
|
|
return { statusCode: 400, message: "Requested quantity exceeds available inventory." } as const;
|
|
}
|
|
|
|
const updatedAt = new Date().toISOString();
|
|
await updateOrderItemQuantity(context, input.itemId, input.quantity);
|
|
await updateOrderTimestamp(context, input.orderId, updatedAt);
|
|
await appendAuditEvent(context, {
|
|
orderId: input.orderId,
|
|
actor: input.actor,
|
|
type: "order.item.quantity_changed",
|
|
message: `Updated item ${input.itemId} quantity to ${input.quantity}.`,
|
|
createdAt: updatedAt
|
|
});
|
|
|
|
return {
|
|
statusCode: 200,
|
|
order: await findOrderDetail(context, input.orderId)
|
|
} as const;
|
|
}
|
|
|
|
export async function updateOrderNotes(
|
|
context: DatabaseContext,
|
|
input: {
|
|
orderId: string;
|
|
notes: string;
|
|
actor: string;
|
|
}
|
|
) {
|
|
const order = await findOrderDetail(context, input.orderId);
|
|
|
|
if (!order) {
|
|
return { statusCode: 404, message: "Order not found." } as const;
|
|
}
|
|
|
|
const notes = input.notes.trim();
|
|
|
|
if (!notes) {
|
|
return { statusCode: 400, message: "Notes cannot be empty." } as const;
|
|
}
|
|
|
|
if (notes.length > 1000) {
|
|
return { statusCode: 400, message: "Notes must be 1000 characters or fewer." } as const;
|
|
}
|
|
|
|
const updatedAt = new Date().toISOString();
|
|
await saveOrderNotes(context, input.orderId, notes);
|
|
await updateOrderTimestamp(context, input.orderId, updatedAt);
|
|
await appendAuditEvent(context, {
|
|
orderId: input.orderId,
|
|
actor: input.actor,
|
|
type: "order.notes_updated",
|
|
message: "Updated internal order notes.",
|
|
createdAt: updatedAt
|
|
});
|
|
|
|
return {
|
|
statusCode: 200,
|
|
order: await findOrderDetail(context, input.orderId)
|
|
} as const;
|
|
}
|