Skip to main content

Cookbook

Cookbook is a module designed to consolidate your financial events and export them as bookings on your general ledgers. The logic telling EVA how to transform your financial events into consolidated bookings is defined in so-called recipes.


A recipe is always attached to financial event type, and therefore only relevant for that specific event type. Above example shows a recipe in its simplest form and applies to the 'Sales' event.

After stating the event, the recipe contains logic defining what amounts should be debited to which account, and what amounts should be credited to which account. In its simplest form, the recipe just credits one account with the full sales amount, and just debits another account with the full sales amount. In this, accounts represent your general ledgers. In the actual Cookbook language, this would look something like this:

recipe for Sales

debit:
- book [Amount] to 1111 'EVA'

credit:
- book [Amount] to 2222 'Revenue'

The [Amount] can represent a lot of different things, depending on the event type.

With the above recipe in place, all sales made will result in a journal debit entry of the full sales amount to general ledger account 1111, and a credit entry of the same value to the general ledger account 2222. Upon day closing, these bookings will be consolidated and exported to an endpoint. If we only had one sales transaction made of 1812.25 on a day, the export would look like this:

{
"OrganizationUnit": {
"BackendID": "tortuga_store",
"BackendCompanyID": null,
"Name": "Tortuga Store",
"TimeZone": "Etc/GMT-5",
"CurrentOffset": 300
},
"Period": {
"ID": 23,
"Number": null,
"OpeningTime": "2021-06-08T13:06:19.97Z",
"ClosingTime": "2021-06-08T13:08:07.273Z"
},
"Entries": [
{
"CurrencyID": "HTG",
"AccountName": "EVA",
"AccountObject": "1111",
"TaxCodeBackendID": null,
"Offset1": null,
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": 1812.25,
"Remark": null,
"Reference": null
},
{
"CurrencyID": "HTG",
"AccountName": "Revenue",
"AccountObject": "2222",
"TaxCodeBackendID": null,
"Offset1": null,
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": -1812.25,
"Remark": null,
"Reference": null
}
]
}

Setting up your configuration

Before we can start crafting our recipes, there's a few things that should be in place.

Setting up accounts

First off, you need to set up your Accounts. You should create an account for every general ledger you have in place in your ERP system so that every general ledger is represented by an account in EVA. Accounts can be set up in the General ledger accounts chapter.

Specifying an endpoint

Secondly, you have to specify an endpoint for your end-of-day report export where the report will be sent to. Set the endpoint in the settings module under the setting name FinancialPeriodGeneralLedgerExportEndpoint.

Use for accounting

Lastly, you need to specify for which organization units you'd like the exports to happen. This can be done by checking the Use for accounting on/off box Management Stores Advanced info in Admin 1.0.

Recipes

The recipes tab in Cookbook Admin 1.0 gives you a complete overview of all your configured recipes, both active and inactive. The event type for which the recipe is relevant is also clearly stated for each recipe.

Clicking +Add in the top-right corner, or View for a specific recipe will open up the recipe editor:


note

Clicking the Recipe history button will call for the service GetAccountingRecipeHistory, giving you the recipe history.

Recipe concepts

We have already covered the most basic form of a recipe:

recipe '<OptionalRecipeDescription>' for <FinancialEventType>

debit:
- book [Amount] to <AccountNumber> '<OptionalAccountDescription>'

credit:
- book [Amount] to <AccountNumber> '<OptionalAccountDescription>'

- book is followed by a variable, usually [Amount]. This can also be a calculation or a plain number, as long as the line produces a valid number to book.

Whitespace

A recipe doesn't mind a little whitespace, use as many as you like.

Variables

Any variables that are contained in a financial event can be used in the events corresponding recipe. In a recipe, anything inside block quotes is a variable.

Commonly used variables are:

  • [Amount]
  • [Payment]
  • [OrganizationUnit]

Variables also contain sub-variables. There are many sub-variables that can be created. For example, an organization unit has a name, which can be referred to using [OrganizationUnit.Name], but you might also use its BackendID or even set a custom field to initiate a split; it would look something like this: OrganizationUnit.CustomField.XXX, while the X's refer to the custom field name. Custom fields can be created under using the respective Custom fields chapter in Admin Suite.

