created foundation for ledger

This commit is contained in:
Roger Oriol Pérez
2023-12-10 11:42:13 +01:00
commit aa4571b09c
15 changed files with 349 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
venv/

2
commands/balance-sheet Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
echo "TO DO"

2
commands/cash-flow-statement Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
echo "TO DO"

2
commands/check Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
bean-check ledger/main.beancount

2
commands/income-statement Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
echo "TO DO"

2
commands/serve Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
fava ledger/main.beancount -p 8080

65
ledger/accounts.beancount Normal file
View File

@@ -0,0 +1,65 @@
1970-01-01 open Assets:Liquid:Caixabank:Corrent EUR
1970-01-01 open Assets:Liquid:Caixabank:Estalvi EUR
1970-01-01 open Assets:Liquid:R4:EUR EUR
1970-01-01 open Assets:Invest:R4:Vanguard:EMMK VANEMMK
1970-01-01 open Assets:Invest:R4:Amundi:MSCIWRLD AMNDMSCIWRLD
1970-01-01 open Assets:Invest:R4:BNP:DISTECH BNPDISTECH
1970-01-01 open Assets:Invest:R4:Fidelity:GLTECH FIGLTECH
1970-01-01 open Assets:Invest:R4:Amundi:SUSTINC AMNDSUSINC
1970-01-01 open Assets:Invest:R4:PLTR PLTR
1970-01-01 open Assets:Invest:R4:MSFT MSFT
1970-01-01 open Assets:Benefits:Edenred:TicketsRestaurant EUR
1970-01-01 open Assets:Benefits:Edenred:TarjetaTransport EUR
1970-01-01 open Assets:PersonalProperty:VivendaPrincipal EUR
1970-01-01 open Assets:PersonalProperty:Cotxe EUR
1970-01-01 open Assets:PersonalProperty:JoiesArtCollecionables EUR
1970-01-01 open Assets:PersonalProperty:MetallsPreciosos EUR
1970-01-01 open Assets:PersonalProperty:AltresPropietats EUR
1970-01-01 open Assets:Debt:DeutesPerCobrar EUR
1970-01-01 open Liabilities:Credit:Caixabank:TargetaCredit EUR
1970-01-01 open Liabilities:Factures:FacturesPendents EUR
1970-01-01 open Liabilities:Taxes:IRPF EUR
;1970-01-01 open Liabilities:Hipoteca:VivendaPrincipal EUR
1970-01-01 open Income:Work:Zurich:Salari EUR
1970-01-01 open Income:Work:Zurich:TicketsRestaurant EUR
1970-01-01 open Income:Work:Zurich:TarjetaTransport EUR
1970-01-01 open Income:Work:Zurich:SeguroMedic EUR
1970-01-01 open Income:Work:Zurich:Gimnas EUR
1970-01-01 open Income:Other:Caixabank:Transferencia EUR
1970-01-01 open Income:Other:Caixabank:Bizum EUR
1970-01-01 open Income:Savings:Caixabank:RentabilitatEstalvis EUR
1970-01-01 open Income:Invest:R4:Dividends EUR
1970-01-01 open Income:Invest:R4:CapitalGains EUR
1970-01-01 open Expenses:R4:Comissions EUR
1970-01-01 open Expenses:Taxes:IRPF EUR
1970-01-01 open Expenses:Taxes:BeneficisDividends EUR
1970-01-01 open Expenses:Taxes:BeneficisDividendsOrigen EUR
1970-01-01 open Expenses:Taxes:ImpostCirculacio EUR
1970-01-01 open Expenses:Insurance:Cotxe EUR
1970-01-01 open Expenses:Lloguer EUR
1970-01-01 open Expenses:FacturesUtilitats EUR
1970-01-01 open Expenses:Internet EUR
1970-01-01 open Expenses:Gasolina EUR
1970-01-01 open Expenses:MantenimentCotxe EUR
1970-01-01 open Expenses:Roba EUR
1970-01-01 open Expenses:Educació EUR
1970-01-01 open Expenses:Medic EUR
1970-01-01 open Expenses:Vacances EUR
1970-01-01 open Expenses:NintendoOnline EUR
1970-01-01 open Expenses:Perruqueria EUR
1970-01-01 open Expenses:AmazonPrime EUR
1970-01-01 open Expenses:CarnetJove EUR
1970-01-01 open Expenses:Supermercat EUR
1970-01-01 open Expenses:Gimnàs EUR
1970-01-01 open Expenses:Parking EUR
1970-01-01 open Expenses:Mobilitat EUR
1970-01-01 open Expenses:MarcaPersonal EUR
1970-01-01 open Expenses:MenjarFora EUR
1970-01-01 open Expenses:Entreteniment EUR
1970-01-01 open Expenses:Altres EUR
1970-01-01 open Equity:Opening-Balances EUR
1970-01-01 open Equity:Opening-Balances:USD USD

24
ledger/budget.beancount Normal file
View File

