858 lines
33 KiB
Markdown
858 lines
33 KiB
Markdown
# Domain Model Schema (Toon Format)
|
|
|
|
> Part of `Nop.Plugin.Misc.FruitBankPlugin`. See `README.md` for project overview.
|
|
> Full domain model in Toon (Token-Oriented Object Notation) format — see `AyCode.Core/Serializers/Toons/README.md` (in AyCode.Core solution).
|
|
> This is the authoritative schema for entities, DTOs, and enums in the FruitBank domain.
|
|
> For behavioral documentation (workflows, lifecycles, event cascades) see `docs/DOMAIN_MODEL.md`.
|
|
|
|
@meta {
|
|
version = "1.0"
|
|
format = "toon"
|
|
source-code-language = "C#"
|
|
context = "This is a nopCommerce plugin developed for FruitBank, a fruit and vegetable wholesaler. The plugin manages supplier inbound delivery (receiving), warehouse weighing (net/gross/pallet/tare weights), and inventory stocktaking. The business logic is centered around FruitBank's requirement for precise physical measurement and quantity tracking."
|
|
types = ["OrderStatus", "ShippingStatus", "PaymentStatus", "GenericAttributeDto", "MeasuringStatus", "VatNumberStatus", "TaxDisplayType", "OrderNote", "PreOrderItemStatus", "PreOrderStatus", "DocumentType", "Files", "Pallet", "ProductDto", "Customer", "PreOrderItem", "PreOrder", "CargoPartner", "CargoTruck", "FullProcessModel", "OrderDto", "OrderItemDto", "OrderItemPallet", "Partner", "Shipping", "ShippingDocument", "ShippingDocumentToFiles", "ShippingItem", "ShippingItemPallet", "StockTaking", "StockTakingItem", "StockTakingItemPallet"]
|
|
}
|
|
|
|
@types {
|
|
OrderStatus: enum
|
|
underlying-type: "int"
|
|
default-value: 10
|
|
values:
|
|
Pending = 10
|
|
Processing = 20
|
|
Complete = 30
|
|
Cancelled = 40
|
|
|
|
ShippingStatus: enum
|
|
underlying-type: "int"
|
|
default-value: 10
|
|
values:
|
|
ShippingNotRequired = 10
|
|
NotYetShipped = 20
|
|
PartiallyShipped = 25
|
|
Shipped = 30
|
|
Delivered = 40
|
|
|
|
PaymentStatus: enum
|
|
underlying-type: "int"
|
|
default-value: 10
|
|
values:
|
|
Pending = 10
|
|
Authorized = 20
|
|
Paid = 30
|
|
PartiallyRefunded = 35
|
|
Refunded = 40
|
|
Voided = 50
|
|
|
|
GenericAttributeDto: "Data transfer object for GenericAttribute"
|
|
table-name: "GenericAttribute"
|
|
related-type: "dto-of GenericAttribute"
|
|
CreatedOrUpdatedDateUTC: DateTime?
|
|
EntityId: int
|
|
constraints: "polymorphic-fk(KeyGroup)"
|
|
Key: string
|
|
KeyGroup: string
|
|
StoreId: int
|
|
Value: string
|
|
purpose: "Raw string representation of the Key's value"
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
MeasuringStatus: enum
|
|
underlying-type: "int"
|
|
default-value: 0
|
|
values:
|
|
NotStarted = 0
|
|
Started = 10
|
|
Finnished = 20
|
|
Audited = 30
|
|
|
|
VatNumberStatus: enum
|
|
underlying-type: "int"
|
|
default-value: 0
|
|
values:
|
|
Unknown = 0
|
|
Empty = 10
|
|
Valid = 20
|
|
Invalid = 30
|
|
|
|
TaxDisplayType: enum
|
|
underlying-type: "int"
|
|
default-value: 0
|
|
values:
|
|
IncludingTax = 0
|
|
ExcludingTax = 10
|
|
|
|
OrderNote: "NopCommerce order note entity"
|
|
table-name: "OrderNote"
|
|
CreatedOnUtc: DateTime
|
|
DisplayToCustomer: bool
|
|
DownloadId: int
|
|
Note: string
|
|
OrderId: int
|
|
description: "Foreign key to parent Order"
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
PreOrderItemStatus: enum
|
|
underlying-type: "int"
|
|
default-value: 0
|
|
values:
|
|
Pending = 0
|
|
Fulfilled = 10
|
|
PartiallyFulfilled = 20
|
|
Dropped = 30
|
|
|
|
PreOrderStatus: enum
|
|
underlying-type: "int"
|
|
default-value: 0
|
|
values:
|
|
Pending = 0
|
|
Confirmed = 10
|
|
PartiallyFulfilled = 20
|
|
Cancelled = 30
|
|
|
|
DocumentType: enum
|
|
underlying-type: "int"
|
|
default-value: 0
|
|
values:
|
|
NotSet = 0
|
|
Unknown = 5
|
|
ShippingDocument = 10
|
|
OrderConfirmation = 15
|
|
Invoice = 20
|
|
|
|
Files: "Uploaded file with extracted text content"
|
|
table-name: "fbFiles"
|
|
purpose: "A centralized repository for all uploaded binary content and metadata, featuring a 'RawText' field that stores OCR-extracted information for full-text search and automated data validation across the system"
|
|
Created: DateTime
|
|
FileExtension: string
|
|
FileHash: string
|
|
FileName: string
|
|
FileSubPath: string
|
|
IsCompressed: bool
|
|
purpose: "Status flag"
|
|
Modified: DateTime
|
|
RawText: string
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
Pallet: "Pallet type definition with size and weight"
|
|
table-name: "fbPallet"
|
|
Created: DateTime
|
|
Modified: DateTime
|
|
Name: string
|
|
Size: string
|
|
Weight: double?
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
ProductDto: "Product data with measurements and generic attributes"
|
|
table-name: "Product"
|
|
related-type: "dto-of Product"
|
|
AvailableQuantity: int
|
|
business-logic: "get => StockQuantity + IncomingQuantity"
|
|
constraints: "readonly, not-mapped"
|
|
AverageWeight: double
|
|
business-logic: "get => GenericAttributes.GetValueOrDefault<double>('AverageWeight')"
|
|
constraints: "readonly, not-mapped"
|
|
AverageWeightTreshold: double
|
|
business-logic: "get => GenericAttributes.GetValueOrDefault<double>('AverageWeightTreshold')"
|
|
constraints: "readonly, not-mapped"
|
|
GenericAttributes: List<GenericAttributeDto>
|
|
navigation: "one-to-many"
|
|
IncomingQuantity: int
|
|
business-logic: "get => GenericAttributes.GetValueOrDefault<int>('IncomingQuantity')"
|
|
constraints: "not-mapped"
|
|
IsMeasurable: bool
|
|
purpose: "Master flag: if false, the system bypasses weight validation but still creates one Measurement Record (PalletItem) with TrayQuantity."
|
|
business-logic: "get => GenericAttributes.GetValueOrDefault<bool>('IsMeasurable')"
|
|
constraints: "not-mapped"
|
|
NetWeight: double
|
|
business-logic: "get => GenericAttributes.GetValueOrDefault<double>('NetWeight')"
|
|
constraints: "not-mapped"
|
|
Tare: double
|
|
business-logic: "get => GenericAttributes.GetValueOrDefault<double>('Tare')"
|
|
constraints: "not-mapped"
|
|
Deleted: bool
|
|
FullDescription: string
|
|
Height: decimal
|
|
Length: decimal
|
|
LimitedToStores: bool
|
|
Name: string
|
|
ParentGroupedProductId: int
|
|
Price: decimal
|
|
ProductCost: decimal
|
|
ProductTypeId: int
|
|
ShortDescription: string
|
|
StockQuantity: int
|
|
SubjectToAcl: bool
|
|
WarehouseId: int
|
|
Weight: decimal
|
|
Width: decimal
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
Customer: "NopCommerce customer entity"
|
|
table-name: "Customer"
|
|
Active: bool
|
|
AdminComment: string
|
|
AffiliateId: int
|
|
BillingAddressId: int?
|
|
CannotLoginUntilDateUtc: DateTime?
|
|
City: string
|
|
Company: string
|
|
CountryId: int
|
|
County: string
|
|
CreatedOnUtc: DateTime
|
|
CurrencyId: int?
|
|
CustomCustomerAttributesXML: string
|
|
CustomerGuid: Guid
|
|
DateOfBirth: DateTime?
|
|
Deleted: bool
|
|
Email: string
|
|
constraints: "email-format"
|
|
EmailToRevalidate: string
|
|
constraints: "email-format"
|
|
FailedLoginAttempts: int
|
|
Fax: string
|
|
FirstName: string
|
|
Gender: string
|
|
HasShoppingCartItems: bool
|
|
IsSystemAccount: bool
|
|
purpose: "Status flag"
|
|
IsTaxExempt: bool
|
|
purpose: "Status flag"
|
|
LanguageId: int?
|
|
constraints: "range: 0-150"
|
|
LastActivityDateUtc: DateTime
|
|
LastIpAddress: string
|
|
LastLoginDateUtc: DateTime?
|
|
LastName: string
|
|
MustChangePassword: bool
|
|
Phone: string
|
|
RegisteredInStoreId: int
|
|
RequireReLogin: bool
|
|
ShippingAddressId: int?
|
|
StateProvinceId: int
|
|
StreetAddress: string
|
|
StreetAddress2: string
|
|
SystemName: string
|
|
TaxDisplayType: TaxDisplayType?
|
|
TaxDisplayTypeId: int?
|
|
TimeZoneId: string
|
|
Username: string
|
|
VatNumber: string
|
|
VatNumberStatus: VatNumberStatus
|
|
VatNumberStatusId: int
|
|
VendorId: int
|
|
ZipPostalCode: string
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
PreOrderItem: "Single product line of a customer preorder with fulfilment tracking"
|
|
table-name: "fbPreOrderItem"
|
|
purpose: "A requested product line within a PreOrder. Tracks requested versus cumulatively fulfilled quantity as incoming stock is allocated across one or more shipping-document conversion runs."
|
|
FulfilledQuantity: int
|
|
purpose: "Quantity allocated from incoming stock so far; accumulates across conversion runs until it reaches RequestedQuantity."
|
|
business-logic: "this >= 0 && this <= RequestedQuantity"
|
|
PreOrderId: int
|
|
purpose: "FK to the parent PreOrder."
|
|
ProductId: int
|
|
purpose: "FK to the nopCommerce Product being preordered."
|
|
RequestedQuantity: int
|
|
purpose: "Quantity of the product the customer requested."
|
|
constraints: "positive"
|
|
Status: PreOrderItemStatus
|
|
purpose: "Item lifecycle: Pending / Fulfilled (fully allocated) / PartiallyFulfilled (partly allocated) / Dropped (expired or no incoming stock)."
|
|
business-logic: "set during conversion: FulfilledQuantity >= RequestedQuantity ? Fulfilled : FulfilledQuantity > 0 ? PartiallyFulfilled : Dropped; stays Pending until first allocation"
|
|
UnitPriceInclTax: decimal
|
|
purpose: "Gross unit price locked at preorder time. Used as the order-item price on conversion for non-measurable products; measurable products are priced 0 at conversion and weighed afterwards."
|
|
constraints: "non-negative"
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
PreOrder: "Customer advance order placed before the goods physically arrive"
|
|
table-name: "fbPreOrder"
|
|
purpose: "Header of a customer pre-order against an upcoming inbound delivery. When a supplier shipping document confirms incoming stock, pending items are allocated first-come-first-served by PreOrderId (only within the conversion window — PreOrderConversionWindowDays, 4 days, of DateOfReceipt) and the preorder is converted into a real NopCommerce Order once any quantity is fulfilled. Preorders past DateOfReceipt are swept closed, dropping any still-Pending items."
|
|
CreatedOnUtc: DateTime
|
|
CustomerId: int
|
|
purpose: "FK to the nopCommerce Customer who placed the preorder."
|
|
CustomerNote: string
|
|
purpose: "Optional free-text note entered by the customer when placing the preorder."
|
|
DateOfReceipt: DateTime
|
|
purpose: "Requested delivery date. Drives the conversion window (only preorders within PreOrderConversionWindowDays — 4 days — of this date are eligible for allocation) and the expiry sweep — once this date is past, any still-Pending items are Dropped."
|
|
OrderId: int?
|
|
purpose: "FK to the real NopCommerce Order created from this preorder. Null until the first item is fulfilled; set once on first conversion and reused so subsequent shipping documents append items to the same order."
|
|
PreOrderItems: List<PreOrderItem>
|
|
other-key: "PreOrderId"
|
|
navigation: "one-to-many"
|
|
Status: PreOrderStatus
|
|
purpose: "Header lifecycle: Pending / Confirmed (all items Fulfilled) / PartiallyFulfilled (some Dropped or partial, none left Pending) / Cancelled."
|
|
business-logic: "set by RefreshPreOrderStatusAsync from item states: items.All(Fulfilled) => Confirmed; (any Dropped or PartiallyFulfilled) && none Pending => PartiallyFulfilled; else Pending. Cancelled is set explicitly."
|
|
StoreId: int
|
|
purpose: "nopCommerce multi-store scope."
|
|
UpdatedOnUtc: DateTime
|
|
purpose: "Bumped to UtcNow on every status / allocation change."
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
CargoPartner: "Transport / haulage company (carrier) with its vehicle fleet"
|
|
table-name: "fbCargoPartner"
|
|
purpose: "A carrier that delivers goods to the warehouse and owns the CargoTrucks (both trucks and trailers). Distinct from Partner, which is the goods supplier. Name, address and tax fields are inherited from PartnerBase."
|
|
CargoTrucks: List<CargoTruck>
|
|
other-key: "CargoPartnerId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "CargoPartner"
|
|
CertificationNumber: string
|
|
City: string
|
|
Country: string
|
|
CountryCode: string
|
|
County: string
|
|
Created: DateTime
|
|
Modified: DateTime
|
|
Name: string
|
|
PostalCode: string
|
|
State: string
|
|
Street: string
|
|
TaxId: string
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
CargoTruck: "Cargo vehicle — truck or trailer — owned by a transport partner"
|
|
table-name: "fbCargoTruck"
|
|
purpose: "A single vehicle in a transport company's fleet. One table holds both tractor units and trailers, distinguished by IsTrailer. Truck and trailer are tracked as separate vehicles because Hungarian EKÁER road-freight reporting (NAV) declares the towing vehicle and the trailer as distinct entries (vehicle / vehicle2), each with its own licence plate and country code — i.e. these shipments carry an EKÁER declaration obligation."
|
|
CargoPartner: CargoPartner
|
|
foreign-key: "CargoPartnerId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "CargoTrucks"
|
|
CargoPartnerId: int
|
|
purpose: "FK to the owning transport company (CargoPartner) — the carrier, not the goods supplier."
|
|
CargoPartnerName: string
|
|
constraints: "readonly, not-mapped"
|
|
CountryCode: string
|
|
Created: DateTime
|
|
IsTrailer: bool
|
|
purpose: "Discriminates the shared table: false = tractor/truck unit, true = trailer."
|
|
LicencePlate: string
|
|
Modified: DateTime
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
FullProcessModel: "Object of type FullProcessModel"
|
|
table-name: "FullProcessModel"
|
|
purpose: "Container model for Shipping, Order"
|
|
Orders: List<OrderDto>
|
|
navigation: "one-to-many"
|
|
PreOrders: List<PreOrder>
|
|
navigation: "one-to-many"
|
|
Shippings: List<Shipping>
|
|
navigation: "one-to-many"
|
|
StockTakings: List<StockTaking>
|
|
navigation: "one-to-many"
|
|
|
|
OrderDto: "Data transfer object for Order"
|
|
table-name: "Order"
|
|
related-type: "dto-of Order"
|
|
DateOfReceipt: DateTime?
|
|
business-logic: "get => GenericAttributes.GetValueOrNull<DateTime>('DateOfReceipt')"
|
|
constraints: "readonly, not-mapped"
|
|
DateOfReceiptOrCreated: DateTime
|
|
constraints: "readonly, not-mapped"
|
|
GenericAttributes: List<GenericAttributeDto>
|
|
navigation: "one-to-many"
|
|
IsAllOrderItemAudited: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => OrderItemDtos.Count > 0 && OrderItemDtos.All(oi => oi.IsAudited)"
|
|
constraints: "readonly, not-mapped"
|
|
IsAllOrderItemAvgWeightValid: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => OrderItemDtos.All(oi => oi.AverageWeightIsValid)"
|
|
constraints: "readonly, not-mapped"
|
|
IsComplete: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => OrderStatus == OrderStatus.Complete"
|
|
constraints: "readonly, not-mapped"
|
|
IsMeasurable: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => OrderItemDtos.Any(oi => oi.IsMeasurable)"
|
|
constraints: "readonly, not-mapped"
|
|
IsMeasured: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => Id > 0 && OrderItemDtos.Count > 0 && OrderItemDtos.All(x => x.IsMeasured)"
|
|
constraints: "readonly, not-mapped"
|
|
MeasurementOwnerId: int
|
|
business-logic: "get => GenericAttributes.GetValueOrDefault('MeasurementOwnerId', 0)"
|
|
constraints: "readonly, not-mapped"
|
|
MeasuringStatus: MeasuringStatus
|
|
constraints: "readonly, not-mapped"
|
|
RevisorId: int
|
|
business-logic: "get => GenericAttributes.GetValueOrDefault('RevisorId', 0)"
|
|
constraints: "readonly, not-mapped"
|
|
TimeOfReceiptText: string
|
|
constraints: "readonly, not-mapped"
|
|
CreatedOnUtc: DateTime
|
|
CustomOrderNumber: string
|
|
CustomValuesXml: string
|
|
Customer: Customer
|
|
foreign-key: "CustomerId"
|
|
navigation: "many-to-one"
|
|
CustomerId: int
|
|
Deleted: bool
|
|
OrderDiscount: decimal
|
|
OrderGuid: Guid
|
|
OrderItemDtos: List<OrderItemDto>
|
|
other-key: "OrderId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "OrderDto"
|
|
OrderNotes: List<OrderNote>
|
|
other-key: "OrderId"
|
|
navigation: "one-to-many"
|
|
OrderStatus: OrderStatus
|
|
purpose: "Enum wrapper"
|
|
business-logic: "get, set => OrderStatusId"
|
|
OrderStatusId: int
|
|
OrderTotal: decimal
|
|
PaidDateUtc: DateTime?
|
|
PaymentStatus: PaymentStatus
|
|
purpose: "Enum wrapper"
|
|
business-logic: "get, set => PaymentStatusId"
|
|
PaymentStatusId: int
|
|
ShippingMethod: string
|
|
ShippingStatus: ShippingStatus
|
|
purpose: "Enum wrapper"
|
|
business-logic: "get, set => ShippingStatusId"
|
|
ShippingStatusId: int
|
|
StoreId: int
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
OrderItemDto: "Order item with measurements, pallets, and validation"
|
|
table-name: "OrderItem"
|
|
related-type: "dto-of OrderItem"
|
|
AverageWeight: double
|
|
business-logic: "get => IsMeasurable && OrderItemPallets.Count > 0 ? double.Round(OrderItemPallets.Sum(oip => oip.AverageWeight) / OrderItemPallets.Count, 1) : 0d"
|
|
constraints: "readonly, not-mapped"
|
|
AverageWeightDifference: double
|
|
business-logic: "get => IsMeasurable ? double.Round(ProductDto!.AverageWeight - AverageWeight, 1) : 0"
|
|
constraints: "readonly, not-mapped"
|
|
AverageWeightIsValid: bool
|
|
business-logic: "get => !IsMeasurable || (ProductDto!.AverageWeight > 0 && ((AverageWeightDifference / ProductDto!.AverageWeight) * 100) < ProductDto!.AverageWeightTreshold)"
|
|
constraints: "readonly, not-mapped"
|
|
GenericAttributes: List<GenericAttributeDto>
|
|
navigation: "one-to-many"
|
|
GrossWeight: double
|
|
business-logic: "get => double.Round(OrderItemPallets.Sum(x => x.NetWeight), 1)"
|
|
constraints: "not-mapped"
|
|
IsAudited: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => OrderItemPallets.Count > 0 && OrderItemPallets.All(oip => oip.IsAudited)"
|
|
constraints: "readonly, not-mapped"
|
|
IsMeasurable: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => ProductDto!.IsMeasurable"
|
|
constraints: "not-mapped"
|
|
IsMeasured: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => IsMeasuredAndValid()"
|
|
constraints: "not-mapped"
|
|
MeasuringStatus: MeasuringStatus
|
|
business-logic: "get => complex conditional logic based on IsAudited, IsMeasured, and OrderItemPallets status"
|
|
constraints: "readonly, not-mapped"
|
|
NetWeight: double
|
|
business-logic: "get => double.Round(OrderItemPallets.Sum(x => x.NetWeight), 1)"
|
|
constraints: "not-mapped"
|
|
OrderDto: OrderDto
|
|
foreign-key: "OrderId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "OrderItemDtos"
|
|
OrderItemPallets: List<OrderItemPallet>
|
|
other-key: "OrderItemId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "OrderItemDto"
|
|
TrayQuantity: int
|
|
business-logic: "get => OrderItemPallets.Sum(x => x.TrayQuantity)"
|
|
constraints: "not-mapped"
|
|
AttributesXml: string
|
|
ItemWeight: decimal?
|
|
OrderId: int
|
|
OrderItemGuid: Guid
|
|
PriceExclTax: decimal
|
|
PriceInclTax: decimal
|
|
ProductDto: ProductDto
|
|
foreign-key: "ProductId"
|
|
navigation: "many-to-one"
|
|
ProductId: int
|
|
ProductName: string
|
|
business-logic: "get => ProductDto?.Name ?? 'ProductDto is null!!!'"
|
|
constraints: "readonly"
|
|
Quantity: int
|
|
UnitPriceExclTax: decimal
|
|
UnitPriceInclTax: decimal
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
OrderItemPallet: "Pallet measurements for order items with audit tracking"
|
|
table-name: "fbOrderItemPallet"
|
|
purpose: "A measurement record for outgoing goods, used to verify that the net weight being sent to the customer is accurate and audited. NOTE: Despite the 'Pallet' name, this is a general measurement record that is ALWAYS created for every item. If the product is not measurable (IsMeasurable=false), weights are recorded as 0.0 and only TrayQuantity is stored."
|
|
AverageWeight: double
|
|
business-logic: "get => double.Round(NetWeight / TrayQuantity, 1)"
|
|
constraints: "readonly, not-mapped"
|
|
IsAudited: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => RevisorId > 0"
|
|
constraints: "readonly, not-mapped"
|
|
MeasuringStatus: MeasuringStatus
|
|
business-logic: "get => IsAudited ? MeasuringStatus.Audited : base.MeasuringStatus"
|
|
constraints: "readonly, not-mapped"
|
|
OrderItemDto: OrderItemDto
|
|
foreign-key: "OrderItemId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "OrderItemPallets"
|
|
OrderItemId: int
|
|
RevisorId: int
|
|
purpose: "User/Customer ID of the quality auditor"
|
|
Created: DateTime
|
|
CreatorId: int?
|
|
ForeignKey: int
|
|
business-logic: "get => ForeignItemId"
|
|
constraints: "readonly, not-mapped"
|
|
GrossWeight: double
|
|
purpose: "Measured gross weight; 0.0 if product is not measurable"
|
|
IsMeasured: bool
|
|
purpose: "Status flag"
|
|
Modified: DateTime
|
|
ModifierId: int?
|
|
NetWeight: double
|
|
business-logic: "get => GrossWeight - PalletWeight - (TrayQuantity * TareWeight)"
|
|
constraints: "readonly, not-mapped"
|
|
PalletWeight: double
|
|
purpose: "Weight of the physical pallet if used; 0.0 if goods arrive without a pallet"
|
|
TareWeight: double
|
|
TrayQuantity: int
|
|
purpose: "Always recorded, regardless of measurability"
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
Partner: "Business partner with address and tax information"
|
|
table-name: "fbPartner"
|
|
purpose: "Represents an external legal entity, specifically a Supplier who provides goods or a business partner involved in the procurement chain"
|
|
ShippingDocuments: List<ShippingDocument>
|
|
other-key: "PartnerId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "Partner"
|
|
CertificationNumber: string
|
|
City: string
|
|
Country: string
|
|
CountryCode: string
|
|
County: string
|
|
Created: DateTime
|
|
Modified: DateTime
|
|
Name: string
|
|
PostalCode: string
|
|
State: string
|
|
Street: string
|
|
TaxId: string
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
Shipping: "Shipping record with documents and measurement tracking"
|
|
table-name: "fbShipping"
|
|
purpose: "Inbound delivery event (truck arrival) at the warehouse. Created early and filled progressively — carrier, truck and trailer are assigned later."
|
|
CargoCompany: string
|
|
CargoPartner: CargoPartner
|
|
purpose: "Carrier (transport company); assigned later, null until known. Supplier is separate — see ShippingDocument.Partner."
|
|
foreign-key: "CargoPartnerId"
|
|
navigation: "many-to-one"
|
|
CargoPartnerId: int?
|
|
CargoTrailer: CargoTruck
|
|
purpose: "Trailer (CargoTruck table, IsTrailer=true); optional, assigned later — null if none or not yet known."
|
|
foreign-key: "CargoTrailerId"
|
|
navigation: "many-to-one"
|
|
CargoTrailerId: int?
|
|
CargoTruck: CargoTruck
|
|
purpose: "Tractor unit (CargoTruck, IsTrailer=false) from the carrier's fleet; assigned later, null until known."
|
|
foreign-key: "CargoTruckId"
|
|
navigation: "many-to-one"
|
|
CargoTruckId: int?
|
|
Comment: string
|
|
Created: DateTime
|
|
IsAllMeasured: bool
|
|
purpose: "Status flag"
|
|
LicencePlate: string
|
|
MeasuredDate: DateTime?
|
|
Modified: DateTime
|
|
ShippingDate: DateTime
|
|
ShippingDocuments: List<ShippingDocument>
|
|
other-key: "ShippingId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "Shipping"
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
ShippingDocument: "Shipping document with partner, items and files"
|
|
table-name: "fbShippingDocument"
|
|
purpose: "Supplier's delivery note or invoice for the shipment; reconciles paper data with measured reality. Populated progressively — much entered at order time, the rest as it becomes known."
|
|
Comment: string
|
|
Country: string
|
|
Created: DateTime
|
|
DocumentIdNumber: string
|
|
IsAllMeasured: bool
|
|
purpose: "Status flag"
|
|
Modified: DateTime
|
|
Partner: Partner
|
|
foreign-key: "PartnerId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "ShippingDocuments"
|
|
PartnerId: int
|
|
PdfFileName: string
|
|
Shipping: Shipping
|
|
foreign-key: "ShippingId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "ShippingDocuments"
|
|
ShippingDate: DateTime
|
|
ShippingDocumentToFiles: List<ShippingDocumentToFiles>
|
|
other-key: "ShippingDocumentId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "ShippingDocument"
|
|
ShippingId: int?
|
|
ShippingItems: List<ShippingItem>
|
|
other-key: "ShippingDocumentId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "ShippingDocument"
|
|
TotalPallets: int
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
ShippingDocumentToFiles: "Links shipping documents to files with document type"
|
|
table-name: "fbShippingDocumentToFiles"
|
|
purpose: "A many-to-many link table that associates general uploaded files with specific shipping documents, assigning a functional context (DocumentType) to each file, such as identifying which PDF is the supplier's invoice versus the packing list"
|
|
Created: DateTime
|
|
DocumentType: DocumentType
|
|
purpose: "Enum wrapper"
|
|
business-logic: "get, set => DocumentTypeId"
|
|
constraints: "not-mapped"
|
|
DocumentTypeId: int
|
|
constraints: "enum-reference: DocumentType, enum-type: DocumentType"
|
|
FilesId: int
|
|
Modified: DateTime
|
|
ShippingDocument: ShippingDocument
|
|
foreign-key: "ShippingDocumentId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "ShippingDocumentToFiles"
|
|
ShippingDocumentFile: Files
|
|
foreign-key: "FilesId"
|
|
navigation: "many-to-one"
|
|
ShippingDocumentId: int
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
ShippingItem: "Shipping document item with measurements and pallets"
|
|
table-name: "fbShippingItem"
|
|
purpose: "Represents a specific product line item within a shipping document, storing the discrepancy between the supplier's declared weight/quantity and the warehouse's measured values"
|
|
Created: DateTime
|
|
GrossWeightOnDocument: double
|
|
HungarianName: string
|
|
IsMeasurable: bool
|
|
purpose: "Status flag"
|
|
IsMeasured: bool
|
|
purpose: "Status flag"
|
|
MeasuredGrossWeight: double
|
|
constraints: "range: 1-100000"
|
|
MeasuredNetWeight: double
|
|
constraints: "range: 1-100000"
|
|
MeasuredQuantity: int
|
|
constraints: "range: 1-100000"
|
|
MeasuringCount: int
|
|
constraints: "range: 1-100000, non-negative"
|
|
MeasuringStatus: MeasuringStatus
|
|
business-logic: "get => complex conditional logic based on IsMeasured and ShippingItemPallets status"
|
|
constraints: "readonly, not-mapped"
|
|
Modified: DateTime
|
|
Name: string
|
|
NameOnDocument: string
|
|
NetWeightOnDocument: double
|
|
Pallet: Pallet
|
|
foreign-key: "PalletId"
|
|
navigation: "many-to-one"
|
|
PalletId: int?
|
|
PalletsOnDocument: int
|
|
ProductDto: ProductDto
|
|
foreign-key: "ProductId"
|
|
navigation: "many-to-one"
|
|
ProductId: int?
|
|
ProductName: string
|
|
business-logic: "get => ProductDto?.Name ?? Name"
|
|
constraints: "readonly, not-mapped"
|
|
QuantityOnDocument: int
|
|
ShippingDocument: ShippingDocument
|
|
foreign-key: "ShippingDocumentId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "ShippingItems"
|
|
ShippingDocumentId: int
|
|
ShippingItemPallets: List<ShippingItemPallet>
|
|
other-key: "ShippingItemId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "ShippingItem"
|
|
UnitPriceOnDocument: double
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
ShippingItemPallet: "Pallet measurements for shipping items"
|
|
table-name: "fbShippingItemPallet"
|
|
purpose: "The smallest unit of measurement tracking, representing a single physical measurement event. NOTE: Technically named 'Pallet' for legacy reasons, but it is ALWAYS created even if goods arrive without a physical pallet. For non-measurable products, weights are 0.0 and only TrayQuantity is tracked for tare-weight calculations."
|
|
ShippingItem: ShippingItem
|
|
foreign-key: "ShippingItemId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "ShippingItemPallets"
|
|
ShippingItemId: int
|
|
Created: DateTime
|
|
CreatorId: int?
|
|
ForeignKey: int
|
|
business-logic: "get => ForeignItemId"
|
|
constraints: "readonly, not-mapped"
|
|
GrossWeight: double
|
|
purpose: "Measured gross weight; 0.0 if product is not measurable"
|
|
IsMeasured: bool
|
|
purpose: "Status flag"
|
|
MeasuringStatus: MeasuringStatus
|
|
business-logic: "get => IsMeasured ? MeasuringStatus.Finnished : Id > 0 ? MeasuringStatus.Started : MeasuringStatus.NotStarted"
|
|
constraints: "readonly, not-mapped"
|
|
Modified: DateTime
|
|
ModifierId: int?
|
|
NetWeight: double
|
|
business-logic: "get => GrossWeight - PalletWeight - (TrayQuantity * TareWeight)"
|
|
constraints: "readonly, not-mapped"
|
|
PalletWeight: double
|
|
purpose: "Weight of the physical pallet if used; 0.0 if goods arrive without a pallet"
|
|
TareWeight: double
|
|
TrayQuantity: int
|
|
purpose: "Always recorded, regardless of measurability"
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
StockTaking: "Inventory session record"
|
|
table-name: "fbStockTaking"
|
|
purpose: "Orchestrates inventory sessions by freezing logical stock states"
|
|
Created: DateTime
|
|
Creator: int
|
|
IsClosed: bool
|
|
purpose: "Status flag"
|
|
Modified: DateTime
|
|
StartDateTime: DateTime
|
|
StockTakingItems: List<StockTakingItem>
|
|
other-key: "StockTakingId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "StockTaking"
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
StockTakingItem: "Line item for product reconciliation"
|
|
table-name: "fbStockTakingItem"
|
|
purpose: "Reconciles snapshot quantity with physical count to calculate final stock delta"
|
|
DisplayText: string
|
|
business-logic: "get => conditional string based on IsInvalid, IsMeasured, IsRequiredForMeasuring"
|
|
constraints: "readonly, not-mapped"
|
|
InProcessOrdersQuantity: int
|
|
purpose: "Reserved stock buffer (not yet shipped) to prevent double-deduction during closing"
|
|
IsInvalid: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => TotalOriginalQuantity < 0"
|
|
constraints: "readonly, not-mapped"
|
|
IsMeasurable: bool
|
|
purpose: "Status flag"
|
|
IsRequiredForMeasuring: bool
|
|
purpose: "Status flag"
|
|
business-logic: "get => !IsInvalid && (TotalOriginalQuantity != 0 || OriginalNetWeight != 0)"
|
|
constraints: "readonly, not-mapped"
|
|
MeasuredNetWeight: double
|
|
NetWeightDiff: double
|
|
business-logic: "get => IsMeasurable && IsMeasured ? double.Round(MeasuredNetWeight - OriginalNetWeight, 1) : 0d"
|
|
constraints: "readonly, not-mapped"
|
|
OriginalNetWeight: double
|
|
QuantityDiff: int
|
|
purpose: "Final adjustment value for Product.StockQuantity"
|
|
business-logic: "get => IsMeasured ? MeasuredStockQuantity - TotalOriginalQuantity : 0"
|
|
constraints: "readonly, not-mapped"
|
|
StockTakingItemPallets: List<StockTakingItemPallet>
|
|
other-key: "StockTakingItemId"
|
|
navigation: "one-to-many"
|
|
inverse-property: "StockTakingItem"
|
|
TotalOriginalQuantity: int
|
|
purpose: "Snapshot of total logical stock at session start"
|
|
business-logic: "get => OriginalStockQuantity + InProcessOrdersQuantity"
|
|
constraints: "readonly, not-mapped"
|
|
Created: DateTime
|
|
IsMeasured: bool
|
|
purpose: "Status flag"
|
|
MeasuredStockQuantity: int
|
|
Modified: DateTime
|
|
OriginalStockQuantity: int
|
|
Product: ProductDto
|
|
foreign-key: "ProductId"
|
|
navigation: "many-to-one"
|
|
ProductId: int
|
|
StockTaking: StockTaking
|
|
foreign-key: "StockTakingId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "StockTakingItems"
|
|
StockTakingId: int
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
|
|
StockTakingItemPallet: "Weight record for inventory item"
|
|
table-name: "fbStockTakingItemPallet"
|
|
purpose: "Granular weight-based evidence for a stock taking line item. NOTE: This record is mandatory for every inventory item. If weighing is skipped (non-measurable), it serves as a container for TrayQuantity with zeroed weight fields. The term 'Pallet' is a legacy naming convention."
|
|
StockTakingItem: StockTakingItem
|
|
foreign-key: "StockTakingItemId"
|
|
navigation: "many-to-one"
|
|
inverse-property: "StockTakingItemPallets"
|
|
StockTakingItemId: int
|
|
Created: DateTime
|
|
CreatorId: int?
|
|
ForeignKey: int
|
|
business-logic: "get => ForeignItemId"
|
|
constraints: "readonly, not-mapped"
|
|
GrossWeight: double
|
|
purpose: "Measured gross weight; 0.0 if product is not measurable"
|
|
IsMeasured: bool
|
|
purpose: "Status flag"
|
|
MeasuringStatus: MeasuringStatus
|
|
business-logic: "get => IsMeasured ? MeasuringStatus.Finnished : Id > 0 ? MeasuringStatus.Started : MeasuringStatus.NotStarted"
|
|
constraints: "readonly, not-mapped"
|
|
Modified: DateTime
|
|
ModifierId: int?
|
|
NetWeight: double
|
|
business-logic: "get => GrossWeight - PalletWeight - (TrayQuantity * TareWeight)"
|
|
constraints: "readonly, not-mapped"
|
|
PalletWeight: double
|
|
purpose: "Weight of the physical pallet if used; 0.0 if goods arrive without a pallet"
|
|
TareWeight: double
|
|
TrayQuantity: int
|
|
purpose: "Always recorded, regardless of measurability"
|
|
Id: int
|
|
purpose: "Primary key / unique identification"
|
|
primary-key: true
|
|
}
|