Changeset 2666

Show
Ignore:
Timestamp:
02/11/06 11:59:13 (19 years ago)
Author:
jerome
Message:

Revamped the functionnality completely, to base invoices on the printing
history instead of on the account balance : this way we can use date
based filtering ala dumpykota, and we also have additionnal informations.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/pkinvoice

    r2663 r2666  
    4646    hasPIL = 1 
    4747 
    48 from pykota.tool import PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_ 
     48from pykota.tool import PyKotaToolError, PyKotaCommandLineError, crashed, N_ 
     49from pykota.dumper import DumPyKota 
    4950from pykota.config import PyKotaConfigError 
    5051from pykota.storage import PyKotaStorageError 
     
    6263  -v | --version       Prints edpykota's version number then exits. 
    6364  -h | --help          Prints this message then exits. 
    64    
    65   -g | --groups        Generate invoices for users groups instead of users. 
    6665   
    6766  -l | --logo img      Use the image as the banner's logo. The logo will 
     
    7574  -n | --number N      Sets the number of the first invoice. This number 
    7675                       will automatically be incremented for each invoice. 
    77                         
    78   -r | --reference v   Uses v as the initial reference value : an invoice 
    79                        will be generated for any account balance's value 
    80                        lower or equal to the reference value. The 
    81                        default reference value is of course 0.0 credits. 
    8276                        
    8377  -o | --output f.pdf  Defines the name of the invoice file which will 
     
    9488                       information will be included. 
    9589                        
    96   user1 through userN and group1 through groupN can use wildcards if  
    97   needed. If no user argument is used, a wildcard of '*' is assumed,  
    98   meaning include all users or groups. 
    99    
     90  -s | --start date    Sets the starting date for the print jobs invoiced. 
     91   
     92  -e | --end date      Sets the ending date for the print jobs invoiced. 
     93                        
     94  user1 through userN can use wildcards if needed. If no user argument is 
     95  used, a wildcard of '*' is assumed, meaning include all users. 
     96   
     97  Dates formating with --start and --end : 
     98   
     99    YYYY : year boundaries 
     100    YYYYMM : month boundaries 
     101    YYYYMMDD : day boundaries 
     102    YYYYMMDDhh : hour boundaries 
     103    YYYYMMDDhhmm : minute boundaries 
     104    YYYYMMDDhhmmss : second boundaries 
     105    yesterday[+-NbDays] : yesterday more or less N days (e.g. : yesterday-15) 
     106    today[+-NbDays] : today more or less N days (e.g. : today-15) 
     107    tomorrow[+-NbDays] : tomorrow more or less N days (e.g. : tomorrow-15) 
     108    now[+-NbDays] : now more or less N days (e.g. now-15) 
     109 
     110  'now' and 'today' are not exactly the same since today represents the first 
     111  or last second of the day depending on if it's used in a start= or end= 
     112  date expression. The utility to be able to specify dates in the future is 
     113  a question which remains to be answered :-) 
     114                                         
    100115examples :                        
    101116 
    102   $ pkinvoice --reference 15.0 --unit EURO --output invoices.pdf 
    103    
    104   Will generate a PDF document containing invoices for all users whose 
    105   account balance is below 15.0 credits. For each user the amount due 
    106   will be (15.0 - AccountBalance) EURO when that value is positive.  
    107   No VAT information will be included. 
     117  $ pkinvoice --unit EURO --output invoices.pdf --start=now-30 
     118   
     119  Will generate a PDF document containing invoices for all users 
     120  who have spent some credits last month. Invoices will be done in 
     121  EURO.  No VAT information will be included. 
    108122""")  
    109123         
    110 class PKInvoice(PyKotaTool) :         
     124class PKInvoice(DumPyKota) :         
    111125    """A class for pkinvoice.""" 
    112126    def getPageSize(self, pgsize) : 
     
    120134                pass 
    121135                 
    122     def pagePDF(self, invoicenumber, name, amount, vatamount) : 
     136    def pagePDF(self, invoicenumber, entry, vat, start, end) : 
    123137        """Generates a new page in the PDF document.""" 
    124         sys.stderr.write("#%06i    %s     %.2f    %.2f\n" % (invoicenumber, name, amount, vatamount)) 
    125138        self.canvas.doForm("background") 
     139         
     140        extractonly = { "username" : entry.Name } 
     141        if start : 
     142            extractonly["start"] = start 
     143        if end :     
     144            extractonly["end"] = end 
     145        records = self.storage.extractHistory(extractonly) 
     146        amount = vatamount = 0.0 
     147        vatamount = 0.0 
     148        if records : 
     149            records = self.summarizeDatas(records, "history", extractonly, True) 
     150            fieldnames = records[0] 
     151            fields = {} 
     152            for i in range(len(fieldnames)) : 
     153                fields[fieldnames[i]] = i 
     154            numberofbytes = records[1][fields["jobsizebytes"]] 
     155            numberofpages = records[1][fields["jobsize"]] 
     156            amount = records[1][fields["jobprice"]] 
     157            if amount > 0.0 : 
     158                # There's something due ! 
     159                ht = ((amount * 10000.0) / (100.0 + vat)) / 100.0 
     160                vatamount = amount - ht 
     161            sys.stderr.write("#%06i    %s     %s    %s    %.2f    %.2f\n" % (invoicenumber, entry.Name, numberofpages, numberofbytes, amount, vatamount)) 
     162         
    126163        self.canvas.showPage() 
    127164         
    128     def initPDF(self, pagesize, logo) : 
     165    def initPDF(self, logo) : 
    129166        """Initializes the PDF document.""" 
    130167        self.pdfDocument = cStringIO.StringIO()         
    131         self.canvas = c = canvas.Canvas(self.pdfDocument, pagesize=pagesize, pageCompression=1) 
     168        self.canvas = c = canvas.Canvas(self.pdfDocument, \ 
     169                                        pagesize=self.pagesize, \ 
     170                                        pageCompression=1) 
    132171         
    133172        c.setAuthor(pwd.getpwuid(os.geteuid())[0]) 
     
    135174        c.setSubject("This is an invoice generated with PyKota") 
    136175         
    137         xcenter = pagesize[0] / 2.0 
    138         ycenter = pagesize[1] / 2.0 
     176        xcenter = self.pagesize[0] / 2.0 
     177        ycenter = self.pagesize[1] / 2.0 
    139178                     
    140         ypos = pagesize[1] - (2 * cm)             
     179        ypos = self.pagesize[1] - (2 * cm)             
    141180         
    142181        self.canvas.beginForm("background") 
     
    158197         
    159198        # New top 
    160         xpos = pagesize[0] / 5.0 
     199        xpos = self.pagesize[0] / 5.0 
    161200        ypos -= (1 * cm) + 20 
    162201         
     
    193232             
    194233        try :     
    195             reference = float(options["reference"]) 
    196         except :     
    197             raise PyKotaCommandLineError, _("Incorrect value '%s' for the --reference command line option") % options["reference"] 
    198              
    199         try :     
    200234            number = float(options["number"]) 
    201235            if number <= 0 : 
     
    204238            raise PyKotaCommandLineError, _("Incorrect value '%s' for the --number command line option") % options["number"] 
    205239             
    206         pagesize = self.getPageSize(options["pagesize"]) 
    207         if pagesize is None : 
    208             pagesize = self.getPageSize("a4") 
     240        self.pagesize = self.getPageSize(options["pagesize"]) 
     241        if self.pagesize is None : 
     242            self.pagesize = self.getPageSize("a4") 
    209243            self.printInfo(_("Invalid 'pagesize' option %s, defaulting to A4.") % options["pagesize"], "warn") 
    210244             
     
    216250            self.display("%s...\n" % _("Processing")) 
    217251             
    218         suffix = (options["groups"] and "Group") or "User"         
    219         entries = getattr(self.storage, "getMatching%ss" % suffix)(",".join(names)) 
     252        entries = self.storage.getMatchingUsers(",".join(names)) 
    220253        if entries : 
    221             self.initPDF(pagesize, options["logo"].strip()) 
     254            self.initPDF(options["logo"].strip()) 
    222255            nbtotal = len(entries) 
    223256            for i in range(nbtotal) : 
    224257                entry = entries[i] 
    225                 amount = reference - entry.AccountBalance 
    226                 if amount > 0.0 : 
    227                     # There's something due ! 
    228                     ht = ((amount * 10000.0) / (100.0 + vat)) / 100.0 
    229                     vatamount = amount - ht 
    230                     self.pagePDF(number, entry.Name, amount, vatamount) 
    231                     number += 1 
     258                self.pagePDF(number, entry, vat, options["start"], options["end"]) 
     259                number += 1 
    232260                if outfname != "-" : 
    233261                    percent = 100.0 * float(i) / float(nbtotal) 
     
    243271    retcode = 0 
    244272    try : 
    245         defaults = { "reference" : "0.0", 
    246                      "vat" : "0.0", 
     273        defaults = { "vat" : "0.0", 
    247274                     "unit" : N_("Credits"), 
    248275                     "output" : "-", 
     
    251278                     "number" : "1", 
    252279                   } 
    253         short_options = "vho:gr:u:V:p:l:n:" 
    254         long_options = ["help", "version", \ 
    255                         "groups", "reference=", "unit=", "output=", \ 
     280        short_options = "vho:r:u:V:p:l:n:s:e:" 
     281        long_options = ["help", "version", "start=", "end=", \ 
     282                        "reference=", "unit=", "output=", \ 
    256283                        "pagesize=", "logo=", "vat=", "number="] 
    257284         
     
    267294        options["version"] = options["v"] or options["version"] 
    268295         
    269         options["groups"] = options["g"] or options["groups"] 
    270         options["reference"] = options["r"] or options["reference"] or defaults["reference"] 
     296        options["start"] = options["s"] or options["start"] 
     297        options["end"] = options["e"] or options["end"] 
    271298        options["vat"] = options["V"] or options["vat"] or defaults["vat"] 
    272299        options["unit"] = options["u"] or options["unit"] or defaults["unit"]