6
3
8
3
Waybill.cs · WaybillBehavior.cs
[KandraDocumentEntity]
public partial class Waybill : DocumentBase, IEntityWithRows<WaybillRow>
{
    public override string Code { get; set; } = "";
    public override DateTime DateTime { get; set; }
    public Guid CounterpartyId { get; set; }
    public Guid WarehouseId { get; set; }
    public List<WaybillRow> Rows { get; set; } = [];
}

// Registers are written only inside a posting scope.
public class WaybillBehavior : DocumentBehavior<Waybill, WaybillDto>
{
    public override async ValueTask OnSubmitAsync(Waybill doc, ISubmitScope scope)
    {
        var inventory = scope.GetWriter<IInventoryRegisterWriter>();
        foreach (var row in doc.Rows)
            await inventory.ExpenseAsync(doc, row.ItemId, doc.WarehouseId, row.Quantity);
    }
}

// Controllers, API client, EF config, DI, Blazor pages: generated.
.NET 10 · C# 14EF Core · SQLite / SQL Server / PostgreSQLBlazor WebAssembly · MudBlazorRoslyn source generatorsQuartz.NET schedulerRefit API clients

DocumentBase

DictionaryBase

BalanceRegister<T> · InfoRegister

[KandraReportForm]

[KandraDataProcessorForm]

Constant<T>

Branch : DictionaryBase
BranchDto
BranchBehavior
BranchValidator

IPostingService · ChartOfAccounts

Quartz.NET · ICallerContext

[SupportedPrintForm]

[FilePicker] · IBlobService

JWT · API keys · policies

LocalizationChain · FeatureManagement

YourCompany.Domain · .Forms · .Application
ASP.NET Core
+ Blazor WASMPostgreSQL · SQL Server
Avalonia
desktop / mobile
Avalonia
standalone

/create-document SalesOrder --rows --posts InventoryRegister
✓ SalesOrder : DocumentBase, IEntityWithRows<SalesOrderRow>
✓ SalesOrderDto · [KandraDocumentForm(ValidatorType = …)]
✓ SalesOrderBehavior · OnSubmitAsync → ISubmitScope
✓ SalesOrderValidator · resx EN/UK/RU · nav tree · migration ×3


kandra.reports.rests(warehouse: "Main", date: today)

Kandra Trading

Free51 000200 ·
Developer1001 000 00010 000
Commercial S1010 0002 000
Commercial M2550 0005 000
Commercial L100500 000

1C:Enterprise
OdooPython / JS
Dynamics 365 BCAL ()
Frappe / ERPNextPython / JS
KandraC# / .NET 10

dotnet tool install -g Kandra.Cli
kandra new Acme.Erp --with-demo-entities
cd Acme.Erp && dotnet run