diff --git a/CHANGELOG.md b/CHANGELOG.md index 68b9f7f..031c511 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This file is the running release and change log for CODEXIUM. Keep it updated wh ### Added +- Reverse project visibility on quote and sales-order detail pages, purchase-order header project linkage, sales-order-driven project auto-derivation for new work orders and purchase orders, quote-to-sales-order project carry-through during conversion, and migration backfill for existing work orders and purchase orders linked through project sales orders - Finance module with customer-payment posting against sales orders, finance costing assumptions, sales-order cash/spend ledger rollups, manufacturing cost snapshots, and CapEx tracking for equipment, tooling, and consumables - Inventory-backed shipment picking from shipment detail pages, including sales-order line remaining-quantity visibility, warehouse/location source selection, issued-stock posting, and shipment pick history - Project cockpit section on project detail pages for commercial, supply, execution, delivery, purchasing, readiness-risk, and project cost snapshot rollups, plus direct launch paths into prefilled work-order and purchase-order follow-through and a chronological project activity timeline diff --git a/README.md b/README.md index 5ab2a59..c31294a 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Current foundation scope includes: - branded quote, sales-order, and purchase-order PDFs through the shared backend document pipeline - purchase-order supporting documents for vendor invoices, acknowledgements, certifications, and backup files - shipping shipments linked to sales orders with inventory-backed picking, stock issue posting, packing slips, shipping labels, bills of lading, and logistics attachments -- projects with customer/commercial/shipment linkage, owners, due dates, milestones, rollups, notes, and attachments +- projects with customer/commercial/shipment linkage, owners, due dates, milestones, rollups, notes, attachments, reverse-linked quote/sales-order visibility, and downstream project-context carry-through into generated work orders and purchase orders - manufacturing work orders with project linkage, station-based operation templates, editable station calendars/capacity settings, calendar-aware operation scheduling, operation execution controls, operator assignment, timer-based and manual labor posting, material issue posting, completion posting, operation rescheduling, and work-order attachments - planning workbench with live project/manufacturing schedule data, exception rail, heatmap load view, agenda view, focus drawer, station load grouping, readiness filters, overload visibility, inline dispatch actions, planner-side operation rebalance controls including station-to-station moves, and station-lane drag scheduling - sales-order demand planning with multi-level BOM explosion, stock/open-supply netting, and build/buy recommendations @@ -116,6 +116,7 @@ Current interactions: - CRM: each project should link to a customer account and relevant contacts - Sales: quotes and sales orders can already attach to projects +- Sales workflow now also exposes the reverse project link on quote and sales-order detail pages, and quote conversion carries linked project context forward into the created sales order - Shipping: shipments tied to project deliverables are visible from the project record - Dashboard: projects now contribute status, risk, backlog, and overdue widgets - Detail/List UX: projects now surface milestone progress and linked execution rollups @@ -123,8 +124,8 @@ Current interactions: Next expansion areas: - Inventory: projects should reference item/BOM scope and later expose shortages or allocations -- Purchasing: project material demand is now visible through linked PO, receipt, vendor, and outstanding-supply rollups, and should later expand into project-side purchasing actions -- Manufacturing: work orders should link back to projects without turning projects into the manufacturing module +- Purchasing: project material demand is now visible through linked PO, receipt, vendor, and outstanding-supply rollups, and purchase orders now persist header-level project context derived from linked sales demand or explicit project selection +- Manufacturing: work orders already auto-link back to the project when the originating sales order belongs to a project, without turning projects into the manufacturing module - Planning: project milestones and execution dates should feed workbench scheduling, dependency views, and richer planner drilldowns ## Manufacturing Direction diff --git a/SHIPPED.md b/SHIPPED.md index b047fb3..20b5746 100644 --- a/SHIPPED.md +++ b/SHIPPED.md @@ -35,6 +35,7 @@ This file tracks roadmap phases, slices, and major foundations that have already - Packing-slip, shipping-label, and bill-of-lading PDF rendering for shipments - Logistics attachments directly on shipment records - Projects foundation with customer, quote, sales-order, shipment, owner, due-date, notes, and attachment linkage +- Reverse project linkage visibility on quote and sales-order detail pages, plus project-context carry-through into generated work orders and purchase orders with sales-order-driven backfill for existing records - Project milestones and project-side milestone/work-order rollups - Project cockpit section on detail pages for commercial, supply, execution, delivery, purchasing, readiness-risk, and cost-snapshot visibility, with direct launch paths into prefilled project work orders and demand-linked purchase orders plus a project activity timeline - Project list/detail/create/edit workflows and dashboard program widgets @@ -78,6 +79,7 @@ This file tracks roadmap phases, slices, and major foundations that have already - Project records with customer linkage, status, owner, priority, due dates, milestones, and notes - Project milestone status tracking and project-side milestone/work-order rollups - Project-to-quote, sales-order, and shipment linkage for delivery context +- Quote-to-sales-order project carry-through plus reverse-linked project visibility from the sales workflow - Project attachments through the shared file pipeline - Project list/detail/create/edit flows and dashboard visibility @@ -103,6 +105,7 @@ This file tracks roadmap phases, slices, and major foundations that have already - Netting against available stock, active reservations, open work orders, and open purchase orders - Build and buy recommendations surfaced directly from the sales-order workflow - Prefilled work-order and purchase-order draft generation launched from demand-planning recommendations +- Generated work orders and purchase orders now auto-carry linked project context when demand traces back to a project-linked sales order - Shared shortage and readiness rollups surfaced across dashboard, planning, project, purchasing, and manufacturing views - Preferred-vendor sourcing on inventory items for buy-side planning defaults - Pegged work-order and purchase-order supply links back to originating sales demand diff --git a/client/src/modules/purchasing/PurchaseDetailPage.tsx b/client/src/modules/purchasing/PurchaseDetailPage.tsx index 4863341..d18152e 100644 --- a/client/src/modules/purchasing/PurchaseDetailPage.tsx +++ b/client/src/modules/purchasing/PurchaseDetailPage.tsx @@ -427,7 +427,18 @@ export function PurchaseDetailPage() {
-

