Using voucher

Voucher Control (Bilagskontroll)

Automatic voucher control (bilagskontroll) can be activated by your accountant. This feature allows Duett to automate crossings and tax lines on vouchers. To verify if bilagskontroll is activated, send a GET request to the https://api.duett.no/system/v2/integration endpoint, and "Bilagsbehandling" should be listed under the activeModules list.

The voucher is an essential part of Duett Økonomi, ensuring compliance with Norwegian accounting laws and regulations. When creating an integration for vouchers, you must agree with the accountant regarding the voucher types and accounts you will use. We can provide a set of standard voucher types and accounts, but adjustments may be required.

Vouchers in Duett Økonomi are typically built either with or without an automatic voucher check. This should not usually be a concern, but it can determine how the accountant prefers the bookkeeping to be handled. Some accountants prefer to have sales attributed to a customer number (cash customer), so make sure you have a switch between using the account and customer number.

It is also good practice to split payment types into their respective customer numbers, for example, one for Vipps, credit card, debit card, cash, etc. Locking functionality can be used to lock vouchers for a specific period of time. Choose a strategy that fits your integration.

Voucher Number Generation

Whether you allow the API to auto-generate voucher numbers or enter your own, a number series must be agreed upon with the responsible accountant for the company requesting the integration. Automatically generated voucher numbers are part of the manual entry series, unless you choose not to use the voucherSerieStartnumber property.

If you choose to enter an invoice number as a voucher number, note that we will reject vouchers if the voucher number already exists in the system. Duplicate voucher numbers or submitting the same voucher number multiple times are not allowed. It is crucial to ensure with your accountant that the chance of overlap is zero.

The default voucher number in Duett starts with 1 each year. There are also some reserved series that should not overlap, such as:

  • 99001-99006
  • 9999001- (year ending)
  • 0

Note that reserved series may change.

Currency

Not all lines need to have currency information. It is common to fill in currency details only on the ledger entries (the lines against the customer/supplier account), but there is no restriction on providing it for other entries as well. Ensure that all currency-related fields are properly filled in, including the currency amount (currencyGross), currency code (currencyCode), and exchange rate (currencyRate), if at least one of them is provided.

The main rule for exchange rates is to use the rate at the time of the invoice. For payments in foreign currency, the exchange rate at the time of payment applies. The difference between the two is classified as either a currency loss or a currency gain.

Crossing Claims with Payments

Crossing claims with payments in accounting means matching an incoming payment to outstanding invoices or receivables, marking them as settled. When a customer makes a payment, or we pay a suppliers claim, it is linked to the corresponding invoice in the accounting system. If the payment does not cover the full invoice amount, it is partially crossed, leaving the remaining balance outstanding. A single payment can also be applied to multiple invoices, distributing the amount according to a predefined priority. This process ensures accurate financial records and provides a clear overview of outstanding receivables and payments.

There are several ways to cross claims with payments:

1. Cash Settlement
  • The payment can be included in the same voucher as the incoming payment.
  • A single incoming payment can cross multiple claims.
  • The crossing follows the order in which the claims are listed.
2. Separate Vouchers, Submitted Together
  • The claim and payment can be in separate vouchers but submitted at the same time.
  • Multiple claims can be crossed with a single/multiple payments.
  • The crossing follows the order of the claims.
3. Crossing a Previous Claim with a Payment
  • The claim's ID can be submitted in IdsToCross within VoucherCreateConfig for the payment.
  • Multiple claims can be crossed or partially crossed with a single payment.
  • The order of IDs in IdsToCross determines the priority of the crossing.

The crossing process is optimistic and not guaranteed unless all prerequisites are met. Here are some possible reasons why crossing might fail:

  • The accounting year covering the selected voucher dates is closed, and the system could not find a suitable accounting year.
  • A selected ledger entry is already crossed or has the LedgerState "Locked".
  • Voucher lines contain missing or invalid ledger references.
  • Not all voucher lines have a reference to a ledger.
  • At least two vouchers must have the LedgerState "blank" or "partCrossed".
  • Among the voucher lines available for crossing ("blank" or "partCrossed"), at least one must have a remaining balance above 0, and at least one must have a remaining balance below 0.
  • Database storage failed, most likely due to an invalid voucher line reference.
