Skip to content

BPM Module

Türkçe

BPM (Business Process Management) modülü, iş ortakları, şubeler, kişiler, sözleşmeler, sözleşme kalemleri, ürünler ve tahakkuk yönetimini kapsar. Entity hiyerarşisi: BusinessPartner → Branch → Contact / Contract → ContractItem / Accrual.

Overview

The BPM module manages the business partner lifecycle — from partner registration through contract management to periodic accrual generation. It runs as a standalone Spring Boot service on port 8020 with context path /icbpm/services.

┌─────────────────────────────────────────────────────────┐
│  BPM Module — icbpm-services (port 8020)                │
├─────────────────────────────────────────────────────────┤
│  Sub-Projects:                                          │
│  ├ ICoSys-BPM-Types-1.0        → Enums (no Spring)     │
│  ├ ICoSys-BPM-Entities-1.0     → JPA Entities          │
│  ├ ICoSys-BPM-Entities-Dto-1.0 → DTOs                  │
│  └ ICoSys-BPM-Services-1.0     → Spring Boot Service   │
│                                                         │
│  Database: icbpm (MySQL 8)                              │
│  ID Table: s_icbpm_id                                   │
└─────────────────────────────────────────────────────────┘

Entity Relationship Diagram

BusinessPartner (1) ─────→ (*) Branch
                               ├──→ (*) Contact
                               └──→ (*) Contract
                                     ├──→ (*) ContractItem ──→ Product (optional)
                                     └──→ (*) Accrual

All entities:
  ├── extend AbstractICEntity6
  ├── reference CrProcess (tenant, required)
  └── use TableGenerator for ID generation
Relationship Type Cascade Orphan Removal
BusinessPartner → Branch OneToMany ALL Yes
Branch → Contact OneToMany ALL Yes
Branch → Contract OneToMany ALL Yes
Contract → ContractItem OneToMany ALL Yes
Contract → Accrual OneToMany ALL Yes
ContractItem → Product ManyToOne
Branch → Country ManyToOne

Entities

BusinessPartner

The root entity representing a customer or vendor.

Field Type Constraints Description
id Long PK, auto-gen Primary key
code String(20) UNIQUE per tenant Auto-generated partner code
legalName String(255) NOT NULL Official legal name
shortName String(100) Display/short name
taxNumber String(20) UNIQUE per tenant VKN or TCKN
taxOffice String(100) Tax office name
isCustomer Boolean default FALSE Partner is a customer
isVendor Boolean default FALSE Partner is a vendor
externalId String(50) External system reference
status BusinessPartnerStatus default ACTIVE Lifecycle status
notes String(1000) Free-text notes

Türkçe

isCustomer veya isVendor alanlarından en az biri true olmalıdır. Her ikisi de false ise validateForCreate hata fırlatır.


Branch

A physical or logical branch belonging to a business partner.

Field Type Constraints Description
id Long PK Primary key
businessPartner BusinessPartner FK, NOT NULL Parent partner
branchName String(100) NOT NULL, UNIQUE per partner Branch name
billingTitle String(255) Invoice billing title
addressText String(500) Full address
country Country FK, optional Country reference
city String(100) City name
postalCode String(20) Postal code
iban String(34) Bank IBAN
einvoiceAlias String(50) GIB e-invoice alias
phone String(20) Phone number
email String(100) Email address
isDefault Boolean default FALSE Default branch flag (unique per partner)
status Boolean default TRUE Active status

Contact

A person associated with a branch.

Field Type Constraints Description
id Long PK Primary key
branch Branch FK, NOT NULL Parent branch
firstName String(50) NOT NULL First name
lastName String(50) NOT NULL Last name
title String(100) Job title
email String(100) Email address
mobilePhone String(20) Mobile phone
officePhone String(20) Office phone
roleType ContactRoleType default GENERAL Contact role
isPrimary Boolean default FALSE Primary contact (unique per branch)
hasConsent Boolean default FALSE KVKK marketing consent
notes String(500) Free-text notes
status Boolean default TRUE Active status

Contract

A contractual agreement attached to a branch.

Field Type Constraints Description
id Long PK Primary key
branch Branch FK, NOT NULL Parent branch
contractNo String UNIQUE per tenant Auto-generated contract number
description String Contract title / description
billingPeriod BillingPeriod Billing cycle type
startDate LocalDate NOT NULL Contract start date
endDate LocalDate Contract end date (≥ startDate)
noticeDays Integer Notice period in days
autoAccrual Boolean Auto-generate accruals flag
currency String(3) ISO 4217 currency code
paymentTermDays Integer Payment term in days
indexationType IndexationType Price indexation type
indexationRate BigDecimal(5,2) Custom indexation rate %
invoiceLanguage String Invoice language
status ContractStatus Contract lifecycle status
notes String(1000) Free-text notes