Notes

+

Project Link

+ {activeDocument.projectId ? ( +
+ + {activeDocument.projectNumber} / {activeDocument.projectName} + +

This purchase order is linked to the project context used by project cockpit and downstream rollups.

+
+ ) : ( +

No linked project is currently attached to this purchase order.

+ )} +

Notes

{activeDocument.notes || "No notes recorded for this document."}

diff --git a/client/src/modules/purchasing/PurchaseFormPage.tsx b/client/src/modules/purchasing/PurchaseFormPage.tsx index 57d5ce7..d2fa391 100644 --- a/client/src/modules/purchasing/PurchaseFormPage.tsx +++ b/client/src/modules/purchasing/PurchaseFormPage.tsx @@ -14,6 +14,9 @@ export function PurchaseFormPage({ mode }: { mode: "create" | "edit" }) { const { orderId } = useParams(); const [searchParams] = useSearchParams(); const seededVendorId = searchParams.get("vendorId"); + const seededProjectId = searchParams.get("projectId"); + const seededProjectNumber = searchParams.get("projectNumber"); + const seededProjectName = searchParams.get("projectName"); const planningOrderId = searchParams.get("planningOrderId"); const selectedPlanningItemId = searchParams.get("itemId"); const [form, setForm] = useState(emptyPurchaseOrderInput); @@ -57,6 +60,12 @@ export function PurchaseFormPage({ mode }: { mode: "create" | "edit" }) { api.getInventoryItemOptions(token).then((options) => setItemOptions(options.filter((option: InventoryItemOptionDto) => option.isPurchasable))).catch(() => setItemOptions([])); }, [mode, seededVendorId, token]); + useEffect(() => { + if (mode === "create" && seededProjectId) { + setForm((current) => ({ ...current, projectId: current.projectId || seededProjectId })); + } + }, [mode, seededProjectId]); + useEffect(() => { if (!token || mode !== "create" || !planningOrderId || itemOptions.length === 0) { return; @@ -103,6 +112,7 @@ export function PurchaseFormPage({ mode }: { mode: "create" | "edit" }) { setForm((current) => ({ ...current, vendorId: current.vendorId || autoVendorId || "", + projectId: current.projectId || seededProjectId || null, notes: current.notes || `Demand-planning recommendation from sales order ${planning.documentNumber}.`, lines: current.lines.length > 0 ? current.lines : recommendedLines, })); @@ -124,7 +134,7 @@ export function PurchaseFormPage({ mode }: { mode: "create" | "edit" }) { .catch(() => { setStatus("Unable to load demand-planning recommendations."); }); - }, [itemOptions, mode, planningOrderId, seededVendorId, selectedPlanningItemId, token, vendors]); + }, [itemOptions, mode, planningOrderId, seededProjectId, seededVendorId, selectedPlanningItemId, token, vendors]); useEffect(() => { if (!token || mode !== "edit" || !orderId) { @@ -135,6 +145,7 @@ export function PurchaseFormPage({ mode }: { mode: "create" | "edit" }) { .then((document) => { setForm({ vendorId: document.vendorId, + projectId: document.projectId, status: document.status, issueDate: document.issueDate, taxPercent: document.taxPercent, @@ -341,6 +352,19 @@ export function PurchaseFormPage({ mode }: { mode: "create" | "edit" }) { updateField("issueDate", new Date(event.target.value).toISOString())} className="w-full rounded-2xl border border-line/70 bg-page px-2 py-2 text-text outline-none transition focus:border-brand" /> +
+
Linked Project
+
+ {mode === "edit" + ? (form.projectId ? "Project context saved on this purchase order." : "No project linked.") + : (seededProjectId ? `${seededProjectNumber || "Project"}${seededProjectName ? ` - ${seededProjectName}` : ""}` : "Will auto-link from sales-order demand when possible.")} +
+
+ {mode === "edit" + ? "This header link is used for downstream project cockpit and finance rollups." + : "Generated purchasing from a project-linked sales order will carry project context automatically."} +
+