5 gnucash_rest.py -- A Flask app which responds to REST requests
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of
13 the License, or (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, contact:
23 Free Software Foundation Voice: +1-617-542-5942
24 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
35 from flask
import Flask, abort, request, Response
39 from decimal
import Decimal
41 from gnucash.gnucash_business
import Vendor, Bill, Entry, GncNumeric, \
42 Customer, Invoice, Split, Account, Transaction
54 QOF_STRING_MATCH_NORMAL, \
55 QOF_STRING_MATCH_CASEINSENSITIVE
74 @app.route(
'/accounts', methods=[
'GET',
'POST'])
77 if request.method ==
'GET':
79 accounts = getAccounts(session.book)
81 return Response(json.dumps(accounts), mimetype=
'application/json')
83 elif request.method ==
'POST':
86 account = addAccount(session.books)
87 except Error
as error:
88 return Response(json.dumps({
'errors': [{
'type' : error.type,
89 'message': error.message,
'data': error.data}]}), status=400,
90 mimetype=
'application/json')
92 return Response(json.dumps(account), status=201,
93 mimetype=
'application/json')
98 @app.route(
'/accounts/<guid>', methods=[
'GET'])
99 def api_account(guid):
101 account = getAccount(session.book, guid)
106 return Response(json.dumps(account), mimetype=
'application/json')
108 @app.route(
'/accounts/<guid>/splits', methods=[
'GET'])
109 def api_account_splits(guid):
111 date_posted_from = request.args.get(
'date_posted_from',
None)
112 date_posted_to = request.args.get(
'date_posted_to',
None)
115 account = getAccount(session.book, guid)
120 splits = getAccountSplits(session.book, guid, date_posted_from,
123 return Response(json.dumps(splits), mimetype=
'application/json')
126 @app.route(
'/transactions', methods=[
'POST'])
127 def api_transactions():
129 if request.method ==
'POST':
131 currency = str(request.form.get(
'currency',
''))
132 description = str(request.form.get(
'description',
''))
133 num = str(request.form.get(
'num',
''))
134 date_posted = str(request.form.get(
'date_posted',
''))
136 splitvalue1 = int(request.form.get(
'splitvalue1',
''))
137 splitaccount1 = str(request.form.get(
'splitaccount1',
''))
138 splitvalue2 = int(request.form.get(
'splitvalue2',
''))
139 splitaccount2 = str(request.form.get(
'splitaccount2',
''))
142 {
'value': splitvalue1,
'account_guid': splitaccount1},
143 {
'value': splitvalue2,
'account_guid': splitaccount2}]
146 transaction = addTransaction(session.book, num, description,
147 date_posted, currency, splits)
148 except Error
as error:
149 return Response(json.dumps({
'errors': [{
'type' : error.type,
150 'message': error.message,
'data': error.data}]}), status=400,
151 mimetype=
'application/json')
153 return Response(json.dumps(transaction), status=201,
154 mimetype=
'application/json')
159 @app.route(
'/transactions/<guid>', methods=[
'GET',
'POST',
'DELETE'])
160 def api_transaction(guid):
162 if request.method ==
'GET':
164 transaction = getTransaction(session.book, guid)
166 if transaction
is None:
169 return Response(json.dumps(transaction), mimetype=
'application/json')
171 elif request.method ==
'POST':
173 currency = str(request.form.get(
'currency',
''))
174 description = str(request.form.get(
'description',
''))
175 num = str(request.form.get(
'num',
''))
176 date_posted = str(request.form.get(
'date_posted',
''))
178 splitguid1 = str(request.form.get(
'splitguid1',
''))
179 splitvalue1 = int(request.form.get(
'splitvalue1',
''))
180 splitaccount1 = str(request.form.get(
'splitaccount1',
''))
181 splitguid2 = str(request.form.get(
'splitguid2',
''))
182 splitvalue2 = int(request.form.get(
'splitvalue2',
''))
183 splitaccount2 = str(request.form.get(
'splitaccount2',
''))
187 'value': splitvalue1,
188 'account_guid': splitaccount1},
190 'value': splitvalue2,
191 'account_guid': splitaccount2}
195 transaction = editTransaction(session.book, guid, num, description,
196 date_posted, currency, splits)
197 except Error
as error:
198 return Response(json.dumps({
'errors': [{
'type' : error.type,
199 'message': error.message,
'data': error.data}]}), status=400, mimetype=
'application/json')
201 return Response(json.dumps(transaction), status=200,
202 mimetype=
'application/json')
204 elif request.method ==
'DELETE':
206 deleteTransaction(session.book, guid)
208 return Response(
'', status=200, mimetype=
'application/json')
213 @app.route(
'/bills', methods=[
'GET',
'POST'])
216 if request.method ==
'GET':
218 is_paid = request.args.get(
'is_paid',
None)
219 is_active = request.args.get(
'is_active',
None)
220 date_opened_to = request.args.get(
'date_opened_to',
None)
221 date_opened_from = request.args.get(
'date_opened_from',
None)
232 elif is_active ==
'0':
237 bills = getBills(session.book,
None, is_paid, is_active,
238 date_opened_from, date_opened_to)
240 return Response(json.dumps(bills), mimetype=
'application/json')
242 elif request.method ==
'POST':
244 id = str(request.form.get(
'id',
None))
251 vendor_id = str(request.form.get(
'vendor_id',
''))
252 currency = str(request.form.get(
'currency',
''))
253 date_opened = str(request.form.get(
'date_opened',
''))
254 notes = str(request.form.get(
'notes',
''))
257 bill = addBill(session.book, id, vendor_id, currency, date_opened,
259 except Error
as error:
261 return Response(json.dumps({
'errors': [{
'type' : error.type,
262 'message': error.message,
'data': error.data}]}), status=400, mimetype=
'application/json')
264 return Response(json.dumps(bill), status=201,
265 mimetype=
'application/json')
270 @app.route(
'/bills/<id>', methods=[
'GET',
'POST',
'PAY'])
273 if request.method ==
'GET':
275 bill = getBill(session.book, id)
280 return Response(json.dumps(bill), mimetype=
'application/json')
282 elif request.method ==
'POST':
284 vendor_id = str(request.form.get(
'vendor_id',
''))
285 currency = str(request.form.get(
'currency',
''))
286 date_opened = request.form.get(
'date_opened',
None)
287 notes = str(request.form.get(
'notes',
''))
288 posted = request.form.get(
'posted',
None)
289 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
290 posted_date = request.form.get(
'posted_date',
'')
291 due_date = request.form.get(
'due_date',
'')
292 posted_memo = str(request.form.get(
'posted_memo',
''))
293 posted_accumulatesplits = request.form.get(
'posted_accumulatesplits',
295 posted_autopay = request.form.get(
'posted_autopay',
'')
302 if (posted_accumulatesplits ==
'1'
303 or posted_accumulatesplits ==
'true'
304 or posted_accumulatesplits ==
'True'
305 or posted_accumulatesplits ==
True):
306 posted_accumulatesplits =
True
308 posted_accumulatesplits =
False
310 if posted_autopay ==
'1':
311 posted_autopay =
True
313 posted_autopay =
False
315 bill = updateBill(session.book, id, vendor_id, currency,
316 date_opened, notes, posted, posted_account_guid, posted_date,
317 due_date, posted_memo, posted_accumulatesplits, posted_autopay)
318 except Error
as error:
319 return Response(json.dumps({
'errors': [{
'type' : error.type,
320 'message': error.message,
'data': error.data}]}), status=400,
321 mimetype=
'application/json')
323 return Response(json.dumps(bill), status=200,
324 mimetype=
'application/json')
329 return Response(json.dumps(bill),
330 mimetype=
'application/json')
332 elif request.method ==
'PAY':
334 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
335 transfer_account_guid = str(request.form.get(
'transfer_account_guid',
337 payment_date = request.form.get(
'payment_date',
'')
338 num = str(request.form.get(
'num',
''))
339 memo = str(request.form.get(
'posted_memo',
''))
340 auto_pay = request.form.get(
'auto_pay',
'')
343 bill = payBill(session.book, id, posted_account_guid,
344 transfer_account_guid, payment_date, memo, num, auto_pay)
345 except Error
as error:
346 return Response(json.dumps({
'errors': [{
'type' : error.type,
347 'message': error.message,
'data': error.data}]}), status=400,
348 mimetype=
'application/json')
350 return Response(json.dumps(bill), status=200,
351 mimetype=
'application/json')
356 @app.route(
'/bills/<id>/entries', methods=[
'GET',
'POST'])
357 def api_bill_entries(id):
359 bill = getBill(session.book, id)
364 if request.method ==
'GET':
365 return Response(json.dumps(bill[
'entries']), mimetype=
'application/json')
366 elif request.method ==
'POST':
368 date = str(request.form.get(
'date',
''))
369 description = str(request.form.get(
'description',
''))
370 account_guid = str(request.form.get(
'account_guid',
''))
371 quantity = str(request.form.get(
'quantity',
''))
372 price = str(request.form.get(
'price',
''))
375 entry = addBillEntry(session.book, id, date, description,
376 account_guid, quantity, price)
377 except Error
as error:
378 return Response(json.dumps({
'errors': [{
'type' : error.type,
379 'message': error.message,
'data': error.data}]}),
380 status=400, mimetype=
'application/json')
382 return Response(json.dumps(entry), status=201,
383 mimetype=
'application/json')
388 @app.route(
'/invoices', methods=[
'GET',
'POST'])
391 if request.method ==
'GET':
393 is_paid = request.args.get(
'is_paid',
None)
394 is_active = request.args.get(
'is_active',
None)
395 date_due_to = request.args.get(
'date_due_to',
None)
396 date_due_from = request.args.get(
'date_due_from',
None)
407 elif is_active ==
'0':
412 invoices = getInvoices(session.book,
None, is_paid, is_active,
413 date_due_from, date_due_to)
415 return Response(json.dumps(invoices), mimetype=
'application/json')
417 elif request.method ==
'POST':
419 id = str(request.form.get(
'id',
None))
426 customer_id = str(request.form.get(
'customer_id',
''))
427 currency = str(request.form.get(
'currency',
''))
428 date_opened = str(request.form.get(
'date_opened',
''))
429 notes = str(request.form.get(
'notes',
''))
432 invoice = addInvoice(session.book, id, customer_id, currency,
434 except Error
as error:
435 return Response(json.dumps({
'errors': [{
'type' : error.type,
436 'message': error.message,
'data': error.data}]}), status=400,
437 mimetype=
'application/json')
439 return Response(json.dumps(invoice), status=201,
440 mimetype=
'application/json')
445 @app.route(
'/invoices/<id>', methods=[
'GET',
'POST',
'PAY'])
448 if request.method ==
'GET':
450 invoice = getInvoice(session.book, id)
455 return Response(json.dumps(invoice), mimetype=
'application/json')
457 elif request.method ==
'POST':
459 customer_id = str(request.form.get(
'customer_id',
''))
460 currency = str(request.form.get(
'currency',
''))
461 date_opened = request.form.get(
'date_opened',
None)
462 notes = str(request.form.get(
'notes',
''))
463 posted = request.form.get(
'posted',
None)
464 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
465 posted_date = request.form.get(
'posted_date',
'')
466 due_date = request.form.get(
'due_date',
'')
467 posted_memo = str(request.form.get(
'posted_memo',
''))
468 posted_accumulatesplits = request.form.get(
'posted_accumulatesplits',
470 posted_autopay = request.form.get(
'posted_autopay',
'')
477 if (posted_accumulatesplits ==
'1'
478 or posted_accumulatesplits ==
'true'
479 or posted_accumulatesplits ==
'True'
480 or posted_accumulatesplits ==
True):
481 posted_accumulatesplits =
True
483 posted_accumulatesplits =
False
485 if posted_autopay ==
'1':
486 posted_autopay =
True
488 posted_autopay =
False
490 invoice = updateInvoice(session.book, id, customer_id, currency,
491 date_opened, notes, posted, posted_account_guid, posted_date,
492 due_date, posted_memo, posted_accumulatesplits, posted_autopay)
493 except Error
as error:
494 return Response(json.dumps({
'errors': [{
'type' : error.type,
495 'message': error.message,
'data': error.data}]}), status=400,
496 mimetype=
'application/json')
498 return Response(json.dumps(invoice), status=200,
499 mimetype=
'application/json')
504 return Response(json.dumps(invoice), mimetype=
'application/json')
506 elif request.method ==
'PAY':
508 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
509 transfer_account_guid = str(request.form.get(
'transfer_account_guid',
511 payment_date = request.form.get(
'payment_date',
'')
512 num = str(request.form.get(
'num',
''))
513 memo = str(request.form.get(
'posted_memo',
''))
514 auto_pay = request.form.get(
'auto_pay',
'')
517 invoice = payInvoice(session.book, id, posted_account_guid,
518 transfer_account_guid, payment_date, memo, num, auto_pay)
519 except Error
as error:
520 return Response(json.dumps({
'errors': [{
'type' : error.type,
521 'message': error.message,
'data': error.data}]}), status=400,
522 mimetype=
'application/json')
524 return Response(json.dumps(invoice), status=200,
525 mimetype=
'application/json')
530 @app.route(
'/invoices/<id>/entries', methods=[
'GET',
'POST'])
531 def api_invoice_entries(id):
533 invoice = getInvoice(session.book, id)
538 if request.method ==
'GET':
539 return Response(json.dumps(invoice[
'entries']),
540 mimetype=
'application/json')
541 elif request.method ==
'POST':
543 date = str(request.form.get(
'date',
''))
544 description = str(request.form.get(
'description',
''))
545 account_guid = str(request.form.get(
'account_guid',
''))
546 quantity = str(request.form.get(
'quantity',
''))
547 price = str(request.form.get(
'price',
''))
550 entry = addEntry(session.book, id, date, description,
551 account_guid, quantity, price)
552 except Error
as error:
553 return Response(json.dumps({
'errors': [{
'type' : error.type,
554 'message': error.message,
'data': error.data}]}),
555 status=400, mimetype=
'application/json')
557 return Response(json.dumps(entry), status=201,
558 mimetype=
'application/json')
563 @app.route(
'/entries/<guid>', methods=[
'GET',
'POST',
'DELETE'])
566 entry = getEntry(session.book, guid)
571 if request.method ==
'GET':
572 return Response(json.dumps(entry), mimetype=
'application/json')
573 elif request.method ==
'POST':
575 date = str(request.form.get(
'date',
''))
576 description = str(request.form.get(
'description',
''))
577 account_guid = str(request.form.get(
'account_guid',
''))
578 quantity = str(request.form.get(
'quantity',
''))
579 price = str(request.form.get(
'price',
''))
582 entry = updateEntry(session.book, guid, date, description,
583 account_guid, quantity, price)
584 except Error
as error:
585 return Response(json.dumps({
'errors': [{
'type' : error.type,
586 'message': error.message,
'data': error.data}]}),
587 status=400, mimetype=
'application/json')
589 return Response(json.dumps(entry), status=200,
590 mimetype=
'application/json')
592 elif request.method ==
'DELETE':
594 deleteEntry(session.book, guid)
596 return Response(
'', status=201, mimetype=
'application/json')
601 @app.route(
'/customers', methods=[
'GET',
'POST'])
604 if request.method ==
'GET':
605 customers = getCustomers(session.book)
606 return Response(json.dumps(customers), mimetype=
'application/json')
607 elif request.method ==
'POST':
609 id = str(request.form.get(
'id',
None))
616 currency = str(request.form.get(
'currency',
''))
617 name = str(request.form.get(
'name',
''))
618 contact = str(request.form.get(
'contact',
''))
619 address_line_1 = str(request.form.get(
'address_line_1',
''))
620 address_line_2 = str(request.form.get(
'address_line_2',
''))
621 address_line_3 = str(request.form.get(
'address_line_3',
''))
622 address_line_4 = str(request.form.get(
'address_line_4',
''))
623 phone = str(request.form.get(
'phone',
''))
624 fax = str(request.form.get(
'fax',
''))
625 email = str(request.form.get(
'email',
''))
628 customer = addCustomer(session.book, id, currency, name, contact,
629 address_line_1, address_line_2, address_line_3, address_line_4,
631 except Error
as error:
632 return Response(json.dumps({
'errors': [{
'type' : error.type,
633 'message': error.message,
'data': error.data}]}), status=400,
634 mimetype=
'application/json')
636 return Response(json.dumps(customer), status=201,
637 mimetype=
'application/json')
642 @app.route(
'/customers/<id>', methods=[
'GET',
'POST'])
643 def api_customer(id):
645 if request.method ==
'GET':
647 customer = getCustomer(session.book, id)
652 return Response(json.dumps(customer), mimetype=
'application/json')
654 elif request.method ==
'POST':
656 id = str(request.form.get(
'id',
None))
658 name = str(request.form.get(
'name',
''))
659 contact = str(request.form.get(
'contact',
''))
660 address_line_1 = str(request.form.get(
'address_line_1',
''))
661 address_line_2 = str(request.form.get(
'address_line_2',
''))
662 address_line_3 = str(request.form.get(
'address_line_3',
''))
663 address_line_4 = str(request.form.get(
'address_line_4',
''))
664 phone = str(request.form.get(
'phone',
''))
665 fax = str(request.form.get(
'fax',
''))
666 email = str(request.form.get(
'email',
''))
669 customer = updateCustomer(session.book, id, name, contact,
670 address_line_1, address_line_2, address_line_3, address_line_4,
672 except Error
as error:
673 if error.type ==
'NoCustomer':
674 return Response(json.dumps({
'errors': [{
'type' : error.type,
675 'message': error.message,
'data': error.data}]}),
676 status=404, mimetype=
'application/json')
678 return Response(json.dumps({
'errors': [{
'type' : error.type,
679 'message': error.message,
'data': error.data}]}),
680 status=400, mimetype=
'application/json')
682 return Response(json.dumps(customer), status=200,
683 mimetype=
'application/json')
688 @app.route(
'/customers/<id>/invoices', methods=[
'GET'])
689 def api_customer_invoices(id):
691 customer = getCustomer(session.book, id)
696 invoices = getInvoices(session.book, customer[
'guid'],
None,
None,
None,
699 return Response(json.dumps(invoices), mimetype=
'application/json')
701 @app.route(
'/vendors', methods=[
'GET',
'POST'])
704 if request.method ==
'GET':
705 vendors = getVendors(session.book)
706 return Response(json.dumps(vendors), mimetype=
'application/json')
707 elif request.method ==
'POST':
709 id = str(request.form.get(
'id',
None))
716 currency = str(request.form.get(
'currency',
''))
717 name = str(request.form.get(
'name',
''))
718 contact = str(request.form.get(
'contact',
''))
719 address_line_1 = str(request.form.get(
'address_line_1',
''))
720 address_line_2 = str(request.form.get(
'address_line_2',
''))
721 address_line_3 = str(request.form.get(
'address_line_3',
''))
722 address_line_4 = str(request.form.get(
'address_line_4',
''))
723 phone = str(request.form.get(
'phone',
''))
724 fax = str(request.form.get(
'fax',
''))
725 email = str(request.form.get(
'email',
''))
728 vendor = addVendor(session.book, id, currency, name, contact,
729 address_line_1, address_line_2, address_line_3, address_line_4,
731 except Error
as error:
732 return Response(json.dumps({
'errors': [{
'type' : error.type,
733 'message': error.message,
'data': error.data}]}), status=400,
734 mimetype=
'application/json')
736 return Response(json.dumps(vendor), status=201,
737 mimetype=
'application/json')
742 @app.route(
'/vendors/<id>', methods=[
'GET',
'POST'])
745 if request.method ==
'GET':
747 vendor = getVendor(session.book, id)
752 return Response(json.dumps(vendor), mimetype=
'application/json')
756 @app.route(
'/vendors/<id>/bills', methods=[
'GET'])
757 def api_vendor_bills(id):
759 vendor = getVendor(session.book, id)
764 bills = getBills(session.book, vendor[
'guid'],
None,
None,
None,
None)
766 return Response(json.dumps(bills), mimetype=
'application/json')
768 def getCustomers(book):
770 query = gnucash.Query()
771 query.search_for(
'gncCustomer')
775 for result
in query.run():
777 gnucash.gnucash_business.Customer(instance=result)))
783 def getCustomer(book, id):
785 customer = book.CustomerLookupByID(id)
792 def getVendors(book):
794 query = gnucash.Query()
795 query.search_for(
'gncVendor')
799 for result
in query.run():
801 gnucash.gnucash_business.Vendor(instance=result)))
807 def getVendor(book, id):
809 vendor = book.VendorLookupByID(id)
816 def getAccounts(book):
822 def getAccountsFlat(book):
826 flat_accounts = getSubAccounts(accounts)
828 for n, account
in enumerate(flat_accounts):
829 account.pop(
'subaccounts')
831 filtered_flat_account = []
835 for n, account
in enumerate(flat_accounts):
836 if account[
'type_id']
in type_ids:
837 filtered_flat_account.append(account)
838 print account[
'name'] +
' ' + str(account[
'type_id'])
840 return filtered_flat_account
842 def getSubAccounts(account):
846 if 'subaccounts' in account.keys():
847 for n, subaccount
in enumerate(account[
'subaccounts']):
848 flat_accounts.append(subaccount)
849 flat_accounts = flat_accounts + getSubAccounts(subaccount)
853 def getAccount(book, guid):
855 account_guid = gnucash.gnucash_core.GUID()
856 gnucash.gnucash_core.GUIDString(guid, account_guid)
858 account = account_guid.AccountLookup(book)
871 def getTransaction(book, guid):
873 transaction_guid = gnucash.gnucash_core.GUID()
874 gnucash.gnucash_core.GUIDString(guid, transaction_guid)
876 transaction = transaction_guid.TransactionLookup(book)
878 if transaction
is None:
883 if transaction
is None:
888 def getTransactions(book, account_guid, date_posted_from, date_posted_to):
890 query = gnucash.Query()
892 query.search_for(
'Trans')
897 for transaction
in query.run():
899 gnucash.gnucash_business.Transaction(instance=transaction)))
905 def getAccountSplits(book, guid, date_posted_from, date_posted_to):
907 account_guid = gnucash.gnucash_core.GUID()
908 gnucash.gnucash_core.GUIDString(guid, account_guid)
910 query = gnucash.Query()
911 query.search_for(
'Split')
916 QOF_DATE_MATCH_NORMAL = 1
918 TRANS_DATE_POSTED =
'date-posted'
920 if date_posted_from !=
None:
921 pred_data = gnucash.gnucash_core.QueryDatePredicate(
922 QOF_COMPARE_GTE, QOF_DATE_MATCH_NORMAL, datetime.datetime.strptime(
923 date_posted_from,
"%Y-%m-%d").date())
924 param_list = [SPLIT_TRANS, TRANS_DATE_POSTED]
925 query.add_term(param_list, pred_data, QOF_QUERY_AND)
927 if date_posted_to !=
None:
928 pred_data = gnucash.gnucash_core.QueryDatePredicate(
929 QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, datetime.datetime.strptime(
930 date_posted_to,
"%Y-%m-%d").date())
931 param_list = [SPLIT_TRANS, TRANS_DATE_POSTED]
932 query.add_term(param_list, pred_data, QOF_QUERY_AND)
934 SPLIT_ACCOUNT =
'account'
935 QOF_PARAM_GUID =
'guid'
938 gnucash.gnucash_core.GUIDString(guid, account_guid)
939 query.add_guid_match(
940 [SPLIT_ACCOUNT, QOF_PARAM_GUID], account_guid, QOF_QUERY_AND)
944 for split
in query.run():
946 gnucash.gnucash_business.Split(instance=split),
947 [
'account',
'transaction',
'other_split']))
953 def getInvoices(book, customer, is_paid, is_active, date_due_from,
956 query = gnucash.Query()
957 query.search_for(
'gncInvoice')
961 query.add_boolean_match([INVOICE_IS_PAID],
False, QOF_QUERY_AND)
963 query.add_boolean_match([INVOICE_IS_PAID],
True, QOF_QUERY_AND)
967 query.add_boolean_match([
'active'],
False, QOF_QUERY_AND)
969 query.add_boolean_match([
'active'],
True, QOF_QUERY_AND)
971 QOF_PARAM_GUID =
'guid'
972 INVOICE_OWNER =
'owner'
975 customer_guid = gnucash.gnucash_core.GUID()
976 gnucash.gnucash_core.GUIDString(customer, customer_guid)
977 query.add_guid_match(
978 [INVOICE_OWNER, QOF_PARAM_GUID], customer_guid, QOF_QUERY_AND)
980 if date_due_from !=
None:
981 pred_data = gnucash.gnucash_core.QueryDatePredicate(
982 QOF_COMPARE_GTE, 2, datetime.datetime.strptime(
983 date_due_from,
"%Y-%m-%d").date())
984 query.add_term([
'date_due'], pred_data, QOF_QUERY_AND)
986 if date_due_to !=
None:
987 pred_data = gnucash.gnucash_core.QueryDatePredicate(
988 QOF_COMPARE_LTE, 2, datetime.datetime.strptime(
989 date_due_to,
"%Y-%m-%d").date())
990 query.add_term([
'date_due'], pred_data, QOF_QUERY_AND)
993 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 1)
994 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
998 for result
in query.run():
1000 gnucash.gnucash_business.Invoice(instance=result)))
1006 def getBills(book, customer, is_paid, is_active, date_opened_from,
1009 query = gnucash.Query()
1010 query.search_for(
'gncInvoice')
1011 query.set_book(book)
1014 query.add_boolean_match([INVOICE_IS_PAID],
False, QOF_QUERY_AND)
1016 query.add_boolean_match([INVOICE_IS_PAID],
True, QOF_QUERY_AND)
1020 query.add_boolean_match([
'active'],
False, QOF_QUERY_AND)
1021 elif is_active == 1:
1022 query.add_boolean_match([
'active'],
True, QOF_QUERY_AND)
1024 QOF_PARAM_GUID =
'guid'
1025 INVOICE_OWNER =
'owner'
1027 if customer !=
None:
1028 customer_guid = gnucash.gnucash_core.GUID()
1029 gnucash.gnucash_core.GUIDString(customer, customer_guid)
1030 query.add_guid_match(
1031 [INVOICE_OWNER, QOF_PARAM_GUID], customer_guid, QOF_QUERY_AND)
1033 if date_opened_from !=
None:
1034 pred_data = gnucash.gnucash_core.QueryDatePredicate(
1035 QOF_COMPARE_GTE, 2, datetime.datetime.strptime(
1036 date_opened_from,
"%Y-%m-%d").date())
1037 query.add_term([
'date_opened'], pred_data, QOF_QUERY_AND)
1039 if date_opened_to !=
None:
1040 pred_data = gnucash.gnucash_core.QueryDatePredicate(
1041 QOF_COMPARE_LTE, 2, datetime.datetime.strptime(
1042 date_opened_to,
"%Y-%m-%d").date())
1043 query.add_term([
'date_opened'], pred_data, QOF_QUERY_AND)
1046 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 2)
1047 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1051 for result
in query.run():
1053 gnucash.gnucash_business.Bill(instance=result)))
1059 def getGnuCashInvoice(book ,id):
1064 query = gnucash.Query()
1065 query.search_for(
'gncInvoice')
1066 query.set_book(book)
1069 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 1)
1070 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1074 pred_data = gnucash.gnucash_core.QueryStringPredicate(
1075 QOF_COMPARE_EQUAL, id, QOF_STRING_MATCH_NORMAL,
False)
1076 query.add_term([INVOICE_ID], pred_data, QOF_QUERY_AND)
1080 for result
in query.run():
1081 invoice = gnucash.gnucash_business.Invoice(instance=result)
1087 def getGnuCashBill(book ,id):
1092 query = gnucash.Query()
1093 query.search_for(
'gncInvoice')
1094 query.set_book(book)
1097 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 2)
1098 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1102 pred_data = gnucash.gnucash_core.QueryStringPredicate(
1103 QOF_COMPARE_EQUAL, id, QOF_STRING_MATCH_NORMAL,
False)
1104 query.add_term([INVOICE_ID], pred_data, QOF_QUERY_AND)
1108 for result
in query.run():
1109 bill = gnucash.gnucash_business.Bill(instance=result)
1115 def getInvoice(book, id):
1119 def payInvoice(book, id, posted_account_guid, transfer_account_guid,
1120 payment_date, memo, num, auto_pay):
1122 invoice = getGnuCashInvoice(book, id)
1124 account_guid2 = gnucash.gnucash_core.GUID()
1125 gnucash.gnucash_core.GUIDString(transfer_account_guid, account_guid2)
1127 xfer_acc = account_guid2.AccountLookup(session.book)
1129 invoice.ApplyPayment(
None, xfer_acc, invoice.GetTotal(), GncNumeric(0),
1130 datetime.datetime.strptime(payment_date,
'%Y-%m-%d'), memo, num)
1134 def payBill(book, id, posted_account_guid, transfer_account_guid, payment_date,
1135 memo, num, auto_pay):
1137 bill = getGnuCashBill(book, id)
1139 account_guid = gnucash.gnucash_core.GUID()
1140 gnucash.gnucash_core.GUIDString(transfer_account_guid, account_guid)
1142 xfer_acc = account_guid.AccountLookup(session.book)
1146 bill.ApplyPayment(
None, xfer_acc, bill.GetTotal().neg(), GncNumeric(0),
1147 datetime.datetime.strptime(payment_date,
'%Y-%m-%d'), memo, num)
1151 def getBill(book, id):
1155 def addVendor(book, id, currency_mnumonic, name, contact, address_line_1,
1156 address_line_2, address_line_3, address_line_4, phone, fax, email):
1159 raise Error(
'NoVendorName',
'A name must be entered for this company',
1162 if (address_line_1 ==
''
1163 and address_line_2 ==
''
1164 and address_line_3 ==
''
1165 and address_line_4 ==
''):
1166 raise Error(
'NoVendorAddress',
1167 'An address must be entered for this company',
1168 {
'field':
'address'})
1170 commod_table = book.get_table()
1171 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1173 if currency
is None:
1174 raise Error(
'InvalidVendorCurrency',
1175 'A valid currency must be supplied for this vendor',
1176 {
'field':
'currency'})
1179 id = book.VendorNextID()
1181 vendor = Vendor(session.book, id, currency, name)
1183 address = vendor.GetAddr()
1184 address.SetName(contact)
1185 address.SetAddr1(address_line_1)
1186 address.SetAddr2(address_line_2)
1187 address.SetAddr3(address_line_3)
1188 address.SetAddr4(address_line_4)
1189 address.SetPhone(phone)
1191 address.SetEmail(email)
1195 def addCustomer(book, id, currency_mnumonic, name, contact, address_line_1,
1196 address_line_2, address_line_3, address_line_4, phone, fax, email):
1199 raise Error(
'NoCustomerName',
1200 'A name must be entered for this company', {
'field':
'name'})
1202 if (address_line_1 ==
''
1203 and address_line_2 ==
''
1204 and address_line_3 ==
''
1205 and address_line_4 ==
''):
1206 raise Error(
'NoCustomerAddress',
1207 'An address must be entered for this company',
1208 {
'field':
'address'})
1210 commod_table = book.get_table()
1211 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1213 if currency
is None:
1214 raise Error(
'InvalidCustomerCurrency',
1215 'A valid currency must be supplied for this customer',
1216 {
'field':
'currency'})
1219 id = book.CustomerNextID()
1221 customer = Customer(session.book, id, currency, name)
1223 address = customer.GetAddr()
1224 address.SetName(contact)
1225 address.SetAddr1(address_line_1)
1226 address.SetAddr2(address_line_2)
1227 address.SetAddr3(address_line_3)
1228 address.SetAddr4(address_line_4)
1229 address.SetPhone(phone)
1231 address.SetEmail(email)
1235 def updateCustomer(book, id, name, contact, address_line_1, address_line_2,
1236 address_line_3, address_line_4, phone, fax, email):
1238 customer = book.CustomerLookupByID(id)
1240 if customer
is None:
1241 raise Error(
'NoCustomer',
'A customer with this ID does not exist',
1245 raise Error(
'NoCustomerName',
1246 'A name must be entered for this company', {
'field':
'name'})
1248 if (address_line_1 ==
''
1249 and address_line_2 ==
''
1250 and address_line_3 ==
''
1251 and address_line_4 ==
''):
1252 raise Error(
'NoCustomerAddress',
1253 'An address must be entered for this company',
1254 {
'field':
'address'})
1256 customer.SetName(name)
1258 address = customer.GetAddr()
1259 address.SetName(contact)
1260 address.SetAddr1(address_line_1)
1261 address.SetAddr2(address_line_2)
1262 address.SetAddr3(address_line_3)
1263 address.SetAddr4(address_line_4)
1264 address.SetPhone(phone)
1266 address.SetEmail(email)
1270 def addInvoice(book, id, customer_id, currency_mnumonic, date_opened, notes):
1272 customer = book.CustomerLookupByID(customer_id)
1274 if customer
is None:
1275 raise Error(
'NoCustomer',
1276 'A customer with this ID does not exist', {
'field':
'id'})
1279 id = book.InvoiceNextID(customer)
1282 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1284 raise Error(
'InvalidDateOpened',
1285 'The date opened must be provided in the form YYYY-MM-DD',
1286 {
'field':
'date_opened'})
1288 if currency_mnumonic
is None:
1289 currency_mnumonic = customer.GetCurrency().get_mnemonic()
1291 commod_table = book.get_table()
1292 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1294 if currency
is None:
1295 raise Error(
'InvalidCustomerCurrency',
1296 'A valid currency must be supplied for this customer',
1297 {
'field':
'currency'})
1299 invoice = Invoice(book, id, currency, customer, date_opened.date())
1301 invoice.SetNotes(notes)
1305 def updateInvoice(book, id, customer_id, currency_mnumonic, date_opened,
1306 notes, posted, posted_account_guid, posted_date, due_date, posted_memo,
1307 posted_accumulatesplits, posted_autopay):
1309 invoice = getGnuCashInvoice(book, id)
1312 raise Error(
'NoInvoice',
1313 'An invoice with this ID does not exist',
1316 customer = book.CustomerLookupByID(customer_id)
1318 if customer
is None:
1319 raise Error(
'NoCustomer',
'A customer with this ID does not exist',
1320 {
'field':
'customer_id'})
1323 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1325 raise Error(
'InvalidDateOpened',
1326 'The date opened must be provided in the form YYYY-MM-DD',
1327 {
'field':
'date_opened'})
1329 if posted_date ==
'':
1331 raise Error(
'NoDatePosted',
1332 'The date posted must be supplied when posted=1',
1333 {
'field':
'date_posted'})
1336 posted_date = datetime.datetime.strptime(posted_date,
"%Y-%m-%d")
1338 raise Error(
'InvalidDatePosted',
1339 'The date posted must be provided in the form YYYY-MM-DD',
1340 {
'field':
'posted_date'})
1344 raise Error(
'NoDatePosted',
1345 'The due date must be supplied when posted=1',
1346 {
'field':
'date_posted'})
1349 due_date = datetime.datetime.strptime(due_date,
"%Y-%m-%d")
1351 raise Error(
'InvalidDatePosted',
1352 'The due date must be provided in the form YYYY-MM-DD',
1353 {
'field':
'due_date'})
1355 if posted_account_guid ==
'':
1357 raise Error(
'NoPostedAccountGuid',
1358 'The posted account GUID must be supplied when posted=1',
1359 {
'field':
'posted_account_guid'})
1361 guid = gnucash.gnucash_core.GUID()
1362 gnucash.gnucash_core.GUIDString(posted_account_guid, guid)
1364 posted_account = guid.AccountLookup(book)
1366 if posted_account
is None:
1367 raise Error(
'NoAccount',
1368 'No account exists with the posted account GUID',
1369 {
'field':
'posted_account_guid'})
1371 invoice.SetOwner(customer)
1372 invoice.SetDateOpened(date_opened)
1373 invoice.SetNotes(notes)
1376 if (invoice.GetDatePosted().strftime(
'%Y-%m-%d') ==
'1970-01-01'
1378 invoice.PostToAccount(posted_account, posted_date, due_date,
1379 posted_memo, posted_accumulatesplits, posted_autopay)
1383 def updateBill(book, id, vendor_id, currency_mnumonic, date_opened, notes,
1384 posted, posted_account_guid, posted_date, due_date, posted_memo,
1385 posted_accumulatesplits, posted_autopay):
1387 bill = getGnuCashBill(book, id)
1390 raise Error(
'NoBill',
'A bill with this ID does not exist',
1393 vendor = book.VendorLookupByID(vendor_id)
1396 raise Error(
'NoVendor',
1397 'A vendor with this ID does not exist',
1398 {
'field':
'vendor_id'})
1401 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1403 raise Error(
'InvalidDateOpened',
1404 'The date opened must be provided in the form YYYY-MM-DD',
1405 {
'field':
'date_opened'})
1407 if posted_date ==
'':
1409 raise Error(
'NoDatePosted',
1410 'The date posted must be supplied when posted=1',
1411 {
'field':
'date_posted'})
1414 posted_date = datetime.datetime.strptime(posted_date,
"%Y-%m-%d")
1416 raise Error(
'InvalidDatePosted',
1417 'The date posted must be provided in the form YYYY-MM-DD',
1418 {
'field':
'posted_date'})
1422 raise Error(
'NoDatePosted',
1423 'The due date must be supplied when posted=1',
1424 {
'field':
'date_posted'})
1427 due_date = datetime.datetime.strptime(due_date,
"%Y-%m-%d")
1429 raise Error(
'InvalidDatePosted',
1430 'The due date must be provided in the form YYYY-MM-DD',
1431 {
'field':
'due_date'})
1433 if posted_account_guid ==
'':
1435 raise Error(
'NoPostedAccountGuid',
1436 'The posted account GUID must be supplied when posted=1',
1437 {
'field':
'posted_account_guid'})
1439 guid = gnucash.gnucash_core.GUID()
1440 gnucash.gnucash_core.GUIDString(posted_account_guid, guid)
1442 posted_account = guid.AccountLookup(book)
1444 if posted_account
is None:
1445 raise Error(
'NoAccount',
1446 'No account exists with the posted account GUID',
1447 {
'field':
'posted_account_guid'})
1449 bill.SetOwner(vendor)
1450 bill.SetDateOpened(date_opened)
1451 bill.SetNotes(notes)
1454 if bill.GetDatePosted().strftime(
'%Y-%m-%d') ==
'1970-01-01' and posted == 1:
1455 bill.PostToAccount(posted_account, posted_date, due_date, posted_memo,
1456 posted_accumulatesplits, posted_autopay)
1460 def addEntry(book, invoice_id, date, description, account_guid, quantity, price):
1462 invoice = getGnuCashInvoice(book, invoice_id)
1465 raise Error(
'NoInvoice',
1466 'No invoice exists with this ID', {
'field':
'invoice_id'})
1469 date = datetime.datetime.strptime(date,
"%Y-%m-%d")
1471 raise Error(
'InvalidDateOpened',
1472 'The date opened must be provided in the form YYYY-MM-DD',
1475 guid = gnucash.gnucash_core.GUID()
1476 gnucash.gnucash_core.GUIDString(account_guid, guid)
1478 account = guid.AccountLookup(book)
1481 raise Error(
'NoAccount',
'No account exists with this GUID',
1482 {
'field':
'account_guid'})
1485 quantity = Decimal(quantity).quantize(Decimal(
'.01'))
1486 except ArithmeticError:
1487 raise Error(
'InvalidQuantity',
'This quantity is not valid',
1488 {
'field':
'quantity'})
1491 price = Decimal(price).quantize(Decimal(
'.01'))
1492 except ArithmeticError:
1493 raise Error(
'InvalidPrice',
'This price is not valid',
1496 entry = Entry(book, invoice, date.date())
1497 entry.SetDateEntered(datetime.datetime.now())
1498 entry.SetDescription(description)
1499 entry.SetInvAccount(account)
1500 entry.SetQuantity(gnc_numeric_from_decimal(quantity))
1501 entry.SetInvPrice(gnc_numeric_from_decimal(price))
1505 def addBillEntry(book, bill_id, date, description, account_guid, quantity,
1508 bill = getGnuCashBill(book,bill_id)
1511 raise Error(
'NoBill',
'No bill exists with this ID',
1512 {
'field':
'bill_id'})
1515 date = datetime.datetime.strptime(date,
"%Y-%m-%d")
1517 raise Error(
'InvalidDateOpened',
1518 'The date opened must be provided in the form YYYY-MM-DD',
1521 guid = gnucash.gnucash_core.GUID()
1522 gnucash.gnucash_core.GUIDString(account_guid, guid)
1524 account = guid.AccountLookup(book)
1527 raise Error(
'NoAccount',
'No account exists with this GUID',
1528 {
'field':
'account_guid'})
1531 quantity = Decimal(quantity).quantize(Decimal(
'.01'))
1532 except ArithmeticError:
1533 raise Error(
'InvalidQuantity',
'This quantity is not valid',
1534 {
'field':
'quantity'})
1537 price = Decimal(price).quantize(Decimal(
'.01'))
1538 except ArithmeticError:
1539 raise Error(
'InvalidPrice',
'This price is not valid',
1542 entry = Entry(book, bill, date.date())
1543 entry.SetDateEntered(datetime.datetime.now())
1544 entry.SetDescription(description)
1545 entry.SetBillAccount(account)
1546 entry.SetQuantity(gnc_numeric_from_decimal(quantity))
1547 entry.SetBillPrice(gnc_numeric_from_decimal(price))
1551 def getEntry(book, entry_guid):
1553 guid = gnucash.gnucash_core.GUID()
1554 gnucash.gnucash_core.GUIDString(entry_guid, guid)
1556 entry = book.EntryLookup(guid)
1563 def updateEntry(book, entry_guid, date, description, account_guid, quantity,
1566 guid = gnucash.gnucash_core.GUID()
1567 gnucash.gnucash_core.GUIDString(entry_guid, guid)
1569 entry = book.EntryLookup(guid)
1572 raise Error(
'NoEntry',
'No entry exists with this GUID',
1573 {
'field':
'entry_guid'})
1576 date = datetime.datetime.strptime(date,
"%Y-%m-%d")
1578 raise Error(
'InvalidDateOpened',
1579 'The date opened must be provided in the form YYYY-MM-DD',
1582 gnucash.gnucash_core.GUIDString(account_guid, guid)
1584 account = guid.AccountLookup(book)
1587 raise Error(
'NoAccount',
'No account exists with this GUID',
1588 {
'field':
'account_guid'})
1590 entry.SetDate(date.date())
1591 entry.SetDateEntered(datetime.datetime.now())
1592 entry.SetDescription(description)
1593 entry.SetInvAccount(account)
1595 gnc_numeric_from_decimal(Decimal(quantity).quantize(Decimal(
'.01'))))
1597 gnc_numeric_from_decimal(Decimal(price).quantize(Decimal(
'.01'))))
1601 def deleteEntry(book, entry_guid):
1603 guid = gnucash.gnucash_core.GUID()
1604 gnucash.gnucash_core.GUIDString(entry_guid, guid)
1606 entry = book.EntryLookup(guid)
1608 invoice = entry.GetInvoice()
1609 bill = entry.GetBill()
1611 if invoice !=
None and entry !=
None:
1612 invoice.RemoveEntry(entry)
1613 elif bill !=
None and entry !=
None:
1614 bill.RemoveEntry(entry)
1619 def deleteTransaction(book, transaction_guid):
1621 guid = gnucash.gnucash_core.GUID()
1622 gnucash.gnucash_core.GUIDString(transaction_guid, guid)
1624 transaction = guid.TransLookup(book)
1626 if transaction !=
None :
1627 transaction.Destroy()
1629 def addBill(book, id, vendor_id, currency_mnumonic, date_opened, notes):
1631 vendor = book.VendorLookupByID(vendor_id)
1634 raise Error(
'NoVendor',
'A vendor with this ID does not exist',
1638 id = book.BillNextID(vendor)
1641 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1643 raise Error(
'InvalidVendorDateOpened',
1644 'The date opened must be provided in the form YYYY-MM-DD',
1645 {
'field':
'date_opened'})
1647 if currency_mnumonic
is None:
1648 currency_mnumonic = vendor.GetCurrency().get_mnemonic()
1650 commod_table = book.get_table()
1651 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1653 if currency
is None:
1654 raise Error(
'InvalidVendorCurrency',
1655 'A valid currency must be supplied for this vendor',
1656 {
'field':
'currency'})
1658 bill = Bill(book, id, currency, vendor, date_opened.date())
1660 bill.SetNotes(notes)
1664 def addAccount(book, name, currency_mnumonic, account_guid):
1666 from gnucash.gnucash_core_c
import \
1667 ACCT_TYPE_ASSET, ACCT_TYPE_RECEIVABLE, ACCT_TYPE_INCOME, \
1668 GNC_OWNER_CUSTOMER, ACCT_TYPE_LIABILITY
1670 root_account = book.get_root_account()
1672 commod_table = book.get_table()
1673 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1675 if currency
is None:
1676 raise Error(
'InvalidCustomerCurrency',
1677 'A valid currency must be supplied for this customer',
1678 {
'field':
'currency'})
1681 root_account.append_child(root_account)
1682 account.SetName(name)
1683 account.SetType(ACCT_TYPE_ASSET)
1684 account.SetCommodity(currency)
1686 def addTransaction(book, num, description, date_posted, currency_mnumonic, splits):
1690 transaction.BeginEdit()
1692 commod_table = book.get_table()
1693 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1695 if currency
is None:
1696 raise Error(
'InvalidTransactionCurrency',
1697 'A valid currency must be supplied for this transaction',
1698 {
'field':
'currency'})
1701 date_posted = datetime.datetime.strptime(date_posted,
"%Y-%m-%d")
1703 raise Error(
'InvalidDatePosted',
1704 'The date posted must be provided in the form YYYY-MM-DD',
1705 {
'field':
'date_posted'})
1708 for split_values
in splits:
1709 account_guid = gnucash.gnucash_core.GUID()
1710 gnucash.gnucash_core.GUIDString(split_values[
'account_guid'], account_guid)
1712 account = account_guid.AccountLookup(book)
1715 raise Error(
'InvalidSplitAccount',
1716 'A valid account must be supplied for this split',
1717 {
'field':
'account'})
1720 split.SetValue(GncNumeric(split_values[
'value'], 100))
1721 split.SetAccount(account)
1722 split.SetParent(transaction)
1724 transaction.SetCurrency(currency)
1725 transaction.SetDescription(description)
1726 transaction.SetNum(num)
1728 transaction.SetDatePostedTS(date_posted)
1730 transaction.CommitEdit()
1734 def getTransaction(book, transaction_guid):
1736 guid = gnucash.gnucash_core.GUID()
1737 gnucash.gnucash_core.GUIDString(transaction_guid, guid)
1739 transaction = guid.TransLookup(book)
1741 if transaction
is None:
1746 def editTransaction(book, transaction_guid, num, description, date_posted,
1747 currency_mnumonic, splits):
1749 guid = gnucash.gnucash_core.GUID()
1750 gnucash.gnucash_core.GUIDString(transaction_guid, guid)
1752 transaction = guid.TransLookup(book)
1754 if transaction
is None:
1755 raise Error(
'NoCustomer',
1756 'A transaction with this GUID does not exist',
1759 transaction.BeginEdit()
1761 commod_table = book.get_table()
1762 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1764 if currency
is None:
1765 raise Error(
'InvalidTransactionCurrency',
1766 'A valid currency must be supplied for this transaction',
1767 {
'field':
'currency'})
1771 date_posted = datetime.datetime.strptime(date_posted,
"%Y-%m-%d")
1773 raise Error(
'InvalidDatePosted',
1774 'The date posted must be provided in the form YYYY-MM-DD',
1775 {
'field':
'date_posted'})
1777 for split_values
in splits:
1779 split_guid = gnucash.gnucash_core.GUID()
1780 gnucash.gnucash_core.GUIDString(split_values[
'guid'], split_guid)
1782 split = split_guid.SplitLookup(book)
1785 raise Error(
'InvalidSplitGuid',
1786 'A valid guid must be supplied for this split',
1789 account_guid = gnucash.gnucash_core.GUID()
1790 gnucash.gnucash_core.GUIDString(
1791 split_values[
'account_guid'], account_guid)
1793 account = account_guid.AccountLookup(book)
1796 raise Error(
'InvalidSplitAccount',
1797 'A valid account must be supplied for this split',
1798 {
'field':
'account'})
1800 split.SetValue(GncNumeric(split_values[
'value'], 100))
1801 split.SetAccount(account)
1802 split.SetParent(transaction)
1804 transaction.SetCurrency(currency)
1805 transaction.SetDescription(description)
1806 transaction.SetNum(num)
1808 transaction.SetDatePostedTS(date_posted)
1810 transaction.CommitEdit()
1814 def gnc_numeric_from_decimal(decimal_value):
1815 sign, digits, exponent = decimal_value.as_tuple()
1823 TEN = int(Decimal(0).radix())
1824 numerator_place_value = 1
1827 for i
in xrange(len(digits)-1,-1,-1):
1828 numerator += digits[i] * numerator_place_value
1829 numerator_place_value *= TEN
1831 if decimal_value.is_signed():
1832 numerator = -numerator
1836 denominator = TEN ** (-exponent)
1840 numerator *= TEN ** exponent
1843 return GncNumeric(numerator, denominator)
1852 """Base class for exceptions in this module."""
1853 def __init__(self, type, message, data):
1859 options, arguments = getopt.getopt(sys.argv[1:],
'nh:', [
'host=',
'new='])
1860 except getopt.GetoptError
as err:
1862 print 'Usage: python-rest.py <connection string>'
1865 if len(arguments) == 0:
1866 print 'Usage: python-rest.py <connection string>'
1873 for option, value
in options:
1874 if option
in (
"-h",
"--host"):
1880 for option, value
in options:
1881 if option
in (
"-n",
"--new"):
1887 session = gnucash.Session(arguments[0], is_new=
True)
1896 session = gnucash.Session(arguments[0], ignore_lock=
True)
1899 atexit.register(shutdown)
1906 from logging
import StreamHandler
1907 stream_handler = StreamHandler()
1908 stream_handler.setLevel(logging.ERROR)
1909 app.logger.addHandler(stream_handler)