Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / API reference

API

Costing API (costing)

HTTP endpoints of the costing module under /api/v1/costing: 30 routes with permissions, schemas, status codes, and error codes.

The costing module serves costing analyses with their calculation and approval lifecycle, labour rates, and overhead rates. All 30 endpoints sit under /api/v1/costing. For business meaning see the Costing module page.

Group facts

Item Value Source
Base path /api/v1/costing src/cluster_erp/core/module_base.py:37-38, src/cluster_erp/modules/costing/module.py:46
Routers 3 router objects in 3 files; listed in the section Endpoint summary src/cluster_erp/modules/costing/module.py:32
Endpoints 30, counted from the route decorators and add_api_route calls of the routers that register_routes mounts src/cluster_erp/modules/costing/costing_analyses/routes.py, src/cluster_erp/modules/costing/labor_rates/routes.py, src/cluster_erp/modules/costing/overhead_rates/routes.py
Authentication Bearer header or session cookie, resolved by get_current_user; see Authentication and headers src/cluster_erp/modules/auth/guards.py:85-167
Permission guard 30 of 30 routes declare require_permission src/cluster_erp/modules/auth/guards.py:205-240
App entitlement gate require_app("costing") on every mounted router src/cluster_erp/modules/costing/module.py:51
Error format JSON body {"error": {...}}; see Errors src/cluster_erp/server/error_handler.py:33-46

Endpoint summary

One row per sub-module folder. The router prefix is added to the base path.

Sub-module Routers Endpoints Router source
costing_analyses router (/analyses) 18 src/cluster_erp/modules/costing/costing_analyses/routes.py:31
labor_rates router (/labor-rates) 6 src/cluster_erp/modules/costing/labor_rates/routes.py:22
overhead_rates router (/overhead-rates) 6 src/cluster_erp/modules/costing/overhead_rates/routes.py:22

Costing analyses endpoints

Analysis records, calculate and recalculate, final price, submit, approve, reject, return to draft, supersede, breakdown, compare, clone as scenario, and rate snapshots.

Method Path Handler Permission Request Query Response Status Source
GET /api/v1/costing/analyses/ list_analyses costing_analysis.read none status, bom_id, quote_id, is_scenario, search, limit, offset dict 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:34
POST /api/v1/costing/analyses/ create_analysis costing_analysis.create CostingAnalysisCreate none CostingAnalysisRead 201 src/cluster_erp/modules/costing/costing_analyses/routes.py:66
GET /api/v1/costing/analyses/{analysis_id} get_analysis costing_analysis.read none none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:78
PUT /api/v1/costing/analyses/{analysis_id} update_analysis costing_analysis.update CostingAnalysisUpdate none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:92
DELETE /api/v1/costing/analyses/{analysis_id} delete_analysis costing_analysis.delete none none none 204 src/cluster_erp/modules/costing/costing_analyses/routes.py:105
POST /api/v1/costing/analyses/bulk-delete bulk_delete_analyses costing_analysis.bulk_delete BulkDeleteRequest none BulkDeleteResponse 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:117
POST /api/v1/costing/analyses/{analysis_id}/calculate calculate_analysis costing_analysis.calculate none none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:129
POST /api/v1/costing/analyses/{analysis_id}/recalculate recalculate_analysis costing_analysis.calculate none none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:144
POST /api/v1/costing/analyses/{analysis_id}/set-final-price set_final_price costing_analysis.update SetFinalPrice none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:159
POST /api/v1/costing/analyses/{analysis_id}/submit-for-approval submit_for_approval costing_analysis.submit none none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:175
POST /api/v1/costing/analyses/{analysis_id}/approve approve_analysis costing_analysis.approve CostingApproveRequest none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:190
POST /api/v1/costing/analyses/{analysis_id}/reject reject_analysis costing_analysis.reject CostingRejectRequest none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:206
POST /api/v1/costing/analyses/{analysis_id}/return-to-draft return_to_draft costing_analysis.update none none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:222
POST /api/v1/costing/analyses/{analysis_id}/supersede supersede_analysis costing_analysis.supersede CostingSupersedeRequest none CostingAnalysisRead 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:237
GET /api/v1/costing/analyses/{analysis_id}/breakdown get_breakdown costing_analysis.read none none dict 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:253
POST /api/v1/costing/analyses/compare compare_analyses costing_analysis.read CostingCompareRequest none dict 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:264
POST /api/v1/costing/analyses/{analysis_id}/clone-as-scenario clone_as_scenario costing_analysis.create ScenarioOverrides none CostingAnalysisRead 201 src/cluster_erp/modules/costing/costing_analyses/routes.py:275
GET /api/v1/costing/analyses/{analysis_id}/rate-snapshots get_rate_snapshots costing_analysis.read none none list 200 (default) src/cluster_erp/modules/costing/costing_analyses/routes.py:292

Labour rates endpoints

Labour rate records.

