🎯 Lead — for the developer
Updated
The lead is the CRM 1.4.0 model, not Core and not a country package.
SalesQuotation ships in the same CRM model. Sales order, realization and
customer payment stay in Sales.
User: which buttons to press. Why the business wants it: sales and purchasing.
Objects#
| Name | Kind |
|---|---|
SalesLead |
a document with no table part |
| Subtypes | New / Qualified / Quoted / Lost |
ILeadService |
CreateQuotationAsync(Guid) → the quotation's id or Empty |
QualifyLead |
New → Qualified |
ConvertLead |
Qualified → Quoted + a Draft quotation |
LoseLead |
New or Qualified → Lost |
SalesQuotation.SourceLead |
a Guid on the quotation (the CRM model), the idempotency key |
There are no transaction scripts. requiresPosting: true is there only so that
the subtype change goes through the posting pipeline.
The service is named LeadService, not SalesLead: otherwise the service class
would collide with the SalesLead document.
There are no public DTOs in ILeadService. No customer / contract / cell /
delivery date (Year < 1902) — Guid.Empty. The optional DeliveryDate on
save: a year < 1902 → 1900-01-01 (SQL datetime).
Idempotency: CountDocumentsAsync<SalesQuotation>("SourceLead = '…'"). The
field lives on SalesQuotation in CRM (the same owner as the quotation — a
same-layer DocumentExtension on someone else's document does not extend the
entity).
The SalesLeadTest test (the Бизнес-слой.Продажи и расчёты group).
What not to do#
- Do not create a
SalesOrderfrom a lead — only a DraftSalesQuotation. - Do not write
Stock/Receivable/ tax from this document. - Opportunity is not in the product: the lead and quotation are the CRM entry points.
- Do not call
CreateQuotationAsyncfromOnAfterPost— the quotation is created by the command.
Same topic for other readers: User