ContractItem

A line item within a contract, optionally linked to a product.

Field Type Constraints Description
id Long PK Primary key
contract Contract FK, NOT NULL Parent contract
product Product FK, optional Product reference
lineNo Integer NOT NULL Line number (ordering)
description String(255) NOT NULL Item description
billingPeriod BillingPeriod Billing cycle
quantity BigDecimal(10,2) NOT NULL Quantity
unit String Unit of measure
unitPrice BigDecimal(18,4) NOT NULL Unit price
discountRate BigDecimal(5,2) Discount percentage
vatRate Integer VAT rate percentage
currency String Currency code
invoiceCurrency String(3) Invoice currency
addMonthDesc Boolean Add month label to invoice
separateInvoice Boolean Generate separate invoice
invoiceLanguage String Invoice language
notes String(500) Free-text notes
accrualStatus Boolean Accrual generated flag
status Boolean Active status

Calculated fields (transient):

subtotal()       = quantity × unitPrice
discountAmount() = subtotal × (discountRate / 100)
netAmount()      = subtotal  discountAmount
vatAmount()      = netAmount × (vatRate / 100)
totalAmount()    = netAmount + vatAmount

Product

A reusable product or service definition.

Field Type Constraints Description
id Long PK Primary key
code String(50) UNIQUE, NOT NULL Auto-generated product code
name String(200) NOT NULL Product / service name
description String(1000) Detailed description
category ProductCategory NOT NULL Product category
defaultPrice BigDecimal(15,2) Default unit price
currency String(3) ISO 4217 currency
unit String(20) Unit of measure
vatRate Integer Default VAT rate %
sku String(100) SKU or external reference
notes String(500) Free-text notes
status Boolean default TRUE Active status

Accrual

A periodic billing record generated from a contract.

Field Type Constraints Description
id Long PK Primary key
contract Contract FK, NOT NULL Parent contract
servicePeriod String(50) NOT NULL Period description (e.g., "JAN-2026")
periodStart LocalDate NOT NULL Service period start
periodEnd LocalDate NOT NULL Service period end
netAmount BigDecimal(18,2) NOT NULL Net amount
vatAmount BigDecimal(18,2) default 0 VAT amount
totalAmount BigDecimal(18,2) NOT NULL Total including VAT
currency String(3) default "TRY" ISO 4217 currency
status AccrualStatus default DRAFT Workflow status
approvedBy String(50) Approver user ID
approvalDate Instant Approval timestamp
invoiceRef String(50) External invoice reference
invoiceDate LocalDate Invoice date
syncLog String(2000) Integration sync log
notes String(500) Free-text notes

Enums

AccrualStatus

The accrual lifecycle workflow.

Value Description
DRAFT Created, awaiting approval
APPROVED Approved, ready for invoicing
INVOICED Sent to external invoicing system
CANCELLED Cancelled
FAILED Integration error during sync

BusinessPartnerStatus

Value Description
ACTIVE Active and available
PASSIVE Temporarily inactive
SUSPENDED Suspended
BLACKLISTED Blacklisted
BLOCKED Blocked (compliance / payment)

ContractStatus

Value Description
DRAFT Not yet active
ACTIVE Currently in effect
SUSPENDED Temporarily suspended
EXPIRED End date has passed
TERMINATED Terminated before end date
RENEWED Replaced by a new contract

BillingPeriod

Value Description
MONTHLY Monthly billing cycle
QUARTERLY Every 3 months
SEMI_ANNUAL Every 6 months
YEARLY Annual
ONE_TIME No recurrence
RANDOM Custom / random dates

IndexationType

Value Description
NONE Fixed price
CPI TÜFE — Consumer Price Index
PPI ÜFE — Producer Price Index
USD USD exchange rate based
EUR EUR exchange rate based
CUSTOM Custom percentage

ContactRoleType

22 values organized by department:

Group Values
General GENERAL, OWNER
Management MANAGEMENT, PROJECT_MANAGER
Finance & Legal ACCOUNTING, LEGAL, CONTRACT
Commercial SALES, PURCHASING, MARKETING, BUSINESS_DEVELOPMENT
Operations TECHNICAL, LOGISTICS, WAREHOUSE, PRODUCTION, QUALITY
Support CUSTOMER_SERVICE, HR
Other OTHER

