5 gnucash_rest.py -- A Flask app which responds to REST requests 8 Copyright (C) 2013 Tom Lofts <dev@loftx.co.uk> 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 25 Boston, MA 02110-1301, USA gnu@gnu.org 27 @author Tom Lofts <dev@loftx.co.uk> 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 from 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':
91 account = addAccount(session.books)
92 except Error
as error:
93 return Response(json.dumps({
'errors': [{
'type' : error.type,
94 'message': error.message,
'data': error.data}]}), status=400,
95 mimetype=
'application/json')
97 return Response(json.dumps(account), status=201,
98 mimetype=
'application/json')
103 @app.route(
'/accounts/<guid>', methods=[
'GET'])
104 def api_account(guid):
106 account = getAccount(session.book, guid)
111 return Response(json.dumps(account), mimetype=
'application/json')
113 @app.route(
'/accounts/<guid>/splits', methods=[
'GET'])
114 def api_account_splits(guid):
116 date_posted_from = request.args.get(
'date_posted_from',
None)
117 date_posted_to = request.args.get(
'date_posted_to',
None)
120 account = getAccount(session.book, guid)
125 splits = getAccountSplits(session.book, guid, date_posted_from,
128 return Response(json.dumps(splits), mimetype=
'application/json')
131 @app.route(
'/transactions', methods=[
'POST'])
132 def api_transactions():
134 if request.method ==
'POST':
136 currency = str(request.form.get(
'currency',
''))
137 description = str(request.form.get(
'description',
''))
138 num = str(request.form.get(
'num',
''))
139 date_posted = str(request.form.get(
'date_posted',
''))
141 splitvalue1 = int(request.form.get(
'splitvalue1',
''))
142 splitaccount1 = str(request.form.get(
'splitaccount1',
''))
143 splitvalue2 = int(request.form.get(
'splitvalue2',
''))
144 splitaccount2 = str(request.form.get(
'splitaccount2',
''))
147 {
'value': splitvalue1,
'account_guid': splitaccount1},
148 {
'value': splitvalue2,
'account_guid': splitaccount2}]
151 transaction = addTransaction(session.book, num, description,
152 date_posted, currency, splits)
153 except Error
as error:
154 return Response(json.dumps({
'errors': [{
'type' : error.type,
155 'message': error.message,
'data': error.data}]}), status=400,
156 mimetype=
'application/json')
158 return Response(json.dumps(transaction), status=201,
159 mimetype=
'application/json')
164 @app.route(
'/transactions/<guid>', methods=[
'GET',
'POST',
'DELETE'])
165 def api_transaction(guid):
167 if request.method ==
'GET':
169 transaction = getTransaction(session.book, guid)
171 if transaction
is None:
174 return Response(json.dumps(transaction), mimetype=
'application/json')
176 elif request.method ==
'POST':
178 currency = str(request.form.get(
'currency',
''))
179 description = str(request.form.get(
'description',
''))
180 num = str(request.form.get(
'num',
''))
181 date_posted = str(request.form.get(
'date_posted',
''))
183 splitguid1 = str(request.form.get(
'splitguid1',
''))
184 splitvalue1 = int(request.form.get(
'splitvalue1',
''))
185 splitaccount1 = str(request.form.get(
'splitaccount1',
''))
186 splitguid2 = str(request.form.get(
'splitguid2',
''))
187 splitvalue2 = int(request.form.get(
'splitvalue2',
''))
188 splitaccount2 = str(request.form.get(
'splitaccount2',
''))
192 'value': splitvalue1,
193 'account_guid': splitaccount1},
195 'value': splitvalue2,
196 'account_guid': splitaccount2}
200 transaction = editTransaction(session.book, guid, num, description,
201 date_posted, currency, splits)
202 except Error
as error:
203 return Response(json.dumps({
'errors': [{
'type' : error.type,
204 'message': error.message,
'data': error.data}]}), status=400, mimetype=
'application/json')
206 return Response(json.dumps(transaction), status=200,
207 mimetype=
'application/json')
209 elif request.method ==
'DELETE':
211 deleteTransaction(session.book, guid)
213 return Response(
'', status=200, mimetype=
'application/json')
218 @app.route(
'/bills', methods=[
'GET',
'POST'])
221 if request.method ==
'GET':
223 is_paid = request.args.get(
'is_paid',
None)
224 is_active = request.args.get(
'is_active',
None)
225 date_opened_to = request.args.get(
'date_opened_to',
None)
226 date_opened_from = request.args.get(
'date_opened_from',
None)
237 elif is_active ==
'0':
242 bills = getBills(session.book,
None, is_paid, is_active,
243 date_opened_from, date_opened_to)
245 return Response(json.dumps(bills), mimetype=
'application/json')
247 elif request.method ==
'POST':
249 id = str(request.form.get(
'id',
None))
256 vendor_id = str(request.form.get(
'vendor_id',
''))
257 currency = str(request.form.get(
'currency',
''))
258 date_opened = str(request.form.get(
'date_opened',
''))
259 notes = str(request.form.get(
'notes',
''))
262 bill = addBill(session.book, id, vendor_id, currency, date_opened,
264 except Error
as error:
266 return Response(json.dumps({
'errors': [{
'type' : error.type,
267 'message': error.message,
'data': error.data}]}), status=400, mimetype=
'application/json')
269 return Response(json.dumps(bill), status=201,
270 mimetype=
'application/json')
275 @app.route(
'/bills/<id>', methods=[
'GET',
'POST',
'PAY'])
278 if request.method ==
'GET':
280 bill = getBill(session.book, id)
285 return Response(json.dumps(bill), mimetype=
'application/json')
287 elif request.method ==
'POST':
289 vendor_id = str(request.form.get(
'vendor_id',
''))
290 currency = str(request.form.get(
'currency',
''))
291 date_opened = request.form.get(
'date_opened',
None)
292 notes = str(request.form.get(
'notes',
''))
293 posted = request.form.get(
'posted',
None)
294 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
295 posted_date = request.form.get(
'posted_date',
'')
296 due_date = request.form.get(
'due_date',
'')
297 posted_memo = str(request.form.get(
'posted_memo',
''))
298 posted_accumulatesplits = request.form.get(
'posted_accumulatesplits',
300 posted_autopay = request.form.get(
'posted_autopay',
'')
307 if (posted_accumulatesplits ==
'1' 308 or posted_accumulatesplits ==
'true' 309 or posted_accumulatesplits ==
'True' 310 or posted_accumulatesplits ==
True):
311 posted_accumulatesplits =
True 313 posted_accumulatesplits =
False 315 if posted_autopay ==
'1':
316 posted_autopay =
True 318 posted_autopay =
False 320 bill = updateBill(session.book, id, vendor_id, currency,
321 date_opened, notes, posted, posted_account_guid, posted_date,
322 due_date, posted_memo, posted_accumulatesplits, posted_autopay)
323 except Error
as error:
324 return Response(json.dumps({
'errors': [{
'type' : error.type,
325 'message': error.message,
'data': error.data}]}), status=400,
326 mimetype=
'application/json')
328 return Response(json.dumps(bill), status=200,
329 mimetype=
'application/json')
334 return Response(json.dumps(bill),
335 mimetype=
'application/json')
337 elif request.method ==
'PAY':
339 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
340 transfer_account_guid = str(request.form.get(
'transfer_account_guid',
342 payment_date = request.form.get(
'payment_date',
'')
343 num = str(request.form.get(
'num',
''))
344 memo = str(request.form.get(
'posted_memo',
''))
345 auto_pay = request.form.get(
'auto_pay',
'')
348 bill = payBill(session.book, id, posted_account_guid,
349 transfer_account_guid, payment_date, memo, num, auto_pay)
350 except Error
as error:
351 return Response(json.dumps({
'errors': [{
'type' : error.type,
352 'message': error.message,
'data': error.data}]}), status=400,
353 mimetype=
'application/json')
355 return Response(json.dumps(bill), status=200,
356 mimetype=
'application/json')
361 @app.route(
'/bills/<id>/entries', methods=[
'GET',
'POST'])
362 def api_bill_entries(id):
364 bill = getBill(session.book, id)
369 if request.method ==
'GET':
370 return Response(json.dumps(bill[
'entries']), mimetype=
'application/json')
371 elif request.method ==
'POST':
373 date = str(request.form.get(
'date',
''))
374 description = str(request.form.get(
'description',
''))
375 account_guid = str(request.form.get(
'account_guid',
''))
376 quantity = str(request.form.get(
'quantity',
''))
377 price = str(request.form.get(
'price',
''))
380 entry = addBillEntry(session.book, id, date, description,
381 account_guid, quantity, price)
382 except Error
as error:
383 return Response(json.dumps({
'errors': [{
'type' : error.type,
384 'message': error.message,
'data': error.data}]}),
385 status=400, mimetype=
'application/json')
387 return Response(json.dumps(entry), status=201,
388 mimetype=
'application/json')
393 @app.route(
'/invoices', methods=[
'GET',
'POST'])
396 if request.method ==
'GET':
398 is_paid = request.args.get(
'is_paid',
None)
399 is_active = request.args.get(
'is_active',
None)
400 date_due_to = request.args.get(
'date_due_to',
None)
401 date_due_from = request.args.get(
'date_due_from',
None)
412 elif is_active ==
'0':
417 invoices = getInvoices(session.book,
None, is_paid, is_active,
418 date_due_from, date_due_to)
420 return Response(json.dumps(invoices), mimetype=
'application/json')
422 elif request.method ==
'POST':
424 id = str(request.form.get(
'id',
None))
431 customer_id = str(request.form.get(
'customer_id',
''))
432 currency = str(request.form.get(
'currency',
''))
433 date_opened = str(request.form.get(
'date_opened',
''))
434 notes = str(request.form.get(
'notes',
''))
437 invoice = addInvoice(session.book, id, customer_id, currency,
439 except Error
as error:
440 return Response(json.dumps({
'errors': [{
'type' : error.type,
441 'message': error.message,
'data': error.data}]}), status=400,
442 mimetype=
'application/json')
444 return Response(json.dumps(invoice), status=201,
445 mimetype=
'application/json')
450 @app.route(
'/invoices/<id>', methods=[
'GET',
'POST',
'PAY'])
453 if request.method ==
'GET':
455 invoice = getInvoice(session.book, id)
460 return Response(json.dumps(invoice), mimetype=
'application/json')
462 elif request.method ==
'POST':
464 customer_id = str(request.form.get(
'customer_id',
''))
465 currency = str(request.form.get(
'currency',
''))
466 date_opened = request.form.get(
'date_opened',
None)
467 notes = str(request.form.get(
'notes',
''))
468 posted = request.form.get(
'posted',
None)
469 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
470 posted_date = request.form.get(
'posted_date',
'')
471 due_date = request.form.get(
'due_date',
'')
472 posted_memo = str(request.form.get(
'posted_memo',
''))
473 posted_accumulatesplits = request.form.get(
'posted_accumulatesplits',
475 posted_autopay = request.form.get(
'posted_autopay',
'')
482 if (posted_accumulatesplits ==
'1' 483 or posted_accumulatesplits ==
'true' 484 or posted_accumulatesplits ==
'True' 485 or posted_accumulatesplits ==
True):
486 posted_accumulatesplits =
True 488 posted_accumulatesplits =
False 490 if posted_autopay ==
'1':
491 posted_autopay =
True 493 posted_autopay =
False 495 invoice = updateInvoice(session.book, id, customer_id, currency,
496 date_opened, notes, posted, posted_account_guid, posted_date,
497 due_date, posted_memo, posted_accumulatesplits, posted_autopay)
498 except Error
as error:
499 return Response(json.dumps({
'errors': [{
'type' : error.type,
500 'message': error.message,
'data': error.data}]}), status=400,
501 mimetype=
'application/json')
503 return Response(json.dumps(invoice), status=200,
504 mimetype=
'application/json')
509 return Response(json.dumps(invoice), mimetype=
'application/json')
511 elif request.method ==
'PAY':
513 posted_account_guid = str(request.form.get(
'posted_account_guid',
''))
514 transfer_account_guid = str(request.form.get(
'transfer_account_guid',
516 payment_date = request.form.get(
'payment_date',
'')
517 num = str(request.form.get(
'num',
''))
518 memo = str(request.form.get(
'posted_memo',
''))
519 auto_pay = request.form.get(
'auto_pay',
'')
522 invoice = payInvoice(session.book, id, posted_account_guid,
523 transfer_account_guid, payment_date, memo, num, auto_pay)
524 except Error
as error:
525 return Response(json.dumps({
'errors': [{
'type' : error.type,
526 'message': error.message,
'data': error.data}]}), status=400,
527 mimetype=
'application/json')
529 return Response(json.dumps(invoice), status=200,
530 mimetype=
'application/json')
535 @app.route(
'/invoices/<id>/entries', methods=[
'GET',
'POST'])
536 def api_invoice_entries(id):
538 invoice = getInvoice(session.book, id)
543 if request.method ==
'GET':
544 return Response(json.dumps(invoice[
'entries']),
545 mimetype=
'application/json')
546 elif request.method ==
'POST':
548 date = str(request.form.get(
'date',
''))
549 description = str(request.form.get(
'description',
''))
550 account_guid = str(request.form.get(
'account_guid',
''))
551 quantity = str(request.form.get(
'quantity',
''))
552 price = str(request.form.get(
'price',
''))
555 entry = addEntry(session.book, id, date, description,
556 account_guid, quantity, price)
557 except Error
as error:
558 return Response(json.dumps({
'errors': [{
'type' : error.type,
559 'message': error.message,
'data': error.data}]}),
560 status=400, mimetype=
'application/json')
562 return Response(json.dumps(entry), status=201,
563 mimetype=
'application/json')
568 @app.route(
'/entries/<guid>', methods=[
'GET',
'POST',
'DELETE'])
571 entry = getEntry(session.book, guid)
576 if request.method ==
'GET':
577 return Response(json.dumps(entry), mimetype=
'application/json')
578 elif request.method ==
'POST':
580 date = str(request.form.get(
'date',
''))
581 description = str(request.form.get(
'description',
''))
582 account_guid = str(request.form.get(
'account_guid',
''))
583 quantity = str(request.form.get(
'quantity',
''))
584 price = str(request.form.get(
'price',
''))
587 entry = updateEntry(session.book, guid, date, description,
588 account_guid, quantity, price)
589 except Error
as error:
590 return Response(json.dumps({
'errors': [{
'type' : error.type,
591 'message': error.message,
'data': error.data}]}),
592 status=400, mimetype=
'application/json')
594 return Response(json.dumps(entry), status=200,
595 mimetype=
'application/json')
597 elif request.method ==
'DELETE':
599 deleteEntry(session.book, guid)
601 return Response(
'', status=201, mimetype=
'application/json')
606 @app.route(
'/customers', methods=[
'GET',
'POST'])
609 if request.method ==
'GET':
610 customers = getCustomers(session.book)
611 return Response(json.dumps(customers), mimetype=
'application/json')
612 elif request.method ==
'POST':
614 id = str(request.form.get(
'id',
None))
621 currency = str(request.form.get(
'currency',
''))
622 name = str(request.form.get(
'name',
''))
623 contact = str(request.form.get(
'contact',
''))
624 address_line_1 = str(request.form.get(
'address_line_1',
''))
625 address_line_2 = str(request.form.get(
'address_line_2',
''))
626 address_line_3 = str(request.form.get(
'address_line_3',
''))
627 address_line_4 = str(request.form.get(
'address_line_4',
''))
628 phone = str(request.form.get(
'phone',
''))
629 fax = str(request.form.get(
'fax',
''))
630 email = str(request.form.get(
'email',
''))
633 customer = addCustomer(session.book, id, currency, name, contact,
634 address_line_1, address_line_2, address_line_3, address_line_4,
636 except Error
as error:
637 return Response(json.dumps({
'errors': [{
'type' : error.type,
638 'message': error.message,
'data': error.data}]}), status=400,
639 mimetype=
'application/json')
641 return Response(json.dumps(customer), status=201,
642 mimetype=
'application/json')
647 @app.route(
'/customers/<id>', methods=[
'GET',
'POST'])
648 def api_customer(id):
650 if request.method ==
'GET':
652 customer = getCustomer(session.book, id)
657 return Response(json.dumps(customer), mimetype=
'application/json')
659 elif request.method ==
'POST':
661 id = str(request.form.get(
'id',
None))
663 name = str(request.form.get(
'name',
''))
664 contact = str(request.form.get(
'contact',
''))
665 address_line_1 = str(request.form.get(
'address_line_1',
''))
666 address_line_2 = str(request.form.get(
'address_line_2',
''))
667 address_line_3 = str(request.form.get(
'address_line_3',
''))
668 address_line_4 = str(request.form.get(
'address_line_4',
''))
669 phone = str(request.form.get(
'phone',
''))
670 fax = str(request.form.get(
'fax',
''))
671 email = str(request.form.get(
'email',
''))
674 customer = updateCustomer(session.book, id, name, contact,
675 address_line_1, address_line_2, address_line_3, address_line_4,
677 except Error
as error:
678 if error.type ==
'NoCustomer':
679 return Response(json.dumps({
'errors': [{
'type' : error.type,
680 'message': error.message,
'data': error.data}]}),
681 status=404, mimetype=
'application/json')
683 return Response(json.dumps({
'errors': [{
'type' : error.type,
684 'message': error.message,
'data': error.data}]}),
685 status=400, mimetype=
'application/json')
687 return Response(json.dumps(customer), status=200,
688 mimetype=
'application/json')
693 @app.route(
'/customers/<id>/invoices', methods=[
'GET'])
694 def api_customer_invoices(id):
696 customer = getCustomer(session.book, id)
701 invoices = getInvoices(session.book, customer[
'guid'],
None,
None,
None,
704 return Response(json.dumps(invoices), mimetype=
'application/json')
706 @app.route(
'/vendors', methods=[
'GET',
'POST'])
709 if request.method ==
'GET':
710 vendors = getVendors(session.book)
711 return Response(json.dumps(vendors), mimetype=
'application/json')
712 elif request.method ==
'POST':
714 id = str(request.form.get(
'id',
None))
721 currency = str(request.form.get(
'currency',
''))
722 name = str(request.form.get(
'name',
''))
723 contact = str(request.form.get(
'contact',
''))
724 address_line_1 = str(request.form.get(
'address_line_1',
''))
725 address_line_2 = str(request.form.get(
'address_line_2',
''))
726 address_line_3 = str(request.form.get(
'address_line_3',
''))
727 address_line_4 = str(request.form.get(
'address_line_4',
''))
728 phone = str(request.form.get(
'phone',
''))
729 fax = str(request.form.get(
'fax',
''))
730 email = str(request.form.get(
'email',
''))
733 vendor = addVendor(session.book, id, currency, name, contact,
734 address_line_1, address_line_2, address_line_3, address_line_4,
736 except Error
as error:
737 return Response(json.dumps({
'errors': [{
'type' : error.type,
738 'message': error.message,
'data': error.data}]}), status=400,
739 mimetype=
'application/json')
741 return Response(json.dumps(vendor), status=201,
742 mimetype=
'application/json')
747 @app.route(
'/vendors/<id>', methods=[
'GET',
'POST'])
750 if request.method ==
'GET':
752 vendor = getVendor(session.book, id)
757 return Response(json.dumps(vendor), mimetype=
'application/json')
761 @app.route(
'/vendors/<id>/bills', methods=[
'GET'])
762 def api_vendor_bills(id):
764 vendor = getVendor(session.book, id)
769 bills = getBills(session.book, vendor[
'guid'],
None,
None,
None,
None)
771 return Response(json.dumps(bills), mimetype=
'application/json')
773 def getCustomers(book):
775 query = gnucash.Query()
776 query.search_for(
'gncCustomer')
780 for result
in query.run():
782 gnucash.gnucash_business.Customer(instance=result)))
788 def getCustomer(book, id):
790 customer = book.CustomerLookupByID(id)
797 def getVendors(book):
799 query = gnucash.Query()
800 query.search_for(
'gncVendor')
804 for result
in query.run():
806 gnucash.gnucash_business.Vendor(instance=result)))
812 def getVendor(book, id):
814 vendor = book.VendorLookupByID(id)
821 def getAccounts(book):
827 def getAccountsFlat(book):
831 flat_accounts = getSubAccounts(accounts)
833 for n, account
in enumerate(flat_accounts):
834 account.pop(
'subaccounts')
836 filtered_flat_account = []
840 for n, account
in enumerate(flat_accounts):
841 if account[
'type_id']
in type_ids:
842 filtered_flat_account.append(account)
843 print(account[
'name'] +
' ' + str(account[
'type_id']))
845 return filtered_flat_account
847 def getSubAccounts(account):
851 if 'subaccounts' in list(account.keys()):
852 for n, subaccount
in enumerate(account[
'subaccounts']):
853 flat_accounts.append(subaccount)
854 flat_accounts = flat_accounts + getSubAccounts(subaccount)
858 def getAccount(book, guid):
860 account_guid = gnucash.gnucash_core.GUID()
861 gnucash.gnucash_core.GUIDString(guid, account_guid)
863 account = account_guid.AccountLookup(book)
876 def getTransaction(book, guid):
878 transaction_guid = gnucash.gnucash_core.GUID()
879 gnucash.gnucash_core.GUIDString(guid, transaction_guid)
881 transaction = transaction_guid.TransactionLookup(book)
883 if transaction
is None:
888 if transaction
is None:
893 def getTransactions(book, account_guid, date_posted_from, date_posted_to):
895 query = gnucash.Query()
897 query.search_for(
'Trans')
902 for transaction
in query.run():
904 gnucash.gnucash_business.Transaction(instance=transaction)))
910 def getAccountSplits(book, guid, date_posted_from, date_posted_to):
912 account_guid = gnucash.gnucash_core.GUID()
913 gnucash.gnucash_core.GUIDString(guid, account_guid)
915 query = gnucash.Query()
916 query.search_for(
'Split')
921 TRANS_DATE_POSTED =
'date-posted' 923 if date_posted_from !=
None:
924 pred_data = gnucash.gnucash_core.QueryDatePredicate(
925 QOF_COMPARE_GTE, QOF_DATE_MATCH_NORMAL, datetime.datetime.strptime(
926 date_posted_from,
"%Y-%m-%d").date())
927 param_list = [SPLIT_TRANS, TRANS_DATE_POSTED]
928 query.add_term(param_list, pred_data, QOF_QUERY_AND)
930 if date_posted_to !=
None:
931 pred_data = gnucash.gnucash_core.QueryDatePredicate(
932 QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, datetime.datetime.strptime(
933 date_posted_to,
"%Y-%m-%d").date())
934 param_list = [SPLIT_TRANS, TRANS_DATE_POSTED]
935 query.add_term(param_list, pred_data, QOF_QUERY_AND)
937 SPLIT_ACCOUNT =
'account' 938 QOF_PARAM_GUID =
'guid' 941 gnucash.gnucash_core.GUIDString(guid, account_guid)
942 query.add_guid_match(
943 [SPLIT_ACCOUNT, QOF_PARAM_GUID], account_guid, QOF_QUERY_AND)
947 for split
in query.run():
949 gnucash.gnucash_business.Split(instance=split),
950 [
'account',
'transaction',
'other_split']))
956 def getInvoices(book, customer, is_paid, is_active, date_due_from,
959 query = gnucash.Query()
960 query.search_for(
'gncInvoice')
964 query.add_boolean_match([INVOICE_IS_PAID],
False, QOF_QUERY_AND)
966 query.add_boolean_match([INVOICE_IS_PAID],
True, QOF_QUERY_AND)
970 query.add_boolean_match([
'active'],
False, QOF_QUERY_AND)
972 query.add_boolean_match([
'active'],
True, QOF_QUERY_AND)
974 QOF_PARAM_GUID =
'guid' 975 INVOICE_OWNER =
'owner' 978 customer_guid = gnucash.gnucash_core.GUID()
979 gnucash.gnucash_core.GUIDString(customer, customer_guid)
980 query.add_guid_match(
981 [INVOICE_OWNER, QOF_PARAM_GUID], customer_guid, QOF_QUERY_AND)
983 if date_due_from !=
None:
984 pred_data = gnucash.gnucash_core.QueryDatePredicate(
985 QOF_COMPARE_GTE, 2, datetime.datetime.strptime(
986 date_due_from,
"%Y-%m-%d").date())
987 query.add_term([
'date_due'], pred_data, QOF_QUERY_AND)
989 if date_due_to !=
None:
990 pred_data = gnucash.gnucash_core.QueryDatePredicate(
991 QOF_COMPARE_LTE, 2, datetime.datetime.strptime(
992 date_due_to,
"%Y-%m-%d").date())
993 query.add_term([
'date_due'], pred_data, QOF_QUERY_AND)
996 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 1)
997 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1001 for result
in query.run():
1003 gnucash.gnucash_business.Invoice(instance=result)))
1009 def getBills(book, customer, is_paid, is_active, date_opened_from,
1012 query = gnucash.Query()
1013 query.search_for(
'gncInvoice')
1014 query.set_book(book)
1017 query.add_boolean_match([INVOICE_IS_PAID],
False, QOF_QUERY_AND)
1019 query.add_boolean_match([INVOICE_IS_PAID],
True, QOF_QUERY_AND)
1023 query.add_boolean_match([
'active'],
False, QOF_QUERY_AND)
1024 elif is_active == 1:
1025 query.add_boolean_match([
'active'],
True, QOF_QUERY_AND)
1027 QOF_PARAM_GUID =
'guid' 1028 INVOICE_OWNER =
'owner' 1030 if customer !=
None:
1031 customer_guid = gnucash.gnucash_core.GUID()
1032 gnucash.gnucash_core.GUIDString(customer, customer_guid)
1033 query.add_guid_match(
1034 [INVOICE_OWNER, QOF_PARAM_GUID], customer_guid, QOF_QUERY_AND)
1036 if date_opened_from !=
None:
1037 pred_data = gnucash.gnucash_core.QueryDatePredicate(
1038 QOF_COMPARE_GTE, 2, datetime.datetime.strptime(
1039 date_opened_from,
"%Y-%m-%d").date())
1040 query.add_term([
'date_opened'], pred_data, QOF_QUERY_AND)
1042 if date_opened_to !=
None:
1043 pred_data = gnucash.gnucash_core.QueryDatePredicate(
1044 QOF_COMPARE_LTE, 2, datetime.datetime.strptime(
1045 date_opened_to,
"%Y-%m-%d").date())
1046 query.add_term([
'date_opened'], pred_data, QOF_QUERY_AND)
1049 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 2)
1050 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1054 for result
in query.run():
1056 gnucash.gnucash_business.Bill(instance=result)))
1062 def getGnuCashInvoice(book ,id):
1067 query = gnucash.Query()
1068 query.search_for(
'gncInvoice')
1069 query.set_book(book)
1072 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 1)
1073 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1077 pred_data = gnucash.gnucash_core.QueryStringPredicate(
1078 QOF_COMPARE_EQUAL, id, QOF_STRING_MATCH_NORMAL,
False)
1079 query.add_term([INVOICE_ID], pred_data, QOF_QUERY_AND)
1083 for result
in query.run():
1084 invoice = gnucash.gnucash_business.Invoice(instance=result)
1090 def getGnuCashBill(book ,id):
1095 query = gnucash.Query()
1096 query.search_for(
'gncInvoice')
1097 query.set_book(book)
1100 pred_data = gnucash.gnucash_core.QueryInt32Predicate(QOF_COMPARE_EQUAL, 2)
1101 query.add_term([INVOICE_TYPE], pred_data, QOF_QUERY_AND)
1105 pred_data = gnucash.gnucash_core.QueryStringPredicate(
1106 QOF_COMPARE_EQUAL, id, QOF_STRING_MATCH_NORMAL,
False)
1107 query.add_term([INVOICE_ID], pred_data, QOF_QUERY_AND)
1111 for result
in query.run():
1112 bill = gnucash.gnucash_business.Bill(instance=result)
1118 def getInvoice(book, id):
1122 def payInvoice(book, id, posted_account_guid, transfer_account_guid,
1123 payment_date, memo, num, auto_pay):
1125 invoice = getGnuCashInvoice(book, id)
1127 account_guid2 = gnucash.gnucash_core.GUID()
1128 gnucash.gnucash_core.GUIDString(transfer_account_guid, account_guid2)
1130 xfer_acc = account_guid2.AccountLookup(session.book)
1132 invoice.ApplyPayment(
None, xfer_acc, invoice.GetTotal(), GncNumeric(0),
1133 datetime.datetime.strptime(payment_date,
'%Y-%m-%d'), memo, num)
1137 def payBill(book, id, posted_account_guid, transfer_account_guid, payment_date,
1138 memo, num, auto_pay):
1140 bill = getGnuCashBill(book, id)
1142 account_guid = gnucash.gnucash_core.GUID()
1143 gnucash.gnucash_core.GUIDString(transfer_account_guid, account_guid)
1145 xfer_acc = account_guid.AccountLookup(session.book)
1149 bill.ApplyPayment(
None, xfer_acc, bill.GetTotal().neg(), GncNumeric(0),
1150 datetime.datetime.strptime(payment_date,
'%Y-%m-%d'), memo, num)
1154 def getBill(book, id):
1158 def addVendor(book, id, currency_mnumonic, name, contact, address_line_1,
1159 address_line_2, address_line_3, address_line_4, phone, fax, email):
1162 raise Error(
'NoVendorName',
'A name must be entered for this company',
1165 if (address_line_1 ==
'' 1166 and address_line_2 ==
'' 1167 and address_line_3 ==
'' 1168 and address_line_4 ==
''):
1169 raise Error(
'NoVendorAddress',
1170 'An address must be entered for this company',
1171 {
'field':
'address'})
1173 commod_table = book.get_table()
1174 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1176 if currency
is None:
1177 raise Error(
'InvalidVendorCurrency',
1178 'A valid currency must be supplied for this vendor',
1179 {
'field':
'currency'})
1182 id = book.VendorNextID()
1184 vendor = Vendor(session.book, id, currency, name)
1186 address = vendor.GetAddr()
1187 address.SetName(contact)
1188 address.SetAddr1(address_line_1)
1189 address.SetAddr2(address_line_2)
1190 address.SetAddr3(address_line_3)
1191 address.SetAddr4(address_line_4)
1192 address.SetPhone(phone)
1194 address.SetEmail(email)
1198 def addCustomer(book, id, currency_mnumonic, name, contact, address_line_1,
1199 address_line_2, address_line_3, address_line_4, phone, fax, email):
1202 raise Error(
'NoCustomerName',
1203 'A name must be entered for this company', {
'field':
'name'})
1205 if (address_line_1 ==
'' 1206 and address_line_2 ==
'' 1207 and address_line_3 ==
'' 1208 and address_line_4 ==
''):
1209 raise Error(
'NoCustomerAddress',
1210 'An address must be entered for this company',
1211 {
'field':
'address'})
1213 commod_table = book.get_table()
1214 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1216 if currency
is None:
1217 raise Error(
'InvalidCustomerCurrency',
1218 'A valid currency must be supplied for this customer',
1219 {
'field':
'currency'})
1222 id = book.CustomerNextID()
1224 customer = Customer(session.book, id, currency, name)
1226 address = customer.GetAddr()
1227 address.SetName(contact)
1228 address.SetAddr1(address_line_1)
1229 address.SetAddr2(address_line_2)
1230 address.SetAddr3(address_line_3)
1231 address.SetAddr4(address_line_4)
1232 address.SetPhone(phone)
1234 address.SetEmail(email)
1238 def updateCustomer(book, id, name, contact, address_line_1, address_line_2,
1239 address_line_3, address_line_4, phone, fax, email):
1241 customer = book.CustomerLookupByID(id)
1243 if customer
is None:
1244 raise Error(
'NoCustomer',
'A customer with this ID does not exist',
1248 raise Error(
'NoCustomerName',
1249 'A name must be entered for this company', {
'field':
'name'})
1251 if (address_line_1 ==
'' 1252 and address_line_2 ==
'' 1253 and address_line_3 ==
'' 1254 and address_line_4 ==
''):
1255 raise Error(
'NoCustomerAddress',
1256 'An address must be entered for this company',
1257 {
'field':
'address'})
1259 customer.SetName(name)
1261 address = customer.GetAddr()
1262 address.SetName(contact)
1263 address.SetAddr1(address_line_1)
1264 address.SetAddr2(address_line_2)
1265 address.SetAddr3(address_line_3)
1266 address.SetAddr4(address_line_4)
1267 address.SetPhone(phone)
1269 address.SetEmail(email)
1273 def addInvoice(book, id, customer_id, currency_mnumonic, date_opened, notes):
1275 customer = book.CustomerLookupByID(customer_id)
1277 if customer
is None:
1278 raise Error(
'NoCustomer',
1279 'A customer with this ID does not exist', {
'field':
'id'})
1282 id = book.InvoiceNextID(customer)
1285 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1287 raise Error(
'InvalidDateOpened',
1288 'The date opened must be provided in the form YYYY-MM-DD',
1289 {
'field':
'date_opened'})
1291 if currency_mnumonic
is None:
1292 currency_mnumonic = customer.GetCurrency().get_mnemonic()
1294 commod_table = book.get_table()
1295 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1297 if currency
is None:
1298 raise Error(
'InvalidCustomerCurrency',
1299 'A valid currency must be supplied for this customer',
1300 {
'field':
'currency'})
1302 invoice = Invoice(book, id, currency, customer, date_opened.date())
1304 invoice.SetNotes(notes)
1308 def updateInvoice(book, id, customer_id, currency_mnumonic, date_opened,
1309 notes, posted, posted_account_guid, posted_date, due_date, posted_memo,
1310 posted_accumulatesplits, posted_autopay):
1312 invoice = getGnuCashInvoice(book, id)
1315 raise Error(
'NoInvoice',
1316 'An invoice with this ID does not exist',
1319 customer = book.CustomerLookupByID(customer_id)
1321 if customer
is None:
1322 raise Error(
'NoCustomer',
'A customer with this ID does not exist',
1323 {
'field':
'customer_id'})
1326 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1328 raise Error(
'InvalidDateOpened',
1329 'The date opened must be provided in the form YYYY-MM-DD',
1330 {
'field':
'date_opened'})
1332 if posted_date ==
'':
1334 raise Error(
'NoDatePosted',
1335 'The date posted must be supplied when posted=1',
1336 {
'field':
'date_posted'})
1339 posted_date = datetime.datetime.strptime(posted_date,
"%Y-%m-%d")
1341 raise Error(
'InvalidDatePosted',
1342 'The date posted must be provided in the form YYYY-MM-DD',
1343 {
'field':
'posted_date'})
1347 raise Error(
'NoDatePosted',
1348 'The due date must be supplied when posted=1',
1349 {
'field':
'date_posted'})
1352 due_date = datetime.datetime.strptime(due_date,
"%Y-%m-%d")
1354 raise Error(
'InvalidDatePosted',
1355 'The due date must be provided in the form YYYY-MM-DD',
1356 {
'field':
'due_date'})
1358 if posted_account_guid ==
'':
1360 raise Error(
'NoPostedAccountGuid',
1361 'The posted account GUID must be supplied when posted=1',
1362 {
'field':
'posted_account_guid'})
1364 guid = gnucash.gnucash_core.GUID()
1365 gnucash.gnucash_core.GUIDString(posted_account_guid, guid)
1367 posted_account = guid.AccountLookup(book)
1369 if posted_account
is None:
1370 raise Error(
'NoAccount',
1371 'No account exists with the posted account GUID',
1372 {
'field':
'posted_account_guid'})
1374 invoice.SetOwner(customer)
1375 invoice.SetDateOpened(date_opened)
1376 invoice.SetNotes(notes)
1379 if (invoice.GetDatePosted().strftime(
'%Y-%m-%d') ==
'1970-01-01' 1381 invoice.PostToAccount(posted_account, posted_date, due_date,
1382 posted_memo, posted_accumulatesplits, posted_autopay)
1386 def updateBill(book, id, vendor_id, currency_mnumonic, date_opened, notes,
1387 posted, posted_account_guid, posted_date, due_date, posted_memo,
1388 posted_accumulatesplits, posted_autopay):
1390 bill = getGnuCashBill(book, id)
1393 raise Error(
'NoBill',
'A bill with this ID does not exist',
1396 vendor = book.VendorLookupByID(vendor_id)
1399 raise Error(
'NoVendor',
1400 'A vendor with this ID does not exist',
1401 {
'field':
'vendor_id'})
1404 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1406 raise Error(
'InvalidDateOpened',
1407 'The date opened must be provided in the form YYYY-MM-DD',
1408 {
'field':
'date_opened'})
1410 if posted_date ==
'':
1412 raise Error(
'NoDatePosted',
1413 'The date posted must be supplied when posted=1',
1414 {
'field':
'date_posted'})
1417 posted_date = datetime.datetime.strptime(posted_date,
"%Y-%m-%d")
1419 raise Error(
'InvalidDatePosted',
1420 'The date posted must be provided in the form YYYY-MM-DD',
1421 {
'field':
'posted_date'})
1425 raise Error(
'NoDatePosted',
1426 'The due date must be supplied when posted=1',
1427 {
'field':
'date_posted'})
1430 due_date = datetime.datetime.strptime(due_date,
"%Y-%m-%d")
1432 raise Error(
'InvalidDatePosted',
1433 'The due date must be provided in the form YYYY-MM-DD',
1434 {
'field':
'due_date'})
1436 if posted_account_guid ==
'':
1438 raise Error(
'NoPostedAccountGuid',
1439 'The posted account GUID must be supplied when posted=1',
1440 {
'field':
'posted_account_guid'})
1442 guid = gnucash.gnucash_core.GUID()
1443 gnucash.gnucash_core.GUIDString(posted_account_guid, guid)
1445 posted_account = guid.AccountLookup(book)
1447 if posted_account
is None:
1448 raise Error(
'NoAccount',
1449 'No account exists with the posted account GUID',
1450 {
'field':
'posted_account_guid'})
1452 bill.SetOwner(vendor)
1453 bill.SetDateOpened(date_opened)
1454 bill.SetNotes(notes)
1457 if bill.GetDatePosted().strftime(
'%Y-%m-%d') ==
'1970-01-01' and posted == 1:
1458 bill.PostToAccount(posted_account, posted_date, due_date, posted_memo,
1459 posted_accumulatesplits, posted_autopay)
1463 def addEntry(book, invoice_id, date, description, account_guid, quantity, price):
1465 invoice = getGnuCashInvoice(book, invoice_id)
1468 raise Error(
'NoInvoice',
1469 'No invoice exists with this ID', {
'field':
'invoice_id'})
1472 date = datetime.datetime.strptime(date,
"%Y-%m-%d")
1474 raise Error(
'InvalidDateOpened',
1475 'The date opened must be provided in the form YYYY-MM-DD',
1478 guid = gnucash.gnucash_core.GUID()
1479 gnucash.gnucash_core.GUIDString(account_guid, guid)
1481 account = guid.AccountLookup(book)
1484 raise Error(
'NoAccount',
'No account exists with this GUID',
1485 {
'field':
'account_guid'})
1488 quantity = Decimal(quantity).quantize(Decimal(
'.01'))
1489 except ArithmeticError:
1490 raise Error(
'InvalidQuantity',
'This quantity is not valid',
1491 {
'field':
'quantity'})
1494 price = Decimal(price).quantize(Decimal(
'.01'))
1495 except ArithmeticError:
1496 raise Error(
'InvalidPrice',
'This price is not valid',
1499 entry = Entry(book, invoice, date.date())
1500 entry.SetDateEntered(datetime.datetime.now())
1501 entry.SetDescription(description)
1502 entry.SetInvAccount(account)
1503 entry.SetQuantity(gnc_numeric_from_decimal(quantity))
1504 entry.SetInvPrice(gnc_numeric_from_decimal(price))
1508 def addBillEntry(book, bill_id, date, description, account_guid, quantity,
1511 bill = getGnuCashBill(book,bill_id)
1514 raise Error(
'NoBill',
'No bill exists with this ID',
1515 {
'field':
'bill_id'})
1518 date = datetime.datetime.strptime(date,
"%Y-%m-%d")
1520 raise Error(
'InvalidDateOpened',
1521 'The date opened must be provided in the form YYYY-MM-DD',
1524 guid = gnucash.gnucash_core.GUID()
1525 gnucash.gnucash_core.GUIDString(account_guid, guid)
1527 account = guid.AccountLookup(book)
1530 raise Error(
'NoAccount',
'No account exists with this GUID',
1531 {
'field':
'account_guid'})
1534 quantity = Decimal(quantity).quantize(Decimal(
'.01'))
1535 except ArithmeticError:
1536 raise Error(
'InvalidQuantity',
'This quantity is not valid',
1537 {
'field':
'quantity'})
1540 price = Decimal(price).quantize(Decimal(
'.01'))
1541 except ArithmeticError:
1542 raise Error(
'InvalidPrice',
'This price is not valid',
1545 entry = Entry(book, bill, date.date())
1546 entry.SetDateEntered(datetime.datetime.now())
1547 entry.SetDescription(description)
1548 entry.SetBillAccount(account)
1549 entry.SetQuantity(gnc_numeric_from_decimal(quantity))
1550 entry.SetBillPrice(gnc_numeric_from_decimal(price))
1554 def getEntry(book, entry_guid):
1556 guid = gnucash.gnucash_core.GUID()
1557 gnucash.gnucash_core.GUIDString(entry_guid, guid)
1559 entry = book.EntryLookup(guid)
1566 def updateEntry(book, entry_guid, date, description, account_guid, quantity,
1569 guid = gnucash.gnucash_core.GUID()
1570 gnucash.gnucash_core.GUIDString(entry_guid, guid)
1572 entry = book.EntryLookup(guid)
1575 raise Error(
'NoEntry',
'No entry exists with this GUID',
1576 {
'field':
'entry_guid'})
1579 date = datetime.datetime.strptime(date,
"%Y-%m-%d")
1581 raise Error(
'InvalidDateOpened',
1582 'The date opened must be provided in the form YYYY-MM-DD',
1585 gnucash.gnucash_core.GUIDString(account_guid, guid)
1587 account = guid.AccountLookup(book)
1590 raise Error(
'NoAccount',
'No account exists with this GUID',
1591 {
'field':
'account_guid'})
1593 entry.SetDate(date.date())
1594 entry.SetDateEntered(datetime.datetime.now())
1595 entry.SetDescription(description)
1596 entry.SetInvAccount(account)
1598 gnc_numeric_from_decimal(Decimal(quantity).quantize(Decimal(
'.01'))))
1600 gnc_numeric_from_decimal(Decimal(price).quantize(Decimal(
'.01'))))
1604 def deleteEntry(book, entry_guid):
1606 guid = gnucash.gnucash_core.GUID()
1607 gnucash.gnucash_core.GUIDString(entry_guid, guid)
1609 entry = book.EntryLookup(guid)
1611 invoice = entry.GetInvoice()
1612 bill = entry.GetBill()
1614 if invoice !=
None and entry !=
None:
1615 invoice.RemoveEntry(entry)
1616 elif bill !=
None and entry !=
None:
1617 bill.RemoveEntry(entry)
1622 def deleteTransaction(book, transaction_guid):
1624 guid = gnucash.gnucash_core.GUID()
1625 gnucash.gnucash_core.GUIDString(transaction_guid, guid)
1627 transaction = guid.TransLookup(book)
1629 if transaction !=
None :
1630 transaction.Destroy()
1632 def addBill(book, id, vendor_id, currency_mnumonic, date_opened, notes):
1634 vendor = book.VendorLookupByID(vendor_id)
1637 raise Error(
'NoVendor',
'A vendor with this ID does not exist',
1641 id = book.BillNextID(vendor)
1644 date_opened = datetime.datetime.strptime(date_opened,
"%Y-%m-%d")
1646 raise Error(
'InvalidVendorDateOpened',
1647 'The date opened must be provided in the form YYYY-MM-DD',
1648 {
'field':
'date_opened'})
1650 if currency_mnumonic
is None:
1651 currency_mnumonic = vendor.GetCurrency().get_mnemonic()
1653 commod_table = book.get_table()
1654 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1656 if currency
is None:
1657 raise Error(
'InvalidVendorCurrency',
1658 'A valid currency must be supplied for this vendor',
1659 {
'field':
'currency'})
1661 bill = Bill(book, id, currency, vendor, date_opened.date())
1663 bill.SetNotes(notes)
1667 def addAccount(book, name, currency_mnumonic, account_guid):
1669 from gnucash.gnucash_core_c
import \
1670 ACCT_TYPE_ASSET, ACCT_TYPE_RECEIVABLE, ACCT_TYPE_INCOME, \
1671 GNC_OWNER_CUSTOMER, ACCT_TYPE_LIABILITY
1673 root_account = book.get_root_account()
1675 commod_table = book.get_table()
1676 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1678 if currency
is None:
1679 raise Error(
'InvalidCustomerCurrency',
1680 'A valid currency must be supplied for this customer',
1681 {
'field':
'currency'})
1684 root_account.append_child(root_account)
1685 account.SetName(name)
1686 account.SetType(ACCT_TYPE_ASSET)
1687 account.SetCommodity(currency)
1689 def addTransaction(book, num, description, date_posted, currency_mnumonic, splits):
1691 transaction = Transaction(book)
1693 transaction.BeginEdit()
1695 commod_table = book.get_table()
1696 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1698 if currency
is None:
1699 raise Error(
'InvalidTransactionCurrency',
1700 'A valid currency must be supplied for this transaction',
1701 {
'field':
'currency'})
1704 date_posted = datetime.datetime.strptime(date_posted,
"%Y-%m-%d")
1706 raise Error(
'InvalidDatePosted',
1707 'The date posted must be provided in the form YYYY-MM-DD',
1708 {
'field':
'date_posted'})
1711 for split_values
in splits:
1712 account_guid = gnucash.gnucash_core.GUID()
1713 gnucash.gnucash_core.GUIDString(split_values[
'account_guid'], account_guid)
1715 account = account_guid.AccountLookup(book)
1718 raise Error(
'InvalidSplitAccount',
1719 'A valid account must be supplied for this split',
1720 {
'field':
'account'})
1723 split.SetValue(GncNumeric(split_values[
'value'], 100))
1724 split.SetAccount(account)
1725 split.SetParent(transaction)
1727 transaction.SetCurrency(currency)
1728 transaction.SetDescription(description)
1729 transaction.SetNum(num)
1731 transaction.SetDatePostedTS(date_posted)
1733 transaction.CommitEdit()
1737 def getTransaction(book, transaction_guid):
1739 guid = gnucash.gnucash_core.GUID()
1740 gnucash.gnucash_core.GUIDString(transaction_guid, guid)
1742 transaction = guid.TransLookup(book)
1744 if transaction
is None:
1749 def editTransaction(book, transaction_guid, num, description, date_posted,
1750 currency_mnumonic, splits):
1752 guid = gnucash.gnucash_core.GUID()
1753 gnucash.gnucash_core.GUIDString(transaction_guid, guid)
1755 transaction = guid.TransLookup(book)
1757 if transaction
is None:
1758 raise Error(
'NoCustomer',
1759 'A transaction with this GUID does not exist',
1762 transaction.BeginEdit()
1764 commod_table = book.get_table()
1765 currency = commod_table.lookup(
'CURRENCY', currency_mnumonic)
1767 if currency
is None:
1768 raise Error(
'InvalidTransactionCurrency',
1769 'A valid currency must be supplied for this transaction',
1770 {
'field':
'currency'})
1774 date_posted = datetime.datetime.strptime(date_posted,
"%Y-%m-%d")
1776 raise Error(
'InvalidDatePosted',
1777 'The date posted must be provided in the form YYYY-MM-DD',
1778 {
'field':
'date_posted'})
1780 for split_values
in splits:
1782 split_guid = gnucash.gnucash_core.GUID()
1783 gnucash.gnucash_core.GUIDString(split_values[
'guid'], split_guid)
1785 split = split_guid.SplitLookup(book)
1788 raise Error(
'InvalidSplitGuid',
1789 'A valid guid must be supplied for this split',
1792 account_guid = gnucash.gnucash_core.GUID()
1793 gnucash.gnucash_core.GUIDString(
1794 split_values[
'account_guid'], account_guid)
1796 account = account_guid.AccountLookup(book)
1799 raise Error(
'InvalidSplitAccount',
1800 'A valid account must be supplied for this split',
1801 {
'field':
'account'})
1803 split.SetValue(GncNumeric(split_values[
'value'], 100))
1804 split.SetAccount(account)
1805 split.SetParent(transaction)
1807 transaction.SetCurrency(currency)
1808 transaction.SetDescription(description)
1809 transaction.SetNum(num)
1811 transaction.SetDatePostedTS(date_posted)
1813 transaction.CommitEdit()
1817 def gnc_numeric_from_decimal(decimal_value):
1818 sign, digits, exponent = decimal_value.as_tuple()
1826 TEN = int(Decimal(0).radix())
1827 numerator_place_value = 1
1830 for i
in range(len(digits)-1,-1,-1):
1831 numerator += digits[i] * numerator_place_value
1832 numerator_place_value *= TEN
1834 if decimal_value.is_signed():
1835 numerator = -numerator
1839 denominator = TEN ** (-exponent)
1843 numerator *= TEN ** exponent
1846 return GncNumeric(numerator, denominator)
1855 """Base class for exceptions in this module.""" 1856 def __init__(self, type, message, data):
1862 options, arguments = getopt.getopt(sys.argv[1:],
'nh:', [
'host=',
'new='])
1863 except getopt.GetoptError
as err:
1865 print(
'Usage: python-rest.py <connection string>')
1868 if len(arguments) == 0:
1869 print(
'Usage: python-rest.py <connection string>')
1876 for option, value
in options:
1877 if option
in (
"-h",
"--host"):
1883 for option, value
in options:
1884 if option
in (
"-n",
"--new"):
1890 session = gnucash.Session(arguments[0], SessionOpenMode.SESSION_NEW_STORE)
1900 session = gnucash.Session(arguments[0], SessionOpenMode.SESSION_BREAK_LOCK)
1903 atexit.register(shutdown)
1910 from logging
import StreamHandler
1911 stream_handler = StreamHandler()
1912 stream_handler.setLevel(logging.ERROR)
1913 app.logger.addHandler(stream_handler)
def transactionToDict(transaction, entities)
def invoiceToDict(invoice)
def splitToDict(split, entities)
def customerToDict(customer)
def accountToDict(account)