@@ -0,0 +1,24 @@
2024-01-01 custom "budget" Expenses:Lloguer "monthly" 600.00 EUR
2024-01-01 custom "budget" Expenses:FacturesUtilitats "monthly" 80.00 EUR
2024-01-01 custom "budget" Expenses:Internet "monthly" 50.00 EUR
2024-01-01 custom "budget" Expenses:Gasolina "monthly" 50.00 EUR
2024-01-01 custom "budget" Expenses:Roba "monthly" 80.00 EUR
2024-01-01 custom "budget" Expenses:Perruqueria "monthly" 16.00 EUR
2024-01-01 custom "budget" Expenses:Supermercat "monthly" 180.00 EUR
2024-01-01 custom "budget" Expenses:Parking "monthly" 122.09 EUR
2024-01-01 custom "budget" Expenses:Mobilitat "monthly" 125.00 EUR
2024-01-01 custom "budget" Expenses:Entreteniment "monthly" 60.00 EUR
2024-01-01 custom "budget" Expenses:MenjarFora "monthly" 250.00 EUR
2024-01-01 custom "budget" Expenses:Altres "monthly" 150.00 EUR
2024-01-01 custom "budget" Expenses:MantenimentCotxe "yearly" 180.00 EUR
2024-01-01 custom "budget" Expenses:Educació "yearly" 200.00 EUR
2024-01-01 custom "budget" Expenses:Medic "yearly" 400.00 EUR
2024-01-01 custom "budget" Expenses:Vacances "yearly" 2000.00 EUR
2024-01-01 custom "budget" Expenses:Taxes:ImpostCirculacio "yearly" 55.00 EUR
2024-01-01 custom "budget" Expenses:NintendoOnline "yearly" 35.00 EUR
2024-01-01 custom "budget" Expenses:AmazonPrime "yearly" 50.00 EUR
2024-01-01 custom "budget" Expenses:Insurance:Cotxe "yearly" 520.00 EUR
2024-01-01 custom "budget" Expenses:CarnetJove "yearly" 10.00 EUR
2024-01-01 custom "budget" Expenses:Gimnàs "yearly" 800.00 EUR
2024-01-01 custom "budget" Expenses:MarcaPersonal "yearly" 150.00 EUR

View File

@@ -0,0 +1,19 @@
1970-01-01 commodity EUR
name: "Euro"
1970-01-01 commodity USD
name: "US Dollar"
1970-01-01 commodity VANEMMK
name: "VANGUARD EM MK ST IX INV (EUR)"
1970-01-01 commodity AMNDMSCIWRLD
name: "Amundi Index MSCI World AE (EUR) INC"
2024-01-01 commodity AMNDSUSINC
name: "AMUNDI FUNDS GLOBAL E A2 (EUR) D C / Amundi Fds Glb EQ Sust Inc A2 EUR Qti D"
1970-01-01 commodity BNPDISTECH
name: "BNP Disrupting Technology C (USD) ACC"
1970-01-01 commodity FIGLTECH
name: "FIDELITY GLOBAL TECHNOLOGY A (EUR)"
1970-01-01 commodity PLTR
name: "Palantir Technologies Inc"
1970-01-01 commodity MSFT
name: "MSFT"
price: "USD:google/NASDAQ:MSFT"

16
ledger/main.beancount Normal file
View File

@@ -0,0 +1,16 @@
* Plugins
option "insert_pythonpath" "True"
plugin "plugins.amortize_over"
plugin "beancount.plugins.implicit_prices"
* Options
option "title" "Roger Oriol Ledger"
option "operating_currency" "EUR"
option "inferred_tolerance_default" "*:0.001"
* Imports
include "accounts.beancount"
include "commodities.beancount"
include "budget.beancount"
include "trading/*"
include "transactions/*"

View File