ProductCategory

24+ categories covering physical goods, licensing, professional services, compliance, operations, financial, and marketing categories.


Accrual Workflow

Türkçe

Tahakkuk akışı DRAFT → APPROVED → INVOICED şeklinde ilerler. Sadece DRAFT durumundaki tahakkuklar güncellenebilir. Silme işlemi yalnızca DRAFT veya CANCELLED için yapılabilir.

                    ┌────────────┐
                    │   DRAFT    │
                    └─────┬──────┘
            ┌─────────────┼─────────────┐
            │             │             │
            ▼             ▼             │
     ┌────────────┐  ┌──────────┐      │
     │  APPROVED  │  │ CANCELLED│      │
     └─────┬──────┘  └──────────┘      │
           │                            │
           ▼                            │
     ┌────────────┐                     │
     │  INVOICED  │                     │
     └────────────┘                     │
     ┌────────────┐                     │
     │   FAILED   │ ◄──────────────────┘
     └────────────┘   (integration error)
Transition Endpoint Rules
DRAFT → APPROVED POST /api/accrual/{id}/approve Sets approvedBy and approvalDate
APPROVED → INVOICED POST /api/accrual/{id}/invoice?invoiceRef=... Requires invoiceRef, sets invoiceDate
DRAFT/APPROVED → CANCELLED POST /api/accrual/{id}/cancel?reason=... Optional reason stored in syncLog
Any → FAILED Internal only Error message stored in syncLog

Validation rules:

Operation Allowed Status Error Code
Update DRAFT only error.accrual.cannot_update
Delete DRAFT or CANCELLED error.accrual.cannot_delete
Approve DRAFT only error.accrual.cannot_approve
Invoice APPROVED only error.accrual.cannot_invoice
Cancel DRAFT or APPROVED error.accrual.cannot_cancel

REST API

Base path: /icbpm/services/api

BusinessPartner — /api/business-partner

Method Endpoint Description
GET /{id} Find by ID
POST / Create new partner
PUT /{id} Update partner
DELETE /{id} Delete partner
POST /list Paginated list with filter
GET /stats Entity statistics
GET /by-code/{crProcessId}/{code} Find by partner code
GET /by-tax/{crProcessId}/{taxNumber} Find by tax number

Branch — /api/branch

Method Endpoint Description
GET /{id} Find by ID
POST / Create new branch
PUT /{id} Update branch
DELETE /{id} Delete branch
POST /list Paginated list
GET /stats Entity statistics

Contact — /api/contact

Standard CRUD + list + stats endpoints.

Contract — /api/contract

Method Endpoint Description
GET /{id} Find by ID
POST / Create new contract
PUT /{id} Update contract
DELETE /{id} Delete contract
POST /list Paginated list
GET /stats Entity statistics
GET /by-no/{crProcessId}/{contractNo} Find by contract number
GET /by-branch/{branchId} Get contracts by branch
GET /by-partner/{businessPartnerId} Get contracts by partner
GET /active/{crProcessId} Get active contracts
GET /by-partner/{businessPartnerId}/active-count Count active contracts

ContractItem — /api/contract-item

Standard CRUD + list endpoints.

Product — /api/product

Standard CRUD + list + stats endpoints.

Accrual — /api/accrual

Method Endpoint Description
GET /{id} Find by ID
POST / Create new accrual
PUT /{id} Update accrual (DRAFT only)
DELETE /{id} Delete accrual (DRAFT/CANCELLED only)
POST /list Paginated list
GET /stats Entity statistics
POST /{id}/approve Workflow: approve
POST /{id}/invoice?invoiceRef=... Workflow: mark invoiced
POST /{id}/cancel?reason=... Workflow: cancel
GET /by-contract/{contractId} Get accruals by contract
GET /by-partner/{businessPartnerId} Get accruals by partner
GET /by-status/{crProcessId}/{status} Get by status
GET /drafts/by-contract/{contractId} Get draft accruals

Service Lifecycle Hooks

BusinessPartnerService

Hook Logic
validateForCreate Tax number uniqueness check; isCustomer OR isVendor must be true
validateForUpdate Tax number uniqueness (excluding self); customer/vendor check
beforeCreate Set CrProcess; auto-generate code via CodeGeneratorService

BranchService

Hook Logic
validateForCreate businessPartnerId & branchName required; branch name unique within partner; default branch unique within partner
validateForUpdate branchName required; name unique (excl. self); default unique (excl. self)
beforeCreate Set CrProcess; resolve businessPartner; resolve country
beforeUpdate Update country reference if changed