Essentially, any information related to a financial event can be used as a variable. For example, a Sales event relates to an order, this basically means that you can use any property on the order as a variable, like Order.SoldFromOrganizationUnit.CountryID.

Balancing

The total sum of credit bookings must always match the total sum of debit bookings. That's basic accounting, we all know that.

Conditions

A recipe can use when conditions to further specify what events beyond the event type it applies to. An example:

recipe for Payment   

when:
- [Payment.Type.Name] = 'Cash'

debit:
- book [Amount] to 2065 'KAS'
credit:
- book [Amount] to 2400 'EVA'

else when:
- [Payment.Type.Name] = 'PIN'

debit:
- book [Amount] to 2075 'MSP'
credit:
- book [Amount] to 2400 'EVA'

else when:
- [Payment.Type.Name] = 'Rounding'

debit:
- book [Amount] to 3300 'Differences'
credit:
- book [Amount] to 2400 'EVA'

Above recipe performs different entries depending on type of payment used. Conditions always use some sort comparison for example, in the above recipe the [Payment.Type.Name] was being compared with actual payment type names.

Sequence matters!

When evaluating what action to execute for an event the first valid match is always chosen, they are simply evaluated from top to bottom and the action of the first match is executed.

Comparisons

A number of symbols can be used to make comparisons:

SymbolComparison
=Left and right must be equal
<>Left and right must not be equal
>Left must be greater than right
<Left must be smaller than right
>=Left must be greater or equal to right
<=Left must be smaller or equal to right
inCan be used to check if something is one of a number of things. Example: [Payment.Type.Name] in ['PIN', 'CASH']
has valueSome variables are optional. For example, an Order might not always have a Customer. This can be used to check if it does. Example: [Order.Customer] has value
has no valueThe opposite of has value

Calculations

The amount for a debit or credit booking can contain calculations for example, you might want to book a 2% kickback to some party in your sales entry. Here is how it would look like:

credit:
- book 0.98 * [Amount] to 7800 'Revenue'
- book 0.02 * [Amount] to 3400 'Kickback'

Ignoring

Some Financial Events bear no financial impact. In such scenarios, here is how you can set such an event. Example:

recipe for StockMutation

when:
- [OrganizationUnit.Name] = 'Warehouse'

debit:
- ignore

credit:
- ignore

This would ignore all Stock Mutation events that happen inside the organization unit "Warehouse".

Overrides

Inside a recipe, you can override some values on the resulting booking. The fields that can currently be overridden are:

  • TaxCodeBackendID
  • Remark
  • Reference
  • Offset 1
  • Offset 2
  • Offset 3
  • Offset 4
  • Offset 5
  • Offset 6

You can override a value like this:

credit:
- book [Amount] to 7800 'Revenue' with 'AN68' as [TaxCodeBackendID].

This will then result in the following booking:

{
"CurrencyID": "HTG",
"AccountName": "Revenue",
"AccountObject": "7800",
"TaxCodeBackendID": 'AN64',
"Offset1": null,
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": -1812.25,
"Remark": null,
"Reference": null
}

Functions

Functions can be used to create more complex conditions. Essentially, functions are predefined conditions.

A function can look like this:

with [isEuCountry] as:
- [Order.BillingAddress.CountryID] in ['AX','AT','BE','BG',
'HR','CY','CZ','EE','FO','FI','FR','GF',
'DE','GI','GR','HU','IE','IM','IT','LV','LT',
'LU','MT','NL','PL','PT','RO','SK','SI','ES','SE','GB']

In this function, we have created a condition that checks whether the CountryID on the BillingAddress is that of a European country. The function can be called in the recipe as follows:

when:
- [isEuCountry]

Offset

Cookbook entries are consolidated per account to derive total amounts for each. To break such amounts down into more detailed bookings, use Offset.

To illustrate, let's use the following recipe:

recipe for Sales

