QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142) getrackt, ohne .gitmodules und ohne erreichbares Remote. Der Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen. Umstellung: - Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6) - Gitlink aus dem Index entfernt - Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
18 KiB
Receipts Backend Architecture
This document describes the generic architecture and components of the receipts system in the c-entron.NET backend, which provides a unified foundation for all receipt types including offers, orders, delivery lists, invoices, contracts, and credit vouchers.
Overview
The receipts system follows a layered architecture pattern with a shared base implementation that is extended by specific receipt types. All receipt types inherit from common base classes and share fundamental operations while providing specialized functionality through their own business logic classes.
Core Components
Entity Layer
ReceiptBase Abstract Class
Location: src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs
The ReceiptBase abstract class serves as the foundation for all receipt entities in the system. It inherits from BaseEntity and implements the IReceiptBase interface.
Key Properties:
- Receipt Header Information: Number, Date, Version, State, Editor
- Branch Information: BranchI3D, BranchOrigin
- Currency Information: CurrencyI3D, CurrencyFactor, CurrencyString, ExclusiveOfVAT
- Contact Information: Receiver, Phone, Fax, Email
- Address Information: AddressI3D, ContactPersonI3D, Street, PostOfficeBox, Zip, City, ContactName, CountryI3D
- Audit Fields: CreatedByI3D, CreatedAt, ChangedByI3D, ChangedAt, Application Version tracking
- System Fields: ConcurrencyControlGuid, CustomUpdateArticlePricesAndTexts
Abstract Methods:
ReceiptKind: Returns the specific receipt type (CentronObjectKindNumeric)GetReceiptItems(): Returns all receipt itemsSetReceiptItems(): Sets receipt items collectionAddItem(): Adds a new item to the receiptRemoveItem(): Removes an item from the receipt
Receipt Types Hierarchy
All receipt types extend ReceiptBase and follow a consistent pattern of entity classes, database tables, and views:
| Receipt Type | Entity Class | Database Table | Database View | Items Table | Items View |
|---|---|---|---|---|---|
| Offers | ReceiptOffer |
AngKopf |
Offers |
AngPos |
OfferItems |
| Orders | ReceiptOrder |
AufKopf |
Orders |
AufPos |
OrderItems |
| Delivery Lists | ReceiptDeliveryList |
LiefKopf |
DeliveryLists |
LiefPos |
DeliveryListItems |
| Invoices | ReceiptInvoice |
RechKopf |
Invoices |
RechPos |
InvoiceItems |
| Contracts | ReceiptContract |
VertragKopf |
Contracts |
VertragPos |
ContractItems |
| Credit Vouchers | ReceiptCreditVoucher |
GutKopf |
CreditVouchers |
GutPos |
CreditVoucherItems |
| Pickup Lists | ReceiptPickupList |
AbholKopf |
PickupLists |
AbholPos |
PickupListItems |
Entity Locations:
src/backend/Centron.Entities/Entities/Sales/Receipts/Offers/ReceiptOffer.cssrc/backend/Centron.Entities/Entities/Sales/Receipts/Orders/ReceiptOrder.cssrc/backend/Centron.Entities/Entities/Sales/Receipts/DeliveryLists/ReceiptDeliveryList.cssrc/backend/Centron.Entities/Entities/Sales/Receipts/Invoices/ReceiptInvoice.cssrc/backend/Centron.Entities/Entities/Sales/Receipts/ContractLists/ReceiptContract.cssrc/backend/Centron.Entities/Entities/Sales/Receipts/CreditVouchers/ReceiptCreditVoucher.cssrc/backend/Centron.Entities/Entities/Sales/Receipts/PickupLists/ReceiptPickupList.cs
Database Schema
Dual Layer Architecture: Tables and Views
The receipts system uses a dual-layer database architecture consisting of legacy tables and modern views. This design maintains backward compatibility while providing cleaner interfaces for the C# application.
Legacy Tables (German Names)
The original database tables use German naming conventions and contain historical structure:
*Header Tables (Kopf):
AngKopf- Offer headersAufKopf- Order headersLiefKopf- Delivery list headersRechKopf- Invoice headersVertragKopf- Contract headersGutKopf- Credit voucher headersAbholKopf- Pickup list headers
*Position Tables (Pos):
AngPos- Offer itemsAufPos- Order itemsLiefPos- Delivery list itemsRechPos- Invoice itemsVertragPos- Contract itemsGutPos- Credit voucher itemsAbholPos- Pickup list items
*Version Tables (Versions): Each receipt type maintains version history through dedicated version tables:
AngKopfVersions/AngPosVersions- Offer version historyAufKopfVersions/AufPosVersions- Order version historyLiefKopfVersions/LiefPosVersions- Delivery list version historyRechKopfVersions/RechPosVersions- Invoice version historyVertragKopfVersions/VertragPosVersions- Contract version historyGutKopfVersions/GutPosVersions- Credit voucher version historyAbholKopfVersions/AbholPosVersions- Pickup list version history
Modern Views (English Names)
For C# application compatibility, cleaner views with English names are used:
Header Views:
Offers- Clean view of AngKopfOrders- Clean view of AufKopfDeliveryLists- Clean view of LiefKopfInvoices- Clean view of RechKopfContracts- Clean view of VertragKopfCreditVouchers- Clean view of GutKopfPickupLists- Clean view of AbholKopf
Item Views:
OfferItems- Clean view of AngPosOrderItems- Clean view of AufPosDeliveryListItems- Clean view of LiefPosInvoiceItems- Clean view of RechPosContractItems- Clean view of VertragPosCreditVoucherItems- Clean view of GutPosPickupListItems- Clean view of AbholPos
Version Views:
OfferVersions/OfferItemVersions- Offer version viewsOrderVersions/OrderItemVersions- Order version viewsDeliveryListVersions/DeliveryListItemVersions- Delivery list version viewsInvoiceVersions/InvoiceItemVersions- Invoice version viewsContractVersions/ContractItemVersions- Contract version viewsCreditVoucherVersions/CreditVoucherItemVersions- Credit voucher version viewsPickupListVersions/PickupListItemVersions- Pickup list version views
Shared Logging Infrastructure
AnlageLog Table
Purpose: Centralized logging for all receipt types
Structure: Shared table with receipt type differentiation
Key Columns:
AnlageI3D- References the specific receipt's I3DAnlageArt- Receipt type identifier (corresponds to ObjectKind)- Log entry details and timestamps
AnlageArt Values:
1= Offer2= Order3= Delivery List4= Invoice5= Pickup List6= Credit Voucher22= Contract
This pattern (ObjectI3D + ObjectKind / AnlageI3D + AnlageArt) is used throughout the system for shared references across different entity types.
Schema Maintenance
Version Tables: 1:1 Copies of Original Tables
Critical Requirement: Version tables (*KopfVersions, *PosVersions) are exact 1:1 copies of their corresponding original tables. This means every column that exists in the base table must also exist in the version table with identical structure and data types.
Version Table Structure:
- Contains all columns from the original table
- Excludes certain system columns (I3D, OriginalI3D)
- Adds
OriginalI3Dcolumn to reference the original record - Adds
KopfVersionsI3Dcolumn (for *Pos version tables) to reference the header version
Versioning Implementation Example:
The versioning mechanism (as seen in AssetHeadDAO.SaveAssetVersion) works by:
-- Copy header record to version table
INSERT INTO AngKopfVersions (all_columns_except_I3D, OriginalI3D)
SELECT all_columns_except_I3D, I3D AS OriginalI3D
FROM AngKopf
WHERE I3D = @receiptId
-- Copy all item records to version table
INSERT INTO AngPosVersions (all_columns_except_I3D, OriginalI3D, KopfVersionsI3D)
SELECT all_columns_except_I3D, I3D AS OriginalI3D, @headerVersionId AS KopfVersionsI3D
FROM AngPos
WHERE AngKopfI3D = @receiptId
Adding New Columns - Complete Checklist
When adding new columns to receipts, all of the following must be updated:
- Base Table: Add column to the legacy table (e.g.,
AngKopf) - Version Table: Add the identical column to the version table (e.g.,
AngKopfVersions) - Update Views: Modify both the main view (e.g.,
Offers) and version view (e.g.,OfferVersions) to include the new column - Entity Classes: Add the property to the C# entity class (e.g.,
ReceiptOffer) and version entity if applicable - Mapping Classes: Update NHibernate mapping classes for ORM functionality
- Temporary Legacy Entities: Add the property to the matching
*Kopf/*Postemporary entity undersrc/backend/Centron.Entities/Entities/DbEntities/ - Temporary Entity Mappings: Add the mapping to the matching class under
src/backend/Centron.DAO/Mappings/TemporaryEntities/ - SaveReceipt Repository: Copy the value in the receipt-type-specific
SaveReceipt*Repository(SynchronizeReceiptDatafor header fields,SynchronizeReceiptItemDatafor item fields) - DTOs and Interfaces: Add the property to webservice DTOs and relevant receipt interfaces when the value crosses BL/WebService/UI boundaries
- Version Views: Ensure version views (
OfferVersions,OfferItemVersions) include the new column
⚠️ Critical Warning: Forgetting to add a column to the version table will cause runtime errors when the versioning system attempts to copy records. The DoGetFieldList() method dynamically generates field lists, so missing columns in version tables will break the INSERT statements.
Critical Save Warning: The normal NHibernate receipt entity mapping is not the only persistence path. Receipt saves go through legacy SaveReceipt*Repository classes, which synchronize the modern receipt entities into temporary legacy table entities (RechKopf, RechPos, LiefKopf, LiefPos, etc.) before writing to the database. If a new field is only added to the modern entity/view mapping but not to the temporary entity, temporary mapping, and SaveReceipt*Repository, the value may load correctly from the view but will not be persisted on save.
Version Table Maintenance Process
**For Header Tables (Kopf → KopfVersions):
- Add column to base table:
ALTER TABLE AngKopf ADD NewColumn datatype - Add identical column to version table:
ALTER TABLE AngKopfVersions ADD NewColumn datatype - Update corresponding views to include the new column
**For Item Tables (Pos → PosVersions):
- Add column to base table:
ALTER TABLE AngPos ADD NewColumn datatype - Add identical column to version table:
ALTER TABLE AngPosVersions ADD NewColumn datatype - Update corresponding views to include the new column
This strict 1:1 correspondence ensures that the automatic versioning system (AssetHeadDAO.SaveAssetVersion and similar methods) can create complete snapshots of receipt states for audit trails and change tracking.
Business Logic Layer
ReceiptBL - Core Business Logic
Location: src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs
The ReceiptBL class provides the central business logic for all receipt operations. It contains over 10,000 lines of code handling comprehensive receipt management functionality.
Key Responsibilities:
- CRUD Operations: Generic methods for loading, searching, and saving receipts
- Receipt Processing: State management, workflow processing, validation
- Item Management: Adding, updating, removing receipt items
- Price Calculations: Tax calculations, discounts, currency conversions
- Document Generation: PDF generation, printing, email sending
- Integration: Connection with accounting systems, warehousing, customer management
- Workflow Management: Approval processes, state transitions
- Reporting: Export functionality (Excel, PDF)
Core Methods:
GetReceiptByI3D<T>(int receiptI3D): Generic receipt retrievalGetReceipts<T>(IReceiptFilter filter): Search receipts with filteringSaveReceipt<T>(T receipt): Generic receipt savingDeleteReceipt(int receiptI3D, CentronObjectKindNumeric receiptKind): Receipt deletionExportReceiptToExcel(): Excel export functionality
SpecificLogics Pattern
The ReceiptBL utilizes a SpecificLogics helper class that delegates specialized operations to receipt-type-specific business logic classes:
- ContractSpecificLogic for contracts
- InvoiceSpecificLogic for invoices
- OrderSpecificLogic for orders
- And similar classes for other receipt types
Data Access Layer
Repository Pattern
Each receipt type has its own repository for data persistence:
- SaveReceiptContractRepository →
VertragKopf&VertragPostables - SaveReceiptInvoiceRepository →
RechKopf&RechPostables - SaveReceiptOfferRepository →
AngKopf&AngPostables - SaveReceiptOrderRepository →
AufKopf&AufPostables - SaveReceiptDeliveryListRepository →
LiefKopf&LiefPostables - SaveReceiptCreditVoucherRepository →
GutKopf&GutPostables - SaveReceiptPickupListRepository →
AbholKopf&AbholPostables - And similar repositories for supplier receipt types
These repositories are a legacy persistence layer between the normal NHibernate receipt entities and the database. They create or update temporary table entities and explicitly assign many properties. When adding a persisted receipt header or item field, update the repository method that synchronizes that level:
- Header field:
SynchronizeReceiptData(...) - Item field:
SynchronizeReceiptItemData(...)
Do not rely on AutoMapper or the modern NHibernate entity mapping for this save path. End-to-end tests are the preferred safety net for new receipt fields because they execute the database script, save through ReceiptWebServiceBL.SaveReceipt(...), reload the receipt, and can assert the raw legacy table values.
Database Table Structure
All receipt types follow a consistent two-table pattern:
*Header Tables (Kopf):
- Contains receipt-level information (customer, dates, totals, etc.)
- Inherits from
ReceiptTablebase structure - Primary key:
I3D(identity column) - Common audit fields: CreatedAt, ChangedAt, CreatedByI3D, ChangedByI3D
*Position Tables (Pos):
- Contains individual line items/positions
- Foreign key reference to header table (*KopfI3D)
- Article information, quantities, prices, and item-specific data
- Primary key:
I3D(identity column) - Position number:
Pos(for ordering)
Common Workflows
Receipt Creation Process
- Initialize Receipt Entity - Create new receipt instance with default values
- Set Header Information - Customer, addresses, dates, currency
- Add Receipt Items - Products/services with quantities and prices
- Calculate Totals - Tax calculations, discounts, final amounts
- Validate Business Rules - Check inventory, credit limits, etc.
- Save to Database - Persist header and position records
- Generate Document - Create PDF, send emails if required
Receipt State Management
Receipts progress through defined states:
- Draft - Initial creation, can be freely modified
- Released - Approved for processing, limited modifications
- Processed - Finalized, minimal changes allowed
- Cancelled - Marked as cancelled, read-only
Item Management
- Dynamic Item Addition - Items can be added at any time during draft state
- Price Calculation - Automatic recalculation of totals when items change
- Inventory Integration - Real-time stock checking and updates
- Article Linking - Connection to master article data
Integration Points
Customer Management
- Customer data integration for addresses and contact information
- Credit limit checking and payment term assignment
- Customer-specific pricing and discount structures
Inventory System
- Real-time stock level checking
- Automatic inventory updates on receipt processing
- Serial number and barcode tracking
Accounting System
- Automatic journal entry generation
- Tax calculation and reporting
- Integration with financial reporting systems
Document Management
- PDF generation for all receipt types
- Email delivery capabilities
- Document archiving and retrieval
Extensibility
Adding New Receipt Types
To add a new receipt type:
- Create Entity Classes - Header and position entities extending base classes
- Implement Business Logic - Specific BL class with type-specific operations
- Create Database Tables - Following the *Kopf/*Pos naming convention
- Add Repository Classes - For data persistence operations
- Register with SpecificLogics - Enable integration with core ReceiptBL
Customization Points
- Custom Fields - Additional properties on receipt entities
- Business Rules - Custom validation and processing logic
- Workflow Extensions - Additional states and transitions
- Integration Hooks - Custom external system connections
Performance Considerations
Database Optimization
- Indexed Foreign Keys - All *KopfI3D references are indexed
- Pagination Support - Large result sets handled via paging
- Query Optimization - Efficient queries for common operations
Memory Management
- Lazy Loading - Receipt items loaded on demand
- Batch Operations - Bulk processing for multiple receipts
- Caching Strategy - Frequently accessed data cached appropriately
Security
Access Control
- User-based Permissions - Role-based access to receipt functions
- Branch Isolation - Users can only access receipts from their branches
- Audit Trail - Complete tracking of all receipt changes
Data Protection
- Concurrency Control - GUID-based optimistic locking
- Data Validation - Input validation and sanitization
- Transaction Management - ACID compliance for all operations
Best Practices
Development Guidelines
- Use Generic Methods - Leverage ReceiptBL generic operations where possible
- Follow Inheritance Patterns - Extend base classes rather than duplicating code
- Implement Proper Error Handling - Use try-catch blocks and meaningful error messages
- Maintain Audit Trails - Always populate CreatedBy/ChangedBy fields
Testing Considerations
- Unit Tests - Test business logic methods in isolation
- Integration Tests - Test complete receipt workflows
- Database Tests - Verify data persistence and retrieval
- Performance Tests - Ensure acceptable response times under load