ContractService

Hook Logic
validateForCreate branchId & startDate required; endDate ≥ startDate
validateForUpdate startDate required; endDate ≥ startDate
beforeCreate Set CrProcess; resolve branch; auto-generate contractNo

AccrualService

Hook Logic
validateForCreate contractId required; validate common fields (period, amounts)
validateForUpdate Only DRAFT status can be updated; validate common fields
validateDeletion Only DRAFT or CANCELLED can be deleted
beforeCreate Set CrProcess; resolve contract; set default status to DRAFT

ContactService

Hook Logic
validateForCreate branchId required; firstName/lastName required; primary contact unique within branch
beforeCreate Set CrProcess; resolve branch

Specification (Search & Filter)

BusinessPartnerSpecification

Filter Field Operator
code CONTAINS (LIKE)
legalName CONTAINS
taxNumber CONTAINS
status EQUALS
isCustomer EQUALS
isVendor EQUALS
creationDateFrom >= (date range)
creationDateTo <= (date range)

Global search fields: code, legalName, shortName, taxNumber

AccrualSpecification

Filter Field Operator
contractId EQUALS
businessPartnerId EQUALS (via contract → branch → partner)
status EQUALS
currency EQUALS
periodStartFrom >= (date range)
periodStartTo <= (date range)
invoiceRef CONTAINS
hasInvoice IS NOT NULL / IS NULL

Global search fields: servicePeriod, invoiceRef, contractNo

Türkçe

Tüm specification sınıfları ilk koşul olarak crProcessId (tenant isolation) filtresi uygular. Bu filtre olmadan veri çekilemez.


Error Codes

All error constants are defined in ServiceErrorMsgCodes.java:

Constant Message Key Context
ERROR_FIELD_REQUIRED error.field_required General
ERROR_ENTITY_NOT_FOUND error.not_found General
ERROR_INVALID_TENANT error.invalid_tenant General
ERROR_TAX_NUMBER_EXISTS error.business_partner.tax_number_exists BusinessPartner
ERROR_MUST_BE_CUSTOMER_OR_VENDOR error.business_partner.must_be_customer_or_vendor BusinessPartner
ERROR_BRANCH_NAME_EXISTS error.branch.name_exists Branch
ERROR_BRANCH_DEFAULT_EXISTS error.branch.default_exists Branch
ERROR_CONTACT_PRIMARY_EXISTS error.contact.primary_exists Contact
ERROR_CONTRACT_INVALID_DATES error.contract.invalid_dates Contract
ERROR_ACCRUAL_PERIOD_EXISTS error.accrual.period_exists Accrual
ERROR_ACCRUAL_CANNOT_UPDATE error.accrual.cannot_update Accrual
ERROR_ACCRUAL_CANNOT_DELETE error.accrual.cannot_delete Accrual
ERROR_ACCRUAL_CANNOT_APPROVE error.accrual.cannot_approve Accrual
ERROR_ACCRUAL_CANNOT_INVOICE error.accrual.cannot_invoice Accrual
ERROR_ACCRUAL_CANNOT_CANCEL error.accrual.cannot_cancel Accrual

All error codes are mapped to ErrorCodes.BPM_* enum constants in the global error code registry.


Configuration

Application Properties

Property Value Description
server.port 8020 Dev server port
server.servlet.context-path /icbpm/services Context path
spring.datasource.url jdbc:mysql://localhost:3306/icbpm Database URL
spring.jpa.hibernate.ddl-auto validate Schema validation only
jwt.expiration.ms 28800000 JWT expiry (8 hours)

CORS (Development)

cors.allowed-origins=http://localhost:8080,http://localhost:5174

Rate Limiting

Tier Requests/min
Public endpoints 60
API-Key endpoints 100
JWT endpoints 200

Package Structure

com.icom.icosys.bpm
├── (root)                          → Entity classes
├── enums/                          → Enum types
├── code/                           → CodePrefix constants
├── dto/                            → All DTO classes
└── service/
    ├── codes/                      → ServiceErrorMsgCodes
    └── zapi/
        ├── accrual/
        │   ├── controller/         → AccrualController
        │   ├── converter/          → EditDtoConverter, ListDtoConverter
        │   ├── service/            → AccrualService
        │   ├── specification/      → AccrualSpecification
        │   └── AccrualRepository
        ├── branch/                 → (same structure)
        ├── businesspartner/        → (same structure)
        ├── contact/                → (same structure)
        ├── contract/               → (same structure)
        ├── contractitem/           → (same structure)
        └── product/                → (same structure)