debit:
- book [Amount] to 1111 'EVA'

credit:
- book [Amount] to 2222 'Revenue'

With this recipe in place, we will open a financial period and perform three different transactions of the following values:

  • 1812,25
  • 3624,50
  • 7249,00

We then close the financial period. The resulting export will look like this:

{
"OrganizationUnit": {
"BackendID": "tortuga_store",
"BackendCompanyID": null,
"Name": "Tortuga Store",
"TimeZone": "Etc/GMT-5",
"CurrentOffset": 300
},
"Period": {
"ID": 24,
"Number": null,
"OpeningTime": "2021-06-09T08:02:47.7Z",
"ClosingTime": "2021-06-09T08:05:27.43Z"
},
"Entries": [
{
"CurrencyID": "HTG",
"AccountName": "EVA",
"AccountObject": "1111",
"TaxCodeBackendID": null,
"Offset1": null,
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": 12685.75,
"Remark": null,
"Reference": null
},
{
"CurrencyID": "HTG",
"AccountName": "Revenue",
"AccountObject": "2222",
"TaxCodeBackendID": null,
"Offset1": null,
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": -12685.75,
"Remark": null,
"Reference": null
}
]
}

As you can see, the amounts are consolidated into totals: 1812,25 + 3624,50 + 7249,00 = 12685,75

If we update our recipe with an Offset for [OrderLine.ID], we can break that amount down into order lines by using their respective ID's. Here is how it would look like:

recipe 'sales test' for Sales

debit:
- book [Amount] to 1111 'EVA'
with [OrderLine.ID] as [Offset1]

credit:
- book [Amount] to 2222 'Revenue'
with [OrderLine.ID] as [Offset1]

Now, when we open a new financial period, perform the same order, and close the financial period; your export would look something like this (note the Offsets impact on how it now looks compared to the one without above):

{
"OrganizationUnit": {
"BackendID": "tortuga_store",
"BackendCompanyID": null,
"Name": "Tortuga Store",
"TimeZone": "Etc/GMT-5",
"CurrentOffset": 300
},
"Period": {
"ID": 26,
"Number": null,
"OpeningTime": "2021-06-09T08:20:56.913Z",
"ClosingTime": "2021-06-09T08:22:14.697Z"
},
"Entries": [
{
"CurrencyID": "HTG",
"AccountName": "EVA",
"AccountObject": "1111",
"TaxCodeBackendID": null,
"Offset1": "231",
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": 1812.25,
"Remark": null,
"Reference": null
},
{
"CurrencyID": "HTG",
"AccountName": "Revenue",
"AccountObject": "2222",
"TaxCodeBackendID": null,
"Offset1": "231",
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": -1812.25,
"Remark": null,
"Reference": null
},
{
"CurrencyID": "HTG",
"AccountName": "EVA",
"AccountObject": "1111",
"TaxCodeBackendID": null,
"Offset1": "232",
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": 3624.5,
"Remark": null,
"Reference": null
},
{
"CurrencyID": "HTG",
"AccountName": "Revenue",
"AccountObject": "2222",
"TaxCodeBackendID": null,
"Offset1": "232",
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": -3624.5,
"Remark": null,
"Reference": null
},
{
"CurrencyID": "HTG",
"AccountName": "EVA",
"AccountObject": "1111",
"TaxCodeBackendID": null,
"Offset1": "233",
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": 7249,
"Remark": null,
"Reference": null
},
{
"CurrencyID": "HTG",
"AccountName": "Revenue",
"AccountObject": "2222",
"TaxCodeBackendID": null,
"Offset1": "233",
"Offset2": null,
"Offset3": null,
"Offset4": null,
"Offset5": null,
"Offset6": null,
"Amount": -7249,
"Remark": null,
"Reference": null
}
]
}

As you can see, debit and credit bookings are now broken down per order line ID.

Booking Flags

Make sure the ledger account used isn't configured as WithoutOffsets if you want to use offsets.

Export logs

An overview of exports, what triggered them, and whether they were successful or not, can be found in the Finance module under Export logs.