|
1 | 1 | #!/usr/bin/env python2.7
|
2 | 2 | # -*- coding: utf-8 -*-
|
| 3 | +# PYTHON_ARGCOMPLETE_OK |
| 4 | + |
3 | 5 | #
|
4 |
| -# FabLabKasse, a Point-of-Sale Software for FabLabs and other public and trust-based workshops. |
| 6 | +# FabLabKasse, a Point-of-Sale Software for FabLabs and other public and |
| 7 | +# trust-based workshops. |
5 | 8 | # Copyright (C) 2015 Julian Hammer <[email protected]>
|
6 | 9 | # Maximilian Gaukler <[email protected]>
|
7 | 10 | # Patrick Kanzler <[email protected]>
|
8 | 11 |
|
9 | 12 | #
|
10 |
| -# This program is free software: you can redistribute it and/or modify it under the terms of the GNU |
11 |
| -# General Public License as published by the Free Software Foundation, either version 3 of the |
12 |
| -# License, or (at your option) any later version. |
| 13 | +# This program is free software: you can redistribute it and/or modify it under |
| 14 | +# the terms of the GNU General Public License as published by the Free Software |
| 15 | +# Foundation, either version 3 of the License, or (at your option) any later |
| 16 | +# version. |
13 | 17 | #
|
14 |
| -# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without |
15 |
| -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 |
| -# General Public License for more details. |
| 18 | +# This program is distributed in the hope that it will be useful, but WITHOUT |
| 19 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 20 | +# FOR A PARTICULAR PURPOSE. |
| 21 | +# See the GNU General Public License for more details. |
17 | 22 | #
|
18 |
| -# You should have received a copy of the GNU General Public License along with this program. If not, |
19 |
| -# see <http://www.gnu.org/licenses/>. |
20 |
| - |
21 |
| -"""Kassenbuch Backend mit doppelter Buchführung. |
| 23 | +# You should have received a copy of the GNU General Public License along with |
| 24 | +# this program. If not, see <http://www.gnu.org/licenses/>. |
22 | 25 |
|
| 26 | +""" |
| 27 | +Kassenbuch Backend mit doppelter Buchführung. |
| 28 | +""" |
| 29 | +""" |
23 | 30 | Usage:
|
24 | 31 | kassenbuch.py show [--hide-receipts] [<from> [<until>]]
|
25 | 32 | kassenbuch.py export (book|invoices) <outfile> [<from> [<until>]] [--format=<fileformat>]
|
|
46 | 53 | from datetime import datetime
|
47 | 54 | from decimal import Decimal, InvalidOperation
|
48 | 55 | import dateutil.parser
|
49 |
| -from docopt import docopt |
50 | 56 | import csv
|
51 | 57 | import cStringIO
|
52 | 58 | import codecs
|
|
55 | 61 | import os
|
56 | 62 | import random
|
57 | 63 | import scriptHelper
|
| 64 | +import argparse |
| 65 | +try: |
| 66 | + import argcomplete |
| 67 | +except ImportError: |
| 68 | + pass |
58 | 69 |
|
59 | 70 | import doctest
|
60 | 71 |
|
@@ -767,22 +778,185 @@ def parse_date(date):
|
767 | 778 | else:
|
768 | 779 | raise ValueError('cannot parse date value')
|
769 | 780 |
|
| 781 | + |
| 782 | +def argparse_parse_date(date): |
| 783 | + """ |
| 784 | + a wrapper for parings dates for argparse |
| 785 | +
|
| 786 | + :type date: see :meth:`parse_date` |
| 787 | + :rtype: see :meth:`parse_date` |
| 788 | + """ |
| 789 | + try: |
| 790 | + return parse_date(date) |
| 791 | + except ValueError as e: |
| 792 | + raise argparse.ArgumentTypeError(e.message) |
| 793 | + |
| 794 | + |
| 795 | +def parse_args(argv=sys.argv[1:]): |
| 796 | + """ |
| 797 | + Parse arguments |
| 798 | + :return: the parse arguments as object (see argparse doc) |
| 799 | + """ |
| 800 | + parser = argparse.ArgumentParser(description=__doc__) |
| 801 | + subparsers = parser.add_subparsers(help='sub-command help') |
| 802 | + |
| 803 | + DATE_HELP = "ISO formatted datetime, (2016-12-31 or 2016-12-31 13:37:42)" |
| 804 | + # show |
| 805 | + parser_show = subparsers.add_parser( |
| 806 | + 'show', |
| 807 | + help='show receipts' |
| 808 | + ) |
| 809 | + parser_show.add_argument( |
| 810 | + '--hide-receipts', |
| 811 | + action='store_true', |
| 812 | + dest='hide_receipts', |
| 813 | + default=False, |
| 814 | + help="Don't show receipts in summary output, just the account balances" |
| 815 | + ) |
| 816 | + parser_show.add_argument( |
| 817 | + '--from', |
| 818 | + action='store', |
| 819 | + type=argparse_parse_date, |
| 820 | + metavar='date', |
| 821 | + help=DATE_HELP |
| 822 | + ) |
| 823 | + parser_show.add_argument( |
| 824 | + '--until', |
| 825 | + action='store', |
| 826 | + type=argparse_parse_date, |
| 827 | + metavar='date', |
| 828 | + help=DATE_HELP |
| 829 | + ) |
| 830 | + # export |
| 831 | + parser_export = subparsers.add_parser( |
| 832 | + 'export', |
| 833 | + help='export book or invoices' |
| 834 | + ) |
| 835 | + parser_export.add_argument( |
| 836 | + 'what', |
| 837 | + action='store', |
| 838 | + choices=['book', 'invoices'], |
| 839 | + help="what do you want to export (book|invoices)" |
| 840 | + ) |
| 841 | + parser_export.add_argument( |
| 842 | + 'outfile', |
| 843 | + action='store', |
| 844 | + type=argparse.FileType('w'), |
| 845 | + default='-', |
| 846 | + help="the output file, - for stdout" |
| 847 | + ) |
| 848 | + parser_export.add_argument( |
| 849 | + '--from', |
| 850 | + action='store', |
| 851 | + type=argparse_parse_date, |
| 852 | + metavar='date', |
| 853 | + help=DATE_HELP |
| 854 | + ) |
| 855 | + parser_export.add_argument( |
| 856 | + '--until', |
| 857 | + action='store', |
| 858 | + type=argparse_parse_date, |
| 859 | + metavar='date', |
| 860 | + help=DATE_HELP |
| 861 | + ) |
| 862 | + parser_export.add_argument( |
| 863 | + '--format', |
| 864 | + action='store', |
| 865 | + dest='format', |
| 866 | + metavar='fileformat', |
| 867 | + default='csv', |
| 868 | + choices=['csv'], # TODO more fileformats |
| 869 | + help="format for the output file (default csv)" |
| 870 | + ) |
| 871 | + # summary |
| 872 | + parser_summary = subparsers.add_parser( |
| 873 | + 'summary', |
| 874 | + help='show the summary' |
| 875 | + ) |
| 876 | + parser_summary.add_argument( |
| 877 | + '--until', |
| 878 | + action='store', |
| 879 | + type=argparse_parse_date, |
| 880 | + metavar='date', |
| 881 | + help=DATE_HELP |
| 882 | + ) |
| 883 | + # transfer |
| 884 | + parser_transfer = subparsers.add_parser( |
| 885 | + 'transfer', |
| 886 | + help="transfer money from one resource to another" |
| 887 | + ) |
| 888 | + parser_transfer.add_argument( |
| 889 | + 'source', |
| 890 | + action='store', |
| 891 | + type=str, |
| 892 | + help="the source" |
| 893 | + ) |
| 894 | + parser_transfer.add_argument( |
| 895 | + 'destination', |
| 896 | + action='store', |
| 897 | + type=str, |
| 898 | + help="the destination" |
| 899 | + ) |
| 900 | + parser_transfer.add_argument( |
| 901 | + 'amount', |
| 902 | + action='store', |
| 903 | + type=int, |
| 904 | + help="the amount" |
| 905 | + ) |
| 906 | + parser_transfer.add_argument( |
| 907 | + 'comment', |
| 908 | + action='store', |
| 909 | + type=str, |
| 910 | + help="a comment" |
| 911 | + ) |
| 912 | + # receipt |
| 913 | + parser_receipt = subparsers.add_parser( |
| 914 | + 'transfer', |
| 915 | + help="receipt" |
| 916 | + ) |
| 917 | + parser_receipt.add_argument( |
| 918 | + '--print', |
| 919 | + action='store_true', |
| 920 | + dest='print', |
| 921 | + default=False, |
| 922 | + help="print?" |
| 923 | + ) |
| 924 | + parser_receipt.add_argument( |
| 925 | + '--export', |
| 926 | + action='store_true', |
| 927 | + dest='export', |
| 928 | + default=False, |
| 929 | + help="export?" |
| 930 | + ) |
| 931 | + parser_receipt.add_argument( |
| 932 | + 'id', |
| 933 | + action='store', |
| 934 | + type=int, # TODO Kunde |
| 935 | + help="the Kunden ID" |
| 936 | + ) |
| 937 | + |
| 938 | + if 'argcomplete' in globals(): |
| 939 | + argcomplete.autocomplete(parser) |
| 940 | + |
| 941 | + args = parser.parse_args(argv) |
| 942 | + |
| 943 | + return args |
| 944 | + |
770 | 945 | if __name__ == '__main__':
|
771 |
| - arguments = docopt(__doc__, version='Kassenbuch 1.0') |
| 946 | + args = parse_args() |
772 | 947 |
|
773 | 948 | # go to script dir (configs are relative path names)
|
774 | 949 | os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
775 | 950 |
|
776 | 951 | # Decode all arguments with proper utf-8 decoding:
|
777 |
| - arguments.update( |
778 |
| - dict(map(lambda t: (t[0], t[1].decode('utf-8')), |
779 |
| - filter(lambda t: isinstance(t[1], str), arguments.items())))) |
| 952 | + #arguments.update( |
| 953 | + # dict(map(lambda t: (t[0], t[1].decode('utf-8')), |
| 954 | + # filter(lambda t: isinstance(t[1], str), arguments.items())))) |
780 | 955 |
|
781 | 956 | # decode date arguments
|
782 |
| - for arg_name in ['<until>', '<from>']: |
783 |
| - # TODO also parse rechnung ID here (convert to date=max(rechnung.datum, rechnung.buchungen.datum) ?) |
784 |
| - arguments[arg_name] = parse_date(arguments[arg_name]) |
785 |
| - |
| 957 | + #for arg_name in ['<until>', '<from>']: |
| 958 | + # # TODO also parse rechnung ID here (convert to date=max(rechnung.datum, rechnung.buchungen.datum) ?) |
| 959 | + # arguments[arg_name] = parse_date(arguments[arg_name]) |
786 | 960 |
|
787 | 961 | cfg = scriptHelper.getConfig()
|
788 | 962 | k = Kasse(cfg.get('general', 'db_file'))
|
|
0 commit comments