To confirm that a crossing was successful, a lookup must be made of the requirements and the LedgerState and RestAmount must be looked at.

Acceptance Test

As part of the acceptance test before the pilot period begins, you will be asked to submit the combinations you want to produce and submit. For example, payments and refunds.

It is good practice to filter on the financial year when retrieving vouchers. Adding

?filter[voucherYear][EQ]=2023
for example, to any GET requests to the Voucher endpoint will prevent you from retrieving data from other years and also prevent unnecessary load on our server.

Config (optional)
Property Description Default Create
voucherSerieStartnumber Which number series the vouchers are to be created on. The default is 1 which corresponds to the range for manual registration. It is very important to agree on the series and get verification that it will not overlap with other series. 1 X
handleAmountAsNetto If true, amounts are handled as if they are net. Affects diff check. Affects VAT calculation. True X
automatedVATHandling If true, the import will calculate VAT automatically based on the VAT code on the specified voucher line. True X
automatedLedgerPosting If true, ledger entries will automatically be added to the general ledger. Typically to account 1500/2400.
If false, entries will not be added to the general ledger (hovedbok in Duett Web/Win). This will cause the account entry to be missing and entries must be manually added. (for example, to account 1500 for customers or 2400 for suppliers).
True X
getNextActiveYearIfClosed If true, will post to the next year if the voucher date is in a closed year. True X

Voucher header
Property Description Default Create
voucherNumber If blank, voucherNumber will be autogenerated. If a series has been agreed, this is used continuously without gaps. Autogenerated X
voucherDate Required. The time part are ignored so send in without time like 2024-12-31T00:00:00.000Z or 2024-12-31. X
voucherYear The accounting year of the voucher Takes year from voucherDate X
carriers List of carriers. Carrier ids when creating voucher. Only allowed carriers that have usedInAccounting = true in the CarrierType. See Carrier and CarrierType. The default is that this field is not returned in output without being specified in extends. Note that it is Carrier.Id and not id on e.g. Project, Employee. Use the Carrier endpoint to find the correct ID. X
voucherList List of voucher lines. The lines should be sorted logically X
attachments List of file attachments. Valid filetypes are png, tiff, jpg, jpeg, bmp and pdf. All of the graphic formats are converted to pdf. The default is that this field is not returned in output without being specified in extends. X
lockVoucher Lock the voucher from editing False X
rowversion Is generally used as a mechanism for version-stamping table rows. Useful for retrieving new and changed rows since last.

