Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Business modules

Module

CRM module (crm)

Module page for crm, with the customer facet of a party, customer part numbers and revisions, customer RFQs with line items and materials, and the RFQ inbox.

The crm module in src/cluster_erp/modules/crm/ handles the customer side before a quote. It keeps the customer facet of a party, maps customer part numbers to the company's products with revisions, records customer requests for quotation (RFQs) with their line items and materials, and keeps an inbox of RFQ e-mails. Quotes that answer RFQs live in the quotations module. This page is the overview; the sub-topics have their own pages.

At a glance

Item Value Source
Package src/cluster_erp/modules/crm/ folder
Module class Module src/cluster_erp/modules/crm/module.py:18
name / version crm / 0.1.0 src/cluster_erp/modules/crm/module.py:20-25
API prefix /api/v1/crm (ModuleBase.api_prefix) src/cluster_erp/core/module_base.py:37-38
Sub-modules 7: customers, customer_parts, customer_part_revisions, rfqs, rfq_line_items, rfq_line_materials, inbox folder listing
Tables 8: crm_customers, crm_customer_parts, crm_customer_part_revisions, crm_rfqs, crm_rfq_packages, crm_rfq_line_items, crm_rfq_line_materials, crm_rfq_inbox_messages __tablename__ in the seven models.py files
Entities in metadata 8 keys in entities src/cluster_erp/modules/crm/module.py:393-402
Routes 57 route decorators in the package grep for @...router.get/post/put/patch/delete
Actions 12 ActionMeta entries grep "ActionMeta(" in the package
Migrations 16 files files in migrations/versions/ whose text contains one of the eight table names
Web app presence Catalogue apps customer-parts and rfqs, both list screens in the folder crm src/cluster_erp/modules/app_store/catalog.json:1002-1018, src/cluster_erp/modules/app_store/catalog.json:1052-1068
Desktop presence generic widgets only src/cluster_erp/desktop/modules/ has no crm folder

What the module does

  • Keeps a customer facet per party, with identity fields derived from the party (src/cluster_erp/modules/crm/customers/services.py:75-146).
  • Maps a customer's part number to one of the company's products and keeps revisions of that part (src/cluster_erp/modules/crm/customer_parts/models.py:13-52, src/cluster_erp/modules/crm/customer_part_revisions/models.py:13-43).
  • Records customer RFQs with a status machine, line items, materials, and a document package (src/cluster_erp/modules/crm/rfqs/services.py:64-80).
  • Keeps inbound RFQ e-mails and matches them to RFQs (src/cluster_erp/modules/crm/inbox/services.py:67-131).

Sub-modules

Sub-module Purpose Main entities Router Source
customers Customer facet of a party Customer /customers src/cluster_erp/modules/crm/customers/routes.py:28-37
customer_parts Customer part numbers CustomerPart /customer-parts src/cluster_erp/modules/crm/customer_parts/routes.py:27-47
customer_part_revisions Revisions of a customer part CustomerPartRevision /customer-parts/{id}/revisions, /customer-part-revisions src/cluster_erp/modules/crm/customer_part_revisions/routes.py:21-24
rfqs Customer RFQs and their document package Rfq, RfqPackage /rfqs, /rfq-packages src/cluster_erp/modules/crm/rfqs/routes.py:36-51
rfq_line_items RFQ lines RfqLineItem /rfqs/{rfq_id}/line-items, /line-items src/cluster_erp/modules/crm/rfq_line_items/routes.py:20-23
rfq_line_materials Materials per RFQ line RfqLineMaterial /line-items/{id}/materials, /line-materials src/cluster_erp/modules/crm/rfq_line_materials/routes.py:26-29
inbox RFQ e-mails RfqInboxMessage /inbox src/cluster_erp/modules/crm/inbox/routes.py:22-25

All routers are mounted under the module prefix with require_app("crm") (src/cluster_erp/modules/crm/module.py:66-74).

Data model

Fields are listed on customers and customer parts, RFQs, and inbox. CustomerPart.part_id names a product only; it carries no model or version (src/cluster_erp/modules/crm/customer_parts/models.py:35). The module stores no money column.