@@ -0,0 +1,143 @@
# Copyright (c) 2017 Cary Kempston
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from collections import namedtuple
from beancount.core.data import Transaction
from beancount.core.amount import Amount
from datetime import date
from dateutil.relativedelta import relativedelta
__plugins__ = ('amortize_over',)
AmortizationError = namedtuple('AmortizationError', 'source message entry')
def amortize_over(entries, unused_options_map):
"""Repeat a transaction based on metadata.
Args:
entries: A list of directives. We're interested only in the
Transaction instances.
unused_options_map: A parser options dict.
Returns:
A list of entries and a list of errors.
Example use:
This plugin will convert the following transactions
2017-06-01 * "Pay car insurance"
Assets:Bank:Checking -600.00 USD
Assets:Prepaid-Expenses
2017-06-01 * "Amortize car insurance over six months"
amortize_months: 3
Assets:Prepaid-Expenses -600.00 USD
Expenses:Insurance:Auto
into the following transactions over six months:
2017/06/01 * Pay car insurance
Assets:Bank:Checking -600.00 USD
Assets:Prepaid-Expenses 600.00 USD
2017/06/01 * Amortize car insurance over six months
Assets:Prepaid-Expenses -200.00 USD
Expenses:Insurance:Auto 200.00 USD
2017/07/01 * Amortize car insurance over six months
Assets:Prepaid-Expenses -200.00 USD
Expenses:Insurance:Auto 200.00 USD
2017/08/01 * Amortize car insurance over six months
Assets:Prepaid-Expenses -200.00 USD
Expenses:Insurance:Auto 200.00 USD
Note that transactions are not included past today's date. For example,
if the above transactions are processed on a date of 2017/07/25, the
transaction dated 2017/08/01 is not included.
"""
new_entries = []
errors = []
for entry in entries:
if isinstance(entry, Transaction) and 'amortize_months' in entry.meta:
a_entires, a_errors = amortize_transaction(entry)
new_entries.extend(a_entires)
errors.extend(a_errors)
else:
# Always replicate the existing entries - unless 'amortize_months'
# is in the metadata
new_entries.append(entry)
return new_entries, errors
def split_amount(amount, periods):
if periods == 1:
return [amount]
amount_this_period = amount / periods
amount_this_period = amount_this_period.quantize(amount)
return [amount_this_period] + split_amount(amount - amount_this_period, periods - 1)
def amortize_transaction(entry):
new_entries = []
errors = []
if len(entry.postings) != 2:
error = AmortizationError(
entry.meta,
'Amortized transactions must have exactly two postings.',
entry
)
errors.append(error)
return new_entries, errors
periods = entry.meta['amortize_months']
amount = abs(entry.postings[0].units.number)
currency = entry.postings[0].units.currency
monthly_amounts = split_amount(amount, periods)
for (n_month, monthly_number) in enumerate(monthly_amounts):
new_postings = []
for posting in entry.postings:
new_monthly_number = monthly_number
if posting.units.number < 0:
new_monthly_number = -monthly_number
new_posting = posting._replace(units=Amount(number=new_monthly_number,
currency=currency))
new_postings.append(new_posting)
new_narration = f'{entry.narration} ({n_month + 1}/{periods})'
new_entry = entry._replace(
narration=new_narration,
postings=new_postings,
date=entry.date + relativedelta(months=n_month),
)
if new_entry.date <= date.today():
new_entries.append(new_entry)
return new_entries, errors

View File

@@ -0,0 +1,6 @@
;2021-07-19 price AMNDEMWRLD 99.326565 EUR
;2021-07-19 price AMNDMSCIWRLD 204.929967 EUR
;2021-07-19 price BNPDISTECH 1567.214485 EUR
;2021-07-19 price JPMTECH 6.101629 EUR
;2021-07-19 price PLTR 5.994 EUR
;2021-07-19 price IRNT 0.2185 EUR

View File

@@ -0,0 +1,15 @@
2024-01-01 * "Balanç inicial EUR"
Assets:Liquid:Caixabank:Corrent 18903.80 EUR
Assets:Liquid:Caixabank:Estalvi 12666.49 EUR
Assets:Liquid:R4:EUR 44.04 EUR
Assets:Invest:R4:Amundi:MSCIWRLD 86.005 AMNDMSCIWRLD {237.62 EUR}
Assets:Invest:R4:Vanguard:EMMK 14.99 VANEMMK {177.773 EUR}
Assets:Invest:R4:Fidelity:GLTECH 344.47 FIGLTECH {41.06 EUR}
Assets:Invest:R4:Amundi:SUSTINC 11.295 AMNDSUSINC {62.84 EUR}
Equity:Opening-Balances:USD 2315.65 USD {0.93 EUR}
Equity:Opening-Balances
2024-01-01 * "Balanç inicial USD"
Assets:Invest:R4:BNP:DISTECH 0.359 BNPDISTECH {2195.55 USD}
Assets:Invest:R4:PLTR 10 PLTR {16.025 USD}
Assets:Invest:R4:MSFT 4 MSFT {341.8 USD}
Equity:Opening-Balances:USD

50
requirements.txt Normal file
View File

@@ -0,0 +1,50 @@
Babel==2.13.1
beancount==2.3.6
beautifulsoup4==4.12.2
blinker==1.7.0
bottle==0.12.25
cachetools==5.3.2
certifi==2023.11.17
chardet==5.2.0
charset-normalizer==3.3.2
cheroot==10.0.0
click==8.1.7
fava==1.26.2
fava-plugins==1.0
Flask==3.0.0
flask-babel==4.0.0
google-api-core==2.14.0
google-api-python-client==2.109.0
google-auth==2.25.1
google-auth-httplib2==0.1.1
googleapis-common-protos==1.61.0
httplib2==0.22.0
idna==3.6
iniconfig==2.0.0
itsdangerous==2.1.2
jaraco.functools==4.0.0
Jinja2==3.1.2
lxml==4.9.3
markdown2==2.4.11
MarkupSafe==2.1.3
more-itertools==10.1.0
packaging==23.2
pdfminer2==20151206
pluggy==1.3.0
ply==3.11
protobuf==4.25.1
pyasn1==0.5.1
pyasn1-modules==0.3.0
pyparsing==3.1.1
pytest==7.4.3
python-dateutil==2.8.2
python-magic==0.4.27
pytz==2023.3.post1
requests==2.31.0
rsa==4.9
simplejson==3.19.2
six==1.16.0
soupsieve==2.5
uritemplate==4.1.1
urllib3==2.1.0
Werkzeug==3.0.1