Current situation:
Considerations for the future:
Other considerations:
there are two main reasons for doing the work:
Christian is mostly interested in number 2, synching from OC to bookkeeping as most people are not looking so much into the state of the economy of the association on an ongoing basis.
opened questions:
Fort knox API: https://apps.fortnox.se/apidocs
Rate limits
The limit per access-token is 25 requests per 5 seconds. This equals to 300 requests per minute.
Regarding legal requirements on book-keeping and accounting, here's a good guide: https://www.bfn.se/wp-content/uploads/2020/06/bokforingsskyldig-ideell-kons.pdf
And here's the final result after putting it together in the annual financial statement: https://docs.google.com/document/d/10d5jJVwn1Bmr47E3yn6Viz9vKnP0I_sCVfJvmeugVN0/edit#heading=h.jy0trka6pa0e
https://drive.google.com/file/d/1pkWdpPPi336PCMh02xq6EXErvE0iCBQb/view?usp=sharing P&L report
do we need to register app with Fortnox in order to get access tokens to the API? https://www.fortnox.se/developer/authorization/get-authorization-code (Viktor has registered as Dev to recieve api key, unclear still how to authenticate without using browser)
Are supplier invoices resonable for both incoming invoices and all expenses? https://apps.fortnox.se/apidocs#tag/SupplierInvoiceAccrualsResource
(Nope, we use Vouchers (verifikat) for everything)
is there a way to use the API without having to authorize through a UI? So that there can be an authorized agent/server just entering the bookings? there is a server setting in fortnox api for server-to-server integrations.. https://www.fortnox.se/developer/authorization
(There has to be one initial verification in order to get the authcode with Oauth, then it can be refreshed within 30 days consecutively so that no more human authentications are needed)
what are the max size limits for files in the OC reinbursments/invoices? fortnox has a default 5gb storage where files can be reached at paths: https://www.fortnox.se/developer/guides-and-good-to-know/best-practices/vouchers 1500 reciepts with 3MB photos would take up all the space..(Open collective hosts the reciept photos openly, we can just link to there)
Batch process:
information needed in order to book in fortnox.
{
"SupplierInvoice": {
"@url": "string",
"AdministrationFee": "string",
"Balance": "string",
"Booked": true,
"Cancelled": true,
"Comments": "string",
"CostCenter": "string",
"Credit": true,
"CreditReference": 0,
"Currency": "string",
"CurrencyRate": "string",
"CurrencyUnit": 0,
"DisablePaymentFile": true,
"DueDate": "2019-08-24",
"ExternalInvoiceNumber": "string",
"ExternalInvoiceSeries": "string",
"Freight": "string",
"GivenNumber": "string",
"InvoiceDate": "2019-08-24",
"InvoiceNumber": "string",
"OCR": "string",
"OurReference": "string",
"PaymentPending": true,
"Project": "string",
"RoundOffValue": "string",
"SupplierInvoiceRows": [],
"SupplierNumber": "string",
"SupplierName": "string",
"Total": "string",
"VAT": "string",
"YourReference": "string",
"VoucherNumber": 0,
"VoucherSeries": "string",
"VoucherYear": 0,
"VATType": "NORMAL",
"SalesType": "STOCK",
"AccountingMethod": "ACCRUAL",
"Vouchers": [],
"FinalPayDate": "2019-08-24"
}
}
{
"Voucher": {
"@url": "string",
"Comments": "string",
"CostCenter": "string",
"Description": "string",
"Project": "string",
"ReferenceNumber": "string",
"ReferenceType": "INVOICE",
"TransactionDate": "2019-08-24",
"VoucherNumber": 0,
"VoucherRows": [],
"VoucherSeries": "string",
"Year": 0,
"ApprovalState": 0
}
}
Question: Does the trasferwise transaction have any identifying information containing the origin opencollective expense/invoice so that reciepts/project data can be retrieved from there?
authentication looks similar to fortnox..: https://docs.wise.com/api-docs/guides/open-banking
GET /v3/spend/profiles/{{profileId}}/cards/{{cardToken}}/transactions?pageSize=10&pageNumber=1&fromTransactionDate=2022-11-01&toTransactionDate=2022-11-15
example get from wise that returns a list of transactions
transaction ID can be stored as identifier, we could create boolean flag inBookkeeping to see if transaction has been processed
In order to book transaction, transaction id, createdDate, amount and currency should be sufficient.
"id": "342671",
"createdDate": "2022-11-28T08:17:54.241236Z",
"transactionAmount": {
"amount": 1.5,
"currency": "SGD"
},
authentication: https://docs.opencollective.com/help/developers/oauth
graphql API docs: https://graphql-docs-v2.opencollective.com/
Blockers cleared:
Other notes:
We discussed how to do the mapping between projects/tags and fortnox accounts. We talked about one possible implementation where the Project (like Dreams 2023) could include the account number in the name or description so that we can do the matching through that. Tags could include the account number like "5410 Radios" which would make it easy for the script to know which account to post to.
Another approach is to have a matching table that is manually updated with "tag/project x = fortnox accounty y"
We talked about what to do in the event that we don't know what fortnox account the expense should be booked at (wrong tag/project not in fortnox yet/other..). Best solution for this would be to recieve information (email?) that there are unprocessed bookings and to allow a user to log in to a screen where a list of the transactions that are uncategorised are shown, along with a list of the available accounts in fortnox (read from API) and that the user chooses and saves, then the transactions are processed. When tags/projects are updated to match the fortnox accounts, further expenses from there should go automatically.
Christian is ok with having automated bookkeeping when there is a match on accounts, so long as we make sure that we only do actually completed wise transactions.
We talked about where the code is going to be executed? (it might need access also to mail-sending for errors and things that need clearing up)
Figured out that the "transfer number" on the Wise side corralates to the "mechantID" on the OC side for a transaction, we should be able to use this to do the matching to get the expense info.
Found that there can sometimes be an issue with transactions not going through due to the banks not accepting the transfer on the other end. We should be able to use the "Status" tag on the wise transfer to only book the transactions that are marked "COMPLETED"
As bookkeeping is done now in October, Christian will send all of the information to Viktor who can then try to replicate the books of gränslandet on a fortnox test account by manually adding the bank-transfers and doing all the wise stuff with the scripts.
If an expense has multiple reciepts, a comment field for a voucher (verifikat) only allows for 1000 characters. Normally a link is around 200 chars, but if there are really long filenames and many reciepts, this would become a problem. Update: it is definitly a problem since expenses are incouraged to have more than one receipt for lower transfer fees. A possible solution is that all the links are collected for each transaction and made into a pdf that is uploaded along with the transaction to fortnox as the "reciept index" for that transaction
It may not be possible to just query for the merchantId only, in that case it may be useful to have the batch process download all transactions from wise since last run, and also download all expenses from all projects on opencollective since last run. Then have those limited lists that can be iterated over to get the information needed for insertion into fortnox.
The other approach would be to create queries one-by-one for the transactions from wise and that the scripts issue queries that iterate through the "accounts" (projects) on open collective until they find the right transaction to get the info from. seems like a slower option.
only status object on Wise we can use is status in the trasactions, this is set to outgoing_payment_sent when a payment is made, however, it can revert if the payment bounces, so if we want to make sure to only book non-bounced payments (about 1-5payments bounced last year), we would have to wait a sufficient time (2-3 bank days would be sufficient for majority of cases). this would have auto-bookkeeping trailing a few days behind when script is run..
Next steps:
sample functions:
https://github.com/digitalocean/sample-functions-python-sendgrid-email/tree/main
https://github.com/digitalocean/sample-functions-python-helloworld/tree/master/packages/sample/hello