The nesting module in src/cluster_erp/modules/nesting/ plans how parts are cut from metal sheets. A nesting job describes the sheet and the parts; the job is exported to an external nesting tool, and the tool's layout is imported back, checked, and stored. The module then draws the layout as SVG or DXF, costs the material, reserves and consumes sheet stock through the inventory module, records reusable remnants, and reports utilisation KPIs. The layout itself is not computed inside the module; see nesting engine.
At a glance¶
| Item | Value | Source |
|---|---|---|
| Package | src/cluster_erp/modules/nesting/ |
folder |
| Module class | Module |
src/cluster_erp/modules/nesting/module.py:15 |
name / version |
nesting / 0.1.0 |
src/cluster_erp/modules/nesting/module.py:16-22 |
| API prefix | /api/v1/nesting (ModuleBase.api_prefix) |
src/cluster_erp/core/module_base.py:37-38 |
| Sub-modules | 6 folders: nesting_jobs, nesting_parts, nesting_remnants, integration, kpi, engine |
folder listing |
| Tables | 3: nesting_nesting_jobs, nesting_nesting_parts, nesting_nesting_remnants |
src/cluster_erp/modules/nesting/nesting_jobs/models.py:23, src/cluster_erp/modules/nesting/nesting_parts/models.py:14, src/cluster_erp/modules/nesting/nesting_remnants/models.py:15 |
| Entities in metadata | 3: nesting_job, nesting_part, nesting_remnant |
src/cluster_erp/modules/nesting/module.py:212-216 |
| Routes | 27 route decorators in the package | grep for @router. |
| Web app presence | Catalogue app nesting, with the custom widget nesting_viewer from a gated bundle |
src/cluster_erp/modules/app_store/catalog.json (entry nesting), gated_apps/nesting/app.js |
| Desktop presence | Generic widgets only; the desktop skips the custom viewer section | src/cluster_erp/modules/nesting/module.py:178-187 |
What the module does¶
- Records a nesting job with sheet size, thickness, material grade, coating, kerf, part gap, edge margin, allowed rotations, mirroring, maximum sheets, and an optional sheet material breakdown and warehouse (
src/cluster_erp/modules/nesting/nesting_jobs/models.py:22-291). - Lists the parts to place, by hand or pulled from production and sales orders (
src/cluster_erp/modules/nesting/nesting_jobs/services.py:676-802). - Exports a job for an external tool and imports the tool's placements, remnants, and part outlines (
src/cluster_erp/modules/nesting/integration/services.py:114-363). - Draws the layout as SVG and writes it as DXF (
src/cluster_erp/modules/nesting/nesting_jobs/routes.py:307-396). - Costs the material, credits remnants, and allocates the net cost to parts (
src/cluster_erp/modules/nesting/nesting_jobs/services.py:555-675). - Approves a job, consumes reserved material, creates remnants, and posts them to stock (
src/cluster_erp/modules/nesting/nesting_jobs/services.py:311-390). - Reports utilisation and scrap KPIs over a period (
src/cluster_erp/modules/nesting/kpi/services.py:36-238).
Sub-modules¶
| Sub-module | Purpose | Main entities | Router | Source |
|---|---|---|---|---|
nesting_jobs |
Jobs, lifecycle, material, costs, drawings | NestingJob |
/api/v1/nesting/nesting-jobs |
src/cluster_erp/modules/nesting/nesting_jobs/routes.py:30 |
nesting_parts |
Parts of a job | NestingPart |
/api/v1/nesting/nesting-parts |
src/cluster_erp/modules/nesting/nesting_parts/routes.py:25 |
nesting_remnants |
Reusable leftovers | NestingRemnant |
/api/v1/nesting/nesting-remnants |
src/cluster_erp/modules/nesting/nesting_remnants/routes.py:27 |
integration |
Export and import with an external tool | none | used by nesting_jobs routes |
src/cluster_erp/modules/nesting/integration/services.py:109 |
kpi |
Utilisation KPIs | none | /api/v1/nesting/nesting-jobs/kpi |
src/cluster_erp/modules/nesting/kpi/routes.py:13-16 |
engine |
Geometry types, transforms, DXF and SVG output | none | none | src/cluster_erp/modules/nesting/engine/ |
Details are on jobs, parts, and remnants, integration and KPI, and nesting engine.
Data model¶
| Entity | Table | Key fields | Notes | Source |
|---|---|---|---|---|
NestingJob |
nesting_nesting_jobs |
code, name, status, sheet and process fields, sheet_material_id triple, warehouse_id, result_source, external_software, layout_placements, remnants, utilisation and area fields, cost fields |
layout and remnants are JSON | src/cluster_erp/modules/nesting/nesting_jobs/models.py:22-291 |
NestingPart |
nesting_nesting_parts |
nesting_job_id, part_id, qty_requested, qty_placed, part_length_mm, part_width_mm, geometry_polygon, placement fields, source_order_id, allocated_material_cost |
one live row per job and part | src/cluster_erp/modules/nesting/nesting_parts/models.py:13-131 |
NestingRemnant |
nesting_nesting_remnants |
code, nesting_job_id, sheet_index, x, y, width, height, area_mm2, material_grade, thickness_mm, status, warehouse_id |
status starts available |
src/cluster_erp/modules/nesting/nesting_remnants/models.py:14-98 |
Screens and metadata¶
get_metadata declares a sidebar group Nesting & Optimization (Turkish Yerleşim & Optimizasyon) with three sections: the layout viewer (custom widget nesting_viewer), Nesting Jobs, and Remnants (src/cluster_erp/modules/nesting/module.py:162-217). The viewer shows the KPIs, the job list, a summary, the SVG drawing, and downloads; a client without the widget skips the section (src/cluster_erp/modules/nesting/module.py:178-187).
Status and actions¶
Job statuses are queued, running, completed, and failed (src/cluster_erp/modules/nesting/nesting_jobs/schemas.py:10). A job starts queued and becomes completed when a result is imported (src/cluster_erp/modules/nesting/nesting_jobs/models.py:31-36, src/cluster_erp/modules/nesting/integration/services.py:322). A grep for "running" and "failed" finds no code that sets either status at this commit. Remnant statuses include available, reserved, consumed, and scrapped (src/cluster_erp/modules/nesting/nesting_remnants/services.py:83, src/cluster_erp/modules/nesting/nesting_remnants/services.py:188-194, src/cluster_erp/modules/nesting/nesting_remnants/services.py:256-262).
| Action | Label | Condition | Endpoint | Permission | Source |
|---|---|---|---|---|---|
approve |
Approve | status is completed |
POST /nesting-jobs/{id}/approve |
nesting_job.approve |
src/cluster_erp/modules/nesting/nesting_jobs/metadata.py:79-86, src/cluster_erp/modules/nesting/nesting_jobs/routes.py:213-224 |
pull_parts |
Pull Parts from Orders | status is queued or failed |
POST /nesting-jobs/{id}/pull-parts |
nesting_job.update |
src/cluster_erp/modules/nesting/nesting_jobs/metadata.py:87-94, src/cluster_erp/modules/nesting/nesting_jobs/routes.py:284-293 |
calculate_costs |
Calculate Costs | status is completed |
POST /nesting-jobs/{id}/calculate-costs |
nesting_job.update |
src/cluster_erp/modules/nesting/nesting_jobs/metadata.py:95-105, src/cluster_erp/modules/nesting/nesting_jobs/routes.py:227-236 |
reserve_material |
Reserve Material | status is queued or failed |
POST /nesting-jobs/{id}/reserve-material |
nesting_job.update |
src/cluster_erp/modules/nesting/nesting_jobs/metadata.py:106-116, src/cluster_erp/modules/nesting/nesting_jobs/routes.py:239-248 |
scrap (remnant) |
Scrap | status is available or reserved |
POST /nesting-remnants/{id}/scrap |
nesting_remnant.update |
src/cluster_erp/modules/nesting/nesting_remnants/metadata.py:41-54, src/cluster_erp/modules/nesting/nesting_remnants/routes.py:113-123 |
The nesting pipeline¶
The diagram shows the path of a job from creation to approval.
flowchart TD A["create job (queued)"] --> B["add parts or pull parts from orders"] B --> C["reserve material (optional, ReserveStock)"] C --> D["export job"] D --> E["external nesting tool"] E --> F["import-result: check and store layout (completed)"] F --> G["svg and dxf drawings"] F --> H["calculate costs (NestingCostCalculated)"] H --> I["approve (NestingApproved)"] I --> J["consume material (ConsumeReservation, PostGoodsIssue)"] I --> K["create remnants and post to stock (PostGoodsReceipt)"] I --> L["NestingScrapRecorded"]
In prose: a job is created queued and filled with parts (src/cluster_erp/modules/nesting/nesting_jobs/services.py:111-160). Sheet stock can be reserved while the job is queued (src/cluster_erp/modules/nesting/nesting_jobs/services.py:394-468). The job is exported, nested by an external tool, and the result is imported, which checks the placements and marks the job completed (src/cluster_erp/modules/nesting/integration/services.py:114-363). A completed job can be drawn and costed (src/cluster_erp/modules/nesting/nesting_jobs/services.py:555-675). Approval checks utilisation, then consumes reserved material, creates remnants from the imported leftovers, posts them to stock, and records scrap (src/cluster_erp/modules/nesting/nesting_jobs/services.py:311-390).
Business rules¶
- A job's sheet material is optional; when given, its model and version are validated (
src/cluster_erp/modules/nesting/nesting_jobs/services.py:116-122). - A job can be edited and deleted only while
queuedorfailed; a completed job accepts onlylow_utilization_acknowledgedandnotes(src/cluster_erp/modules/nesting/nesting_jobs/services.py:187-199,src/cluster_erp/modules/nesting/nesting_jobs/services.py:228-232). - Approval of a job whose utilisation is below the threshold needs
low_utilization_acknowledged; the threshold is the settingnesting_low_utilization_threshold, 60 by default (src/cluster_erp/modules/nesting/nesting_jobs/services.py:332-342,src/cluster_erp/modules/nesting/nesting_jobs/routes.py:221-222,src/cluster_erp/config/settings.py:418). - Reserving material needs a sheet material breakdown and a warehouse (
src/cluster_erp/modules/nesting/nesting_jobs/services.py:394-426). - Money results are rounded to four places with
ROUND_HALF_EVEN(src/cluster_erp/modules/nesting/nesting_jobs/services.py:594-628). codecomes from the yearly sequencesnesting_jobandnesting_remnant(src/cluster_erp/modules/nesting/nesting_jobs/services.py:123,src/cluster_erp/modules/nesting/nesting_remnants/services.py:135).
Events and queries¶
The module consumes 2 contracts and produces 16, counted as on the parties module page.
| Direction | Contract class | Handler or emitter | Source |
|---|---|---|---|
| emits | NestingCompleted |
import | src/cluster_erp/modules/nesting/integration/services.py:350-361 |
| emits | NestingApproved, NestingScrapRecorded |
approve | src/cluster_erp/modules/nesting/nesting_jobs/services.py:351-359, src/cluster_erp/modules/nesting/nesting_jobs/services.py:377-388 |
| emits | NestingMaterialReserved, NestingMaterialConsumed |
reserve, consume | src/cluster_erp/modules/nesting/nesting_jobs/services.py:458-466, src/cluster_erp/modules/nesting/nesting_jobs/services.py:544-552 |
| emits | NestingCostCalculated |
calculate costs | src/cluster_erp/modules/nesting/nesting_jobs/services.py:661-669 |
| emits | NestingRemnantCreated, NestingRemnantConsumed, NestingRemnantScrapped |
remnant service | src/cluster_erp/modules/nesting/nesting_remnants/services.py:166-174, src/cluster_erp/modules/nesting/nesting_remnants/services.py:236-242, src/cluster_erp/modules/nesting/nesting_remnants/services.py:273 |
| queries | ReserveStock, ConsumeReservation, PostGoodsIssue, PostGoodsReceipt |
material and remnant flows | src/cluster_erp/modules/nesting/nesting_jobs/services.py:432-443, src/cluster_erp/modules/nesting/nesting_jobs/services.py:496-528, src/cluster_erp/modules/nesting/nesting_remnants/services.py:324-341 |
| queries | GetProductById, GetProductionOrderById, GetSalesOrderById |
pull parts, costs | src/cluster_erp/modules/nesting/nesting_jobs/services.py:572-576, src/cluster_erp/modules/nesting/nesting_jobs/services.py:709-714 |
| answers query | GetNestingJobById |
_handle_get_nesting_job |
src/cluster_erp/modules/nesting/module.py:61-64, src/cluster_erp/modules/nesting/module.py:70-109 |
| answers query | GetAvailableRemnants |
_handle_get_available_remnants |
src/cluster_erp/modules/nesting/module.py:65-68, src/cluster_erp/modules/nesting/module.py:111-140 |
GetNestingJobById returns money and area values as strings, including net_material_cost, which the costing module reads (src/cluster_erp/modules/nesting/module.py:82-108). The full list is on the contracts reference.
Permissions¶
| Permission key | Used by | Source |
|---|---|---|
nesting_job.read, .create, .update, .delete, .bulk_delete |
job routes, drawings, export, summary, KPI | src/cluster_erp/modules/nesting/nesting_jobs/routes.py:128-367, src/cluster_erp/modules/nesting/kpi/routes.py:22 |
nesting_job.approve |
approve | src/cluster_erp/modules/nesting/nesting_jobs/routes.py:216 |
nesting_job.run |
import a result | src/cluster_erp/modules/nesting/nesting_jobs/routes.py:271 |
nesting_part.read, .create, .update, .delete, .bulk_delete |
part routes | src/cluster_erp/modules/nesting/nesting_parts/routes.py:33-107 |
nesting_remnant.read, .update |
remnant routes and scrap | src/cluster_erp/modules/nesting/nesting_remnants/routes.py:37-117 |
Privacy, retention, and history¶
The module stores no personal data and has no privacy_handlers.py. Jobs are soft-deleted; deleting a job also soft-deletes its parts and remnants (src/cluster_erp/modules/nesting/nesting_jobs/services.py:219-249, src/cluster_erp/modules/nesting/nesting_jobs/services.py:289-309). Changes are captured by change history.
Analytics facts¶
This module has no analytics_facts.py. Its own KPI service is described on integration and KPI.
Settings and reference data¶
The module reads one setting, nesting_low_utilization_threshold (src/cluster_erp/config/settings.py:420). It has no settings section and seeds nothing (src/cluster_erp/modules/nesting/module.py:28-30). See settings reference.
Tests¶
Found by a grep for modules.nesting in tests/ and by file name in web-client/.
| Kind | File | Covers |
|---|---|---|
| pytest | tests/test_nesting_units.py |
geometry, measurement, DXF and SVG output, KPI and costing helpers (12 tests) |
| e2e | web-client/_e2e_nesting_app.mjs |
the nesting app: KPI, job list, summary, drawing, downloads, jobs, and remnants |
Discrepancies¶
Terms introduced¶
| Term | Code identifier | Definition | Turkish term | Source |
|---|---|---|---|---|
| nesting job | NestingJob |
A plan to cut a set of parts from sheets of one material and thickness. | Yerleşim işi | src/cluster_erp/modules/nesting/nesting_jobs/models.py:22 |
| remnant | NestingRemnant |
A reusable leftover rectangle of a nested sheet. | Artık | src/cluster_erp/modules/nesting/nesting_remnants/models.py:14 |
| utilisation | utilization_pct |
The share of sheet area covered by placed parts, in percent. | Kullanım oranı | src/cluster_erp/modules/nesting/nesting_jobs/models.py:99 |
Related pages¶
- Modules index
- Nesting engine
- Jobs, parts, and remnants
- Integration and KPI
- Costing module
- Inventory module
- API reference for this module
Verified against commit 92f8051 on 2026-11-13.