476 lines
19 KiB
C#
476 lines
19 KiB
C#
|
|
using Books.Api.EventFlow.Repositories;
|
||
|
|
using Books.Api.EventFlow.Subscribers;
|
||
|
|
using Books.Api.Tests.Helpers;
|
||
|
|
using Books.Api.Tests.Infrastructure;
|
||
|
|
using AwesomeAssertions;
|
||
|
|
using Microsoft.Extensions.DependencyInjection;
|
||
|
|
|
||
|
|
namespace Books.Api.Tests.GraphQL;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Integration tests for ChartOfAccountsInitializer.
|
||
|
|
/// Verifies that creating a company automatically bootstraps the standard Danish chart of accounts.
|
||
|
|
/// </summary>
|
||
|
|
[Trait("Category", "Integration")]
|
||
|
|
public class ChartOfAccountsInitializerTests(TestWebApplicationFactory factory)
|
||
|
|
: IntegrationTestBase(factory)
|
||
|
|
{
|
||
|
|
[Fact]
|
||
|
|
public async Task CreateCompany_AutomaticallyCreatesStandardAccounts()
|
||
|
|
{
|
||
|
|
// Arrange
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
var expectedAccountCount = StandardDanishAccounts.GetAll().Count();
|
||
|
|
|
||
|
|
// Act - Create a company
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) {
|
||
|
|
id
|
||
|
|
name
|
||
|
|
}
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new
|
||
|
|
{
|
||
|
|
input = new
|
||
|
|
{
|
||
|
|
name = "Auto-Account Test Virksomhed"
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert - Wait for accounts to be created (eventually consistent)
|
||
|
|
var accounts = await Eventually.GetListAsync(
|
||
|
|
async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
return await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
},
|
||
|
|
expectedAccountCount,
|
||
|
|
timeout: TimeSpan.FromSeconds(30), // Allow more time for many accounts
|
||
|
|
failMessage: $"Expected {expectedAccountCount} accounts to be created");
|
||
|
|
|
||
|
|
accounts.Should().HaveCount(expectedAccountCount);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task CreateCompany_CreatesRevenueAccounts()
|
||
|
|
{
|
||
|
|
// Arrange
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "Revenue Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert - Check revenue accounts (1xxx)
|
||
|
|
var accounts = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
var revenue = all.Where(a => a.AccountType == "revenue").ToList();
|
||
|
|
return revenue.Count >= 5 ? revenue : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
accounts.Should().NotBeEmpty();
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "1000"); // Salg af varer, DK
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "1200"); // Salg af ydelser, DK
|
||
|
|
accounts.Should().OnlyContain(a => a.AccountType == "revenue");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task CreateCompany_CreatesExpenseAccounts()
|
||
|
|
{
|
||
|
|
// Arrange
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "Expense Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
var accounts = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
var expenses = all.Where(a => a.AccountType == "expense").ToList();
|
||
|
|
return expenses.Count >= 10 ? expenses : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
accounts.Should().NotBeEmpty();
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "4000"); // Annoncer og reklame
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "5000"); // Husleje
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "7320"); // Køb af software
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task CreateCompany_CreatesSystemAccounts()
|
||
|
|
{
|
||
|
|
// Arrange
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "System Accounts Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert - Check system accounts exist (we have many: equity, revenue, debtors, creditors, tax)
|
||
|
|
var accounts = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
var system = all.Where(a => a.IsSystemAccount).ToList();
|
||
|
|
return system.Count >= 15 ? system : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
accounts.Should().NotBeEmpty();
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "3000"); // Aktiekapital
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "3900"); // Overført resultat
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "3910"); // Årets resultat
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "1900"); // Debitorer
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "6900"); // Kreditorer
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "7950"); // Skyldig selskabsskat
|
||
|
|
accounts.Should().OnlyContain(a => a.IsSystemAccount);
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task CreateCompany_CreatesLiabilityAccounts()
|
||
|
|
{
|
||
|
|
// Arrange
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "Liability Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
var accounts = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
var liabilities = all.Where(a => a.AccountType == "liability").ToList();
|
||
|
|
return liabilities.Count >= 5 ? liabilities : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
accounts.Should().NotBeEmpty();
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "6900"); // Kreditorer
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "7900"); // Skyldig moms
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "7910"); // Skyldig A-skat
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task CreateCompany_AccountsHaveCorrectVatCodes()
|
||
|
|
{
|
||
|
|
// Arrange
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "VAT Code Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert - Check that accounts have correct VAT codes
|
||
|
|
var accounts = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
return all.Count >= 50 ? all.ToList() : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
// Vareforbrug should have I25 (25% input VAT)
|
||
|
|
var vareforbrug = accounts!.FirstOrDefault(a => a.AccountNumber == "2000");
|
||
|
|
vareforbrug.Should().NotBeNull();
|
||
|
|
vareforbrug!.VatCodeId.Should().Be("I25");
|
||
|
|
|
||
|
|
// Salg af varer DK should have U25 (25% output VAT)
|
||
|
|
var salgVarer = accounts.FirstOrDefault(a => a.AccountNumber == "1000");
|
||
|
|
salgVarer.Should().NotBeNull();
|
||
|
|
salgVarer!.VatCodeId.Should().Be("U25");
|
||
|
|
|
||
|
|
// Bankrenter should have no VAT
|
||
|
|
var bankrenter = accounts.FirstOrDefault(a => a.AccountNumber == "9200");
|
||
|
|
bankrenter.Should().NotBeNull();
|
||
|
|
bankrenter!.VatCodeId.Should().BeNull();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task Query_AccountsViaGraphQL_ReturnsBootstrappedAccounts()
|
||
|
|
{
|
||
|
|
// Arrange
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Create company
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "GraphQL Query Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Set company ID header for subsequent requests
|
||
|
|
graphqlClient.SetCompanyId(companyId);
|
||
|
|
|
||
|
|
// Wait for accounts to be created
|
||
|
|
await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
return all.Count >= 50 ? all : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
// Act - Query via GraphQL
|
||
|
|
var queryResponse = await graphqlClient.QueryAsync<AccountsResponse>("""
|
||
|
|
query Accounts($companyId: ID!) {
|
||
|
|
accounts(companyId: $companyId) {
|
||
|
|
id
|
||
|
|
accountNumber
|
||
|
|
name
|
||
|
|
accountType
|
||
|
|
isSystemAccount
|
||
|
|
}
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { companyId });
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
queryResponse.EnsureNoErrors();
|
||
|
|
queryResponse.Data!.Accounts.Should().NotBeEmpty();
|
||
|
|
queryResponse.Data.Accounts.Should().Contain(a => a.AccountNumber == "2000");
|
||
|
|
queryResponse.Data.Accounts.Should().Contain(a => a.Name == "Vareforbrug");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task ChartOfAccountsInitializer_IsIdempotent_CalledTwice()
|
||
|
|
{
|
||
|
|
// Arrange
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
var expectedAccountCount = StandardDanishAccounts.GetAll().Count();
|
||
|
|
|
||
|
|
// Create company (which triggers first initialization)
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "Idempotency Test Company" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Wait for first initialization to complete
|
||
|
|
var initialAccounts = await Eventually.GetListAsync(
|
||
|
|
async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
return await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
},
|
||
|
|
expectedAccountCount,
|
||
|
|
timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
initialAccounts.Should().HaveCount(expectedAccountCount);
|
||
|
|
|
||
|
|
// Act - Call initializer again (should be idempotent)
|
||
|
|
var initializer = GetService<IChartOfAccountsInitializer>();
|
||
|
|
await initializer.InitializeAsync(companyId);
|
||
|
|
|
||
|
|
// Assert - Should still have the same number of accounts (not doubled)
|
||
|
|
var accountsAfterSecondInit = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
return await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
});
|
||
|
|
|
||
|
|
accountsAfterSecondInit.Should().HaveCount(expectedAccountCount,
|
||
|
|
"Calling initializer twice should not create duplicate accounts");
|
||
|
|
}
|
||
|
|
|
||
|
|
#region Danish Compliance: Chart of Accounts Structure Tests
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task ChartOfAccounts_ContainsShareCapitalAccount()
|
||
|
|
{
|
||
|
|
// Arrange - Danish companies are required to have an equity account for share capital
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "Share Capital Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert - Check that Aktiekapital (3000) exists
|
||
|
|
var accounts = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
return all.Any(a => a.AccountNumber == "3000") ? all.ToList() : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
var shareCapital = accounts!.FirstOrDefault(a => a.AccountNumber == "3000");
|
||
|
|
shareCapital.Should().NotBeNull("Aktiekapital/Anpartskapital account (3000) is required per Selskabsloven");
|
||
|
|
shareCapital!.AccountType.Should().Be("equity");
|
||
|
|
shareCapital.IsSystemAccount.Should().BeTrue();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task ChartOfAccounts_ContainsCorporateTaxAccount()
|
||
|
|
{
|
||
|
|
// Arrange - Danish companies need a liability account for corporate tax
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "Corporate Tax Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert - Check that Skyldig selskabsskat (7950) exists
|
||
|
|
var accounts = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
return all.Any(a => a.AccountNumber == "7950") ? all.ToList() : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
var corporateTax = accounts!.FirstOrDefault(a => a.AccountNumber == "7950");
|
||
|
|
corporateTax.Should().NotBeNull("Skyldig selskabsskat account (7950) is required per Selskabsloven");
|
||
|
|
corporateTax!.AccountType.Should().Be("liability");
|
||
|
|
corporateTax.IsSystemAccount.Should().BeTrue();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task ChartOfAccounts_HasProperEquityRange()
|
||
|
|
{
|
||
|
|
// Arrange - Per Danish accounting standards, accounts 3000-3999 should only be Equity
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "Equity Range Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert - Check that all 3xxx accounts are Equity type
|
||
|
|
var accounts = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
var equityRange = all.Where(a =>
|
||
|
|
int.TryParse(a.AccountNumber, out var num) && num >= 3000 && num < 4000).ToList();
|
||
|
|
return equityRange.Count >= 3 ? equityRange : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
accounts.Should().NotBeEmpty("3xxx range should have equity accounts");
|
||
|
|
accounts.Should().OnlyContain(
|
||
|
|
a => a.AccountType == "equity",
|
||
|
|
"Per Danish accounting standards, 3xxx range should ONLY contain equity accounts");
|
||
|
|
}
|
||
|
|
|
||
|
|
[Fact]
|
||
|
|
public async Task ChartOfAccounts_ContainsFixedAssetAccounts()
|
||
|
|
{
|
||
|
|
// Arrange - Danish chart of accounts should include fixed asset accounts for depreciation
|
||
|
|
var graphqlClient = new GraphQLTestClient(Client);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
var createResponse = await graphqlClient.MutateAsync<CreateCompanyResponse>("""
|
||
|
|
mutation CreateCompany($input: CreateCompanyInput!) {
|
||
|
|
createCompany(input: $input) { id }
|
||
|
|
}
|
||
|
|
""",
|
||
|
|
new { input = new { name = "Fixed Assets Test" } });
|
||
|
|
|
||
|
|
createResponse.EnsureNoErrors();
|
||
|
|
var companyId = createResponse.Data!.CreateCompany!.Id;
|
||
|
|
|
||
|
|
// Assert - Check that fixed asset accounts exist (1710-1730)
|
||
|
|
var accounts = await Eventually.GetAsync(async () =>
|
||
|
|
{
|
||
|
|
var repo = GetService<IAccountRepository>();
|
||
|
|
var all = await repo.GetByCompanyIdAsync(companyId);
|
||
|
|
var fixedAssets = all.Where(a => new[] { "1710", "1720", "1730" }.Contains(a.AccountNumber)).ToList();
|
||
|
|
return fixedAssets.Count >= 3 ? all.ToList() : null;
|
||
|
|
}, timeout: TimeSpan.FromSeconds(30));
|
||
|
|
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "1710", "Bygninger account required");
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "1720", "Maskiner og inventar account required");
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "1730", "Køretøjer account required");
|
||
|
|
|
||
|
|
// Also verify corresponding depreciation accounts exist
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "8010", "Afskrivning, bygninger account required");
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "8020", "Afskrivning, maskiner account required");
|
||
|
|
accounts.Should().Contain(a => a.AccountNumber == "8030", "Afskrivning, køretøjer account required");
|
||
|
|
}
|
||
|
|
|
||
|
|
#endregion
|
||
|
|
|
||
|
|
// Response DTOs
|
||
|
|
private class CreateCompanyResponse { public CompanyDto? CreateCompany { get; set; } }
|
||
|
|
private class AccountsResponse { public List<AccountDto> Accounts { get; set; } = []; }
|
||
|
|
private class CompanyDto { public string Id { get; set; } = string.Empty; }
|
||
|
|
|
||
|
|
private class AccountDto
|
||
|
|
{
|
||
|
|
public string Id { get; set; } = string.Empty;
|
||
|
|
public string AccountNumber { get; set; } = string.Empty;
|
||
|
|
public string Name { get; set; } = string.Empty;
|
||
|
|
public string AccountType { get; set; } = string.Empty;
|
||
|
|
public string? VatCodeId { get; set; }
|
||
|
|
public bool IsSystemAccount { get; set; }
|
||
|
|
}
|
||
|
|
}
|