Method Path Handler Permission Request Query Response Status Source
GET /api/v1/costing/labor-rates/ list_labor_rates labor_rate.read none work_center_id, operation_type, rate_type, active_only, search, limit, offset dict 200 (default) src/cluster_erp/modules/costing/labor_rates/routes.py:25
POST /api/v1/costing/labor-rates/ create_labor_rate labor_rate.create LaborRateCreate none LaborRateRead 201 src/cluster_erp/modules/costing/labor_rates/routes.py:57
GET /api/v1/costing/labor-rates/{rate_id} get_labor_rate labor_rate.read none none LaborRateRead 200 (default) src/cluster_erp/modules/costing/labor_rates/routes.py:69
PUT /api/v1/costing/labor-rates/{rate_id} update_labor_rate labor_rate.update LaborRateUpdate none LaborRateRead 200 (default) src/cluster_erp/modules/costing/labor_rates/routes.py:83
POST /api/v1/costing/labor-rates/bulk-delete bulk_delete_labor_rates labor_rate.bulk_delete BulkDeleteRequest none BulkDeleteResponse 200 (default) src/cluster_erp/modules/costing/labor_rates/routes.py:98
DELETE /api/v1/costing/labor-rates/{rate_id} delete_labor_rate labor_rate.delete none none none 204 src/cluster_erp/modules/costing/labor_rates/routes.py:110

Overhead rates endpoints

Overhead rate records.

Method Path Handler Permission Request Query Response Status Source
GET /api/v1/costing/overhead-rates/ list_overhead_rates overhead_rate.read none rate_type, active_only, search, limit, offset dict 200 (default) src/cluster_erp/modules/costing/overhead_rates/routes.py:25
POST /api/v1/costing/overhead-rates/ create_overhead_rate overhead_rate.create OverheadRateCreate none OverheadRateRead 201 src/cluster_erp/modules/costing/overhead_rates/routes.py:53
GET /api/v1/costing/overhead-rates/{rate_id} get_overhead_rate overhead_rate.read none none OverheadRateRead 200 (default) src/cluster_erp/modules/costing/overhead_rates/routes.py:65
PUT /api/v1/costing/overhead-rates/{rate_id} update_overhead_rate overhead_rate.update OverheadRateUpdate none OverheadRateRead 200 (default) src/cluster_erp/modules/costing/overhead_rates/routes.py:79
POST /api/v1/costing/overhead-rates/bulk-delete bulk_delete_overhead_rates overhead_rate.bulk_delete BulkDeleteRequest none BulkDeleteResponse 200 (default) src/cluster_erp/modules/costing/overhead_rates/routes.py:94
DELETE /api/v1/costing/overhead-rates/{rate_id} delete_overhead_rate overhead_rate.delete none none none 204 src/cluster_erp/modules/costing/overhead_rates/routes.py:106

Error codes

The table lists the error codes that code under src/cluster_erp/modules/costing/ raises, found by a syntax-tree scan for AppError(...), the factories in src/cluster_erp/core/errors.py (not_found, conflict, protected, permission_denied, privilege_escalation, check_version), and HTTPException(...). A status of 400 is the AppError default (src/cluster_erp/core/errors.py:23). Guard errors (401, 403), the entitlement codes, and validation errors (422) apply to every route and are listed on Errors.

Code HTTP status Raised in First site
CONCURRENCY_VERSION_CONFLICT 409 costing_analyses, labor_rates, overhead_rates src/cluster_erp/modules/costing/costing_analyses/services.py:221
COSTING_BOM_NOT_FOUND 404 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:272
COSTING_BOM_NO_ITEMS 400 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:287
COSTING_COMPARE_MAX_ITEMS 400 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:967
COSTING_COMPARE_MIN_ITEMS 400 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:962
COSTING_CURRENCY_MISMATCH 422 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:304
COSTING_FINAL_PRICE_REQUIRED 400 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:751
COSTING_IMMUTABLE 400 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:120
COSTING_INVALID_STATUS 400 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:113
COSTING_NOT_FOUND 404 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:103
COSTING_RATE_INVALID_DATES 400 labor_rates, overhead_rates src/cluster_erp/modules/costing/labor_rates/services.py:160
COSTING_SCENARIO_SOURCE_INVALID 400 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:1039
COSTING_SUPERSEDE_SAME_BOM 400 costing_analyses src/cluster_erp/modules/costing/costing_analyses/services.py:874
RESOURCE_NOT_FOUND 404 costing_analyses, labor_rates, overhead_rates src/cluster_erp/modules/costing/costing_analyses/routes.py:88

Events emitted

The table lists the contract classes that code under src/cluster_erp/modules/costing/ passes directly to EventBus.emit, found by a syntax-tree scan. Events built in a variable first are not counted. The contracts are described in Contracts reference.

Contract Sites First site
CostingApproved 1 src/cluster_erp/modules/costing/costing_analyses/services.py:786
CostingCalculated 1 src/cluster_erp/modules/costing/costing_analyses/services.py:674
CostingCreated 1 src/cluster_erp/modules/costing/costing_analyses/services.py:200
CostingRateUpdated 2 src/cluster_erp/modules/costing/labor_rates/services.py:218
CostingRejected 1 src/cluster_erp/modules/costing/costing_analyses/services.py:828
CostingSuperseded 1 src/cluster_erp/modules/costing/costing_analyses/services.py:886
LowMarginAlert 1 src/cluster_erp/modules/costing/costing_analyses/services.py:694
QuoteCostingCompleted 1 src/cluster_erp/modules/costing/costing_analyses/services.py:800

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13