5gnucash_rest.py -- A Flask app which responds to REST requests
8Copyright (C) 2013 Tom Lofts <dev@loftx.co.uk>
10This program is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License as
12published by the Free Software Foundation; either version 2 of
13the License, or (at your option) any later version.
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
20You should have received a copy of the GNU General Public License
21along with this program; if not, contact:
23Free Software Foundation Voice: +1-617-542-5942
2451 Franklin Street, Fifth Floor Fax: +1-617-542-2652
25Boston, MA 02110-1301, USA gnu@gnu.org
27@author Tom Lofts <dev@loftx.co.uk>
35from flask
import Flask, abort, request, Response
39from decimal
import Decimal
41from gnucash.gnucash_business
import Vendor, Bill, Entry, GncNumeric, \
42 Customer, Invoice, Split, Account, Transaction
54 QOF_STRING_MATCH_NORMAL, \
55 QOF_STRING_MATCH_CASEINSENSITIVE
74from gnucash
import SessionOpenMode
79@app.route('/accounts', methods=['GET', 'POST'])
82 if request.method ==
'GET':
84 accounts = getAccounts(session.book)
86 return Response(json.dumps(accounts), mimetype=
'application/json')
88 elif request.method ==
'POST':
90 name = str(request.form.get(
'name',
''))
91 currency = str(request.form.get(
'currency',
''))
92 account_type_id = request.form.get(
'account_type_id',
'')
93 parent_account_guid = str(request.form.get(
'parent_account_guid',
''))
94 description = str(request.form.get(
'description',
''))
95 code = str(request.form.get(
'code',
''))
98 account = addAccount(session.book, name, currency,
99 account_type_id, parent_account_guid, description, code)
100 except Error
as error:
101 return Response(json.dumps({
'errors': [{
'type' : error.type,
102 'message': error.message,
'data': error.data}]}), status=400,
103 mimetype=
'application/json')
105 return Response(json.dumps(account), status=201,
106 mimetype=
'application/json')
111@app.route('/accounts/<guid>', methods=['GET'])
112def api_account(guid):
114 account = getAccount(session.book, guid)
119 return Response(json.dumps(account), mimetype=
'application/json')
121@app.route('/accounts/<guid>/splits', methods=['GET'])
122def api_account_splits(guid):
124 date_posted_from = request.args.get(
'date_posted_from',
None)
125 date_posted_to = request.args.get(
'date_posted_to',
None)
128 account = getAccount(session.book, guid)
133 splits = getAccountSplits(session.book, guid, date_posted_from,
136 return Response(json.dumps(splits), mimetype=
'application/json')
139@app.route('/transactions', methods=['POST'])
140def api_transactions():
142 if request.method ==
'POST':
144 currency = str(request.form.get(
'currency',
''))
145 description = str(request.form.get(
'description',
''))
146 num = str(request.form.get(
'num',
''))
147 date_posted = str(request.form.get(
'date_posted',
''))
149 splitvalue1 = int(request.form.get(
'splitvalue1',
''))
150 splitaccount1 = str(request.form.get(
'splitaccount1',
''))
151 splitvalue2 = int(request.form.get(
'splitvalue2',
''))
152 splitaccount2 = str(request.form.get(
'splitaccount2',
''))
155 {
'value': splitvalue1,
'account_guid': splitaccount1},
156 {
'value': splitvalue2,
'account_guid': splitaccount2}]
159 transaction = addTransaction(session.book, num, description,
160 date_posted, currency, splits)
161 except Error
as error:
162 return Response(json.dumps({
'errors': [{
'type' : error.type,
163 'message': error.message,
'data': error.data}]}), status=400,
164 mimetype=
'application/json')
166 return Response(json.dumps(transaction), status=201,
167 mimetype=
'application/json')
172@app.route('/transactions/<guid>', methods=['GET', 'POST', 'DELETE'])
173def api_transaction(guid):
175 if request.method ==
'GET':
177 transaction = getTransaction(session.book, guid)
179 if transaction
is None:
182 return Response(json.dumps(transaction), mimetype=
'application/json')
184 elif request.method ==
'POST':
186 currency = str(request.form.get(
'currency',
''))
187 description = str(request.form.get(
'description',
''))
188 num = str(request.form.get(
'num',
''))
189 date_posted = str(request.form.get(
'date_posted',
''))
191 splitguid1 = str(request.form.get(
'splitguid1',
''))
192 splitvalue1 = int(request.form.get(
'splitvalue1',
''))
193 splitaccount1 = str(request.form.get(
'splitaccount1',
''))
194 splitguid2 = str(request.form.get(
'splitguid2',
''))
195 splitvalue2 = int(request.form.get(
'splitvalue2',
''))
196 splitaccount2 = str(request.form.get(
'splitaccount2',
''))
200 'value': splitvalue1,
201 'account_guid': splitaccount1},
203 'value': splitvalue2,
204 'account_guid': splitaccount2}
208 transaction = editTransaction(session.book, guid, num, description,
209 date_posted, currency, splits)
210 except Error
as error:
211 return Response(json.dumps({
'errors': [{
'type' : error.type,
212 'message': error.message,
'data': error.data}]}), status=400, mimetype=
'application/json')
214 return Response(json.dumps(transaction), status=200,
215 mimetype=
'application/json')
217 elif request.method ==
'DELETE':
219 deleteTransaction(session.book, guid)
221 return Response(
'', status=200, mimetype=
'application/json')
226@app.route('/bills', methods=['GET', 'POST'])
229 if request.method ==
'GET':
231 is_paid = request.args.get(
'is_paid',
None)
232 is_active = request.args.get(
'is_active',
None)
233 date_opened_to = request.args.get(
'date_opened_to',
None)
234 date_opened_from = request.args.get(
'date_opened_from',
None)
245 elif is_active ==
'0':
250 bills = getBills(session.book,
None, is_paid, is_active,
251 date_opened_from, date_opened_to)
253 return Response(json.dumps(bills), mimetype=
'application/json')
255 elif request.method ==
'POST':
257 id = str(request.form.get(
'id',
None))
264 vendor_id = str(request.form.get(
'vendor_id',
''))
265 currency = str(request.form.get(
'currency',
''))
266 date_opened = str(request.form.get(
'date_opened',
''))
267 notes = str(request.form.get(
'notes',
''))
270 bill = addBill(session.book, id, vendor_id, currency, date_opened,
272 except Error
as error:
274 return Response(json.dumps({
'errors': [{
'type' : error.type,
275 'message': error.message,
'data': error.data}]}), status=400, mimetype=
'application/json')
277 return Response(json.dumps(bill), status=201,
278 mimetype=
'application/json')
283@app.route('/bills/<id>', methods=['GET', 'POST', 'PAY'])
286 if request.method ==
'GET':
288 bill = getBill(session.book, id)
293 return Response(json.dumps(bill), mimetype=
'application/json')
295 elif request.method ==
'POST':
297 vendor_id = str(request.form.get(
'vendor_id',
''))
298 currency = str(request.form.get(
'currency',
''))
299 date_opened = request.form.get(
'date_opened',
None)
300 notes = str(request.form.get(
'notes',
''))
301 posted = request.form.get(
'posted',
None)
302 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
303 posted_date = request.form.get(
'posted_date',
'')
304 due_date = request.form.get(
'due_date',
'')
305 posted_memo = str(request.form.get(
'posted_memo',
''))
306 posted_accumulatesplits = request.form.get(
'posted_accumulatesplits',
308 posted_autopay = request.form.get(
'posted_autopay',
'')
315 if (posted_accumulatesplits ==
'1'
316 or posted_accumulatesplits ==
'true'
317 or posted_accumulatesplits ==
'True'
318 or posted_accumulatesplits ==
True):
319 posted_accumulatesplits =
True
321 posted_accumulatesplits =
False
323 if posted_autopay ==
'1':
324 posted_autopay =
True
326 posted_autopay =
False
328 bill = updateBill(session.book, id, vendor_id, currency,
329 date_opened, notes, posted, posted_account_guid, posted_date,
330 due_date, posted_memo, posted_accumulatesplits, posted_autopay)
331 except Error
as error:
332 return Response(json.dumps({
'errors': [{
'type' : error.type,
333 'message': error.message,
'data': error.data}]}), status=400,
334 mimetype=
'application/json')
336 return Response(json.dumps(bill), status=200,
337 mimetype=
'application/json')
342 return Response(json.dumps(bill),
343 mimetype=
'application/json')
345 elif request.method ==
'PAY':
347 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
348 transfer_account_guid = str(request.form.get(
'transfer_account_guid',
350 payment_date = request.form.get(
'payment_date',
'')
351 num = str(request.form.get(
'num',
''))
352 memo = str(request.form.get(
'posted_memo',
''))
353 auto_pay = request.form.get(
'auto_pay',
'')
356 bill = payBill(session.book, id, posted_account_guid,
357 transfer_account_guid, payment_date, memo, num, auto_pay)
358 except Error
as error:
359 return Response(json.dumps({
'errors': [{
'type' : error.type,
360 'message': error.message,
'data': error.data}]}), status=400,
361 mimetype=
'application/json')
363 return Response(json.dumps(bill), status=200,
364 mimetype=
'application/json')
369@app.route('/bills/<id>/entries', methods=['GET', 'POST'])
370def api_bill_entries(id):
372 bill = getBill(session.book, id)
377 if request.method ==
'GET':
378 return Response(json.dumps(bill[
'entries']), mimetype=
'application/json')
379 elif request.method ==
'POST':
381 date = str(request.form.get(
'date',
''))
382 description = str(request.form.get(
'description',
''))
383 account_guid = str(request.form.get(
'account_guid',
''))
384 quantity = str(request.form.get(
'quantity',
''))
385 price = str(request.form.get(
'price',
''))
388 entry = addBillEntry(session.book, id, date, description,
389 account_guid, quantity, price)
390 except Error
as error:
391 return Response(json.dumps({
'errors': [{
'type' : error.type,
392 'message': error.message,
'data': error.data}]}),
393 status=400, mimetype=
'application/json')
395 return Response(json.dumps(entry), status=201,
396 mimetype=
'application/json')
401@app.route('/invoices', methods=['GET', 'POST'])
404 if request.method ==
'GET':
406 is_paid = request.args.get(
'is_paid',
None)
407 is_active = request.args.get(
'is_active',
None)
408 date_due_to = request.args.get(
'date_due_to',
None)
409 date_due_from = request.args.get(
'date_due_from',
None)
420 elif is_active ==
'0':
425 invoices = getInvoices(session.book,
None, is_paid, is_active,
426 date_due_from, date_due_to)
428 return Response(json.dumps(invoices), mimetype=
'application/json')
430 elif request.method ==
'POST':
432 id = str(request.form.get(
'id',
None))
439 customer_id = str(request.form.get(
'customer_id',
''))
440 currency = str(request.form.get(
'currency',
''))
441 date_opened = str(request.form.get(
'date_opened',
''))
442 notes = str(request.form.get(
'notes',
''))
445 invoice = addInvoice(session.book, id, customer_id, currency,
447 except Error
as error:
448 return Response(json.dumps({
'errors': [{
'type' : error.type,
449 'message': error.message,
'data': error.data}]}), status=400,
450 mimetype=
'application/json')
452 return Response(json.dumps(invoice), status=201,
453 mimetype=
'application/json')
458@app.route('/invoices/<id>', methods=['GET', 'POST', 'PAY'])
461 if request.method ==
'GET':
463 invoice = getInvoice(session.book, id)
468 return Response(json.dumps(invoice), mimetype=
'application/json')
470 elif request.method ==
'POST':
472 customer_id = str(request.form.get(
'customer_id',
''))
473 currency = str(request.form.get(
'currency',
''))
474 date_opened = request.form.get(
'date_opened',
None)
475 notes = str(request.form.get(
'notes',
''))
476 posted = request.form.get(
'posted',
None)
477 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
478 posted_date = request.form.get(
'posted_date',
'')
479 due_date = request.form.get(
'due_date',
'')
480 posted_memo = str(request.form.get(
'posted_memo',
''))
481 posted_accumulatesplits = request.form.get(
'posted_accumulatesplits',
483 posted_autopay = request.form.get(
'posted_autopay',
'')
490 if (posted_accumulatesplits ==
'1'
491 or posted_accumulatesplits ==
'true'
492 or posted_accumulatesplits ==
'True'
493 or posted_accumulatesplits ==
True):
494 posted_accumulatesplits =
True
496 posted_accumulatesplits =
False
498 if posted_autopay ==
'1':
499 posted_autopay =
True
501 posted_autopay =
False
503 invoice = updateInvoice(session.book, id, customer_id, currency,
504 date_opened, notes, posted, posted_account_guid, posted_date,
505 due_date, posted_memo, posted_accumulatesplits, posted_autopay)
506 except Error
as error:
507 return Response(json.dumps({
'errors': [{
'type' : error.type,
508 'message': error.message,
'data': error.data}]}), status=400,
509 mimetype=
'application/json')
511 return Response(json.dumps(invoice), status=200,
512 mimetype=
'application/json')
517 return Response(json.dumps(invoice), mimetype=
'application/json')
519 elif request.method ==
'PAY':
521 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
522 transfer_account_guid = str(request.form.get(
'transfer_account_guid',
524 payment_date = request.form.get(
'payment_date',
'')
525 num = str(request.form.get(
'num',
''))
526 memo = str(request.form.get(
'posted_memo',
''))
527 auto_pay = request.form.get(
'auto_pay',
'')
530 invoice = payInvoice(session.book, id, posted_account_guid,
531 transfer_account_guid, payment_date, memo, num, auto_pay)
532 except Error
as error:
533 return Response(json.dumps({
'errors': [{
'type' : error.type,
534 'message': error.message,
'data': error.data}]}), status=400,
535 mimetype=
'application/json')
537 return Response(json.dumps(invoice), status=200,
538 mimetype=
'application/json')
543@app.route('/invoices/<id>/entries', methods=['GET', 'POST'])
544def api_invoice_entries(id):
546 invoice = getInvoice(session.book, id)
551 if request.method ==
'GET':
552 return Response(json.dumps(invoice[
'entries']),
553 mimetype=
'application/json')
554 elif request.method ==
'POST':
556 date = str(request.form.get(
'date',
''))
557 description = str(request.form.get(
'description',
''))
558 account_guid = str(request.form.get(
'account_guid',
''))
559 quantity = str(request.form.get(
'quantity',
''))
560 price = str(request.form.get(
'price',
''))
563 entry = addEntry(session.book, id, date, description,
564 account_guid, quantity, price)
565 except Error
as error:
566 return Response(json.dumps({
'errors': [{
'type' : error.type,
567 'message': error.message,
'data': error.data}]}),
568 status=400, mimetype=
'application/json')
570 return Response(json.dumps(entry), status=201,
571 mimetype=
'application/json')
576@app.route('/entries/<guid>', methods=['GET', 'POST', 'DELETE'])
579 entry = getEntry(session.book, guid)
584 if request.method ==
'GET':
585 return Response(json.dumps(entry), mimetype=
'application/json')
586 elif request.method ==
'POST':
588 date = str(request.form.get(
'date',
''))
589 description = str(request.form.get(
'description',
''))
590 account_guid = str(request.form.get(
'account_guid',
''))
591 quantity = str(request.form.get(
'quantity',
''))
592 price = str(request.form.get(
'price',
''))
595 entry = updateEntry(session.book, guid, date, description,
596 account_guid, quantity, price)
597 except Error
as error:
598 return Response(json.dumps({
'errors': [{
'type' : error.type,
599 'message': error.message,
'data': error.data}]}),
600 status=400, mimetype=
'application/json')
602 return Response(json.dumps(entry), status=200,
603 mimetype=
'application/json')
605 elif request.method ==
'DELETE':
607 deleteEntry(session.book, guid)
609 return Response(
'', status=201, mimetype=
'application/json')
614@app.route('/customers', methods=['GET', 'POST'])
617 if request.method ==
'GET':
618 customers = getCustomers(session.book)
619 return Response(json.dumps(customers), mimetype=
'application/json')
620 elif request.method ==
'POST':
622 id = str(request.form.get(
'id',
None))
629 currency = str(request.form.get(
'currency',
''))
630 name = str(request.form.get(
'name',
''))
631 contact = str(request.form.get(
'contact',
''))
632 address_line_1 = str(request.form.get(
'address_line_1',
''))
633 address_line_2 = str(request.form.get(
'address_line_2',
''))
634 address_line_3 = str(request.form.get(
'address_line_3',
''))
635 address_line_4 = str(request.form.get(
'address_line_4',
''))
636 phone = str(request.form.get(
'phone',
''))
637 fax = str(request.form.get(
'fax',
''))
638 email = str(request.form.get(
'email',
''))
641 customer = addCustomer(session.book, id, currency, name, contact,
642 address_line_1, address_line_2, address_line_3, address_line_4,
644 except Error
as error:
645 return Response(json.dumps({
'errors': [{
'type' : error.type,
646 'message': error.message,
'data': error.data}]}), status=400,
647 mimetype=
'application/json')
649 return Response(json.dumps(customer), status=201,
650 mimetype=
'application/json')
655@app.route('/customers/<id>', methods=['GET', 'POST'])
658 if request.method ==
'GET':
660 customer = getCustomer(session.book, id)
665 return Response(json.dumps(customer), mimetype=
'application/json')
667 elif request.method ==
'POST':
669 id = str(request.form.get(
'id',
None))
671 name = str(request.form.get(
'name',
''))
672 contact = str(request.form.get(
'contact',
''))
673 address_line_1 = str(request.form.get(
'address_line_1',
''))
674 address_line_2 = str(request.form.get(
'address_line_2',
''))
675 address_line_3 = str(request.form.get(
'address_line_3',
''))
676 address_line_4 = str(request.form.get(
'address_line_4',
''))
677 phone = str(request.form.get(
'phone',
''))
678 fax = str(request.form.get(
'fax',
''))
679 email = str(request.form.get(
'email',
''))
682 customer = updateCustomer(session.book, id, name, contact,
683 address_line_1, address_line_2, address_line_3, address_line_4,
685 except Error
as error:
686 if error.type ==
'NoCustomer':
687 return Response(json.dumps({
'errors': [{
'type' : error.type,
688 'message': error.message,
'data': error.data}]}),
689 status=404, mimetype=
'application/json')
691 return Response(json.dumps({
'errors': [{
'type' : error.type,
692 'message': error.message,
'data': error.data}]}),
693 status=400, mimetype=
'application/json')
695 return Response(json.dumps(customer), status=200,
696 mimetype=
'application/json')
701@app.route('/customers/<id>/invoices', methods=['GET'])
702def api_customer_invoices(id):
704 customer = getCustomer(session.book, id)
709 invoices = getInvoices(session.book, customer[
'guid'],
None,
None,
None,
712 return Response(json.dumps(invoices), mimetype=
'application/json')
714@app.route('/vendors', methods=['GET', 'POST'])
717 if request.method ==
'GET':
718 vendors = getVendors(session.book)
719 return Response(json.dumps(vendors), mimetype=
'application/json')
720 elif request.method ==
'POST':
722 id = str(request.form.get(
'id',
None))
729 currency = str(request.form.get(
'currency',
''))
730 name = str(request.form.get(
'name',
''))
731 contact = str(request.form.get(
'contact',
''))
732 address_line_1 = str(request.form.get(
'address_line_1',
''))
733 address_line_2 = str(request.form.get(
'address_line_2',
''))
734 address_line_3 = str(request.form.get(
'address_line_3',
''))
735 address_line_4 = str(request.form.get(
'address_line_4',
''))
736 phone = str(request.form.get(
'phone',
''))
737 fax = str(request.form.get(
'fax',
''))
738 email = str(request.form.get(
'email',
''))
741 vendor = addVendor(session.book, id, currency, name, contact,
742 address_line_1, address_line_2, address_line_3, address_line_4,
744 except Error
as error:
745 return Response(json.dumps({
'errors': [{
'type' : error.type,
746 'message': error.message,
'data': error.data}]}), status=400,
747 mimetype=
'application/json')
749 return Response(json.dumps(vendor), status=201,
750 mimetype=
'application/json')
755@app.route('/vendors/<id>', methods=['GET', 'POST'])
758 if request.method ==
'GET':
760 vendor = getVendor(session.book, id)
765 return Response(json.dumps(vendor), mimetype=
'application/json')
769@app.route('/vendors/<id>/bills', methods=['GET'])
770def api_vendor_bills(id):
772 vendor = getVendor(session.book, id)
777 bills = getBills(session.book, vendor[
'guid'],
None,
None,
None,
None)
779 return Response(json.dumps(bills), mimetype=
'application/json')
781def getCustomers(book):
783 query = gnucash.Query()
784 query.search_for(
'gncCustomer')
788 for result
in query.run():
790 gnucash.gnucash_business.Customer(instance=result)))
796def getCustomer(book, id):
798 customer = book.CustomerLookupByID(id)
807 query = gnucash.Query()
808 query.search_for(
'gncVendor')
812 for result
in query.run():
814 gnucash.gnucash_business.Vendor(instance=result)))
820def getVendor(book, id):
822 vendor = book.VendorLookupByID(id)
829def getAccounts(book):
835def getAccountsFlat(book):
839 flat_accounts = getSubAccounts(accounts)
841 for n, account
in enumerate(flat_accounts):
842 account.pop(
'subaccounts')
844 filtered_flat_account = []
848 for n, account
in enumerate(flat_accounts):
849 if account[
'type_id']
in type_ids:
850 filtered_flat_account.append(account)
851 print(account[
'name'] +
' ' + str(account[
'type_id']))
853 return filtered_flat_account
855def getSubAccounts(account):
859 if 'subaccounts' in list(account.keys()):
860 for n, subaccount
in enumerate(account[
'subaccounts']):
861 flat_accounts.append(subaccount)
862 flat_accounts = flat_accounts + getSubAccounts(subaccount)
866def getAccount(book, guid):
868 account_guid = gnucash.gnucash_core.GUID()
869 gnucash.gnucash_core.GUIDString(guid, account_guid)
871 account = account_guid.AccountLookup(book)
884def getTransaction(book, guid):
886 transaction_guid = gnucash.gnucash_core.GUID()
887 gnucash.gnucash_core.GUIDString(guid, transaction_guid)
889 transaction = transaction_guid.TransactionLookup(book)
891 if transaction
is None:
896 if transaction
is None:
901def getTransactions(book, account_guid, date_posted_from, date_posted_to):
903 query = gnucash.Query()
905 query.search_for(
'Trans')
910 for transaction
in query.run():
912 gnucash.gnucash_business.Transaction(instance=transaction)))
918def getAccountSplits(book, guid, date_posted_from, date_posted_to):
920 account_guid = gnucash.gnucash_core.GUID()
921 gnucash.gnucash_core.GUIDString(guid, account_guid)
923 query = gnucash.Query()
924 query.search_for(
'Split')
929 TRANS_DATE_POSTED =
'date-posted'
931 if date_posted_from !=
None:
932 pred_data = gnucash.gnucash_core.QueryDatePredicate(
933 QOF_COMPARE_GTE, QOF_DATE_MATCH_NORMAL, datetime.datetime.strptime(
934 date_posted_from,
"%Y-%m-%d").date())
935 param_list = [SPLIT_TRANS, TRANS_DATE_POSTED]
936 query.add_term(param_list, pred_data, QOF_QUERY_AND)
938 if date_posted_to !=
None:
939 pred_data = gnucash.gnucash_core.QueryDatePredicate(
940 QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, datetime.datetime.strptime(
941 date_posted_to,
"%Y-%m-%d").date())
942 param_list = [SPLIT_TRANS, TRANS_DATE_POSTED]
943 query.add_term(param_list, pred_data, QOF_QUERY_AND)
945 SPLIT_ACCOUNT =
'account'
946 QOF_PARAM_GUID =
'guid'
949 gnucash.gnucash_core.GUIDString(guid, account_guid)
950 query.add_guid_match(
951 [SPLIT_ACCOUNT, QOF_PARAM_GUID], account_guid, QOF_QUERY_AND)
955 for split
in query.run():
957 gnucash.gnucash_business.Split(instance=split),
958 [
'account',
'transaction',
'other_split']))
964def getInvoices(book, customer, is_paid, is_active, date_due_from,
967 query = gnucash.Query()
968 query.search_for(
'gncInvoice')
972 query.add_boolean_match([INVOICE_IS_PAID],
False, QOF_QUERY_AND)
974 query.add_boolean_match([INVOICE_IS_PAID],
True, QOF_QUERY_AND)
978 query.add_boolean_match([
'active'],
False, QOF_QUERY_AND)
980 query.add_boolean_match([
'active'],
True, QOF_QUERY_AND)
982 QOF_PARAM_GUID =
'guid'
983 INVOICE_OWNER =
'owner'
986 customer_guid = gnucash.gnucash_core.GUID()
987 gnucash.gnucash_core.GUIDString(customer, customer_guid)
988 query.add_guid_match(
989 [INVOICE_OWNER, QOF_PARAM_GUID], customer_guid, QOF_QUERY_AND)
991 if date_due_from !=
None:
992 pred_data = gnucash.gnucash_core.QueryDatePredicate(
993 QOF_COMPARE_GTE, 2, datetime.datetime.strptime(
994 date_due_from,
"%Y-%m-%d").date())
995 query.add_term([
'date_due'], pred_data, QOF_QUERY_AND)
997 if date_due_to !=
None:
998 pred_data = gnucash.gnucash_core.QueryDatePredicate(
999 QOF_COMPARE_LTE, 2, datetime.datetime.strptime(
1000 date_due_to,
"%Y-%m-%d").date())
1001 query.add_term([
'date_due'], pred_data, QOF_QUERY_AND)
1004 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 1)
1005 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1009 for result
in query.run():
1011 gnucash.gnucash_business.Invoice(instance=result)))
1017def getBills(book, customer, is_paid, is_active, date_opened_from,
1020 query = gnucash.Query()
1021 query.search_for(
'gncInvoice')
1022 query.set_book(book)
1025 query.add_boolean_match([INVOICE_IS_PAID],
False, QOF_QUERY_AND)
1027 query.add_boolean_match([INVOICE_IS_PAID],
True, QOF_QUERY_AND)
1031 query.add_boolean_match([
'active'],
False, QOF_QUERY_AND)
1032 elif is_active == 1:
1033 query.add_boolean_match([
'active'],
True, QOF_QUERY_AND)
1035 QOF_PARAM_GUID =
'guid'
1036 INVOICE_OWNER =
'owner'
1038 if customer !=
None:
1039 customer_guid = gnucash.gnucash_core.GUID()
1040 gnucash.gnucash_core.GUIDString(customer, customer_guid)
1041 query.add_guid_match(
1042 [INVOICE_OWNER, QOF_PARAM_GUID], customer_guid, QOF_QUERY_AND)
1044 if date_opened_from !=
None:
1045 pred_data = gnucash.gnucash_core.QueryDatePredicate(
1046 QOF_COMPARE_GTE, 2, datetime.datetime.strptime(
1047 date_opened_from,
"%Y-%m-%d").date())
1048 query.add_term([
'date_opened'], pred_data, QOF_QUERY_AND)
1050 if date_opened_to !=
None:
1051 pred_data = gnucash.gnucash_core.QueryDatePredicate(
1052 QOF_COMPARE_LTE, 2, datetime.datetime.strptime(
1053 date_opened_to,
"%Y-%m-%d").date())
1054 query.add_term([
'date_opened'], pred_data, QOF_QUERY_AND)
1057 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 2)
1058 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1062 for result
in query.run():
1064 gnucash.gnucash_business.Bill(instance=result)))
1070def getGnuCashInvoice(book ,id):
1075 query = gnucash.Query()
1076 query.search_for(
'gncInvoice')
1077 query.set_book(book)
1080 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 1)
1081 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1085 pred_data = gnucash.gnucash_core.QueryStringPredicate(
1086 QOF_COMPARE_EQUAL, id, QOF_STRING_MATCH_NORMAL,
False)
1087 query.add_term([INVOICE_ID], pred_data, QOF_QUERY_AND)
1091 for result
in query.run():
1092 invoice = gnucash.gnucash_business.Invoice(instance=result)
1098def getGnuCashBill(book ,id):
1103 query = gnucash.Query()
1104 query.search_for(
'gncInvoice')
1105 query.set_book(book)
1108 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 2)
1109 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1113 pred_data = gnucash.gnucash_core.QueryStringPredicate(
1114 QOF_COMPARE_EQUAL, id, QOF_STRING_MATCH_NORMAL,
False)
1115 query.add_term([INVOICE_ID], pred_data, QOF_QUERY_AND)
1119 for result
in query.run():
1120 bill = gnucash.gnucash_business.Bill(instance=result)
1126def getInvoice(book, id):
1130def payInvoice(book, id, posted_account_guid, transfer_account_guid,
1131 payment_date, memo, num, auto_pay):
1133 invoice = getGnuCashInvoice(book, id)
1135 account_guid2 = gnucash.gnucash_core.GUID()
1136 gnucash.gnucash_core.GUIDString(transfer_account_guid, account_guid2)
1138 xfer_acc = account_guid2.AccountLookup(session.book)
1140 invoice.ApplyPayment(
None, xfer_acc, invoice.GetTotal(), GncNumeric(0),
1141 datetime.datetime.strptime(payment_date,
'%Y-%m-%d'), memo, num)
1145def payBill(book, id, posted_account_guid, transfer_account_guid, payment_date,
1146 memo, num, auto_pay):
1148 bill = getGnuCashBill(book, id)
1150 account_guid = gnucash.gnucash_core.GUID()
1151 gnucash.gnucash_core.GUIDString(transfer_account_guid, account_guid)
1153 xfer_acc = account_guid.AccountLookup(session.book)
1157 bill.ApplyPayment(
None, xfer_acc, bill.GetTotal().neg(), GncNumeric(0),
1158 datetime.datetime.strptime(payment_date,
'%Y-%m-%d'), memo, num)
1162def getBill(book, id):
1166def addVendor(book, id, currency_mnumonic, name, contact, address_line_1,
1167 address_line_2, address_line_3, address_line_4, phone, fax, email):
1170 raise Error(
'NoVendorName',
'A name must be entered for this company',
1173 if (address_line_1 ==
''
1174 and address_line_2 ==
''
1175 and address_line_3 ==
''
1176 and address_line_4 ==
''):
1177 raise Error(
'NoVendorAddress',
1178 'An address must be entered for this company',
1179 {
'field':
'address'})
1181 commod_table = book.get_table()
1182 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1184 if currency
is None:
1185 raise Error(
'InvalidVendorCurrency',
1186 'A valid currency must be supplied for this vendor',
1187 {
'field':
'currency'})
1190 id = book.VendorNextID()
1192 vendor = Vendor(session.book, id, currency, name)
1194 address = vendor.GetAddr()
1195 address.SetName(contact)
1196 address.SetAddr1(address_line_1)
1197 address.SetAddr2(address_line_2)
1198 address.SetAddr3(address_line_3)
1199 address.SetAddr4(address_line_4)
1200 address.SetPhone(phone)
1202 address.SetEmail(email)
1206def addCustomer(book, id, currency_mnumonic, name, contact, address_line_1,
1207 address_line_2, address_line_3, address_line_4, phone, fax, email):
1210 raise Error(
'NoCustomerName',
1211 'A name must be entered for this company', {
'field':
'name'})
1213 if (address_line_1 ==
''
1214 and address_line_2 ==
''
1215 and address_line_3 ==
''
1216 and address_line_4 ==
''):
1217 raise Error(
'NoCustomerAddress',
1218 'An address must be entered for this company',
1219 {
'field':
'address'})
1221 commod_table = book.get_table()
1222 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1224 if currency
is None:
1225 raise Error(
'InvalidCustomerCurrency',
1226 'A valid currency must be supplied for this customer',
1227 {
'field':
'currency'})
1230 id = book.CustomerNextID()
1232 customer = Customer(session.book, id, currency, name)
1234 address = customer.GetAddr()
1235 address.SetName(contact)
1236 address.SetAddr1(address_line_1)
1237 address.SetAddr2(address_line_2)
1238 address.SetAddr3(address_line_3)
1239 address.SetAddr4(address_line_4)
1240 address.SetPhone(phone)
1242 address.SetEmail(email)
1246def updateCustomer(book, id, name, contact, address_line_1, address_line_2,
1247 address_line_3, address_line_4, phone, fax, email):
1249 customer = book.CustomerLookupByID(id)
1251 if customer
is None:
1252 raise Error(
'NoCustomer',
'A customer with this ID does not exist',
1256 raise Error(
'NoCustomerName',
1257 'A name must be entered for this company', {
'field':
'name'})
1259 if (address_line_1 ==
''
1260 and address_line_2 ==
''
1261 and address_line_3 ==
''
1262 and address_line_4 ==
''):
1263 raise Error(
'NoCustomerAddress',
1264 'An address must be entered for this company',
1265 {
'field':
'address'})
1267 customer.SetName(name)
1269 address = customer.GetAddr()
1270 address.SetName(contact)
1271 address.SetAddr1(address_line_1)
1272 address.SetAddr2(address_line_2)
1273 address.SetAddr3(address_line_3)
1274 address.SetAddr4(address_line_4)
1275 address.SetPhone(phone)
1277 address.SetEmail(email)
1281def addInvoice(book, id, customer_id, currency_mnumonic, date_opened, notes):
1283 customer = book.CustomerLookupByID(customer_id)
1285 if customer
is None:
1286 raise Error(
'NoCustomer',
1287 'A customer with this ID does not exist', {
'field':
'id'})
1290 id = book.InvoiceNextID(customer)
1293 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1295 raise Error(
'InvalidDateOpened',
1296 'The date opened must be provided in the form YYYY-MM-DD',
1297 {
'field':
'date_opened'})
1299 if currency_mnumonic
is None:
1300 currency_mnumonic = customer.GetCurrency().get_mnemonic()
1302 commod_table = book.get_table()
1303 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1305 if currency
is None:
1306 raise Error(
'InvalidCustomerCurrency',
1307 'A valid currency must be supplied for this customer',
1308 {
'field':
'currency'})
1310 invoice = Invoice(book, id, currency, customer, date_opened.date())
1312 invoice.SetNotes(notes)
1316def updateInvoice(book, id, customer_id, currency_mnumonic, date_opened,
1317 notes, posted, posted_account_guid, posted_date, due_date, posted_memo,
1318 posted_accumulatesplits, posted_autopay):
1320 invoice = getGnuCashInvoice(book, id)
1323 raise Error(
'NoInvoice',
1324 'An invoice with this ID does not exist',
1327 customer = book.CustomerLookupByID(customer_id)
1329 if customer
is None:
1330 raise Error(
'NoCustomer',
'A customer with this ID does not exist',
1331 {
'field':
'customer_id'})
1334 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1336 raise Error(
'InvalidDateOpened',
1337 'The date opened must be provided in the form YYYY-MM-DD',
1338 {
'field':
'date_opened'})
1340 if posted_date ==
'':
1342 raise Error(
'NoDatePosted',
1343 'The date posted must be supplied when posted=1',
1344 {
'field':
'date_posted'})
1347 posted_date = datetime.datetime.strptime(posted_date,
"%Y-%m-%d")
1349 raise Error(
'InvalidDatePosted',
1350 'The date posted must be provided in the form YYYY-MM-DD',
1351 {
'field':
'posted_date'})
1355 raise Error(
'NoDatePosted',
1356 'The due date must be supplied when posted=1',
1357 {
'field':
'date_posted'})
1360 due_date = datetime.datetime.strptime(due_date,
"%Y-%m-%d")
1362 raise Error(
'InvalidDatePosted',
1363 'The due date must be provided in the form YYYY-MM-DD',
1364 {
'field':
'due_date'})
1366 if posted_account_guid ==
'':
1368 raise Error(
'NoPostedAccountGuid',
1369 'The posted account GUID must be supplied when posted=1',
1370 {
'field':
'posted_account_guid'})
1372 guid = gnucash.gnucash_core.GUID()
1373 gnucash.gnucash_core.GUIDString(posted_account_guid, guid)
1375 posted_account = guid.AccountLookup(book)
1377 if posted_account
is None:
1378 raise Error(
'NoAccount',
1379 'No account exists with the posted account GUID',
1380 {
'field':
'posted_account_guid'})
1382 invoice.SetOwner(customer)
1383 invoice.SetDateOpened(date_opened)
1384 invoice.SetNotes(notes)
1387 if (invoice.GetDatePosted().strftime(
'%Y-%m-%d') ==
'1970-01-01'
1389 invoice.PostToAccount(posted_account, posted_date, due_date,
1390 posted_memo, posted_accumulatesplits, posted_autopay)
1394def updateBill(book, id, vendor_id, currency_mnumonic, date_opened, notes,
1395 posted, posted_account_guid, posted_date, due_date, posted_memo,
1396 posted_accumulatesplits, posted_autopay):
1398 bill = getGnuCashBill(book, id)
1401 raise Error(
'NoBill',
'A bill with this ID does not exist',
1404 vendor = book.VendorLookupByID(vendor_id)
1407 raise Error(
'NoVendor',
1408 'A vendor with this ID does not exist',
1409 {
'field':
'vendor_id'})
1412 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1414 raise Error(
'InvalidDateOpened',
1415 'The date opened must be provided in the form YYYY-MM-DD',
1416 {
'field':
'date_opened'})
1418 if posted_date ==
'':
1420 raise Error(
'NoDatePosted',
1421 'The date posted must be supplied when posted=1',
1422 {
'field':
'date_posted'})
1425 posted_date = datetime.datetime.strptime(posted_date,
"%Y-%m-%d")
1427 raise Error(
'InvalidDatePosted',
1428 'The date posted must be provided in the form YYYY-MM-DD',
1429 {
'field':
'posted_date'})
1433 raise Error(
'NoDatePosted',
1434 'The due date must be supplied when posted=1',
1435 {
'field':
'date_posted'})
1438 due_date = datetime.datetime.strptime(due_date,
"%Y-%m-%d")
1440 raise Error(
'InvalidDatePosted',
1441 'The due date must be provided in the form YYYY-MM-DD',
1442 {
'field':
'due_date'})
1444 if posted_account_guid ==
'':
1446 raise Error(
'NoPostedAccountGuid',
1447 'The posted account GUID must be supplied when posted=1',
1448 {
'field':
'posted_account_guid'})
1450 guid = gnucash.gnucash_core.GUID()
1451 gnucash.gnucash_core.GUIDString(posted_account_guid, guid)
1453 posted_account = guid.AccountLookup(book)
1455 if posted_account
is None:
1456 raise Error(
'NoAccount',
1457 'No account exists with the posted account GUID',
1458 {
'field':
'posted_account_guid'})
1460 bill.SetOwner(vendor)
1461 bill.SetDateOpened(date_opened)
1462 bill.SetNotes(notes)
1465 if bill.GetDatePosted().strftime(
'%Y-%m-%d') ==
'1970-01-01' and posted == 1:
1466 bill.PostToAccount(posted_account, posted_date, due_date, posted_memo,
1467 posted_accumulatesplits, posted_autopay)
1471def addEntry(book, invoice_id, date, description, account_guid, quantity, price):
1473 invoice = getGnuCashInvoice(book, invoice_id)
1476 raise Error(
'NoInvoice',
1477 'No invoice exists with this ID', {
'field':
'invoice_id'})
1480 date = datetime.datetime.strptime(date,
"%Y-%m-%d")
1482 raise Error(
'InvalidDateOpened',
1483 'The date opened must be provided in the form YYYY-MM-DD',
1486 guid = gnucash.gnucash_core.GUID()
1487 gnucash.gnucash_core.GUIDString(account_guid, guid)
1489 account = guid.AccountLookup(book)
1492 raise Error(
'NoAccount',
'No account exists with this GUID',
1493 {
'field':
'account_guid'})
1496 quantity = Decimal(quantity).quantize(Decimal(
'.01'))
1497 except ArithmeticError:
1498 raise Error(
'InvalidQuantity',
'This quantity is not valid',
1499 {
'field':
'quantity'})
1502 price = Decimal(price).quantize(Decimal(
'.01'))
1503 except ArithmeticError:
1504 raise Error(
'InvalidPrice',
'This price is not valid',
1507 entry = Entry(book, invoice, date.date())
1508 entry.SetDateEntered(datetime.datetime.now())
1509 entry.SetDescription(description)
1510 entry.SetInvAccount(account)
1511 entry.SetQuantity(gnc_numeric_from_decimal(quantity))
1512 entry.SetInvPrice(gnc_numeric_from_decimal(price))
1516def addBillEntry(book, bill_id, date, description, account_guid, quantity,
1519 bill = getGnuCashBill(book,bill_id)
1522 raise Error(
'NoBill',
'No bill exists with this ID',
1523 {
'field':
'bill_id'})
1526 date = datetime.datetime.strptime(date,
"%Y-%m-%d")
1528 raise Error(
'InvalidDateOpened',
1529 'The date opened must be provided in the form YYYY-MM-DD',
1532 guid = gnucash.gnucash_core.GUID()
1533 gnucash.gnucash_core.GUIDString(account_guid, guid)
1535 account = guid.AccountLookup(book)
1538 raise Error(
'NoAccount',
'No account exists with this GUID',
1539 {
'field':
'account_guid'})
1542 quantity = Decimal(quantity).quantize(Decimal(
'.01'))
1543 except ArithmeticError:
1544 raise Error(
'InvalidQuantity',
'This quantity is not valid',
1545 {
'field':
'quantity'})
1548 price = Decimal(price).quantize(Decimal(
'.01'))
1549 except ArithmeticError:
1550 raise Error(
'InvalidPrice',
'This price is not valid',
1553 entry = Entry(book, bill, date.date())
1554 entry.SetDateEntered(datetime.datetime.now())
1555 entry.SetDescription(description)
1556 entry.SetBillAccount(account)
1557 entry.SetQuantity(gnc_numeric_from_decimal(quantity))
1558 entry.SetBillPrice(gnc_numeric_from_decimal(price))
1562def getEntry(book, entry_guid):
1564 guid = gnucash.gnucash_core.GUID()
1565 gnucash.gnucash_core.GUIDString(entry_guid, guid)
1567 entry = book.EntryLookup(guid)
1574def updateEntry(book, entry_guid, date, description, account_guid, quantity,
1577 guid = gnucash.gnucash_core.GUID()
1578 gnucash.gnucash_core.GUIDString(entry_guid, guid)
1580 entry = book.EntryLookup(guid)
1583 raise Error(
'NoEntry',
'No entry exists with this GUID',
1584 {
'field':
'entry_guid'})
1587 date = datetime.datetime.strptime(date,
"%Y-%m-%d")
1589 raise Error(
'InvalidDateOpened',
1590 'The date opened must be provided in the form YYYY-MM-DD',
1593 gnucash.gnucash_core.GUIDString(account_guid, guid)
1595 account = guid.AccountLookup(book)
1598 raise Error(
'NoAccount',
'No account exists with this GUID',
1599 {
'field':
'account_guid'})
1601 entry.SetDate(date.date())
1602 entry.SetDateEntered(datetime.datetime.now())
1603 entry.SetDescription(description)
1604 entry.SetInvAccount(account)
1606 gnc_numeric_from_decimal(Decimal(quantity).quantize(Decimal(
'.01'))))
1608 gnc_numeric_from_decimal(Decimal(price).quantize(Decimal(
'.01'))))
1612def deleteEntry(book, entry_guid):
1614 guid = gnucash.gnucash_core.GUID()
1615 gnucash.gnucash_core.GUIDString(entry_guid, guid)
1617 entry = book.EntryLookup(guid)
1619 invoice = entry.GetInvoice()
1620 bill = entry.GetBill()
1622 if invoice !=
None and entry !=
None:
1623 invoice.RemoveEntry(entry)
1624 elif bill !=
None and entry !=
None:
1625 bill.RemoveEntry(entry)
1630def deleteTransaction(book, transaction_guid):
1632 guid = gnucash.gnucash_core.GUID()
1633 gnucash.gnucash_core.GUIDString(transaction_guid, guid)
1635 transaction = guid.TransLookup(book)
1637 if transaction !=
None :
1638 transaction.Destroy()
1640def addBill(book, id, vendor_id, currency_mnumonic, date_opened, notes):
1642 vendor = book.VendorLookupByID(vendor_id)
1645 raise Error(
'NoVendor',
'A vendor with this ID does not exist',
1649 id = book.BillNextID(vendor)
1652 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1654 raise Error(
'InvalidVendorDateOpened',
1655 'The date opened must be provided in the form YYYY-MM-DD',
1656 {
'field':
'date_opened'})
1658 if currency_mnumonic
is None:
1659 currency_mnumonic = vendor.GetCurrency().get_mnemonic()
1661 commod_table = book.get_table()
1662 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1664 if currency
is None:
1665 raise Error(
'InvalidVendorCurrency',
1666 'A valid currency must be supplied for this vendor',
1667 {
'field':
'currency'})
1669 bill = Bill(book, id, currency, vendor, date_opened.date())
1671 bill.SetNotes(notes)
1675def addAccount(book, name, currency_mnumonic, account_type_id,
1676 parent_account_guid, description, code):
1678 from gnucash.gnucash_core_c
import ACCT_TYPE_ROOT, ACCT_TYPE_TRADING
1681 raise Error(
'NoAccountName',
1682 'A name must be entered for this account',
1686 account_type_id = int(account_type_id)
1687 except (TypeError, ValueError):
1688 raise Error(
'InvalidAccountTypeID',
1689 'A valid account type id must be supplied for this account',
1690 {
'field':
'account_type_id'})
1694 if (account_type_id < 0
or account_type_id > ACCT_TYPE_TRADING
1695 or account_type_id == ACCT_TYPE_ROOT):
1696 raise Error(
'InvalidAccountTypeID',
1697 'A valid account type id must be supplied for this account',
1698 {
'field':
'account_type_id'})
1700 commod_table = book.get_table()
1701 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1703 if currency
is None:
1704 raise Error(
'InvalidAccountCurrency',
1705 'A valid currency must be supplied for this account',
1706 {
'field':
'currency'})
1708 if parent_account_guid ==
'':
1709 raise Error(
'NoParentAccount',
1710 'A parent account guid must be supplied for this account',
1711 {
'field':
'parent_account_guid'})
1713 guid = gnucash.gnucash_core.GUID()
1714 gnucash.gnucash_core.GUIDString(parent_account_guid, guid)
1715 parent_account = guid.AccountLookup(book)
1717 if parent_account
is None:
1718 raise Error(
'InvalidParentAccount',
1719 'A parent account with this guid does not exist',
1720 {
'field':
'parent_account_guid'})
1722 account = Account(book)
1723 parent_account.append_child(account)
1724 account.SetName(name)
1725 account.SetType(account_type_id)
1726 account.SetCommodity(currency)
1728 if description !=
'':
1729 account.SetDescription(description)
1732 account.SetCode(code)
1736def addTransaction(book, num, description, date_posted, currency_mnumonic, splits):
1738 transaction = Transaction(book)
1740 transaction.BeginEdit()
1742 commod_table = book.get_table()
1743 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1745 if currency
is None:
1746 raise Error(
'InvalidTransactionCurrency',
1747 'A valid currency must be supplied for this transaction',
1748 {
'field':
'currency'})
1751 date_posted = datetime.datetime.strptime(date_posted,
"%Y-%m-%d")
1753 raise Error(
'InvalidDatePosted',
1754 'The date posted must be provided in the form YYYY-MM-DD',
1755 {
'field':
'date_posted'})
1758 for split_values
in splits:
1759 account_guid = gnucash.gnucash_core.GUID()
1760 gnucash.gnucash_core.GUIDString(split_values[
'account_guid'], account_guid)
1762 account = account_guid.AccountLookup(book)
1765 raise Error(
'InvalidSplitAccount',
1766 'A valid account must be supplied for this split',
1767 {
'field':
'account'})
1770 split.SetValue(GncNumeric(split_values[
'value'], 100))
1771 split.SetAccount(account)
1772 split.SetParent(transaction)
1774 transaction.SetCurrency(currency)
1775 transaction.SetDescription(description)
1776 transaction.SetNum(num)
1778 transaction.SetDatePostedTS(date_posted)
1780 transaction.CommitEdit()
1784def getTransaction(book, transaction_guid):
1786 guid = gnucash.gnucash_core.GUID()
1787 gnucash.gnucash_core.GUIDString(transaction_guid, guid)
1789 transaction = guid.TransLookup(book)
1791 if transaction
is None:
1796def editTransaction(book, transaction_guid, num, description, date_posted,
1797 currency_mnumonic, splits):
1799 guid = gnucash.gnucash_core.GUID()
1800 gnucash.gnucash_core.GUIDString(transaction_guid, guid)
1802 transaction = guid.TransLookup(book)
1804 if transaction
is None:
1805 raise Error(
'NoCustomer',
1806 'A transaction with this GUID does not exist',
1809 transaction.BeginEdit()
1811 commod_table = book.get_table()
1812 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1814 if currency
is None:
1815 raise Error(
'InvalidTransactionCurrency',
1816 'A valid currency must be supplied for this transaction',
1817 {
'field':
'currency'})
1821 date_posted = datetime.datetime.strptime(date_posted,
"%Y-%m-%d")
1823 raise Error(
'InvalidDatePosted',
1824 'The date posted must be provided in the form YYYY-MM-DD',
1825 {
'field':
'date_posted'})
1827 for split_values
in splits:
1829 split_guid = gnucash.gnucash_core.GUID()
1830 gnucash.gnucash_core.GUIDString(split_values[
'guid'], split_guid)
1832 split = split_guid.SplitLookup(book)
1835 raise Error(
'InvalidSplitGuid',
1836 'A valid guid must be supplied for this split',
1839 account_guid = gnucash.gnucash_core.GUID()
1840 gnucash.gnucash_core.GUIDString(
1841 split_values[
'account_guid'], account_guid)
1843 account = account_guid.AccountLookup(book)
1846 raise Error(
'InvalidSplitAccount',
1847 'A valid account must be supplied for this split',
1848 {
'field':
'account'})
1850 split.SetValue(GncNumeric(split_values[
'value'], 100))
1851 split.SetAccount(account)
1852 split.SetParent(transaction)
1854 transaction.SetCurrency(currency)
1855 transaction.SetDescription(description)
1856 transaction.SetNum(num)
1858 transaction.SetDatePostedTS(date_posted)
1860 transaction.CommitEdit()
1864def gnc_numeric_from_decimal(decimal_value):
1865 sign, digits, exponent = decimal_value.as_tuple()
1873 TEN = int(Decimal(0).radix())
1874 numerator_place_value = 1
1877 for i
in range(len(digits)-1,-1,-1):
1878 numerator += digits[i] * numerator_place_value
1879 numerator_place_value *= TEN
1881 if decimal_value.is_signed():
1882 numerator = -numerator
1886 denominator = TEN ** (-exponent)
1890 numerator *= TEN ** exponent
1893 return GncNumeric(numerator, denominator)
1902 """Base class for exceptions in this module."""
1903 def __init__(self, type, message, data):
1909 options, arguments = getopt.getopt(sys.argv[1:],
'nh:', [
'host=',
'new='])
1910except getopt.GetoptError
as err:
1912 print(
'Usage: python-rest.py <connection string>')
1915if len(arguments) == 0:
1916 print(
'Usage: python-rest.py <connection string>')
1923for option, value
in options:
1924 if option
in (
"-h",
"--host"):
1930for option, value
in options:
1931 if option
in (
"-n",
"--new"):
1937 session = gnucash.Session(arguments[0], SessionOpenMode.SESSION_NEW_STORE)
1947session = gnucash.Session(arguments[0], SessionOpenMode.SESSION_BREAK_LOCK)
1950atexit.register(shutdown)
1957 from logging
import StreamHandler
1958 stream_handler = StreamHandler()
1959 stream_handler.setLevel(logging.ERROR)
1960 app.logger.addHandler(stream_handler)
splitToDict(split, entities)
transactionToDict(transaction, entities)