ledger
: General accounting¶
The lino_xl.lib.ledger
plugin adds basic notions for
accounting: accounts, journals, vouchers and movements.
Table of contents:
The
reregister
admin command
Examples in this document use the lino_book.projects.apc
demo project.
>>> from lino import startup
>>> startup('lino_book.projects.apc.settings.demo')
>>> from lino.api.doctest import *
>>> ses = rt.login("robin")
>>> translation.activate('en')
List of partners who are both supplier and customer and have open movements:
>>> from lino_xl.lib.ledger.choicelists import TradeTypes
>>> def has_mvt(obj, tt):
... qs = ledger.Movement.objects.filter(partner=obj, cleared=False, voucher__journal__trade_type=tt)
... return qs.count()
>>> for p in contacts.Partner.objects.all():
... if has_mvt(p, TradeTypes.purchases) and has_mvt(p, TradeTypes.sales):
... print(p.pk, p)
Overview¶
A ledger is a book in which the monetary transactions of a business are posted in the form of debits and credits (from 1).
In Lino, the ledger is implemented by three database models:
- ledger voucher
Any document that serves as legal proof for a ledger transaction in the ledger. Examples of vouchers include invoices, bank statements, or payment orders, VAT declarations, ...
Vouchers are stored in the database using some subclass of the
Voucher
model. The voucher model is never being used directly despite the fact that it is a concrete model.- journal
A series of sequentially numbered vouchers.
- ledger movement
An atomic "transfer" of a given amount of money from (or to) a given ledger account at a given date. It is just a conceptual transfer, not a cash or bank transfer.
Moving money from (out of) an account is called "to debit", moving money to an account is called "to credit".
Movements are never created individually but by registering a ledger voucher.
- ledger account
The most abstract representation for "something where you can place money and retrieve it later".
An account always has a given balance which can be negative or positive.
In applications which use the
ledger
plugin, accounts are used as the target of ledger movements.- payable transaction
A transaction that is expected to cause a payment by a partner.
For example sales invoices, purchase invoices, VAT declarations are payable transactions.
Some more concepts:
- ledger transaction
The group of movements generated by a same ledger voucher. For each transaction there must be at least two movements for which the sum of debited money equals the sum of credited money.
A transaction always happens at a given date and in a given accounting period which itself is part of a given fiscal year.
- common account
A well-known account for which the site manager must configure a corresponding account in your accounts chart. See
CommonAccounts
.- fiscal year
A sequence of consecutive accounting periods covered by an annual business activity report.
This usually corresponds to a calendar year. But not always. Exceptions may be companies having a shifted annual report or transitional periods.
When the annual report has been published (declared to the national tax office), the fiscal year should be closed to prevent accidental changes in the ledger of that year.
- accounting period
The month or quarter into which a given transaction is booked. Usually the same as the calendar month of the voucher's entry date.
- invoice
A ledger voucher sent to or received from a business partner, showing a list of goods or services, their price, and the amount due.
- product invoice
An invoice that is also a trade document, i.e. the items of which point to a product.
Each product mentioned in the items maps to a ledger account according to configurable rules.
- account invoice
An invoice where each row points directly to ledger accounts and doesn't mention any product. This is in contrast to an product invoice.
In a default Lino Così site, purchase invoices are implemented as account invoices while sales invoices are product invoices.
- paycheck
A ledger voucher sent to each employee every month, detailing the amount of the salary or wage and resulting tax and other legal transactions.
- cash book
A journal of all transactions in a given cash box.
The transactions are grouped into cash statements, which are similar to a bank statement, but issued internally and potentially to be signed by a responsible person.
- preliminary transactions
Transactions that happened before the accounting period they are recorded for. They are part of the opening balance, but not to be considered as part of the actual accounting period's history.
They are used to enter any relevant account activity of a corporation that has been booked using another software and/or database.
Note that opening entries, i.e. transactions made at the start of an organization as part of the foundation process, are are not preliminary.
In Lino, you create them in a dedicated journal that has its
preliminary
field checked.- trade type
The type of a trade operation. For example "sales" and "purchases" are the most common trade types. But we can also have "salaries", "taxes", ... See Trade types
There are some secondary models and choice lists:
A match rule specifies that a movement into given account can be cleared using a given journal.
The payment term of an invoice (
PaymentTerm
) is a convention on how the invoice should be paid.
And then there are many views for looking at this data.
GeneralAccountsBalance
,CustomerAccountsBalance
andSupplierAccountsBalance
Debtors
andCreditors
are tables with one row for each partner who has a positive balance (either debit or credit). Accessible via and
Partner accounts¶
Some ledger accounts require an external partner
needs_partner
Account {} needs a partner
Accounts¶
-
class
lino_xl.lib.ledger.
Account
¶ Django model for representing a ledger account.
-
name
¶ The multilingual designation of this account, as the users see it.
-
ref
¶ An optional unique name which can be used to reference a given account.
-
type
¶ The account type of this account. This points to an item of
CommonAccounts
.
-
needs_partner
¶ Whether bookings to this account need a partner specified.
For payment orders this causes the counter entry of financial documents to be detailed or not (i.e. one contra entry for every item or a single counter entry per voucher.
-
vat_class
¶ The default VAT class to use for transactions on this account.
-
default_amount
¶ The default amount to book in bank statements or journal entries when this account has been selected manually. The default booking direction is that of the
type
.
-
purchases_allowed
¶
-
sales_allowed
¶
-
wages_allowed
¶
-
clearings_allowed
¶
-
FOO_allowed
¶ These checkboxes indicate whether this account can be used on an item of a purchases (or sales or wages or FOO) invoice. There is one such checkbox for every trade type (
TradeTypes
). They exist only when theledger
plugin is installed as well. See also theget_allowed_accounts
method.
-
needs_ana
¶ Whether transactions on this account require the user to also specify an analytic account.
This file exists only when
lino_xl.lib.ana
is installed as well.
-
ana_account
¶ Which analytic account to suggest for transactions on this account.
This file exists only when
lino_xl.lib.ana
is installed as well.
-
sheet_item
¶ Pointer to the item of the balance sheet or income statement that will report the movements of this account.
This file is a dummy field when
lino_xl.lib.sheets
is not installed.
-
Common accounts¶
The accounts plugin defines a choicelist of common accounts, which are used to reference the database object for certain accounts that have a well-known meaning, i.e. that represent a convention of giving a name to some legally recognized concept.
-
class
lino_xl.lib.ledger.
CommonAccounts
¶ The global list of common accounts.
This is a
lino.core.choicelists.ChoiceList
. Every item is an instance ofCommonAccount
.This list is automatically sorted at startup because it is populated by several plugins, and because the natural sorting order would be useless and irritating.
-
class
lino_xl.lib.ledger.
CommonAccount
¶ The base class for items of :
CommonAccounts
.It defines two additional attributes:
-
clearable
¶ Default value for
Account.clearable
.
-
needs_partner
¶ Default value for
Account.needs_partner
.
-
get_object
(self)¶ Return the database object representing this common account.
-
set_object
(self, obj)¶ Set the cached database object representing this common account.
Called internally when
Account.common_account
is updated via web interface.
-
Here is the standard list of common accounts in a Lino Così application:
>>> rt.show(ledger.CommonAccounts, language="en")
...
======= ========================= ========================= =========== ================================
value name text Clearable Account
------- ------------------------- ------------------------- ----------- --------------------------------
1000 net_income_loss Net income (loss) Yes (1000) Net income (loss)
4000 customers Customers Yes (4000) Customers
4100 suppliers Suppliers Yes (4100) Suppliers
4200 employees Employees Yes (4200) Employees
4300 pending_po Pending Payment Orders Yes (4300) Pending Payment Orders
4500 tax_offices Tax Offices Yes (4500) Tax Offices
4510 vat_due VAT due No (4510) VAT due
4513 due_taxes VAT declared No (4513) VAT declared
4520 vat_deductible VAT deductible No (4520) VAT deductible
4530 vat_returnable VAT returnable No (4530) VAT returnable
4800 clearings Internal clearings Yes (4800) Internal clearings
4900 waiting Waiting account Yes (4900) Waiting account
5500 best_bank BestBank No (5500) BestBank
5700 cash Cash No (5700) Cash
6010 purchase_of_services Purchase of services No (6010) Purchase of services
6020 purchase_of_investments Purchase of investments No (6020) Purchase of investments
6040 purchase_of_goods Purchase of goods No (6040) Purchase of goods
6300 wages Wages No (6300) Wages
6900 net_income Net income No (6900) Net income
7000 sales Sales No (7000) Sales
7900 net_loss Net loss No
======= ========================= ========================= =========== ================================
Lino applications can add specific items to that list or potentially redefine it completely.
Keep in mind that common accounts are no database objects. See them rather as a list of configuration values. They are just a list of named pointers to actual database objects.
For example you might want to know how many sales operations are in your database:
>>> obj = ledger.CommonAccounts.sales.get_object()
>>> obj
Account #20 ('(7000) Sales')
>>> ledger.Movement.objects.filter(account=obj).count()
92
A common account neither requires nor makes sure that its database object exists. For example the common account "Net loss" has no database object in the accounts chart pointing to it. The above trick won't work for counting the number of net loss operations:
>>> obj = ledger.CommonAccounts.net_loss.get_object()
>>> obj
MissingAccount(<ledger.CommonAccounts.net_loss:7900>)
>>> ledger.Movement.objects.filter(account=obj).count()
Traceback (most recent call last):
...
TypeError: Field 'id' expected a number but got MissingAccount(<ledger.CommonAccounts.net_loss:7900>).
Debit and credit¶
Every movement of a financial transaction "moves" some amount either out of or into a given account. Accountants don't want to express this "direction" of a movement simply by using an either positive or negative number, they want an explicit word for it and call it debiting and crediting. A debit entry in an account represents a transfer of value to that account, and a credit entry represents a transfer from the account.
By convention, Lino stores the amount of a debiting movement as a negative number in the database. As an end user you don't need to know this because amounts are always shown translated into "debit" or "credit".
A sales invoice debits the customer's account (an asset) and credits the turnover account (a revenue). The payment of this invoice credits the customer's account and debits your bank account (causing its balance to increase because it is an asset).
A purchase invoice credits the supplier's account (a liability) and debits the costs account (an expense). The payment of this invoice in the bank statement debits the supplier's account and credits your bank account (causing its balance to decrease because it is an asset). If you use a payment order, then the payment order debits the supplier's account and credits your pending payment orders account, which the bank statement debits.
Every journal has its specific default booking direction (configured in
Journal.dc
). For example a (positive) amount in a sales invoice means
the opposite direction of a (positive) amount in a purchase invoice.
See also The Accounting Equation.
When migrating from Lino before 20201008, keep in mind that that a checked
dc
field means credit and not checked means debit.
-
class
lino_xl.lib.ledger.
DC
¶ A choicelist with the two values "debit" and "credit".
It can be used e.g. to express the "expected" or "normal" booking direction for a journal, account or field in an accounting report.
>>> rt.show(ledger.DC)
======= ======== ========
value name text
------- -------- --------
D debit Debit
C credit Credit
======= ======== ========
For the following code examples we import it:
>>> from lino_xl.lib.ledger.choicelists import DC
The balance of an account¶
The balance of an account is the amount of money in that account. An account balance is either debiting or crediting.
-
class
lino_xl.lib.ledger.
Balance
¶ A light-weight object to represent a balance, i.e. an amount together with its booking direction (debiting or crediting).
Attributes:
-
d
¶ The amount of this balance when it is debiting, otherwise zero.
-
c
¶ The amount of this balance when it is crediting, otherwise zero.
-
>>> from lino_xl.lib.ledger.utils import Balance
>>> b = Balance(10, 2)
>>> b
Balance(8,0)
>>> print(b)
8 DB
>>> b.value(DC.debit)
Decimal('8')
>>> Balance(15, 23)
Balance(0,8)
A negative value on one side of the balance is automatically moved to the other side.
>>> Balance(10, -2)
Balance(12,0)
>>> Balance(10, 2) + Balance(15, 23)
Balance(0,0)
>>> from decimal import Decimal
>>> Balance(Decimal("12.34"), Decimal("12.33"))
Balance(0.01,0)
Database fields¶
-
class
lino_xl.lib.ledger.
DebitOrCreditField
¶ After 20201008 this is replaced by
DC.field()
.A field that stores the "direction" of a movement, i.e. either
DEBIT
orCREDIT
.
-
class
lino_xl.lib.ledger.
DebitOrCreditStoreField
¶ No longer used after 20201008.
Used as lino_atomizer_class for
DebitOrCreditField
.
Movements¶
-
class
lino_xl.lib.ledger.
Movement
¶ Django model used to represent a ledger movement
-
value_date
¶ The date at which this movement is to be entered into the ledger. This is usually the voucher's
entry_date
, except e.g. for bank statements where each item can have its own value date.
-
voucher
¶ Pointer to the ledger voucher that caused this movement.
-
partner
¶ Pointer to the partner involved in this movement.
If
account
hasAccount.needs_partner
set, this may not be blank, otherwise it must be blank.
-
seqno
¶ Sequential number within a voucher.
-
amount
¶
-
dc
¶
-
cleared
¶ Whether
-
voucher_partner
¶ A virtual field which returns the partner of the voucher. For incoming invoices this is the supplier, for outgoing invoices this is the customer, for financial vouchers this is empty.
-
voucher_link
¶ A virtual field which shows a link to the voucher.
-
match_link
¶ A virtual field which shows a clickable variant of the match string. Clicking it will open a table with all movements having that match.
-
ana_account
¶ The analytic account to move together with this transactions.
This file exists only when
lino_xl.lib.ana
is installed as well.
-
-
class
lino_xl.lib.ledger.
Movements
¶ The base table for all tables having ledger movements as rows.
Defines filtering parameters and general behaviour.
-
start_period
¶
-
end_period
¶
-
start_date
¶
-
end_date
¶
-
cleared
¶
-
journal_group
¶
-
journal
¶
-
year
¶
-
project
¶
-
partner
¶
-
account
¶
-
-
class
lino_xl.lib.ledger.
MovementsByPartner
¶ Shows the ledger movements linked to a given partner.
-
class
lino_xl.lib.ledger.
MovementsByAccount
¶ Shows the ledger movements done on a given general account.
-
description
¶ A virtual field showing a comma-separated list of the following items:
voucher narration
voucher partner
transaction's partner
transaction's project
-
-
class
lino_xl.lib.ledger.
MovementsByMatch
¶ Show all movements having a given
Movement.match
.This is another example of a slave table whose master is not a database object, and the first example of a slave table whose master is a simple string.
-
class
lino_xl.lib.ledger.
MovementsByProject
¶ Show the ledger movements of a project.
-
class
lino_xl.lib.ledger.
AllMovements
¶ Show all the ledger movements in the database.
Displayed by
.
-
class
lino_xl.lib.ledger.
MovementsByVoucher
¶ Show the ledger movements generated by a given voucher.
The summary of MovementsByPartner
shows a balance. A negative number
means that we owe money to this partner, a positive number means that this
partner owes us money.
For example David da Vinci has 4 open invoices:
>>> obj = rt.models.contacts.Person.objects.get(pk=165)
>>> obj
Person #165 ('Mr David da Vinci')
>>> rt.show(rt.models.ledger.MovementsByPartner, obj)
**2 open movements (-1946.43 €)**
>>> rt.show(rt.models.ledger.MovementsByPartner, obj, nosummary=True)
============ =============== ======================================= ============== ======== ============= =========
Value date Voucher Description Debit Credit Match Cleared
------------ --------------- --------------------------------------- -------------- -------- ------------- ---------
12/03/2015 *SLS 15/2015* *(4000) Customers* | *da Vinci David* 1 299,08 SLS 15/2015 No
11/03/2015 *SLS 14/2015* *(4000) Customers* | *da Vinci David* 647,35 SLS 14/2015 No
**Balance 1946.43 (2 movements)** **1 946,43**
============ =============== ======================================= ============== ======== ============= =========
Vouchers¶
-
class
lino_xl.lib.ledger.
Voucher
¶ Django model used to represent a ledger voucher.
This model is not abstract so that
Movement
can have a ForeignKey to a Voucher.A voucher is never instantiated using this base model but using one of its subclasses. Here are the voucher subclasses available in Lino Così:
>>> pprint(rt.models_by_base(ledger.Voucher)) [<class 'lino_xl.lib.bevat.models.Declaration'>, <class 'lino_xl.lib.finan.models.BankStatement'>, <class 'lino_xl.lib.finan.models.JournalEntry'>, <class 'lino_xl.lib.finan.models.PaymentOrder'>, <class 'lino_xl.lib.ledger.models.Voucher'>, <class 'lino_xl.lib.sales.models.VatProductInvoice'>, <class 'lino_xl.lib.vat.models.VatAccountInvoice'>]
When the partner of an empty voucher has a purchase account, Lino automatically creates a voucher item using this account with empty amount.
-
state
¶ The workflow state of this voucher.
This field is defined by the implementing voucher class, which depends on the journal's voucher type.
Choices are defined in
VoucherStates
-
journal
¶ The journal into which this voucher has been booked. This is a mandatory pointer to a
Journal
instance.
-
number
¶ The sequence number of this voucher in the
journal
.The voucher number is automatically assigned when the voucher is saved for the first time. The voucher number depends on whether
yearly_numbering
is enabled or not.There might be surprising numbering if two users create vouchers in a same journal at the same time.
-
entry_date
¶ The date of the journal entry, i.e. when this voucher is to journalized or booked.
-
voucher_date
¶ The date on the voucher (i.e. when it has been issued by its emitter).
This is usually the same as
entry_date
. Exceptions may be invoices arriving after their fiscal year has been closed. Note that if you changeentry_date
of a voucher, then Lino will set thevoucher_date
to that date.
-
accounting_period
¶ The accounting period to use when booking this voucher. The default value is determined from
entry_date
.If user changes this field, the
number
gets re-computed because it might change depending on the fiscal year of the accounting period.
-
narration
¶ A short explanation which ascertains the subject matter of this journal entry.
-
number_with_year
¶ A text like "2019-12".
-
do_and_clear
(func, do_clear)¶ Delete all movements of this voucher, then run the given callable func, passing it a set with all partners who had at least one movement in this voucher. The function is expected to add more partners to this set. Then call
check_clearings()
for all these partners.
-
create_movement(item, acc_tuple, project, dc, amount, **kw):
Create a movement for this voucher.
The specified item may be None if this the movement is caused by more than one item. It is used by
DatedFinancialVoucher
.
-
get_partner
()¶ Return the partner related to this voucher. Overridden by PartnerRelated vouchers.
-
get_movement_description
(self, ar)¶ Generate a series of HTML chunks to be displayed in the
Movment.description
field.
-
get_wanted_movements
()¶ Subclasses must implement this. Supposed to return or yield a list of unsaved
Movement
instances.
-
get_mti_leaf(self):
Return the specialized form of this voucher.
From any
Voucher
instance we can get the actual document (Invoice, PaymentOrder, BankStatement, ...) by calling this method.
-
Class inheritance diagram

Registering a voucher¶
A ledger voucher is always in one of the three states "Draft", "Registered" or "Cancelled". "Registering a voucher" means to change it status from "Draft" to "Registered".
When a voucher is registered, it receives a sequence number in its journal and Lino generates the movements according to the data in the voucher.
A registered voucher cannot be edited or deleted.
You can deregister a voucher at any moment (except when you lack permission for this actions, or when the voucher is in a fiscal year that has been closed).
When you deregister a voucher, all movements are deleted.
-
class
lino_xl.lib.ledger.
RegistrableVoucher
¶ -
toggle_state
¶ Toggle between "registered" and "draft" state.
A one-click action to quickly toggle between the two the most-used states of a voucher.
>>> finan.BankStatement.toggle_state.help_text 'Toggle between "registered" and "draft" state.'
-
hide_editable_number
¶ We usually don't want to see the number of a voucher in an editable state because that number may change. We prefer to see the primary key prefixed with a hash to indicate that the voucher is not registered. But e.g. in
lino_xl.lib.orders
we want to disable this feature.NB we might simply override
__str__()
, but maybe this feature will be used in other contexts as well.
-
The state of a voucher is stored in a field voucher_state
. The available states and the rules
for changing the state are called the workflow.
-
class
lino_xl.lib.ledger.
ToggleState
¶ The action behind
RegistrableVoucher.toggle_state
.
Journals¶
Here is the list of all journals.
>>> ses.show(ledger.Journals,
... column_names="ref name trade_type account dc")
...
=========== ============================ ============================ ============================ ===================== =============================== ===========================
Reference Designation Designation (fr) Designation (en) Trade type Account Primary booking direction
----------- ---------------------------- ---------------------------- ---------------------------- --------------------- ------------------------------- ---------------------------
SLS Verkaufsrechnungen Factures vente Sales invoices Sales Credit
SLC Gutschriften Verkauf Notes de crédit vente Sales credit notes Sales Debit
PRC Einkaufsrechnungen Factures achat Purchase invoices Purchases Debit
PMO Zahlungsaufträge Ordre de paiement Bestbank Bestbank Payment Orders Bank payment orders (4300) Pending Payment Orders Credit
CSH Kassenbuch Livre de caisse Cash book (5700) Cash Credit
BNK Bestbank Bestbank Bestbank (5500) BestBank Credit
MSC Miscellaneous transactions Opérations diverses Miscellaneous transactions (5700) Cash Credit
PRE Preliminary transactions Preliminary transactions Preliminary transactions (5700) Cash Credit
SAL Lohnscheine Fiches de paie Paychecks (5700) Cash Debit
VAT MwSt.-Erklärungen Déclarations TVA VAT declarations Taxes (4513) VAT declared Debit
=========== ============================ ============================ ============================ ===================== =============================== ===========================
-
class
lino_xl.lib.ledger.
Journal
¶ Django model used to represent a journal.
Fields:
-
ref
¶
-
trade_type
¶ Pointer to
TradeTypes
.
-
voucher_type
¶ Pointer to an item of
VoucherTypes
.
-
journal_group
¶ Pointer to an item of
JournalGroups
.
-
force_sequence
¶
-
preliminary
¶ Whether transactions in this journal are considered preliminary.
-
account
¶ The account to use for the counter-movements generated by vouchers in this journal.
-
partner
¶ The partner to use as default partner for all vouchers in this journal.
-
printed_name
¶
-
dc
¶ The primary booking direction. Voucher items in this direction increase the total amount of the voucher.
In a journal of sales invoices this should be Credit because a positive invoice item should credit the turnover account (and hence their sum will debit the customers receivable account).
In a journal of purchase invoices this should be Debit because a positive invoice item should debit the cost account (and hence their sum will credit the suppliers payable account).
In a journal of bank statements this should be Credit because a crediting item (income) should increase the balance of the bank account while a debiting item (expense) should decrease it.
In a journal of payment orders this should be Debit because a positive total means an expense to be debited from the pending payment orders account (see
CommonAccounts
).In a journal of paychecks this should be Debit because a positive paycheck item should debit the wages account (and hence their sum will credit the employees payable account).
-
auto_check_clearings
¶ Whether to automatically check and update the 'cleared' status of involved transactions when (de)registering a voucher of this journal.
This can be temporarily disabled e.g. by batch actions in order to save time.
-
auto_fill_suggestions
¶ Whether to automatically fill voucher item from due payments of the partner when entering a financial voucher.
-
template
¶ See
PrintableType.template
.
-
sepa_account
¶ Your bank account to specify in payment order.
-
-
class
lino_xl.lib.ledger.
Journals
¶ List of all Journals. Accessible via
.
-
class
lino_xl.lib.ledger.
JournalsOverview
¶ The list of all Journals shown in the dashboard.
This is used as the primary dashboard item in Lino Così. It gives an idea of how much data is in the database, and it adds links for quickly opening a journal (which is after all one of the frequent actions in an accounting application).
>>> rt.login("robin").show(ledger.JournalsOverview) ... **72 Sales invoices (SLS)** **⊕** **0 Sales credit notes (SLC)** **⊕** **105 Purchase invoices (PRC)** **⊕** **14 Bestbank Payment Orders (PMO)** **⊕** **0 Cash book (CSH)** **⊕** **14 Bestbank (BNK)** **⊕** **0 Miscellaneous transactions (MSC)** **⊕** **1 Preliminary transactions (PRE)** **⊕** **0 Paychecks (SAL)** **⊕** **14 VAT declarations (VAT)** **⊕**
>>> rt.login("robin").show(ledger.JournalsOverview, nosummary=True) ... ======================================================== ========= =========== ============ ============ ========== Description Total This year This month Unfinished Warnings -------------------------------------------------------- --------- ----------- ------------ ------------ ---------- Sales invoices (SLS) / **New Invoice** **72** **15** **6** Sales credit notes (SLC) / **New Credit note** Purchase invoices (PRC) / **New Invoice** **105** **21** **7** Bestbank Payment Orders (PMO) / **New Payment order** **14** **2** Cash book (CSH) / **New Cash statement** Bestbank (BNK) / **New Bank statement** **14** **2** Miscellaneous transactions (MSC) / **New Transaction** Preliminary transactions (PRE) / **New Transaction** **1** Paychecks (SAL) / **New Paycheck** VAT declarations (VAT) / **New VAT declaration** **14** **2** **Total (10 rows)** **220** **42** **13** **0** ======================================================== ========= =========== ============ ============ ==========
Class inheritance diagram

Debit or credit? The PCSD rule¶
The "PCSD" rule: A purchase invoice credits the supplier's account, a sales invoice debits the customer's account.
>>> obj = vat.VatAccountInvoice.objects.order_by('id')[0]
>>> rt.show(vat.MovementsByVoucher, obj)
============================= ========== =========== =========== ========================== ================ =========
Account Partner Debit Credit VAT class Match Cleared
----------------------------- ---------- ----------- ----------- -------------------------- ---------------- ---------
(6010) Purchase of services 33,06 Goods at normal VAT rate Yes
(4520) VAT deductible 6,94 Goods at normal VAT rate Yes
(4100) Suppliers Bestbank 40,00 **PRC 1/2014** Yes
**40,00** **40,00**
============================= ========== =========== =========== ========================== ================ =========
>>> obj = sales.VatProductInvoice.objects.order_by('id')[0]
>>> rt.show(vat.MovementsByVoucher, obj)
================== ========== ============== ============== =========== ================ =========
Account Partner Debit Credit VAT class Match Cleared
------------------ ---------- -------------- -------------- ----------- ---------------- ---------
(7000) Sales 2 999,85 Services Yes
(4510) VAT due 629,97 Services Yes
(4000) Customers Bestbank 3 629,82 **SLS 1/2014** Yes
**3 629,82** **3 629,82**
================== ========== ============== ============== =========== ================ =========
So the balance of a supplier's account (when open) is usually on the credit side (they gave us money) while a customer's balance is usually on the debit side (they owe us money).
>>> print(ledger.TradeTypes.purchases.dc)
Credit
>>> print(ledger.TradeTypes.sales.dc)
Debit
Ledger info¶
-
class
lino_xl.lib.ledger.
LedgerInfo
¶ Django model used to store ledger specific information per user.
-
user
¶ OneToOneField pointing to the user.
-
entry_date
¶ The last value this user typed as
entry_date
of a voucher. It is the default value for every new voucher.
-
classmethod
get_by_user
(self, user)¶ Returns the ledger info entry for a given user.
-
Match rules¶
-
class
lino_xl.lib.ledger.
MatchRule
¶ Django model used to store match rules.
Payment terms¶
-
class
lino_xl.lib.ledger.
PaymentTerm
¶ Django model used to store payment terms.
The following fields define the default value for due_date:
-
days
¶ Number of days to add to
voucher_date
.
-
months
¶ Number of months to add to
voucher_date
.
-
end_of_month
¶ Whether to move
voucher_date
to the end of month.
-
worker
¶ The worker who pays or collects the invoice using Internal clearings.
-
printed_text
¶ Used in
sales/VatProductInvoice/trailer.html
as follows:{% if obj.payment_term.printed_text %} {{parse(obj.payment_term.printed_text)}} {% else %} {{_("Payment terms")}} : {{obj.payment_term}} {% endif %}
The
printed_text
field is important when using prepayments or other more complex payment terms. Lino uses a rather simple approach to handle prepayment invoices: only the global amount and the final due date is stored in the database, all intermediate amounts and due dates are just generated in the printable document. You just define onePaymentTerm
row for each prepayment formula and configure yourprinted_text
field. For example:Prepayment <b>30%</b> ({{(obj.total_incl*30)/100}} {{obj.currency}}) due on <b>{{fds(obj.due_date)}}</b>, remaining {{obj.total_incl - (obj.total_incl*30)/100}} {{obj.currency}} due 10 days before delivery.
-
Accounting periods¶
-
class
lino_xl.lib.ledger.
AccountingPeriod
¶ An accounting period is the smallest time slice to be observed (declare) in accounting reports. Usually it corresponds to one month. Except for some small companies which declare per quarter.
For each period it is possible to specify the exact dates during which it is allowed to register vouchers into this period, and also its "state": whether it is "closed" or not.
-
start_date
¶
-
end_date
¶
-
state
¶
-
year
¶
-
ref
¶
-
Actors¶
-
class
lino_xl.lib.ledger.
ByJournal
¶ Mixin for journal-based tables of vouchers.
Note that this is not explicitly marked as abstract by the application developer, but Lino knows that it is abstract because it has no model.
>>> ledger.ByJournal.abstract False >>> ledger.ByJournal.is_abstract() True
-
class
lino_xl.lib.ledger.
ExpectedMovements
¶ A virtual table of
DueMovement
rows, showing all "expected" "movements (payments)".Subclasses are
DebtsByAccount
andDebtsByPartner
.Also subclassed by
lino_xl.lib.finan.SuggestionsByVoucher
.-
date_until
¶ Show only movements whose booking date is before or on the given date.
-
trade_type
¶ Show only movements in the given trade type.
-
from_journal
¶ Show only movements generated by a voucher in the given journal.
-
for_journal
¶ Show only movements that may be matched by the given journal (i.e. for which a match rule exists).
-
account
¶ Show only movements on the given account.
-
partner
¶ Show only movements with the given partner.
-
project
¶ Show only movements about the given project.
-
show_sepa
¶ Show only movements whose partner has a SEPA account.
-
same_dc
¶ Show only movements having the same booking direction as the target voucher.
-
-
class
lino_xl.lib.ledger.
DebtsByAccount
¶ The
ExpectedMovements
accessible by clicking the "Debts" action button on an account.
-
class
lino_xl.lib.ledger.
DebtsByPartner
¶ This is the table being printed in a Payment Reminder. Usually this table has one row per sales invoice which is not fully paid. But several invoices ("debts") may be grouped by match. If the partner has purchase invoices, these are deduced from the balance.
This table is accessible by clicking the "Debts" action button on a Partner.
-
class
lino_xl.lib.ledger.
PartnerVouchers
¶ Base class for tables of partner vouchers.
-
cleared
¶ Yes : show only completely cleared vouchers.
No : show only vouchers with at least one open partner movement.
empty: don't care about movements.
-
-
class
lino_xl.lib.ledger.
AccountsBalance
¶ A virtual table, the base class for different reports that show a list of accounts with the following columns:
ref description old_d old_c during_d during_c new_d new_c
Subclasses are :class:'GeneralAccountsBalance`, :class:'CustomerAccountsBalance` and :class:'SupplierAccountsBalance`.
-
class
lino_xl.lib.ledger.
GeneralAccountsBalance
¶ An
AccountsBalance
for general accounts.
-
class
lino_xl.lib.ledger.
PartnerAccountsBalance
¶ An
AccountsBalance
for partner accounts.
-
class
lino_xl.lib.ledger.
CustomerAccountsBalance
¶ A
PartnerAccountsBalance
for the TradeType "sales".
-
class
lino_xl.lib.ledger.
SuppliersAccountsBalance
¶ A
PartnerAccountsBalance
for the TradeType "purchases".
-
class
lino_xl.lib.ledger.
DebtorsCreditors
¶ Abstract base class for different tables showing a list of partners with the following columns:
partner due_date balance actions
-
class
lino_xl.lib.ledger.
Debtors
¶ Shows partners who have some debt against us. Inherits from
DebtorsCreditors
.
-
class
lino_xl.lib.ledger.
Creditors
¶ Shows partners who give us some form of credit. Inherits from
DebtorsCreditors
.
Trade types¶
The trade type is one of the basic properties of every ledger operation that involves an external partner. Every movement involving a partner is of one and only one trade type.
The default list of trade types is:
>>> rt.show(ledger.TradeTypes)
...
======= =========== ===================== ======================================================== ============================================== =============================== =====================================
value name text Main account Base account Product account field Invoice account field
------- ----------- --------------------- -------------------------------------------------------- ---------------------------------------------- ------------------------------- -------------------------------------
S sales Sales (4000) Customers (Customers) (7000) Sales (Sales) Sales account (sales_account)
P purchases Purchases (4100) Suppliers (Suppliers) (6040) Purchase of goods (Purchase of goods) Purchase account (purchase_account)
W wages Wages (4200) Employees (Employees) (6300) Wages (Wages)
T taxes Taxes (4500) Tax Offices (Tax Offices) (4513) VAT declared (VAT declared)
C clearings Clearings (4800) Internal clearings (Internal clearings)
B bank_po Bank payment orders (4300) Pending Payment Orders (Pending Payment Orders)
======= =========== ===================== ======================================================== ============================================== =============================== =====================================
Your application might have a different list. You can see the actually configured list for your site via
.-
class
lino_xl.lib.ledger.
TradeTypes
¶ The choicelist with the trade types defined for this application.
The default configuration defines the following trade types:
-
sales
¶ When you write an invoice to a customer and when the customer pays it.
-
purchases
¶ When you get an invoice from a provider and when you pay it.
-
wages
¶ When you write a payroll (declare the fact that you owe some wage to an employee) and later pay it (e.g. via a payment order).
-
clearings
¶ When an employee declares that he paid some invoice for you, and later you pay that money back to his account. Or the employee collects money for a sales invoice and later returns that money to you. See Internal clearings.
-
bank_po
¶ When you ask your bank to execute a payment, and later the bank debits your account.
-
Every trade type has the following properties.
-
class
lino_xl.lib.ledger.
TradeType
¶ Base class for the choices of
TradeTypes
.-
dc
¶ The default booking direction.
-
main_account
¶ The common account into which the total amount of partner vouchers (base + taxes) and their payments should be booked.
-
base_account
¶ The default common account into which the base amount of any operation should be booked.
-
invoice_account_field_name
¶ The name of a field to be injected on the
Partner
model which points to an account to be used instead of the defaultbase_account
.
-
base_account_field_name
¶ The name of a field to be injected on the
Product
database model which points to an account to be used instead of the defaultbase_account
.
-
price_field
¶ The name and label of the price field to be defined on the
Product
database model.
-
get_product_base_account
(product)¶ Return the account into which the base amount of any operation of this rete type should be booked.
This is either the base account defined in the
base_account_field_name
for the given product, or the site-widebase_account
.
-
get_catalog_price
(product)¶ Return the catalog price of the given product for operations with this trade type.
-
get_partner_invoice_account
(partner)¶ Return the account to use as default value for account invoice items. This is the
invoice_account_field
of the given partner and can be None.
-
Match rules¶
A match rule specifies that a movement into given account can be cleared using a given journal.
You can configure match rules either in the detail view of a journal or globally via
.The demo database has the following match rules:
>>> ses.show(ledger.MatchRules)
...
==== =============================== ==================================
ID Account Journal
---- ------------------------------- ----------------------------------
1 (4000) Customers Sales invoices (SLS)
2 (4000) Customers Sales credit notes (SLC)
3 (4100) Suppliers Purchase invoices (PRC)
4 (4000) Customers Bestbank Payment Orders (PMO)
5 (4100) Suppliers Bestbank Payment Orders (PMO)
6 (4500) Tax Offices Bestbank Payment Orders (PMO)
7 (6300) Wages Bestbank Payment Orders (PMO)
8 (4000) Customers Cash book (CSH)
9 (4100) Suppliers Cash book (CSH)
10 (4500) Tax Offices Cash book (CSH)
11 (6300) Wages Cash book (CSH)
12 (4300) Pending Payment Orders Cash book (CSH)
13 (4000) Customers Bestbank (BNK)
14 (4100) Suppliers Bestbank (BNK)
15 (4500) Tax Offices Bestbank (BNK)
16 (6300) Wages Bestbank (BNK)
17 (4300) Pending Payment Orders Bestbank (BNK)
18 (4000) Customers Miscellaneous transactions (MSC)
19 (4100) Suppliers Miscellaneous transactions (MSC)
20 (4500) Tax Offices Miscellaneous transactions (MSC)
21 (6300) Wages Miscellaneous transactions (MSC)
22 (4300) Pending Payment Orders Miscellaneous transactions (MSC)
23 (4000) Customers Preliminary transactions (PRE)
24 (4100) Suppliers Preliminary transactions (PRE)
25 (4500) Tax Offices Preliminary transactions (PRE)
26 (6300) Wages Preliminary transactions (PRE)
27 (4300) Pending Payment Orders Preliminary transactions (PRE)
28 (4000) Customers Paychecks (SAL)
29 (4100) Suppliers Paychecks (SAL)
30 (4500) Tax Offices Paychecks (SAL)
31 (6300) Wages Paychecks (SAL)
32 (4300) Pending Payment Orders Paychecks (SAL)
33 (4500) Tax Offices VAT declarations (VAT)
==== =============================== ==================================
For example a payment order can be used to pay wages and suppliers invoices or (less frequently) to send back money that a customer had paid too much:
>>> jnl = ledger.Journal.objects.get(ref="PMO")
>>> rt.show(ledger.MatchRulesByJournal, jnl)
====================
Account
--------------------
(4000) Customers
(4100) Suppliers
(4500) Tax Offices
(6300) Wages
====================
Or a sales invoice can be used to clear another sales invoice:
>>> jnl = ledger.Journal.objects.get(ref="SLS")
>>> rt.show(ledger.MatchRulesByJournal, jnl)
==================
Account
------------------
(4000) Customers
==================
Debtors¶
Debtors are partners who received credit from us and therefore are in debt towards us.
The most common debtors are customers, i.e. partners who received a sales invoice from us and did not yet pay that invoice.
There can be debtors who are not customers. For example a tax office. A bank is a debtor when pending payment orders are booked to this account. A tax office is a debtor when we had more VAT deductible (sales) than VAT due (purchases).
>>> ses.show(ledger.Debtors, column_names="due_date partner partner_id balance")
...
==================== ======================= ========== ===============
Due date Partner ID Balance
-------------------- ----------------------- ---------- ---------------
10/02/2014 Dubois Robin 179 8 908,45
08/02/2015 Radermacher Christian 155 853,97
11/02/2015 Radermacher Fritz 158 632,96
07/03/2015 Radermacher Hedi 161 3 629,82
09/03/2015 Radermacher Jean 163 822,57
10/03/2015 di Rupo Didier 164 338,80
11/03/2015 da Vinci David 165 1 946,43
**Total (7 rows)** **1145** **17 133,00**
==================== ======================= ========== ===============
The DebtsByPartner
shows one row
per uncleared invoice, and a list of --usually partial-- payments per invoice.
This table is used for both debtors and creditors, which can be useful when you
have business partners who are both customers and providers.
By convention, this list shows a debit balance as a negative number and a crediting balance as a positive number.
For example here is the detail of the debts for partner 165 from above list:
>>> obj = contacts.Partner.objects.get(pk=165)
>>> obj
Partner #165 ('da Vinci David')
>>> ses.show(ledger.DebtsByPartner, obj)
...
==================== =============== ========================== ==========
Due date Balance Debts Payments
-------------------- --------------- -------------------------- ----------
11/03/2015 -647,35 `SLS 14/2015 <Detail>`__
12/03/2015 -1 299,08 `SLS 15/2015 <Detail>`__
**Total (2 rows)** **-1 946,43**
==================== =============== ========================== ==========
Here is an example of a provider to whom we owe money:
>>> obj = contacts.Partner.objects.get(pk=101)
>>> obj
Partner #101 ('Rumma & Ko OÜ')
>>> ses.show(ledger.DebtsByPartner, obj)
...
==================== ============ ======= ==========================
Due date Balance Debts Payments
-------------------- ------------ ------- --------------------------
04/03/2015 141,60 `PRC 16/2015 <Detail>`__
**Total (1 rows)** **141,60**
==================== ============ ======= ==========================
Creditors are partners who gave us credit, IOW to whom we owe money. The most common creditors are providers, i.e. partners who sent us a purchase invoice (which we did not yet pay).
>>> ses.show(ledger.Creditors, column_names="partner partner_id balance")
...
===================== ========= ==============
Partner ID Balance
--------------------- --------- --------------
Bestbank 100 42,90
Rumma & Ko OÜ 101 141,60
Bäckerei Ausdemwald 102 608,20
Bäckerei Mießen 103 1 214,40
Bäckerei Schmitz 104 3 272,98
Garage Mergelsberg 105 143,40
Donderweer BV 106 204,40
**Total (7 rows)** **721** **5 627,88**
===================== ========= ==============
(Currently not tested because the only example is a sales invoice for 101 in 2014-01 which is already paid. need to adapt some fixture to getmore cases) Partner 101 from above list is both a supplier and a customer: Note that most numbers in above table are negative. A purchase invoice is a credit received from the provider, and we asked a list of debts by partner.
>>> obj = contacts.Partner.objects.get(pk=101)
>>> ses.show(ledger.DebtsByPartner, obj)
...
===================== ============ ========================= ==========================
Due date Balance Debts Payments
--------------------- ------------ ------------------------- --------------------------
04/01/2016 -141,30 `PRC 2/2016 <Detail>`__
08/01/2016 2 039,82 `SLS 2/2016 <Detail>`__
04/02/2016 -142,00 `PRC 9/2016 <Detail>`__
04/03/2016 -143,40 `PRC 16/2016 <Detail>`__
04/04/2016 -142,10 `PRC 23/2016 <Detail>`__
04/05/2016 -140,20 `PRC 30/2016 <Detail>`__
04/06/2016 -141,30 `PRC 37/2016 <Detail>`__
04/07/2016 -142,00 `PRC 44/2016 <Detail>`__
04/08/2016 -143,40 `PRC 51/2016 <Detail>`__
04/09/2016 -142,10 `PRC 58/2016 <Detail>`__
04/10/2016 -140,20 `PRC 65/2016 <Detail>`__
04/11/2016 -141,30 `PRC 72/2016 <Detail>`__
04/12/2016 -142,00 `PRC 79/2016 <Detail>`__
04/01/2017 -144,80 `PRC 2/2017 <Detail>`__
04/02/2017 -143,50 `PRC 9/2017 <Detail>`__
04/03/2017 -141,60 `PRC 16/2017 <Detail>`__
**Total (16 rows)** **-91,38**
===================== ============ ========================= ==========================
Fiscal years¶
Lino has a table of fiscal years. A fiscal year often corresponds to the calendar year, but not necessarily.
If lino_xl.lib.sheets
is installed, the detail window of a
FiscalYear object shows the financial reports (balance sheet and
income statement) for this year.
-
class
lino_xl.lib.ledger.
FiscalYears
¶ The fiscal years available in this database.
The lino_xl.lib.ledger.fixtures.std
fixture fills this table
with 5 years starting from start_year
.
>>> dd.plugins.ledger.start_year
2014
>>> dd.today()
datetime.date(2015, 3, 12)
>>> dd.today().year + 5
2020
>>> rt.show(ledger.FiscalYears)
...
=========== ============ ============ =======
Reference Start date End date State
----------- ------------ ------------ -------
2014 01/01/2014 31/12/2014 Open
2015 01/01/2015 31/12/2015 Open
2016 01/01/2016 31/12/2016 Open
2017 01/01/2017 31/12/2017 Open
2018 01/01/2018 31/12/2018 Open
2019 01/01/2019 31/12/2019 Open
2020 01/01/2020 31/12/2020 Open
=========== ============ ============ =======
Accounting periods¶
Each ledger movement happens in a given accounting period. An accounting period usually corresponds to a month of the calendar. Accounting periods are automatically created the first time they are needed by some operation.
>>> rt.show(ledger.AccountingPeriods)
...
=========== ============ ============ ============= ======= ========
Reference Start date End date Fiscal year State Remark
----------- ------------ ------------ ------------- ------- --------
2014-01 01/01/2014 31/01/2014 2014 Open
2014-02 01/02/2014 28/02/2014 2014 Open
2014-03 01/03/2014 31/03/2014 2014 Open
2014-04 01/04/2014 30/04/2014 2014 Open
2014-05 01/05/2014 31/05/2014 2014 Open
2014-06 01/06/2014 30/06/2014 2014 Open
2014-07 01/07/2014 31/07/2014 2014 Open
2014-08 01/08/2014 31/08/2014 2014 Open
2014-09 01/09/2014 30/09/2014 2014 Open
2014-10 01/10/2014 31/10/2014 2014 Open
2014-11 01/11/2014 30/11/2014 2014 Open
2014-12 01/12/2014 31/12/2014 2014 Open
2015-01 01/01/2015 31/01/2015 2015 Open
2015-02 01/02/2015 28/02/2015 2015 Open
2015-03 01/03/2015 31/03/2015 2015 Open
2015-12 01/12/2015 31/12/2015 2015 Open
=========== ============ ============ ============= ======= ========
The reference of a new accounting period is computed by applying the
voucher's entry date to the template defined in the date_to_period_tpl
attribute of the ledger
plugin. The default implementation leads to the following references:
>>> print(ledger.AccountingPeriod.get_ref_for_date(i2d(19940202)))
1994-02
>>> print(ledger.AccountingPeriod.get_ref_for_date(i2d(20150228)))
2015-02
>>> print(ledger.AccountingPeriod.get_ref_for_date(i2d(20150401)))
2015-04
You may manually create additional accounting periods. For example
2015-00 might stand for a fictive "opening" period before January 2015 and after December 2014.
2015-13 might stand for January 2016 in a company which is changing their fiscal year from "January-December" to "July-June".
Payment terms¶
>>> rt.show('ledger.PaymentTerms')
==================== ==================================== ==================================== ======================================= ======== ========= ============== =================
Reference Designation Designation (fr) Designation (en) Months Days End of month Worker
-------------------- ------------------------------------ ------------------------------------ --------------------------------------- -------- --------- -------------- -----------------
07 Zahlung sieben Tage Rechnungsdatum Zahlung sieben Tage Rechnungsdatum Payment seven days after invoice date 0 7 No
10 Zahlung zehn Tage Rechnungsdatum Zahlung zehn Tage Rechnungsdatum Payment ten days after invoice date 0 10 No
30 Zahlung 30 Tage Rechnungsdatum Zahlung 30 Tage Rechnungsdatum Payment 30 days after invoice date 0 30 No
60 Zahlung 60 Tage Rechnungsdatum Zahlung 60 Tage Rechnungsdatum Payment 60 days after invoice date 0 60 No
90 Zahlung 90 Tage Rechnungsdatum Zahlung 90 Tage Rechnungsdatum Payment 90 days after invoice date 0 90 No
EOM Zahlung Monatsende Zahlung Monatsende Payment end of month 0 0 Yes
P30 Anzahlung 30% Anzahlung 30% Prepayment 30% 0 30 No
PIA Vorauszahlung Vorauszahlung Payment in advance 0 0 No
robin Cash Robin Cash Robin Cash Robin 0 0 No Mr Robin Dubois
**Total (9 rows)** **0** **227**
==================== ==================================== ==================================== ======================================= ======== ========= ============== =================
Journal groups¶
-
class
lino_xl.lib.ledger.
JournalGroup
¶ The name of another plugin
For each journal group there will be a menu item in the main menu.
If the journal group has a
menu_group
, then journals are added to the menu of the named plugin, otherwise to the menu of the ledger plugin.
-
class
lino_xl.lib.ledger.
JournalGroups
¶ The list of possible journal groups.
This list is used to build the main menu. Journals whose
journal_group
is empty will not be available through the main user menu. See alsoJournalGroup.menu_group
.The default configuration defines the following journal groups:
>>> rt.show(ledger.JournalGroups) ... ======= =========== ============================ value name text ------- ----------- ---------------------------- 10 sales Sales 20 purchases Purchases 30 wages Wages 40 financial Financial 50 vat VAT 60 misc Miscellaneous transactions ======= =========== ============================
-
sales
¶ For sales journals.
-
purchases
¶ For purchases journals.
-
wages
¶ For wages journals.
-
financial
¶ For financial journals (bank statements and cash reports)
-
Voucher types¶
The ledger plugin defines a list of voucher types, a choicelist that is
populated by other plugins like lino_xl.lib.vat
, lino_xl.lib.sales
or lino_xl.lib.orders
who define some subclass of Voucher
and
then must "register" that model to be used by one or several voucher types.
Every journal must have its voucher type, configured in the journal's
voucher_type
field. Several
journals may share a same voucher type. The voucher type of a journal must not
change as long as the journal has at least one voucher.
-
class
lino_xl.lib.ledger.
VoucherTypes
¶ The list of voucher types available in this application.
Each item is an instances of
VoucherType
.-
get_for_model
()¶
-
get_for_table
()¶
-
-
class
lino_xl.lib.ledger.
VoucherType
¶ Base class for all items of
VoucherTypes
.The voucher type defines the database model used to store vouchers of this type (
model
).In more complex cases the application developer can define more than one voucher type per model by providing alternative tables (views) for it.
-
model
¶ The database model used to store vouchers of this type. A subclass of
lino_xl.lib.ledger.models.Voucher`
.
-
-
class
lino_xl.lib.ledger.
VoucherState
¶ Base class for items of
VoucherStates
.-
is_editable
¶ Whether a voucher in this state is editable.
-
-
class
lino_xl.lib.ledger.
VoucherStates
¶ The list of possible states of a voucher.
In a default configuration, vouchers can be
draft
,registered
,cancelled
orsigned
.>>> rt.show(ledger.VoucherStates) ======= ============ ============ ========== value name text Editable ------- ------------ ------------ ---------- 10 draft Draft Yes 20 registered Registered No 30 signed Signed No 40 cancelled Cancelled No ======= ============ ============ ==========
-
draft
¶ Draft vouchers can be modified but are not yet visible as movements in the ledger.
-
registered
¶ Registered vouchers cannot be modified, but are visible as movements in the ledger.
-
cancelled
¶ Cancelled is similar to Draft, except that you cannot edit the fields. This is used for invoices which have been sent, but the customer signaled that they doen't agree. Instead of writing a credit nota, you can decide to just cancel the invoice.
-
signed
¶ The Signed state is similar to registered, but cannot usually be deregistered anymore. This state is not visible in the default configuration. In order to make it usable, you must define a custom workflow for
VoucherStates
.
-
Model mixins¶
-
class
lino_xl.lib.ledger.
SequencedVoucherItem
¶ A
VoucherItem
which also inherits fromlino.mixins.sequenced.Sequenced
.
-
class
lino_xl.lib.ledger.
AccountVoucherItem
¶ Abstract base class for voucher items which point to an account.
This is also a
SequencedVoucherItem
.This is subclassed by
lino_xl.lib.vat.models.InvoiceItem
andlino_xl.lib.vatless.models.InvoiceItem
.It defines the
account
field and some related methods.-
account
¶ ForeignKey pointing to the account (
ledger.Account
) that is to be moved.
-
-
class
lino_xl.lib.ledger.
VoucherItem
¶ Base class for items of a voucher.
Subclasses must define the following fields:
-
voucher
¶ Pointer to the voucher which contains this item. Non nullable. The voucher must be a subclass of
ledger.Voucher
. The related_name must be 'items'.
-
title
¶ The title of this voucher.
Currently (because of Django ticket #19465), this field is not implemented here but in the subclasses:
lino_xl.lib.vat.models.AccountInvoice
lino_xl.lib.vat.models.InvoiceItem
-
-
class
lino_xl.lib.ledger.
Matching
¶ Model mixin for database objects that are considered matching transactions. A matching transaction is a transaction that points to some other movement which it "clears" at least partially.
A movement is cleared when its amount equals the sum of all matching movements.
Adds a field
match
and a chooser for it. Requires a field partner. The default implementation of the chooser formatch
requires a journal.Base class for
lino_xl.lib.vat.AccountInvoice
(and e.g. lino_xl.lib.sales.Invoice, lino_xl.lib.finan.DocItem)-
match
¶ Pointer to the
movement
which is being cleared by this movement.
-
-
class
lino_xl.lib.ledger.
PartnerRelated
¶ Base class for things that are related to one and only one trade partner. This is base class for both (1) trade document vouchers (e.g. invoices or offers) and (2) for the individual entries of financial vouchers and ledger movements.
-
partner
¶ The recipient of this document. A pointer to
lino_xl.lib.contacts.models.Partner
.
-
payment_term
¶ The payment terms to be used in this document. A pointer to
PaymentTerm
.
-
recipient
¶ Alias for the partner
-
-
class
lino_xl.lib.ledger.
ProjectRelated
¶ Model mixin for objects that are related to a
project
.-
project
¶ Pointer to the "project". This field exists only if the
project_model
setting is nonempty.
-
-
class
lino_xl.lib.ledger.
Payable
¶ Model mixin for objects that represent a payable transaction.
Inherits from
PartnerRelated
.-
your_ref
¶
-
due_date
¶
-
payment_term
¶ See
lino_xl.lib.ledger.mixins.PartnerRelated.payment_term
-
title
¶ A char field with a description for this transaction.
-
get_payable_sums_dict
(self)¶ To be implemented by subclasses. Expected to return a dict which maps 4-tuples (acc_tuple, project, vat_class, vat_regime) to the payable amount. acc_tuple is itself a tuple (general_account, analytic_account), vat_class is a
lino_xl.lib.vat.VatClasses
choice and vat_regime alino_xl.lib.vat.VatRegimes
choice.
-
get_wanted_movements
(self)¶ Implements
lino_xl.lib.ledger.Voucher.get_wanted_movements()
.
-
-
class
lino_xl.lib.ledger.
PeriodRange
¶ Model mixin for objects that cover a range of accounting periods.
-
start_period
¶ The first period of the range to cover.
-
end_period
¶ The last period of the range to cover.
Leave empty if you want only one period (specified in
start_period
). If this is non-empty, all periods between and including these two are covered.
-
get_period_filter
(self, voucher_prefix, **kwargs)¶
-
-
class
lino_xl.lib.ledger.
PeriodRangeObservable
¶ Model mixin for objects that can be filtered by a range of accounting periods. This adds two parameter fields
start_period
andend_period
to every table on this model.Class attribute:
-
observable_period_field = 'accounting_period'
The name of the database field on the observed model to use for filtering.
-
-
class
lino_xl.lib.ledger.
ItemsByVoucher
¶ Shows the items of this voucher.
This is used as base class for slave tables in
lino_xl.lib.finan
,lino_xl.lib.vat
,lino_xl.lib.vatless
,lino_xl.lib.ana
, ...
Filtering partners regarding ledger movements¶
The ledger plugin adds a choice
has_open_movements
to the
observed_events
parameter field
of the lino_xl.lib.contacts.Partners
table.
Show only companies that have at least one open ledger movement:
>>> pv = dict(observed_event=rt.models.contacts.PartnerEvents.has_open_movements)
>>> rt.login("robin").show(contacts.Companies, param_values=pv)
...
===================== ===================================================== ================ ======= ===== ===== ==========
Name Address e-mail address Phone GSM ID Language
--------------------- ----------------------------------------------------- ---------------- ------- ----- ----- ----------
Bestbank 100
Bäckerei Ausdemwald Vervierser Straße 45, 4700 Eupen 102
Bäckerei Mießen Gospert 103, 4700 Eupen 103
Bäckerei Schmitz Aachener Straße 53, 4700 Eupen 104
Donderweer BV Edisonstraat 12, 4816 AR Breda, Netherlands 106
Garage Mergelsberg Hauptstraße 13, 4730 Raeren 105
Rumma & Ko OÜ Uus tn 1, Vigala vald, 78003 Rapla maakond, Estonia 101
===================== ===================================================== ================ ======= ===== ===== ==========
>>> settings.SITE.the_demo_date
datetime.date(2015, 3, 12)
>>> pv['start_date'] = i2d(20141231)
>>> rt.login("robin").show(contacts.Companies, param_values=pv)
...
===================== ===================================================== ================ ======= ===== ===== ==========
Name Address e-mail address Phone GSM ID Language
--------------------- ----------------------------------------------------- ---------------- ------- ----- ----- ----------
Bestbank 100
Bäckerei Ausdemwald Vervierser Straße 45, 4700 Eupen 102
Bäckerei Mießen Gospert 103, 4700 Eupen 103
Bäckerei Schmitz Aachener Straße 53, 4700 Eupen 104
Donderweer BV Edisonstraat 12, 4816 AR Breda, Netherlands 106
Garage Mergelsberg Hauptstraße 13, 4730 Raeren 105
Rumma & Ko OÜ Uus tn 1, Vigala vald, 78003 Rapla maakond, Estonia 101
===================== ===================================================== ================ ======= ===== ===== ==========
>>> pv['start_date'] = i2d(20151231)
>>> rt.login("robin").show(contacts.Companies, param_values=pv)
...
No data to display
Utilities¶
-
class
lino_xl.lib.ledger.
DueMovement
¶ A volatile object representing a group of matching movements.
A due movement is a movement which a partner should do in order to clear their debt. Or which we should do in order to clear our debt towards a partner.
The "matching" movements of a given movement are those whose match, partner and account fields have the same values.
These movements are themselves grouped into "debts" and "payments". A "debt" increases the debt and a "payment" decreases it.
-
match
¶ The common match string of these movments
-
dc
¶ Whether I mean my debts and payments (towards that partner) or those of the partner (towards me).
-
partner
¶
-
account
¶
-
-
lino_xl.lib.ledger.
get_due_movements
(dc, flt)¶ Generates a series of
DueMovement
objects which --if they were booked-- would clear the movements given by the filter condition flt.There will be at most one
DueMovement
per (account, partner, project, match), each of them grouping the movements with same partner, account, project and match.This is the data source for
ExpectedMovements
and subclasses.The balances of the
DueMovement
objects will be positive or negative depending on the specified dc.Arguments:
-
lino_xl.lib.ledger.
check_clearings
(qs, matches=[])¶ Check whether involved movements are cleared or not, and update their
cleared
field accordingly.
-
lino_xl.lib.ledger.
check_clearings_by_account
(account, matches=[])¶ Call
check_clearings()
for the given ledger account.
-
lino_xl.lib.ledger.
check_clearings_by_partner
(partner, matches=[])¶ Call
check_clearings()
for the given partner.
Plugin attributes¶
See lino_xl.lib.ledger.Plugin
.
Mixins¶
-
class
lino_xl.lib.ledger.
AccountBalances
¶ A table which shows a list of general ledger accounts during the observed period, showing their old and new balances and the sum of debit and credit movements.
The Y2K problem¶
Lino supports accounting across milleniums.
>>> FiscalYear = rt.models.ledger.FiscalYear
>>> print(FiscalYear.year2ref(1985))
1985
>>> print(FiscalYear.year2ref(9985))
9985
But there are legacy systems where the year was internally represented using a two-letter code.
The
fix_y2k
is either True or
False.
>>> dd.plugins.ledger.fix_y2k
False
>>> dd.plugins.ledger.fix_y2k = True
>>> print(FiscalYear.year2ref(1985))
85
>>> print(FiscalYear.year2ref(1999))
99
>>> print(FiscalYear.year2ref(2000))
A0
>>> print(FiscalYear.year2ref(2015))
B5
>>> print(FiscalYear.year2ref(2135))
N5
>>> print(FiscalYear.year2ref(2259))
Z9
>>> print(FiscalYear.year2ref(2260))
[0
The on_ledger_movement signal¶
-
lino_xl.lib.ledger.
on_ledger_movement
¶ Custom signal sent when a partner has had at least one change in a ledger movement.
sender the database model
instance the partner
Don't read me¶
Until 20181016 it was not possible to manually reverse the sort order
of a virtual field having a sortable_by which contained itself a
reversed field. The Movement.credit
field is an example:
>>> rmu(ledger.Movement.get_data_elem('credit').sortable_by)
['-amount', 'value_date']
>>> par = contacts.Partner.objects.get(pk=109)
>>> rt.show(ledger.MovementsByPartner, par, nosummary=True)
============ =============== ================================================== ============ ============ ============= =========
Value date Voucher Description Debit Credit Match Cleared
------------ --------------- -------------------------------------------------- ------------ ------------ ------------- ---------
21/04/2014 *BNK 4/2014* *(4000) Customers* | *Bernd Brechts Bücherladen* 19,36 SLS 10/2014 Yes
21/03/2014 *BNK 3/2014* *(4000) Customers* | *Bernd Brechts Bücherladen* 367,84 SLS 10/2014 Yes
07/03/2014 *SLS 10/2014* *(4000) Customers* 387,20 SLS 10/2014 Yes
**Balance 0.00 (3 movements)** **387,20** **387,20**
============ =============== ================================================== ============ ============ ============= =========
>>> mt = contenttypes.ContentType.objects.get_for_model(par.__class__).pk
>>> url = "api/ledger/MovementsByPartner?fmt=json&mk={}&mt={}".format(par.pk, mt)
>>> args = ('count rows no_data_text success title param_values', 3)
>>> demo_get('robin', url + "&sort=credit&dir=ASC", *args)
The following failed before 20181016:
>>> demo_get('robin', url + "&sort=credit&dir=DESC", *args)
Templates¶
-
payment_reminder.body.html
¶ Defines the body text of a payment reminder.
-
base.weasy.html
¶
-
payment_reminder.weasy.html
¶ Defines the body text of a payment reminder.
Generating counter-entries¶
A payment order generates counter entries
If you want Lino to suggest the cleaning of payment orders when entering bank
statements, then create a an organization (contacts.Company
)
representing your bank and have the Journal.partner
field point to that
partner.
Note that the journal must also have an account
with
Account.needs_partner
enabled in order to prevent Lino from generating
detailed counter-entries (one per item). Clearing a payment order makes sense
only when the counter-entry is the sum of all movements.
The reregister
admin command¶
In certain exceptional situations you may want to rebuild all the ledger movements on your site. For example after the changes on 2020-10-15 (see 2020). Or when you have changed something in your site configuration so that certain movements would go to other accounts than before (and want to apply this change to all registered vouchers).
The reregister
admin command re-registers all ledger vouchers.
-
reregister
¶
Re-register all ledger vouchers.
If no arguments are given, run it on all vouchers. Otherwise every positional argument is expected to be the ref of a journal, and are being re-registered.
When called with no arguments, all movements are deleted from the database. This can help if the database contains movments with invalid voucher pointer.
Example run:
>>> from atelier.sheller import Sheller
>>> shell = Sheller(settings.SITE.project_dir.parent)
>>> shell('python manage.py reregister --noinput')
...
Re-register all vouchers in journal Verkaufsrechnungen (SLS)
Re-register all vouchers in journal Gutschriften Verkauf (SLC)
Re-register all vouchers in journal Einkaufsrechnungen (PRC)
Re-register all vouchers in journal Zahlungsaufträge (PMO)
Re-register all vouchers in journal Kassenbuch (CSH)
Re-register all vouchers in journal Bestbank (BNK)
Re-register all vouchers in journal Miscellaneous transactions (MSC)
Re-register all vouchers in journal Preliminary transactions (PRE)
Re-register all vouchers in journal Lohnscheine (SAL)
Re-register all vouchers in journal MwSt.-Erklärungen (VAT)
220 vouchers have been re-registered.
Check clearings for all partners