root / pykota / trunk / bin / pkinvoice @ 2662

Revision 2662, 8.5 kB (checked in by jerome, 18 years ago)

pkinvoice now basically works. TODO : PDF generation.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#! /usr/bin/env python
2# -*- coding: ISO-8859-15 -*-
3
4# PyKota Invoice generator
5#
6# PyKota - Print Quotas for CUPS and LPRng
7#
8# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com>
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22#
23# $Id$
24#
25#
26
27import sys
28import os
29import pwd
30import grp
31from pykota.tool import PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_
32from pykota.config import PyKotaConfigError
33from pykota.storage import PyKotaStorageError
34
35__doc__ = N_("""pkinvoice v%(__version__)s (c) %(__years__)s %(__author__)s
36
37An invoice generator for PyKota.
38
39command line usage :
40
41  pkinvoice [options] user1 user2 ... userN
42
43options :
44
45  -v | --version       Prints edpykota's version number then exits.
46  -h | --help          Prints this message then exits.
47 
48  -g | --groups        Generate invoices for users groups instead of users.
49 
50  -l | --logo img      Use the image as the banner's logo. The logo will
51                       be drawn at the center top of the page. The default
52                       logo is /usr/share/pykota/logos/pykota.jpeg
53                       
54  -p | --pagesize sz   Sets sz as the page size. Most well known
55                       page sizes are recognized, like 'A4' or 'Letter'
56                       to name a few. The default size is A4.
57                       
58  -n | --number N      Sets the number of the first invoice. This number
59                       will automatically be incremented for each invoice.
60                       
61  -r | --reference v   Uses v as the initial reference value : an invoice
62                       will be generated for any account balance's value
63                       lower or equal to the reference value. The
64                       default reference value is of course 0.0 credits.
65                       
66  -o | --output f.pdf  Defines the name of the invoice file which will
67                       be generated as a PDF document. If not set or
68                       set to '-', the PDF document is sent to standard
69                       output.
70                       
71  -u | --unit u        Defines the name of the unit to use on the invoice.                       
72                       The default unit is 'Credits', optionally translated
73                       to your native language if it is supported by PyKota.
74 
75  -V | --vat p         Sets the percent value of the applicable VAT to be
76                       exposed. The default is 0.0, meaning no VAT
77                       information will be included.
78                       
79  user1 through userN and group1 through groupN can use wildcards if
80  needed. If no user argument is used, a wildcard of '*' is assumed,
81  meaning include all users or groups.
82 
83examples :                       
84
85  $ pkinvoice --reference 15.0 --unit EURO --output invoices.pdf
86 
87  Will generate a PDF document containing invoices for all users whose
88  account balance is below 15.0 credits. For each user the amount due
89  will be (15.0 - AccountBalance) EURO when that value is positive.
90  No VAT information will be included.
91""") 
92       
93class PKInvoice(PyKotaTool) :       
94    """A class for pkinvoice."""
95    def main(self, names, options) :
96        """Generate invoices."""
97        if not self.config.isAdmin :
98            raise PyKotaCommandLineError, "%s : %s" % (pwd.getpwuid(os.geteuid())[0], _("You're not allowed to use this command."))
99       
100        try :   
101            vat = float(options["vat"])
102            if not (0.0 <= vat < 100.0) :
103                raise ValueError
104        except :   
105            raise PyKotaCommandLineError, _("Incorrect value '%s' for the --vat command line option") % options["vat"]
106           
107        try :   
108            reference = float(options["reference"])
109        except :   
110            raise PyKotaCommandLineError, _("Incorrect value '%s' for the --reference command line option") % options["reference"]
111           
112        try :   
113            number = float(options["number"])
114            if number <= 0 :
115                raise ValueError
116        except :   
117            raise PyKotaCommandLineError, _("Incorrect value '%s' for the --number command line option") % options["number"]
118           
119        if not names :
120            names = [ "*" ]
121           
122        outfname = options["output"]   
123        if outfname != "-" :
124            self.display("%s...\n" % _("Processing"))
125           
126        suffix = (options["groups"] and "Group") or "User"       
127        entries = getattr(self.storage, "getMatching%ss" % suffix)(",".join(names))
128        nbtotal = len(entries)
129        for i in range(nbtotal) :
130            entry = entries[i]
131            amount = reference - entry.AccountBalance
132            if amount > 0.0 :
133                # There's something due !
134                ht = ((amount * 10000.0) / (100.0 + vat)) / 100.0
135                sys.stderr.write("%s => Due : %.2f including %.2f VAT\n" % (entry.Name, amount, amount-ht))
136               
137            if outfname != "-" :
138                percent = 100.0 * float(i) / float(nbtotal)
139                self.display("\r%.02f%%" % percent)
140               
141        if outfname != "-" :       
142            self.display("\r100.00%%\r        ")
143            self.display("\r%s\n" % _("Done."))
144                     
145if __name__ == "__main__" : 
146    retcode = 0
147    try :
148        defaults = { "reference" : "0.0",
149                     "vat" : "0.0",
150                     "unit" : N_("Credits"),
151                     "output" : "-",
152                     "pagesize" : "a4", \
153                     "logo" : "/usr/share/pykota/logos/pykota.jpeg",
154                     "number" : "1",
155                   }
156        short_options = "vho:gr:u:V:p:l:n:"
157        long_options = ["help", "version", \
158                        "groups", "reference=", "unit=", "output=", \
159                        "pagesize=", "logo=", "vat=", "number="]
160       
161        # Initializes the command line tool
162        invoiceGenerator = PKInvoice(doc=__doc__)
163        invoiceGenerator.deferredInit()
164       
165        # parse and checks the command line
166        (options, args) = invoiceGenerator.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=True)
167       
168        # sets long options
169        options["help"] = options["h"] or options["help"]
170        options["version"] = options["v"] or options["version"]
171       
172        options["groups"] = options["g"] or options["groups"]
173        options["reference"] = options["r"] or options["reference"] or defaults["reference"]
174        options["vat"] = options["V"] or options["vat"] or defaults["vat"]
175        options["unit"] = options["u"] or options["unit"] or defaults["unit"]
176        options["output"] = options["o"] or options["output"] or defaults["output"]
177        options["pagesize"] = options["p"] or options["pagesize"] or defaults["pagesize"]
178        options["number"] = options["n"] or options["number"] or defaults["number"]
179        options["logo"] = options["l"] or options["logo"]
180        if options["logo"] is None : # Allows --logo="" to disable the logo entirely
181            options["logo"] = defaults["logo"] 
182       
183        if options["help"] :
184            invoiceGenerator.display_usage_and_quit()
185        elif options["version"] :
186            invoiceGenerator.display_version_and_quit()
187        else :
188            retcode = invoiceGenerator.main(args, options)
189    except KeyboardInterrupt :       
190        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
191        retcode = -3
192    except PyKotaCommandLineError, msg :     
193        sys.stderr.write("%s : %s\n" % (sys.argv[0], msg))
194        retcode = -2
195    except SystemExit :       
196        pass
197    except :
198        try :
199            invoiceGenerator.crashed("pkinvoice failed")
200        except :   
201            crashed("pkinvoice failed")
202        retcode = -1
203
204    try :
205        invoiceGenerator.storage.close()
206    except (TypeError, NameError, AttributeError) :   
207        pass
208       
209    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.