Common
title: "Calendar (CAL)" ---
Calendar (CAL)
The cal submodule of com provides the calendar primitives the rest of the ERP uses for date arithmetic that needs to skip weekends, holidays, and unavailable delivery slots. It owns the Calendar and CalendarEntry reference data and exposes a "move business days" service that shifts a date forward or backward by a given number of business days while honouring the calendar’s holiday entries and per-day delivery-slot rules. The submodule depends only on the sys term types.
Concepts
CalendarA named time-line owned by some domain object (a country, a warehouse, a supplier). Multiple calendars can coexist; callers pick which one to consult.
Calendar TypeA reference type that classifies calendars. Each type has an interval type that says whether its entries describe periods of availability or unavailability.
Calendar EntryA dated period attached to a calendar. Depending on the calendar’s interval type, the entry represents a working interval or a closed interval (typically a holiday).
Business DayA day on which work is performed. Whether weekends or holidays count as business days is decided per move request.
Delivery SlotA weekday-of-week marker (
IsWeekDaySlot) that callers can pass into a move request to skip days that do not match any of their valid weekday slots.Move DirectionForward or backward — selects whether the calculated end date sits after or before the start date.
Entities
Calendar Type (CalendarType)
A classification of calendars. Carries the interval semantics for every entry of a calendar of this type.
| Field | Description |
|---|---|
| Business key (up to 8 characters). |
| Human-readable name. |
| Whether entries describe Available or Unavailable periods. Default |
Calendar Interval Types (CalendarIntervalType)
| Code | Name | Meaning |
|---|---|---|
| Available | Entries describe periods that are working/open; the rest of the time is closed. |
| Unavailable | Entries describe periods that are closed/holidays; the rest of the time is working. |
Calendar (Calendar)
A named calendar attached (loosely) to a domain object such as a country, warehouse, or supplier.
| Field | Description |
|---|---|
| Business key (up to 20 characters). |
| The type of calendar (Available or Unavailable interval semantics). |
| Optional domain-object class name the calendar belongs to. |
| Optional domain-object id. |
| Optional domain-object business code (used for searching). |
Calendar Entry (CalendarEntry)
A dated period within a calendar. The aggregate is parented on the calendar.
| Field | Description |
|---|---|
| Owning calendar (composite business key with |
| Inclusive start of the period (a |
| Optional inclusive end of the period; absent means the entry is single-day. |
Functionality
Period overlap query
COM_CAL_QueryApi.findEntriesOverlappingPeriod returns every CalendarEntry of a calendar whose [firstDate, lastDate] overlaps the supplied DatePeriod. Used by callers that need to enumerate the holiday entries that touch a given window — typically to display them or to short-circuit calendar checks.
Move-business-days
The flagship operation. COM_CAL_QueryApi.moveBusinessDays advances a start date by a number of business days, walking one calendar day at a time and counting only those days that pass the request’s filters. The same call works for any DomainDate subtype.
A move request specifies:
| Field | Description |
|---|---|
| The calendar whose entries are consulted for holidays. |
| The start date to walk away from. |
| Number of business days to count (must be non-negative). |
|
|
| Whether weekends are business days ( |
| Whether calendar holiday entries are business days ( |
| Optional list of |
The result carries the start request, the computed end date, and a textual move description (for audit/logging). Callers can ask whether the date actually moved.
When moveBusinessDays is positive the start date itself is treated as a business day; when it is zero the start date is returned only if it is itself a valid business day.
Date helpers
COM_CAL_Util is a thin static facade for a handful of date operations that do not need the database:
| Helper | Effect |
|---|---|
| Returns the first occurrence of the given day-of-week strictly after |
| Returns the latest occurrence of the given day-of-week strictly before |
| Returns the first occurrence of |
| Returns the latest occurrence of |
| Adds whole weeks to the date, optionally appending a line to an |
| Subtracts whole weeks, optionally with a report line. |
Plan-week constants
Plan weeks run from Monday to Sunday by convention. The two constants FIRST_DAY_OF_PLANWEEK = MONDAY and LAST_DAY_OF_PLANWEEK = SUNDAY on COM_CAL_Constant are the source of truth for any caller that needs to know where a plan week begins or ends. By the same convention, ex-mill is always Sunday and ex-works is the next working day (typically Monday).
Public API
COM_CAL_QueryApi
Read-side facade.
| Method | Description |
|---|---|
| Calendar entries that overlap the given period. |
| Shifts a date by a number of business days, honouring weekends, holidays, and delivery slots. |
COM_CAL_CommandApi
This submodule does not provide a command API class. Calendars and calendar entries are maintained through the standard CRUD UI, not through a cross-module write seam.
COM_CAL_Util
Static utility (see Date helpers above).
IsWeekDaySlot extension
IsWeekDaySlot is the seam used to plug delivery-slot constraints into a move request. Any module that owns weekday slots (delivery windows, shift definitions, …) can implement the interface so its rows are accepted by CalendarRequest.create.
ViewModel actions
The submodule defines view models for Calendar, CalendarType, and CalendarEntry but does not declare any custom UI actions.
title: "Finance Reference Data (FIN)" ---
Finance Reference Data (FIN)
The fin submodule of com owns the cross-cutting financial reference data used by sales, purchasing, and accounting flows: cost components, credit ratings, terms of payment, and terms of invoice. It exposes only one cross-module lookup — findTermsOfPaymentByCodeMandatory — and otherwise provides standard CRUD pages for administrators to maintain the entries.
Concepts
Cost ComponentA named bucket of cost (for example "material", "labour", "freight"). Used by costing/pricing logic to attribute amounts to a category.
Credit RatingA named risk classification attached to partners. Each rating may carry a UI warning style so high-risk customers stand out in the UI.
Terms of PaymentA named payment-due policy: how many days after invoice the payment is due, and whether advance payment is required.
Terms of InvoiceA named invoicing policy: whether invoices are combined per period and how often invoices are emitted.
Entities
Cost Component (CostComponent)
A named cost bucket.
| Field | Description |
|---|---|
| Business key (up to 8 characters). |
| Human-readable name. |
Credit Rating (CreditRating)
A named credit-risk classification.
| Field | Description |
|---|---|
| Business key (up to 3 characters). |
| Human-readable name. |
| Optional |
Terms of Payment (TermsOfPayment)
A named payment-due policy.
| Field | Description |
|---|---|
| Business key (up to 3 characters). |
| Human-readable name. |
| Optional number of days after invoice when payment is due. |
| Whether the policy requires payment in advance. Default |
Terms of Invoice (TermsOfInvoice)
A named invoicing policy.
| Field | Description |
|---|---|
| Business key (up to 3 characters). |
| Human-readable name. |
| Whether multiple deliveries are combined onto a single invoice for the period. |
| How often invoices are emitted — see Invoice Frequencies below. |
Invoice Frequencies (InvoiceFrequency)
| Code | Name | Meaning |
|---|---|---|
| Direct | Each delivery is invoiced immediately. |
| Weekly | Deliveries in a week are invoiced together. |
| Monthly | Deliveries in a month are invoiced together. |
Functionality
Mandatory terms-of-payment lookup
TermsOfPaymentReaderService exposes both an optional and a mandatory lookup of TermsOfPayment by code. The mandatory variant raises a business exception when the code does not exist; this is the seam other modules use when a missing terms-of-payment value should fail loudly. All other entities are read directly through their generated readers.
Public API
COM_FIN_QueryApi
Read-side facade.
| Method | Description |
|---|---|
| Terms of payment by code; raises a business exception if not found. |
COM_FIN_CommandApi
This submodule does not provide a command API class. Cost components, credit ratings, and the two terms entities are maintained through their default CRUD pages.
ViewModel actions
The submodule defines view models for the four entities but does not declare any custom UI actions.
title: "Logistics Reference Data (LOG)" ---
Logistics Reference Data (LOG)
The log submodule of com owns three orthogonal logistics building blocks: units of measure, terms of delivery, and number series. Other modules look up Uom rows for line items, attach TermsOfDelivery to sales/purchase agreements, and call the number-series writer to allocate the next free document code (purchase orders, invoices, …). It depends on sys.loc for the unit-system reference type.
Concepts
Unit of Measure (UoM)A registered unit code used on quantities throughout the ERP. Each UoM is classified as an SI quantity, a piece count, or a dimensionless figure, and resolves to one of the parsing rules in
sys.uom.Terms of DeliveryA delivery-policy code (such as EXW, FOB, CIF) tied to a transport mode and a delivery-location classification. The
exWorksflag highlights agreements where the buyer collects from the supplier’s premises.Number SeriesA configurable counter used to allocate the next free business code for a document type. Each series has a prefix, a fixed numeric length (zero-padded), and a
firstFreeNumberthat increments on every allocation.Default UoM CodesA set of constant unit codes (
kg,lb,mm,cm,m,in,m2,sqf,pcs) other modules use as their default unit when no entity-specific value is configured.
Entities
Unit of Measure (Uom)
A registered unit. The interpretation rules for the unit code (prefix, exponent, conversion factor) live in sys.uom; this entity is the lookup row referenced from sales/purchase/inventory lines.
| Field | Description |
|---|---|
| Business key (a |
| Classification of the unit — see UoM Types below. |
| Human-readable name. |
UoM Types (UomType)
| Code | Name | Meaning |
|---|---|---|
| SI Quantity | A unit that maps to one of the SI base units (mass, length, …). |
| Pieces | Counted units ( |
| Dimensionless | Unitless quantities (e.g. ratios, percentages). |
Terms of Delivery (TermsOfDelivery)
A named delivery-policy code (the Incoterms-style classification used on agreements).
| Field | Description |
|---|---|
| Business key (up to 3 characters). |
| Human-readable name. |
| Optional transport mode — see Transport Modes below. |
| Where the delivery responsibility transfers — see Delivery Locations below. |
| Whether the terms are ex-works (buyer collects). Default |
Transport Modes (TransportMode)
| Code | Name | Notes |
|---|---|---|
| Air | |
| Rail | |
| Road | |
| Sea |
Delivery Locations (TermsOfDeliveryLocation)
| Code | Name | Used by |
|---|---|---|
| Place of delivery | EXW, FCA |
| Place of destination | CPT, CIP, DPU, DAP, DDP |
| Port of shipment | FAS, FOB |
| Port of destination | CFR, CIF |
Number Series (NumberSeries)
A configurable counter used to allocate the next free business code for a document type.
| Field | Description |
|---|---|
| Business key (up to 6 characters). |
| Human-readable name. |
| Static prefix prepended to every allocated code. |
| Fixed numeric length; the allocated number is zero-padded to this length. |
| The next value to allocate. Default |
Functionality
Mandatory unit lookup
COM_LOG_QueryApi.getUom looks up a Uom by its code and raises a business exception when the code does not exist. Used wherever a missing unit must fail loudly. findUomByCode is the optional variant.
Mandatory terms-of-delivery lookup
TermsOfDeliveryReaderService exposes both an optional and a mandatory lookup of TermsOfDelivery by code. The mandatory variant raises a business exception when the code does not exist. A second helper, findOneByExWorks, returns a single TermsOfDelivery row matching a given ex-works flag — used by callers that want a representative ex-works terms code without hard-coding one.
Number-series allocation
NumberSeriesWriterService.createFirstFreeCode returns the next free business code for a number series. The series row is refreshed from the database first to avoid using a stale firstFreeNumber, the next number is composed (prefix + zero-padded number), firstFreeNumber is incremented, and the change is flushed. Callers receive the new code as a string.
Default UoM codes
COM_LOG_Constant exposes the canonical unit codes used as defaults across the system:
| Constant | Code | Usage |
|---|---|---|
|
| Default mass unit (metric). |
|
| Default mass unit (imperial). |
|
| Length in millimetres. |
|
| Length in centimetres. |
|
| Length in metres. |
|
| Length in inches. |
|
| Surface in square metres. |
|
| Surface in square feet. |
|
| Pieces. |
Public API
COM_LOG_QueryApi
Read-side facade.
| Method | Description |
|---|---|
| Mandatory UoM lookup; raises a business exception if not found. |
| Optional UoM lookup; |
| Optional terms-of-delivery lookup. |
| Mandatory terms-of-delivery lookup. |
| A single terms-of-delivery row matching the ex-works flag, or |
COM_LOG_CommandApi
Write-side facade.
| Method | Description |
|---|---|
| Allocates the next free code on the series and increments |
ViewModel actions
The submodule defines view models for Uom, TermsOfDelivery, and NumberSeries but does not declare any custom UI actions.
title: "Organization (ORG)" ---
Organization (ORG)
The org submodule of com owns the legal-entity and internal-organization reference data: the finance companies that own inventory and balance the books, and the departments that issue purchase, sales, and production orders. It exposes a small lookup API and a static utility that other modules use to assert that two records belong to the same finance company. It depends on sys.loc for country/currency, on com.fin for default terms, on com.log for the partner number series, and is referenced by com.par whenever customers and suppliers are scoped to a company.
Concepts
Finance CompanyThe legal entity that owns inventory and to which all costs and revenues from purchase, sales, or production are assigned. Inventory is linked directly to the finance company; orders and production lines are linked to it indirectly through their department.
DepartmentAn internal organizational unit that belongs to a finance company. Departments issue purchase and sales orders; multiple departments can share the same company.
Same-company checkA pre-validation rule applied wherever two records (a department and a partner, two departments) participate in the same business operation: they must (or in some cases, must not) belong to the same finance company.
Entities
Finance Company (Company)
A legal entity that owns inventory and is the bearer of costs and revenues.
| Field | Description |
|---|---|
| Business key (up to 4 characters). |
| Internal/reporting currency (final field — set at creation, never changed). |
| Primary and optional secondary registered name. |
| Registered address. |
| Optional website URL. |
| Optional phone number. |
| Optional email address. |
| Optional Chamber-of-Commerce registration. |
| Optional VAT registration. |
| Optional default terms of payment used as a fallback for new partner records. |
| Optional default terms of delivery. |
| Optional default terms of invoice. |
| The number series allocated for partner codes that belong to this company. |
Department (Department)
An internal organizational unit within a finance company.
| Field | Description |
|---|---|
| Business key (up to 6 characters). |
| Human-readable name. |
| The finance company the department belongs to. |
| Optional number series used when this department creates documents. |
Functionality
Lookups
COM_ORG_QueryApi exposes thin lookups: getAllCompanies, getAllFinancialCompanies (currently identical), findCompanyByCode, and findDepartmentByCode. Other modules use these to resolve a code from a configuration or a request payload to the live entity.
Same-company assertions
COM_ORG_Util is a static helper used wherever a business operation requires two records to share (or not share) a finance company:
| Helper | Effect |
|---|---|
| Fails when the department and supplier belong to different companies. |
| Fails when the department and customer belong to different companies. |
| Fails when two departments belong to different companies. |
| Same as above, with a request trace for diagnostics. |
| Fails when two departments belong to the same company (used for inter-company transfers). |
Each helper raises a business exception that names the offending records.
Public API
COM_ORG_QueryApi
Read-side facade.
| Method | Description |
|---|---|
| Every finance company. |
| Currently the same as |
| Company by code, or |
| Department by code, or |
COM_ORG_CommandApi
This submodule does not provide a command API class. Companies and departments are maintained through their default CRUD pages.
COM_ORG_Util
Static utility (see Same-company assertions above).
ViewModel actions
The submodule defines view models for Company and Department but does not declare any custom UI actions.
title: "Partners (PAR)" ---
Partners (PAR)
The par submodule of com owns every external party the ERP transacts with — partners and the role-specific projections of those partners as customers, suppliers, and clients. It also owns each partner’s addresses (postal and delivery), contacts, departments, bank accounts, status history, and the reference data that classifies them (partner type, partner status, salutation, contact position, line of business, sales channel, purchase channel). It depends on sys.loc for country/currency, com.org for the company a customer/supplier is scoped to, com.fin for the default financial terms and credit rating, com.log for terms of delivery, com.cal for the partner’s working calendar, and sys.usr for representative users.
Concepts
PartnerA legal entity the ERP transacts with — independent of role. Carries the master data (name, country, registration numbers, language, default terms, calendar). Customers, suppliers, and clients all point at the same partner.
Partner TypeA reference type for partners (e.g. "manufacturer", "logistics service provider"). Carries the legal-type and status defaults applied to new partner records and the default financial terms for that type.
Partner StatusA reference type that says whether the partner is allowed to transact. The blocked flag short-circuits new orders.
Partner Status EventAn immutable timestamped record of a status change with optional notes — the audit trail of partner status transitions.
Customer / Supplier / ClientRole projections of a partner inside a finance company. Each role assigns the partner-as-X relationship to one company; the same partner may be a customer in one company and a supplier in another.
Partner AddressA named address of a partner. Two specializations exist: a
PostalAddressadds postbox/zip/city for invoicing; aDeliveryAddressadds transport mode, geo-coordinates, and a calendar plus opening-hours slots for goods receipt.Delivery Address SlotA weekday/opening-hours window on a delivery address — used by the calendar
moveBusinessDaysservice to skip days the address is closed.Partner ContactA named person at the partner with their own contact details, language, salutation, position, and (optionally) the partner department they belong to.
Partner Bank AccountA bank account that belongs to a partner; carries the IBAN/SWIFT plus the bank’s address.
Sales Channel / Purchase ChannelReference types that classify the route through which a sales or purchase relationship is conducted.
Entities
Partner (Partner)
The master record for an external party. Aggregates every address, contact, status event, and bank account.
| Field | Description |
|---|---|
| Business key (up to 12 characters). |
| Display name. |
| Country of registration. |
| Classification of the partner. |
| Legal classification — see Partner Legal Types below. Default |
| Optional website URL. |
| Optional phone number. |
| Optional email address. |
| Optional Chamber-of-Commerce registration. |
| Optional VAT registration. |
| Current status (active/blocked/…). |
| Optional free-form notes. |
| Preferred language for outbound communication. |
| Optional industry classification. |
| Optional default terms of payment. |
| Optional default terms of delivery. |
| Optional default terms of invoice. |
| Default trading currency. |
| Optional working calendar used for date arithmetic involving this partner. |
| Optional code from an external system (operational field). |
Partner Legal Types (PartnerLegalType)
| Code | Name | Meaning |
|---|---|---|
| Business | Commercial entity (default). |
| Non-governmental | NGO. |
| Governmental | Public-sector entity. |
| Natural Person | Private individual. |
Partner Type (PartnerType)
A classification of partners with the defaults applied to new partner records of this type.
| Field | Description |
|---|---|
| Business key (up to 10 characters). |
| Human-readable name. |
| Legal type assigned to new partners. Default |
| Status assigned to new partners. |
| Optional default terms of payment. |
| Optional default terms of delivery. |
| Optional default terms of invoice. |
Partner Status (PartnerStatus)
A status code that may block transactions.
| Field | Description |
|---|---|
| Business key (up to 12 characters). |
| Human-readable name. |
| Whether partners with this status are blocked from transacting. |
Partner Status Event (PartnerStatusEvent)
An immutable timestamped record of a status change.
| Field | Description |
|---|---|
| The partner whose status changed. |
| When the change happened (composite business key with |
| The new status. |
| Optional free-form notes. |
Partner Address (PartnerAddress)
A named address of a partner.
| Field | Description |
|---|---|
| Owning partner (composite business key with |
| Address code (up to 6 characters). |
| Display names. |
| Address lines. |
| Optional free-form notes. |
Postal Address (PostalAddress)
The invoicing/postbox specialization of a partner address. One per partner address at most.
| Field | Description |
|---|---|
| The partner address being specialized (one-to-one). |
| Optional postbox identifier. |
| Optional postbox zip code. |
| Optional postbox city. |
Delivery Address (DeliveryAddress)
The goods-receipt specialization of a partner address. One per partner address at most.
| Field | Description |
|---|---|
| The partner address being specialized (one-to-one). |
| Optional transport mode used for deliveries to this address. |
| Optional default day-of-week for deliveries. |
| Optional longitude. |
| Optional latitude. |
| Optional free-form delivery instructions. |
| Optional calendar (e.g. closures) for this address. |
Delivery Address Slot (DeliveryAddressSlot)
A weekday/opening-hours window for a delivery address. Implements IsWeekDaySlot so it can be passed into com.cal’s `moveBusinessDays.
| Field | Description |
|---|---|
| Owning delivery address (composite business key with |
| Day of the week the slot is open. |
| Opening time (minute precision). |
| Closing time (minute precision). |
Partner Contact (PartnerContact)
A named person at the partner.
| Field | Description |
|---|---|
| Owning partner (composite business key with |
| Contact code (up to 6 characters). |
| Optional address the contact is reached at; must belong to the same partner. |
| Optional partner department. |
| Salutation (Mr/Mrs/…). |
| First/last name. |
| Optional position/title. |
| Country. |
| Preferred language. |
| Optional free-form notes. |
| Contact channels. |
Partner Department (PartnerDepartment)
A department within a partner organization (used to group contacts).
| Field | Description |
|---|---|
| Business key (up to 6 characters). |
| Human-readable name. |
Partner Bank Account (PartnerBankAccount)
A bank account that belongs to a partner.
| Field | Description |
|---|---|
| Owning partner (composite business key with |
| The IBAN. |
| Bank name. |
| Bank address. |
| Optional SWIFT/BIC code. |
| Optional bank reference. |
| Optional phone number. |
Customer (Customer)
A partner acting as a customer inside a specific company.
| Field | Description |
|---|---|
| The company this customer relationship belongs to. |
| The partner. |
| Optional internal sales representative (a |
| Optional external sales representative. |
| Optional credit rating from |
Supplier (Supplier)
A partner acting as a supplier inside a specific company.
| Field | Description |
|---|---|
| The company this supplier relationship belongs to. |
| The partner. |
| Supplier reliability classification — see Supplier Reliability below. Default |
| Optional internal purchasing representative. |
| Optional external purchasing representative. |
Supplier Reliability (SupplierReliability)
| Code | Name | Meaning |
|---|---|---|
| Unknown | No assessment yet (default). |
| Reliable | Trusted supplier. |
| Not Reliable | Supplier flagged as unreliable. |
Client (Client)
A partner acting as a client inside a specific company. Lighter than Customer — used when the relationship does not warrant the customer-specific fields.
| Field | Description |
|---|---|
| The company this client relationship belongs to. |
| The partner. |
Reference Types
LineOfBusinessAn industry classification attached to partners (
code+description).ContactPositionA position/title used on contacts (
code+description).SalutationA salutation prefix used on contacts (
code+description).SalesChannelA classification of the route a sales relationship is conducted through (
code+description).PurchaseChannelA classification of the route a purchase relationship is conducted through (
code+description).
Functionality
Partner lookup
PartnerReaderService provides the canonical lookups: optional and mandatory by-code, plus retrieval of the default postal address (getDefaultInvoiceAddress) and default delivery address (getDefaultDeliveryAddress) for a partner. The mandatory variants raise a business exception when the partner does not exist.
Customer / Supplier resolution
The same service resolves the customer and supplier projections of a partner inside a given company (getCustomer / getCustomerMandatory, getSupplier / getSupplierMandatory). The mandatory variants raise a business exception when the partner is not registered as a customer/supplier in that company. The non-mandatory variants accept a null partner (and return null) so callers can short-circuit cleanly.
Address lookup
AddressReaderService.findByPartnerAndCodeMandatory returns the partner address whose code matches inside a given partner, raising a business exception when the address does not exist. COM_PAR_QueryApi also exposes the optional variant and direct lookups for a partner address’s postal- or delivery-address specialization.
Line-of-business lookup
LineOfBusinessReaderService.findByCodeMandatory returns a LineOfBusiness by code, raising a business exception when not found.
Delivery slot enumeration
COM_PAR_QueryApi.getAddressDeliverySlots returns every weekday/opening-hours slot of a delivery address. Used by transport-planning code that needs to feed slots into com.cal’s `moveBusinessDays.
Public API
COM_PAR_QueryApi
Read-side facade.
| Method | Description |
|---|---|
| Partner by code (optional or mandatory). |
| The partner’s default postal address, or |
| The partner’s default delivery address, or |
| All |
| Address by partner + code. |
| The delivery-address specialization of a partner address. |
| The postal-address specialization of a partner address. |
| Opening-hours slots of a delivery address. |
| Customer projection of a partner inside a company. |
| Supplier projection of a partner inside a company. |
| Customer row for the (company, partner) pair, or |
| Supplier row for the (company, partner) pair, or |
| Line-of-business by code; raises when not found. |
COM_PAR_CommandApi
This submodule does not provide a command API class. Partners and their related entities are maintained through their default CRUD pages.
IsWeekDaySlot extension
com.par.extension.IsWeekDaySlot is the seam that lets DeliveryAddressSlot rows be passed into the calendar moveBusinessDays service. Other modules with their own weekday-slot rows can implement the interface to participate in the same flow.
ViewModel actions
The submodule defines view models for every entity but does not declare any custom UI actions.
title: "Mail and Conversations (POP)" ---
Mail and Conversations (POP)
The pop submodule of com owns the in-app messaging plumbing: conversations attached to a domain entity, mail messages (inbound, outbound, notifications, comments) flowing through those conversations, attachments on each message, and the per-user follower bookkeeping that drives reply-by-mail and read/starred state. It depends on com.org for the company a conversation lives in, on com.par for the partner mail is from/to, on sys.usr for authors and followers, and on sys.xch to actually send and receive emails.
Concepts
ConversationA thread of mail messages linked to a domain entity (a sales order, a purchase order, a partner, …). Other modules call
findOrCreateConversationto attach a conversation to "their" record without owning the entity-to-conversation glue themselves.Mail MessageOne message inside a conversation. Carries from/to/cc/bcc, subject and body, the type (inbound/outbound/notification/comment), and a derived status. Outbound messages start as drafts and become "sent" when processed; inbound messages are received from the mail provider and become "read" once a follower opens them.
Mail Message TypeWhether a message is inbound (
I), outbound (O), a system notification (N), or an internal comment (C). Decides whether the message should be sent over SMTP and how its status moves.Mail Message StatusThe derived state shown in the UI — Received, Read, Draft, Sent. Each conversation message carries one of these.
Conversation FollowerA user that has opted into a conversation. Followers receive notifications and comments by mail when the message is processed.
Mail FollowerA user’s per-message read/starred bookmark on a specific mail message.
Mail AttachmentA file attached to a mail message, with optional extracted (scraped) JSON content for downstream processing.
Mail Message GroupA reference type that bundles a subject and body text-template — used as a starting point when composing notifications.
Entities
Conversation (Conversation)
A mail thread attached to a domain entity.
| Field | Description |
|---|---|
| Business key. |
| The owning finance company. |
| Optional class name of the entity the conversation is attached to. |
| Optional id of that entity. |
| Optional business code of that entity (used for searching). |
Conversation Follower (ConversationFollower)
A user that follows a conversation.
| Field | Description |
|---|---|
| Owning conversation (composite business key with |
| The follower. |
Mail Message (MailMessage)
One message in a conversation.
| Field | Description |
|---|---|
| Business key — the RFC-822 Message-ID (synthesized for system messages). |
| Inbound, outbound, notification, or comment — see Mail Message Types below. |
| Optional user that wrote the message. |
| Optional company the message belongs to. |
| Optional partner the message is from/to. |
| Sender email address. |
| Optional primary recipient. |
| Optional CC/BCC lists. |
| Message subject and body. |
| Optional group whose subject/body templates were used. |
| Timestamp the message was sent (outbound). |
| Timestamp the message was received (inbound). |
| Optional Message-ID this message replies to. |
| Optional direct parent in the thread. |
| Optional thread root. |
| Optional reference back to the domain entity the message is about. |
| The conversation the message belongs to. |
| Status flag: whether the message has been processed (sent/handled). |
| Derived status — see Mail Message Statuses below. |
A validation rule enforces that any parentMessage, rootMessage, or conversation referenced by the message belongs to the same partner and company as the message itself.
Mail Message Types (MailMessageType)
| Code | Name | Meaning |
|---|---|---|
| Inbound | Received from the mail provider. |
| Outbound | Authored in the ERP, to be sent over SMTP. |
| Notification | System-generated notification, distributed by mail to conversation followers. |
| Comment | Internal comment, distributed by mail to conversation followers. |
Mail Message Statuses (MailMessageStatus)
| Code | Name | Meaning |
|---|---|---|
| Received | Inbound message received but not yet read. |
| Read | Inbound message a follower has read. |
| Draft | Outbound message not yet sent. |
| Sent | Outbound message dispatched over SMTP. |
The status is derived: a message is Draft while not processed, Processed (and archived) once processed.
Mail Follower (MailFollower)
A user’s read/starred bookmark on a specific mail message.
| Field | Description |
|---|---|
| The message (composite business key with |
| The user. |
| Whether the user has starred the message. |
| Whether the user has read the message. |
Mail Attachment (MailAttachment)
A file attached to a mail message.
| Field | Description |
|---|---|
| Owning message (composite business key with |
| File name. |
| Path to the file on the document store. |
| Optional JSON extracted from the file by downstream scraping (operational field). |
Mail Message Group (MailMessageGroup)
A bundle of subject and body text templates used as a starting point when composing a notification.
| Field | Description |
|---|---|
| Business key (up to 8 characters). |
| Human-readable name. |
| Text template used for the subject. |
| Text template used for the body. |
Functionality
Conversation creation and reuse
MailMessageWriterService.createConversation allocates a new Conversation and links it to a domain object reference (type/key/code). findOrCreateConversation is the idempotent variant — it locates the existing conversation for an entity and returns it, or creates a new one if none exists. Other modules use this to attach a conversation to "their" record without owning the entity-to-conversation glue.
Outbound email posting
postOutboundEmail records a fresh outbound MailMessage against a conversation with the supplied To/CC/BCC, subject, and body. The message is created in Draft state; sending it over SMTP happens when the user (or a downstream job) processes the message.
Follower management
addFollower adds the current user as a follower of a conversation. The matching UI action mailMessageFollow (on MailMessageViewModel) calls into the same service. Followers receive notifications and comments by mail when those messages are processed.
Mail-message processing
The process and processUndo write actions on MailMessageViewModel flip the message between draft and processed status. MailMessageProcessor.sendOutboundEmail is the engine behind processing: it reads the conversation’s followers and decides whether the message should be dispatched over SMTP and whether it should be marked processed. The behaviour depends on the message type:
| Type | Behaviour on process |
|---|---|
| Sent over SMTP to every follower; the message is marked processed. |
| Sent over SMTP to every follower; the message is marked processed. |
| Not re-sent; the message stays as it was received. |
| Sent over SMTP to the message’s To/CC/BCC; the message is marked processed. |
The actual SMTP send is delegated to `sys.xch’s command API; this submodule only orchestrates the message-level state.
ViewModel ergonomics
MailMessageViewModel sets the author to the logged-in user on createRecord and synthesizes a fresh internetMessageId. It also derives sane defaults for sentAt / receivedAt based on the chosen mailMessageType and refuses to create inbound messages from the UI (those originate from the mail provider). On a processed message, all fields except those of an inbound message are hidden; for inbound processed messages they are read-only.
Public API
COM_POP_QueryApi
Read-side facade.
| Method | Description |
|---|---|
| Mail messages of a given type and processed flag. |
| All attachments of a message. |
| All mail attachments. |
COM_POP_CommandApi
Write-side facade.
| Method | Description |
|---|---|
| Creates a fresh conversation for a domain object reference. |
| Returns the existing conversation for an entity, or creates one. |
| Records a draft outbound mail message in a conversation. |
| Adds the current user as a follower of the conversation. |
ViewModel actions
| Action | User-visible effect |
|---|---|
| Adds the current user as a follower of the message’s conversation. |
| Processes a draft message: sends notifications/comments/outbound mail and marks the message processed. |
| Reverts a processed message to draft state. |