Skip to main content

Kandra.Forms

Kandra.Forms.Accounting.AccountSubcontoSlotDto

One subconto slot declaration on a leaf account (Kandra.Domain.Accounting.SubcontoSlotDeclaration) - a declared TYPE, not a resolved value (there's no posted transaction here). A composite ("OneOf") slot has more than one MemberTypes entry, e.g. account 68's slot 2 (Waybill/GoodsReceipt) - never flattened away, or the OR structure of the declaration is lost.

Kandra.Forms.Accounting.AccountSubcontoTypeDto

One acceptable CLR type for a subconto slot. TypeId matches the same Guid ISubcontoResolutionService/ AccountTransactionsService use to key resolved subconto VALUES elsewhere, so a consumer can correlate a slot declaration here with a resolved SubcontoValueDto. TypeCaptionKey/TypeCaptionIsLiteral is the same resolved-client-side pair as SubcontoValueDto (unlike ChartOfAccountsNodeDto.Name above, which is baked server-side) - this is the Account Transactions viewer's own caption technology, reused as-is.

Properties

PropertyDescription
KindDictionary/Document/Enum/Other - see SubcontoKind's own doc comment.

Kandra.Forms.Accounting.AccountTransactionRowDto

One posted ledger row (both sides of an elementary posting - see Kandra.Domain.Accounting.PostingTransactionRecord). Unlike a register-transactions row (Kandra.Forms.Registers.RegisterTransactionRowDto), there is no shared per-reader field "shape" to hoist metadata into - the subconto set on each side depends on which account this specific row posted to, so every SubcontoValueDto is fully self-describing instead.

Properties

PropertyDescription
DestinationSubcontoundocumented
SourceSubcontoundocumented

Kandra.Forms.Accounting.ChartOfAccountsNodeDto

One node in the chart-of-accounts tree (folder or leaf). The whole chart is returned as a single eagerly-nested payload in one call (see Kandra.Application.Abstractions.Services. IChartOfAccountsTreeService) rather than the flat/lazy-per-level shape hierarchical dictionaries use (Kandra.Forms.Dictionaries.HierarchicalLookupItemDto) - the whole in-memory chart is a few dozen nodes rebuilt once per process (Kandra.Domain.Accounting.ChartOfAccounts), so per-level round-trips would be pure ceremony. There is no Guid Id: an AccountNode's identity is its AccountCode (see Code below), so account selector components bind by that string, not by Guid like every other selector.

Properties

PropertyDescription
ChildrenEmpty for a leaf.
CodeDot-joined account code, e.g. "68" or "28.1" (Kandra.Domain.Accounting.AccountCode.ToString()/ .Parse()) - the whole identity of this node.
NamePre-localized display name, baked server-side (IsLiteral ? Name : localizer[Name]) - mirrors AccountTransactionsService's own convention for AccountNode display names.
SubcontoEmpty for a folder. 0-5 entries (AccountLeafBase.MaxSubconto), one per declared subconto slot in AccountLeafBase.SubcontoSlots order.

Kandra.Forms.Accounting.SubcontoEnumValues<T0>

Guid <-> enum-member resolution for a subconto-backing enum (one decorated with [SubcontoId] per member, e.g. CostingMethod), for anything that needs to bind a Guid to one of these members without pulling in Kandra.Domain.Accounting.EnumSubconto<TEnum> (server-only). Static generic class - per-closed-TEnum cache, same trick EnumSubconto<TEnum> itself already documents. Deliberately a separate, independent implementation of the same small reflection snippet EnumSubconto<TEnum>.ResolveValueIds() uses, rather than a shared refactor - avoids adding a Kandra.Domain -> Kandra.Forms reference for a UI-only concern.

Kandra.Forms.Accounting.SubcontoValueDto

One resolved subconto (analytical dimension) value - self-describing (carries its own type caption) since, unlike a register field, there is no shared per-reader metadata list this could be correlated against by PropertyName. Reference/FormattedValue are mutually exclusive, mirroring Kandra.Forms.Registers.RegisterFieldValueDto's own convention: Reference is set for a dictionary-kind subconto (Item/Counterparty/Warehouse/...), FormattedValue for a document-kind one (Waybill/ GoodsReceipt/...) - documents have no Name property, so Kandra.DtoCommon.Printing.CodeNameRef doesn't fit them; FormattedValue is server-pre-formatted instead (e.g. "GR.26000123 (02.09.2026)").

Kandra.Forms.Blobs.BlobReferenceAdminViewDto

Kandra.Forms.Blobs.BlobReferenceMetadataDto

Kandra.Forms.Blobs.BlobReferenceSearchQueryDto

Kandra.Forms.Blobs.BlobUploadResultDto

Kandra.Forms.ChangeTracking.ChangeEventEntryDto

Kandra.Forms.ChangeTracking.ChangeEventQueryDto

Kandra.Forms.ChangeTracking.ChangeHistoryEntryDto

Kandra.Forms.ChangeTracking.ChangeStateDto

Kandra.Forms.Constants.ConstantHistoryEntryDto

One row for a single constant, as returned by ConstantsController.GetHistoryAsync.

Properties

PropertyDescription
DateThe row's effective instant - see ConstantSummaryDto.SetAt's doc comment.
IdThe row's own id - pass this to the admin API's delete endpoint (not Date, which is a real instant now and needlessly fragile to round-trip through a URL).
ValueJsonThe bare value's JSON, unwrapped the same way as ValueJson.
ValueKindSame per-constant classification as ValueKind - repeated on every row so the client can open an edit-in-place dialog straight from a history row, without a second round trip to look up the constant's declared value type.

Kandra.Forms.Constants.ConstantSummaryDto

One declared constant's current effective value, as returned by the admin Constants list (ConstantsController.GetAllAsync). Every [KandraConstant] class known to IConstantRegistry appears here, even ones never overridden in the database.

Properties

PropertyDescription
HasFutureOverrideTrue when at least one row exists dated after now - a value already scheduled to take effect later, which would otherwise be entirely invisible from this row (its own ValueJson/SetAt only ever reflect what's effective right now). Check the History dialog for the scheduled row(s).
IdThe backing row's id when IsOverridden is true (null otherwise) - edit this exact row via the id-keyed update endpoint rather than re-deriving SetAt.
IsOverriddenFalse when nothing has ever been written for this constant - ValueJson is then the compiled default from the constant's own descriptor class.
SetAtThe exact instant ValueJson's row took effect from. Null when IsOverridden is false. A genuine UTC instant (not day-truncated) - the client's shared UtcToLocalDateTimeJsonConverter is exactly right for this, converting it to the viewer's own local time for display.
ValueJsonThe bare value's JSON (e.g. "UAH", 4.5, true) - never the {"Value": ...} storage envelope, which the controller unwraps before mapping.

Kandra.Forms.Constants.ConstantValueKind

Coarse classification of a constant's declared value type (Constant<T>'s T) - lets a UI pick an appropriate input control (text box, numeric field, switch, date picker) without needing Type to cross the wire. Resolved server-side (ConstantsController) from IConstantRegistry's ValueType metadata.

Fields

FieldDescription
OtherAny other declared value type - not a real shape in this codebase today, kept as a forward-compatible fallback so a new constant value type never breaks classification. Rendered as a plain JSON text box.

Kandra.Forms.Constants.SetConstantValueDto

Request body for ConstantsController's PUT endpoint.

Properties

PropertyDescription
DateEffective instant for this value; defaults to now when omitted. A genuine UTC instant (not day-truncated) - the client must set Kind = DateTimeKind.Utc on an already-correctly-computed value before sending, or the shared UtcToLocalDateTimeJsonConverter will (mis)treat it as local time needing conversion. See ConstantEditDialog.razor's effective-date computation.
ValueJsonThe bare value's JSON (e.g. "UAH", 4.5, true) - the controller wraps it into the {"Value": ...} storage envelope via IConstantsManageService.SetRawAsync.

Kandra.Forms.Constants.UpdateConstantValueDto

Request body for ConstantsController's id-keyed value-update endpoint - deliberately carries no date/instant field, since this path never touches a row's effective instant (see IConstantsManageService.UpdateValueAsync's doc comment for why).

Properties

PropertyDescription
ValueJsonThe bare value's JSON (e.g. "UAH", 4.5, true) - the controller wraps it into the {"Value": ...} storage envelope via IConstantsManageService.UpdateValueAsync.

Kandra.Forms.DataProcessors.IDataProcessorInputDto

Kandra.Forms.DataProcessors.IDataProcessorResultDto

Kandra.Forms.Dictionaries.HierarchicalLookupItemDto

Kandra.Forms.Dictionaries.HierarchicalLookupMode

Fields

FieldDescription
AllFoldersundocumented
AllLeavesundocumented
Breadcrumbsundocumented
Childrenundocumented
FoldersUnderIdundocumented
LeavesUnderIdundocumented
Selfundocumented
Subtreeundocumented
SubtreeExcludingSelfundocumented

Kandra.Forms.Dictionaries.IHierarchicalLookupItemDto

Kandra.Forms.Dictionaries.ILookupItemDto

Kandra.Forms.Dictionaries.LookupItemDto

Kandra.Forms.Documents.DocumentLookupItemDto

Kandra.Forms.Handlers.EmptyHandlerDto

Reusable "no meaningful payload" DTO — usable as either TIn or TOut for a handler that doesn't need one.

Kandra.Forms.Handlers.IHandler<T0, T1>

Marker contract a document/dictionary/report's own handler-marker type implements, e.g. sealed class PriceLookupHandler : IHandler<PriceLookupRequestDto, PriceLookupResponseDto> — the closed TIn/TOut are what the discovering generator reads off this interface. The handler's name (the DI key its backend IHandlerBehavior<TIn,TOut> is registered under, and the literal route segment api/v1/handlers/{Name} the generated controller exposes) lives solely on the [KandraHandler(Name = "...")] attribute — not duplicated here as an interface member, since the generator can only read it from attribute metadata anyway (see HandlerDiscovery). The marker type also carries whatever static FillRequestFrom/ApplyResponseTo overloads make sense for the documents that call it — not part of this interface either, since their signatures are document-specific.

Kandra.Forms.Handlers.ILocalHandler

Marker contract for a UI-only handler — a named class that recomputes a value on an already-in-memory Dto (and optionally a line), with no backend leg at all: no request/response DTO, no IHandlerBehavior, no generated controller, no Refit client. Unlike IHandler there's no TIn/ TOut to deduce — a local handler isn't a wire contract, so the interface stays a pure, member-less marker. The concrete class's HandleAsync (and any helper methods it needs) are plain static methods with whatever call-site-specific signature/overloads make sense — same rule IHandler already applies to FillRequestFrom/ApplyResponseTo, taken one step further since there isn't even a fixed HandleAsync(TIn,...) shape to conform to. The class is decorated with [KandraLocalHandler(Name = "...")]Name is enforced unique by the same generator pass that enforces uniqueness for [KandraHandler], for consistency with that requirement (a Dto property's [HandlerTrigger] attribute references the handler by Type, not by this name).

Kandra.Forms.IEntityDto

Kandra.Forms.Linking.DocumentLinkRowDto

One resolved link row - the other entity's side only (the viewer already knows which document it's looking at). Same self-describing-type-caption shape as Kandra.Forms.Accounting.SubcontoValueDto, deliberately reused rather than inventing a second convention for "a typed entity reference plus a display caption".

Properties

PropertyDescription
LineIdundocumented
Referenceundocumented

Kandra.Forms.Linking.DocumentLinksDto

Both directions of a document's Document Links, for the generated View page's Links tab (see docs on IDocumentLinkService.GetLinksAsync).

Properties

PropertyDescription
LinksFromundocumented
LinksToundocumented

Kandra.Forms.Other.InterfaceDto

The full tree returned by GET api/v1/interfaces/{name}.

Kandra.Forms.Other.InterfaceNodeDto

Properties

PropertyDescription
ChildrenSet for Folder, empty for Link.
HrefSet for Link, null for Folder.

Kandra.Forms.Other.InterfaceNodeDtoKind

On the wire, an Entity/Special/Link node (server-side Kandra.Application.Abstractions. Navigation.InterfaceNodeKind) is already fully resolved down to a plain link - the client never needs to know which of those three it originally was, only that it's a leaf with an Href. Only Folder-vs-leaf actually changes how the client renders a node (MudNavGroup vs MudNavLink).

Kandra.Forms.Other.InterfaceSummaryDto

One entry of GET api/v1/interfaces - just enough to list/switch between the Interfaces the current user can see. TitleKey is a resource key (or a literal when TitleIsLiteral is set), resolved client-side with the live IStringLocalizer, same as every other nav caption in the app.

Kandra.Forms.Printable.PrintFormBase

Base for print-form DTOs — a plain, inert data shape, no rendering behavior.

Kandra.Forms.Printable.PrintFormLineBase

Base for a print-form's tabular part line — a plain, inert data shape, no rendering behavior.

Kandra.Forms.Printing.DocumentExportRequest

Properties

PropertyDescription
Formatundocumented
LayoutTagundocumented

Kandra.Forms.Printing.ReportExportRequest<T0>

Properties

PropertyDescription
LayoutTagundocumented

Kandra.Forms.Querying.DateRangeDto

A reusable From/To date range, for any query/filter Dto property that needs one.

Kandra.Forms.Querying.DictionaryQueryDto

Properties

PropertyDescription
Idundocumented
Idsundocumented

Kandra.Forms.Querying.DocumentQueryDto

Properties

PropertyDescription
Idundocumented

Kandra.Forms.Querying.HierarchicalDictionaryQueryDto

Properties

PropertyDescription
Modeundocumented

Kandra.Forms.Registers.DocumentRegisterTransactionsDto

Every register a Document type is declared to touch (via [RegisterTransactions] on its Behavior), each carrying its own resolved movement/document-info-record rows for one document instance. Empty for a Document with no [RegisterTransactions] attributes — not an error, just "nothing to show".

Kandra.Forms.Registers.RegisterFieldKind

How a register transactions viewer field should be rendered — resolved server-side (dimension classification walks the register's Dimensions/Resources/Details CLR shape), consumed purely as data client-side (no client-side type inspection needed to pick a rendering).

Fields

FieldDescription
DictionaryGuid FK resolved to a Dictionary entity — the row's matching Reference is populated.
DocumentGuid FK resolved to a Document entity — reference-value resolution not implemented yet, renders as an unresolved Guid.
DynamicReference[ReferenceOf(TypeIdProperty = ..., PossibleTypes = ...)] — the target type varies per row, identified at read time by a sibling TypeId property elsewhere on the same register row. Resolves to Reference (Dictionary candidate) or DocumentReference (Document candidate), never both.
UserGuid FK resolved to the Identity user entity — reference-value resolution not implemented yet, renders as an unresolved Guid.

Kandra.Forms.Registers.RegisterFieldMetaDto

One Dimensions/Resources/Details column's display metadata — shared by every row of the owning RegisterTransactionsDto.

Properties

PropertyDescription
ReferencedTypeIdSet only when Kind is Dictionary or Document — the referenced CLR type's IEntityWithTypeId.TypeId.

Kandra.Forms.Registers.RegisterFieldValueDto

One field's value on one RegisterTransactionRowDto, correlated to its RegisterFieldMetaDto by PropertyName.

Properties

PropertyDescription
DocumentReferenceSet for a DynamicReference field resolved to a Document candidate — see Kind.
FormattedValuePre-formatted server-side (Kandra.Printing.PrintValueFormatter.Format) — null when Reference is set instead.
ReferenceSet for a Dictionary-kind field, or a DynamicReference field resolved to a Dictionary candidate — see Kind.
TypeCaptionKeySet only for a DynamicReference field (the resx key naming which of its declared PossibleTypes this row actually resolved to, e.g. "GoodsReceipt" — same convention Kandra.Persistence.Abstractions. Accounting.ResolvedSubconto.TypeCaptionKey already uses: the CLR type's own simple name, always a resx key, never a literal). Null for every other Kind, including a static Dictionary/Document field — those already say what they reference via their own column caption.

Kandra.Forms.Registers.RegisterTransactionRowDto

One register movement/document-info-record row, resolved for display.

Properties

PropertyDescription
IsExpenseNull for DocumentInfoRecord-family rows — the concept only exists on Movement rows.

Kandra.Forms.Registers.RegisterTransactionsDto

One register's resolved movement/document-info-record rows for one document instance, plus the field metadata (captions/kinds) needed to render them without the client knowing this register's CLR shape.

Properties

PropertyDescription
RegisterNameStable/internal register row type name, e.g. "InventoryMovement" — not localized, not shown as-is.
ResourcesEmpty for a DocumentInfoRecord-family register (Resources only exist on Movement rows).

Kandra.Forms.Reports.ICustomAggregate

Contract for a report-line-specific custom group-footer aggregate - the counterpart to ILocalHandler for aggregates (same "attribute references by Type, implementation is a plain static-method class, no DI" shape). Implementations live alongside the report line Dto they aggregate (referenced by [Aggregate(CustomAggregateType = typeof(...))] on one of its properties) and are invoked via a direct static generic call at the generated column's emission site, not through the interface - the interface only enforces the contract shape at the implementing class's declaration. format is the column's own [Format] string (e.g. "N3"), passed through so the aggregate's own computed value renders with the same format as the column's individual cells instead of a hardcoded one - null when the column carries no [Format].

Kandra.Forms.Reports.IReportFiltersDto

Kandra.Forms.Reports.IReportResultDto

Properties

PropertyDescription
CacheTagundocumented

Kandra.Forms.Reports.IReportResult<T0, T1>

Splits the technical envelope (Filters/CacheTag, via the base IReportResult) from the report's actual business/print data - TData is what carries [PrintForm]/[PrintTable]/ [PrintSectionRef], not the wrapper itself.

Kandra.Forms.Reports.ReportGroupingState

Ordered set of a report result grid's currently-grouped column property names, outermost-first (MudDataGrid nests later-grouped columns inside earlier-grouped ones). Backed by a List, not a Queue - a real queue doesn't support arbitrary-position removal, which ungrouping a non-last column needs. "FIFO" only in the sense that grouping always appends to the end; ungrouping can remove from anywhere.

Properties

PropertyDescription
FrontGroupOutermost/first-grouped column, or null if nothing is grouped - what a conditional aggregate (ICustomAggregate) checks against.

Methods

MethodDescription
Set(String, Boolean)Call from a column's GroupingChanged handler: grouped=true appends propertyName if not already present; grouped=false removes it from wherever it sits.

Kandra.Forms.Reports.ReportResult<T0, T1>

Base implementation of a report result's technical envelope - Filters/Data/CacheTag - so a concrete report result is just a closed generic with no members of its own, e.g. sealed class RestsReportResult : ReportResult<ReportRestsDto, RestsReportDataDto>;

Kandra.Forms.Scheduling.JobStateDto

Kandra.Forms.Scheduling.ScheduledJobDto

Properties

PropertyDescription
ProcessorNameundocumented
Stateundocumented

Kandra.Forms.Scheduling.TriggerConfigDto

Properties

PropertyDescription
CronExpressionundocumented
IntervalSecondsundocumented
RepeatCountundocumented
TimeZoneIdundocumented