Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/dotnetcore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ jobs:

- name: Restore packages
run: dotnet restore --configfile nuget.config --verbosity normal
- name: Check generated model is up to date
# The generation is skipped in CI builds, so it is enforced here.
# The file is removed first, because all files have the same timestamp after checkout.
run: |
$generatedFile = "src\SimpleAccounting\Model\AccountingData.designer.cs"
Remove-Item $generatedFile
dotnet msbuild src\SimpleAccounting -t:GenerateModel -p:CI=false
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
git diff --exit-code -- $generatedFile
if ($LASTEXITCODE -ne 0) {
Write-Host "::error file=$generatedFile::The generated model is outdated. Build locally and commit the file."
exit 1
}
shell: pwsh
- name: Publish Small Release
run: dotnet publish --configuration Release
working-directory: src\SimpleAccounting
Expand Down
13 changes: 13 additions & 0 deletions dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-xscgen": {
"version": "3.0.1405",
"commands": [
"xscgen"
],
"rollForward": false
}
}
}
2 changes: 0 additions & 2 deletions samples/sample.acml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
<Column Target="Text" Source="Text" />
<Column Target="Value" Source="Value" />
</Columns>
<Patterns />
</ImportMapping>
</Account>
<Account ID="400" Name="Salary" Type="Income" />
Expand All @@ -42,5 +41,4 @@
<Credit Value="15000" Account="400" Text="Annual extra salary" />
</Booking>
</Journal>
<OpenIssues />
</AccountingData>
19 changes: 11 additions & 8 deletions src/SimpleAccounting/Infrastructure/ImportFileLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,18 @@ private IEnumerable<ImportEntryViewModel> ImportBookings(TextReader reader, IRea
{
var dateField =
this.importMapping.Columns
.Find(x => x.Target == AccountDefinitionImportMappingColumnTarget.Date)?.Source
.Find(x => x.Target == AccountDefinitionImportMappingColumnsColumnTarget.Date)?.Source
?? "date";
var nameField =
this.importMapping.Columns
.Find(x => x.Target == AccountDefinitionImportMappingColumnTarget.Name)?.Source
.Find(x => x.Target == AccountDefinitionImportMappingColumnsColumnTarget.Name)?.Source
?? "name";
var textField =
this.importMapping.Columns
.Find(x => x.Target == AccountDefinitionImportMappingColumnTarget.Text);
.Find(x => x.Target == AccountDefinitionImportMappingColumnsColumnTarget.Text);
var valueField =
this.importMapping.Columns
.Find(x => x.Target == AccountDefinitionImportMappingColumnTarget.Value)?.Source
.Find(x => x.Target == AccountDefinitionImportMappingColumnsColumnTarget.Value)?.Source
?? "value";

using var csv = new CsvReader(reader, configuration);
Expand All @@ -95,7 +95,7 @@ private ImportEntryViewModel ImportBooking(
CsvReader csv,
string dateField,
string nameField,
AccountDefinitionImportMappingColumn? textField,
AccountDefinitionImportMappingColumnsColumn? textField,
string valueField)
{
// date and value are required
Expand All @@ -119,16 +119,19 @@ private ImportEntryViewModel ImportBooking(
text = this.duplicateSpaceExpression.Replace(text, " ");
}

var item = new ImportEntryViewModel(this.accounts) { Date = date, Name = name ?? string.Empty, Text = text, Value = value };
var item = new ImportEntryViewModel(this.accounts)
{
Date = date, Name = name ?? string.Empty, Text = text, Value = value
};

var modelValue = value.ToModelValue();
var patterns = this.importMapping.Patterns ?? Enumerable.Empty<AccountDefinitionImportMappingPattern>();
var patterns = this.importMapping.Patterns ?? Enumerable.Empty<AccountDefinitionImportMappingPatternsPattern>();
var matchedPattern = patterns.FirstOrDefault(PatternPredicate);
item.RemoteAccount = this.accounts.SingleOrDefault(a => a.ID == matchedPattern?.AccountID);

return item;

bool PatternPredicate(AccountDefinitionImportMappingPattern pattern)
bool PatternPredicate(AccountDefinitionImportMappingPatternsPattern pattern)
{
if (!pattern.Regex.IsMatch(text))
{
Expand Down
40 changes: 33 additions & 7 deletions src/SimpleAccounting/Model/AccountingData.Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Serialization;
using lg2de.SimpleAccounting.Extensions;
using lg2de.SimpleAccounting.Infrastructure;
Expand All @@ -25,6 +27,8 @@
private const string DefaultSchemaNamespace = "https://lg2.de/SimpleAccounting/AccountingSchema";
private const string DefaultSchemaLocation = "https://lg2de.github.io/SimpleAccounting/AccountingData.xsd";

private static readonly XmlSerializer Serializer = new(typeof(AccountingData));

private string schema = DefaultXsiSchemaLocation;

public AccountingData()
Expand All @@ -35,11 +39,11 @@
}

[XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
[SuppressMessage(

Check warning on line 42 in src/SimpleAccounting/Model/AccountingData.Extensions.cs

View workflow job for this annotation

GitHub Actions / build

Do not suppress issues.
"Minor Code Smell",
"S100:Methods and properties should be named in PascalCase",
Justification = "fixed name")]
[SuppressMessage("ReSharper", "RedundantCheckBeforeAssignment", Justification = "FP")]

Check warning on line 46 in src/SimpleAccounting/Model/AccountingData.Extensions.cs

View workflow job for this annotation

GitHub Actions / build

Do not suppress issues.
public string xsiSchemaLocation
{
get => this.schema;
Expand All @@ -56,6 +60,28 @@
internal IEnumerable<AccountDefinition> AllAccounts =>
this.Accounts?.SelectMany(g => g.Account) ?? Enumerable.Empty<AccountDefinition>();

/// <summary>
/// Deserializes the project from the specified XML.
/// </summary>
public static AccountingData Deserialize(string xml)
{
using var stringReader = new StringReader(xml);
using var xmlReader = XmlReader.Create(stringReader);
return (AccountingData)Serializer.Deserialize(xmlReader)!;
}

/// <summary>
/// Serializes the project into XML.
/// </summary>
public string Serialize()
{
using var memoryStream = new MemoryStream();
Serializer.Serialize(memoryStream, this);
memoryStream.Seek(0, SeekOrigin.Begin);
using var streamReader = new StreamReader(memoryStream);
return streamReader.ReadToEnd();
}

/// <summary>
/// Creates new project with some template data.
/// </summary>
Expand All @@ -79,7 +105,7 @@
return new AccountingData
{
Setup = new AccountingDataSetup(),
Accounts = [new AccountingDataAccountGroup { Name = "Default", Account = defaultAccounts }],
Accounts = [new AccountingDataAccountsAccountGroup { Name = "Default", Account = defaultAccounts }],
Journal = [accountJournal]
};
}
Expand Down Expand Up @@ -262,9 +288,9 @@
{
public AccountingDataSetup()
{
this.behaviorField = new AccountingDataSetupBehavior();
this.reportsField = new AccountingDataSetupReports();
this.currencyField = new AccountingDataSetupCurrency { Value = AccountingDataSetupCurrency.DefaultValue };
this.Behavior = new AccountingDataSetupBehavior();
this.Reports = new AccountingDataSetupReports();
this.Currency = new AccountingDataSetupCurrency { Value = AccountingDataSetupCurrency.DefaultValue };
}
}

Expand Down Expand Up @@ -305,8 +331,8 @@
}

return
this.Columns.Exists(x => x.Target == AccountDefinitionImportMappingColumnTarget.Date)
&& this.Columns.Exists(x => x.Target == AccountDefinitionImportMappingColumnTarget.Value);
this.Columns.Exists(x => x.Target == AccountDefinitionImportMappingColumnsColumnTarget.Date)
&& this.Columns.Exists(x => x.Target == AccountDefinitionImportMappingColumnsColumnTarget.Value);
}
}

Expand Down Expand Up @@ -362,7 +388,7 @@
/// <summary>
/// Implements a single pattern of an account definition for semi-automatic import.
/// </summary>
public partial class AccountDefinitionImportMappingPattern
public partial class AccountDefinitionImportMappingPatternsPattern
{
private Regex? regex;
internal Regex Regex => this.regex ??= new Regex(this.Expression, RegexOptions.Compiled, TimeSpan.FromSeconds(1));
Expand Down
Loading