Motivation
This is a finance tool project based heavily on beancount but with less features and way less complexity. After reviewing the beancount repo and documentation, I noticed that there are many more features available that I will use. In an attempt to create a new project with a new language, C#, this project was born.
Outline
This is a console application. As of right now the only major dependency is the System.CommandLine
package. The commands code is written in namespace Controllers.Commands
and the parsing and formatting of entries is written in namespace Controllers.VaultAccess
.
Commands
Here is an example of one of my commands.
using System;
using System.CommandLine;
using System.CommandLine.Invocation;
using Controllers.VaultAccess;
using Config;
namespace Controllers.Commands
{
public class NewCommand : Command
{
public NewCommand() : base("new", "Create a new vault entry")
{
AddArgument(DetailsArgument());
AddOption(DateOption());
AddOption(DirectiveOption());
AddOption(ValueOption());
Handler = CommandHandler.Create((DateTime date, string directiveType, string details, double currency) =>
{
JournalEntry entry = new JournalEntry(date, directiveType, details, currency);
Console.WriteLine(entry.ToString());
});
}
The logic is unfinished but clear. My command class inherits from System.CommandLine.Command
and abstracts away all of its logic when initialized. Using this format I am able to encapsulate the Options and Arguments into their own private methods.
private Argument<string> DetailsArgument()
{
Argument<string> details = new Argument<string>("details");
details.Description = "The details of this journal entry";
return details;
}
private Option<DateTime> DateOption()
{
Option<DateTime> date = new Option<DateTime>("--date");
date.AddAlias("-d");
date.Description = "Date of entry";
date.SetDefaultValue(DateTime.Now);
return date;
}
Journal Entry
Beancount is a very mature program and they have tested and perfected the input format for their entries. I am matching their input formats and created the JournalEntry
class to handle the input, parsing, formatting, and output of the journal entry.
Here is an example of the format that I am expecting to output into my journal files
<Date> <Directive> <Details> <Value><Currency>
08/05/2021 open Liability:Food:Restaurant -35 USD
public class JournalEntry
{
private readonly int DATE_MAX_WIDTH = 13;
private readonly int DIRECTIVE_MAX_WIDTH = 7;
private readonly int DETAILS_MAX_WIDTH = 45;
private DateTime entryDate { get; set; }
private string directive { get; set; }
private string details { get; set; }
private double currency { get; set; }
public JournalEntry(DateTime date, string dir, string det, double cur)
{
entryDate = date;
directive = dir;
details = det;
currency = cur;
}
public override string ToString()
{
return string.Format("{0}{1}{2}{3}",
entryDate.ToShortDateString().PadRight(DATE_MAX_WIDTH),
directive.PadRight(DIRECTIVE_MAX_WIDTH),
details.PadRight(DETAILS_MAX_WIDTH),
currency);
}
Next Steps
The hardest feature that I have yet to implement are the accounting logic and maybe more importantly the parsing of each line in the journal to make the various accounting reports. I intend to add reports for all the open assets and liabilities, balances of accounts, and history of expenditures.
The benefit of this project is that it is not the first. I can copy over some of the logic from existing accounting tools and then build and better them.
Top comments (0)