Screens and metadata

get_metadata declares the sidebar Customer Relations (Turkish Müşteri İlişkileri) with two groups: Customer Parts with Customer Part Numbers, and RFQ Management with RFQs and Inbox (src/cluster_erp/modules/crm/module.py:331-390). The customer facet itself is shown on the party card; see party unification.

Status and actions

RFQ statuses and actions are on RFQs; revision and inbox actions on customers and customer parts and inbox.

Business rules

Each sub-topic page lists its rules. Business keys come from the yearly sequences customer, request_for_quotation, and rfq_package (src/cluster_erp/modules/crm/customers/services.py:108, src/cluster_erp/modules/crm/rfqs/services.py:173, src/cluster_erp/modules/crm/rfqs/services.py:583).

Events and queries

The module consumes 9 contracts and produces 14, counted as on the parties module page. The full list is on the contracts reference.

Direction Contract class Handler or emitter Source
emits CustomerCreated, CustomerUpdated, PartyRoleSet customer service src/cluster_erp/modules/crm/customers/services.py:118-207
emits RfqReceived, RfqUpdated, RfqAssigned, RfqDeclined, RfqExpired, RfqWon, RfqLost, RfqPackageCompleted RFQ service src/cluster_erp/modules/crm/rfqs/services.py:147-627
queries GetPartyById, CountPartyChannels, GetBomMaterials services src/cluster_erp/modules/crm/rfqs/services.py:393-417, src/cluster_erp/modules/crm/rfq_line_materials/services.py:116
answers query GetCustomerById, GetRfqById, GetRfqIdsByCustomer, GetCustomerPartById, GetCustomerPartsByCustomer handlers in module.py src/cluster_erp/modules/crm/module.py:88-95
subscribes PartyDeleted, PartyUpdated customer facet sync src/cluster_erp/modules/crm/module.py:96-99, src/cluster_erp/modules/crm/module.py:115-138, src/cluster_erp/modules/crm/module.py:271-297
subscribes CollectSubjectData, AnonymiseSubject privacy_handlers.py src/cluster_erp/modules/crm/module.py:110-113

Permissions

The module checks the families customer.*, customer_part.*, customer_part_revision.*, rfq.*, rfq_package.*, rfq_line_item.*, rfq_line_material.*, and inbox_message.*. Each sub-topic page lists the keys per route.

Privacy, retention, and history

privacy_handlers.py answers data-subject requests for customer facets of individual parties: CollectSubjectData returns the rows, and AnonymiseSubject overwrites the identifying values and deactivates the rows (src/cluster_erp/modules/crm/privacy_handlers.py:1-12). Inbox messages hold e-mail addresses and bodies; see inbox. Deletes set deleted_at (src/cluster_erp/modules/crm/customers/services.py:201). See privacy and data-subject requests.

Analytics facts

This module has no analytics_facts.py.

Settings and reference data

The module has no settings section. The RFQ priority threshold is the module constant PRIORITY_THRESHOLD_HOURS, 48 (src/cluster_erp/modules/crm/rfqs/services.py:82).

Tests

Found by a grep for modules.crm in tests/ and for the path /crm/ in web-client/_e2e_*.mjs.

Kind File Covers
pytest tests/test_party_form_contract.py the customer role on the composite party form
pytest tests/test_tenant_field_catalog.py tenant fields on CRM entities
e2e web-client/_e2e_status_actions.mjs status changes through actions
e2e web-client/_e2e_order_shipment_chain.mjs, web-client/_e2e_quote_line_bom.mjs RFQ to quote to order
e2e web-client/_e2e_party_form_fixes.mjs, web-client/_e2e_fk_labels.mjs customer facet and labels

Discrepancies

Terms introduced

Term Code identifier Definition Turkish term Source
customer facet Customer The customer role record of a party, with commercial defaults. Müşteri rolü src/cluster_erp/modules/crm/customers/models.py:13
customer RFQ Rfq A customer's request for quotation, before a quote exists. Teklif talebi src/cluster_erp/modules/crm/rfqs/models.py:14

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

Verified against commit 92f8051 · 2026-11-13