Make-to-Order production for Drupal Commerce: from a spreadsheet to a contrib module

At Josefinas, every pair of shoes is handmade in Portugal after the order is placed. There is no warehouse full of finished stock: a customer buys, and an atelier starts working. For years, the bridge between "order paid" and "order shipped" was a shared spreadsheet. It listed what had to be produced, who was making it, and when it might be ready. It also lived completely outside the store: no link to the actual orders, no states, no history, and no way to know where time was being lost.

We replaced that spreadsheet with a Drupal module. It has now been running Josefinas' production for months, and today we are releasing it to the community: Commerce Make-to-Order is available on drupal.org, with a stable 1.0.0 release.

What it does

Commerce Make-to-Order adds a production layer to Drupal Commerce. Make-to-order (also written made-to-order, or build-to-order) means producing items only after a customer order is received, instead of keeping pre-made inventory. When an order reaches a state you configure (for example, paid), the module creates one MTO order per order item: a production order the team tracks from queue to completion.

Each MTO order runs a State Machine workflow designed for real ateliers: Draft, Queued, Waiting for Materials, In Production, Quality Check, Rework, Completed, Canceled. QC failures do not silently loop back into production: they move to a dedicated Rework state and back through Quality Check, so first-pass rate and rework are measurable instead of invisible.

Around that core there is everything a production team needs day to day:

  • Production order numbers via Commerce Number Pattern (MTO-2026-00042)
  • Assignment to team members, priorities, and due dates with overdue highlighting
  • Estimated completion dates, calculated automatically from a per-type setting
  • Internal notes, transition notes, and team notes with optional email notification
  • An activity log timeline and a full state history with per-state timing
  • A production analytics dashboard: bottlenecks, team performance, materials wait analysis, QC metrics, on-time delivery

Closing the loop with the store

The interesting part is what happens when production finishes. The module offers two integration modes with the parent Commerce order:

  • State sync: when all MTO orders of a Commerce order complete, the order transitions directly (for example, Processing to Shipped).
  • Shipment integration: with Commerce Shipping, MTO orders link to the checkout shipment, and when the last one completes the order is promoted to a "ready to ship" state. The shipping team adds tracking, splits shipments if needed, and ships.

Automation has one important limit, learned in production: hold states. Some order states represent a deliberate human decision, like a customer asking not to ship yet. You can configure which states automatic promotion must never override; the module logs a note on the order instead and lets a person decide.

Battle-tested, then released

This is not a v1 built in the abstract. The module has managed hundreds of real production orders at Josefinas before its first public release. Publishing it meant generalizing what was site-specific (hold states became per-type configuration, integrations became optional), adding its own test coverage against Drupal Commerce's core workflows, and cleaning everything to drupal.org standards.

It also plays well with the rest of our contrib work: with Commerce Order Amend, amending a placed order keeps production orders in sync with the changed items.

Get it

composer require drupal/commerce_make_to_order:^1.0

Requires Drupal 10 or 11, Commerce 2.x or 3.x, and State Machine. Commerce Shipping is optional, for the shipment integration mode.

If you run a store where things are made after they are sold (furniture, fashion, print on demand, anything artisanal) we would love to hear how it fits your workflow. The issue queue is open.