Voucher lines
Property Description Default Create
accountingPeriod The total amount of accounting periods a client can have is 1, 2, 3, 4, 5, 6, 7, 12, 13, 24 or 25. You need to check with the accountant how many the client have.
If a client has 6 periods, then January-February = period 1, March-April = period 2, and so on.
If a client has 12 periods, then January = period 1, February = period 2, and so on.
Takes accounting period from voucherDate if null X
accountNumber The account number,
See Register -> AccountChart
Required if there is no supplierNumber or customerNumber.
X
agriAccount Special account for agricultural businesses.
1=Finance, 2=Agriculture, 3=Forestry, 5=Fur animals, 6=Other industry,
8=Own business for rental outside industry, 9=Private business
X
amount Value of this voucher. Positive = Debit, Negative = Credit. See the header if you are passing net (without VAT) or gross (including VAT) value. X
carriers Carriers that provide this voucher. Carrier Ids when creating. The carrier on voucher lines override the carriers in the header X
customerNumber Identifier for the customer.
See customerNumber in Customer schema
Required if there is no supplierNumber or accountNumber.
X
description Description of the voucher The default is inherit from VoucherType X
dueDate Invoice due date.
This field is strongly recommended to fill in when invoice is posted.. Both for outgoing and incoming claims.
X
kid Identification number for the payment.
If KID is available, this field is strongly recommended to fill in when invoice is posted.
X
invoiceFlowStatus The attestation-status for the voucher. The possible statuses are: blank = nothing, toAttest = Til attestering/To attest, inProgress = not used, toPay = Til betaling/To pay, toAssign = Attestert/Attested, assigned = Ferdig (Attestert og kontert)/Finished (attested and assigned), rejected = Avvist/Rejected, toSign = Til signering/To sign, onHold = På vent/On hold blank
name Name of account/customer or supplier. Output only for reporting purposes
payedFromBankAccount The account number an incoming invoice is paid from. Must only be used on lines that contain a supplier number and voucherType 13 (incoming invoice). Typically this is fetched from the client and should not be filled. null or the API shall tried to retrieve if attestation is activated and the account number exists on the client. X
payType Nullable enum. Used to store the payment type as Cash, Invoice, AutoPay, PayCard, CreditCard and Currency. Only used in order/invoice null
bankAccount This is the account incoming claims should be paid to. Only valid on incoming claims/invoices. If this is not filled in, the bank account number will be retrieved from the supplier. null or the APi shall retrieve if attestation is activated and the account number exists for whoever the invoice is for. X
refNumber Reference number eg: invoice number, journal number.
This field is strongly recommended to fill in when invoice is posted.
X
quantity1 This field is optional in Duett and can, for example be used for the amount of timber bought/sold.
quantity2 See quantity1
supplierNumber Identifier for the supplier. See supplierNumber in Supplier schema.
Required if there is no accountNumber or customerNumber.
X
taxCode Tax code is generation-driven, so tax code has to be selected with voucher date. This is the 'Key' in TaxCode.
These tax codes are used: blank, 0, 1, 3, 4, 5, 6, 7, 8, 10, 21, 23, 25, 26, 27, 28, 31, 33, 35, 36, 93.
When "automatedVATHandling" is used, the basic codes (codes without VAT rate) will be replaced as follows:
21 -> 1
23 -> 3
25 -> 5
26 -> 6
27 -> 7
28 -> 8
35 -> 31
36 -> 33
See Register -> taxCodes (api.duett.no/Register/v2/TaxCodes endpoint)
X
voucherType 0 to 199. VoucherTypes from 200 can be used by agreement with Duett. This is the 'Key' in VoucherType.
See Register -> voucherTypes
0 X
restAmount The amount left to pay.
reminderDate Date to send warning of unpaid amount.
currencyRestAmount If there is currency on the voucher line, and there is a ledger entry (ie against a customer/supplier account). Similar to restAmount.
currencyGross Optional: The total amount in currency if currency code is used. X
currencyRate Optional: Currency rate can have up to 5 decimal places. Enter the exchange rate as 1 of foreign currency against 1 NOK. X
currencyCode Optional: If the currency is not NOK, then insert currency code here. X
ledgerState Enum: blank, partCrossed, crossed, locked. blank
reminderState Enum: blank, reminder1, reminder2, collectionNext, collectionSent, collection, sentToCollectionPartner, settledCollectionPartner. blank
accountType Enum: account, customer, supplier account

Notes

The Skip and Take filters makes no sense and would have given unforeseen results so these features are turned off for voucher

Differences

The API expects that all incoming amounts are accounted for, both currency amounts and amounts in NOK. If, however, there is a difference in the amount in the voucher, there must be an entry in the "feilkonto" ("incorrect" account) for the difference. Øre rounding: In some cases, you may get small deviations after calculating and posting VAT, especially if you have to change the base amount to net amount first. We suggest that the entire voucher is then offset by transferring the difference to the øre rounding account. In the case of a large difference, greater than NOK 1, it should rather be entered into an "incorrect" account. The selection of the øre rounding account must be based on business carried out against the voucher. In the case of an agricultural client, there may be instructions for more than one business in the same attachment. We suggest that in that case, rounding is applied to the business with the largest amount in total in the appendix. Otherwise, the business used in the appendix is selected. If you as a developer do not have accounting expertise, you should consult with an accountant who uses Duett Økonomi.

Filtering for ledger result

Example for filtering for supplier ledger:
filter[VoucherList.AccountType][EQ]=supplier

Extend with attachments or carriers in output

This enables eg. the output of the original invoice etc:
extend=attachments&extend=carriers

Get delta (new and changed data)

In order to retrieve delta, you save the highest Rowversion you received the last time you retrieved data. Use this next time to be able to retrieve all new and changed vouchers since last:
filter[rowversion][GT]=985566

Example of an incoming invoice

[
  {
     "config":{
         "automatedLedgerPosting":true,
         "automatedVATHandling":true,
         "getNextActiveYearIfClosed":true,
         "handleAmountAsNetto":true
    },
    "voucherDate": "2022-04-01T00:00:00Z",
    "voucherList": [
      {
        "carriers": [
            1,2
        ],
        "refNumber": "1",
        "amount": -785,
        "description": "IF Test Supplier",
        "voucherType": 13,                
        "dueDate": "2022-04-01T00:00:00Z",
        "taxCode": null,
        "supplierNumber":"20002"
      },
      {
        "amount": 628,
        "voucherType": 1,
        "taxCode": 1,
        "accountNumber":"6620"
      }
    ],
    "voucherYear": 2022
  }
]               

Example of an outgoing invoice with tax calculations

The config header is removed because all settings will default to true if it is not present

[
  {
    "voucherDate": "2022-04-05T00:00:00Z",
    "carriers": [
        1,2
    ],
    "voucherList": [
      {
        "refNumber": "1",
        "description": "Test customer",
        "customerNumber": "10000",
        "voucherType": 3,
        "dueDate": "2022-04-20T00:00:00",
        "amount": 85998.00,
        "accountingPeriod": 4
      },
      {
        "accountingPeriod": 4,
        "amount": -3652,
        "voucherType": 1,
        "taxCode": 23,
        "accountNumber":"3020"
      },
      {
        "accountingPeriod": 4,
        "amount": -65146.40,
        "voucherType": 1,
        "taxCode":23,
        "accountNumber":"3000"
      }
    ],
    "voucherNumber": 1234,
    "voucherYear": 2022
  }
]               

Example of credit line voucher regarding a customer


 [
   {
      "config":{
         "automatedLedgerPosting":true,
         "automatedVATHandling":true,
         "getNextActiveYearIfClosed":true,
         "handleAmountAsNetto":false,
         "voucherSerieStartnumber": 5300
      },
      "voucherDate":"2022-08-23T00:00:00+02:00",
      "voucherList":[
         {
            "amount":100.0,
            "customerNumber":"10001",
            "description":"Faktura 1",
            "dueDate":"2022-09-06T00:00:00+02:00",
            "voucherType":3
         },
         {
            "accountNumber":"3000",
            "amount":-100.0,
            "description":"Faktura 1",
            "dueDate":"2022-09-06T00:00:00+02:00",
            "taxCode":3,
            "voucherType":3
         }
      ],
      "voucherYear":2022
   }
]         

Example of debit line voucher regarding a supplier


[
  {
    "config":{
        "handleAmountAsNetto":false
    },
    "voucherDate": "2022-04-01T00:00:00Z",
    "voucherList": [
      {
        "accountingPeriod": 4,
        "refNumber": "{{refNumber}}",
        "amount": -785,
        "description": "IF TestLeverandør",
        "voucherType": 13,                
        "dueDate": "2022-04-01T00:00:00Z",
        "taxCode": null,
        "supplierNumber":"{{supplierNumber}}"
      },
      {
        "accountingPeriod": 4,
        "amount": 785,
        "voucherType": 1,
        "taxCode": 1,
        "accountNumber":"6620"
      }
    ],
    "voucherYear": 2022
  }
]