Changeset 3090 for pykota/trunk/bin
- Timestamp:
- 11/30/06 22:47:26 (18 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/bin/pkinvoice
r3083 r3090 47 47 hasPIL = 1 48 48 49 from pykota.tool import Percent, PyKotaToolError, PyKotaCommandLineError, crashed, N_ 50 from pykota.dumper import DumPyKota 49 from pykota.tool import Percent, PyKotaTool, PyKotaToolError, PyKotaCommandLineError, crashed, N_ 51 50 52 51 __doc__ = N_("""pkinvoice v%(__version__)s (c) %(__years__)s %(__author__)s … … 56 55 command line usage : 57 56 58 pkinvoice [options] user1 user2 ... userN57 pkinvoice [options] [filterexpr] 59 58 60 59 options : … … 86 85 exposed. The default is 0.0, meaning no VAT 87 86 information will be included. 87 88 89 Use the filter expressions to extract only parts of the 90 datas. Allowed filters are of the form : 91 92 key=value 93 94 Allowed keys for now are : 88 95 89 -s | --start date Sets the starting date for the print jobs invoiced. 90 91 -e | --end date Sets the ending date for the print jobs invoiced. 92 93 user1 through userN can use wildcards if needed. If no user argument is 94 used, a wildcard of '*' is assumed, meaning include all users. 95 96 Dates formatting with --start and --end : 96 username User's name 97 printername Printer's name 98 hostname Client's hostname 99 jobid Job's Id 100 billingcode Job's billing code 101 start Job's date of printing 102 end Job's date of printing 103 104 Dates formatting with 'start' and 'end' filter keys : 97 105 98 106 YYYY : year boundaries … … 111 119 date expression. The utility to be able to specify dates in the future is 112 120 a question which remains to be answered :-) 113 114 examples : 115 116 $ pkinvoice --unit EURO --output invoices.pdf --start=now-30 121 122 Contrary to other PyKota management tools, wildcard characters are not 123 expanded, so you can't use them. 124 125 examples : 126 127 $ pkinvoice --unit EURO --output /tmp/invoices.pdf start=now-30 117 128 118 129 Will generate a PDF document containing invoices for all users … … 121 132 """) 122 133 123 class PKInvoice(DumPyKota) : 124 """A class for pkinvoice.""" 134 class PKInvoice(PyKotaTool) : 135 """A class for invoice generator.""" 136 validfilterkeys = [ "username", 137 "printername", 138 "hostname", 139 "jobid", 140 "billingcode", 141 "start", 142 "end", 143 ] 144 125 145 def getPageSize(self, pgsize) : 126 146 """Returns the correct page size or None if not found.""" … … 149 169 self.ypos -= (size + 4) 150 170 151 def pagePDF(self, invoicenumber, entry, vat, start, end, unitname) :171 def pagePDF(self, invoicenumber, name, values, unit, vat) : 152 172 """Generates a new page in the PDF document.""" 153 extractonly = { "username" : entry.Name } 154 if start : 155 extractonly["start"] = start 156 if end : 157 extractonly["end"] = end 158 records = self.storage.extractHistory(extractonly) 159 amount = vatamount = 0.0 160 vatamount = 0.0 161 if records : 173 amount = values["nbcredits"] 174 if amount : # is there's something due ? 175 ht = ((amount * 10000.0) / (100.0 + vat)) / 100.0 176 vatamount = amount - ht 162 177 self.canvas.doForm("background") 163 178 self.ypos = self.yorigine - (cm + 20) 164 records = self.summarizeDatas(records, "history", extractonly, True) 165 fieldnames = records[0] 166 fields = {} 167 for i in range(len(fieldnames)) : 168 fields[fieldnames[i]] = i 169 numberofbytes = records[1][fields["jobsizebytes"]] 170 numberofpages = records[1][fields["jobsize"]] 171 amount = records[1][fields["jobprice"]] 172 if amount > 0.0 : 173 # There's something due ! 174 ht = ((amount * 10000.0) / (100.0 + vat)) / 100.0 175 vatamount = amount - ht 176 self.printVar(_("Invoice"), "#%s" % invoicenumber, 22) 177 self.printVar(_("Username"), entry.Name, 22) 178 self.ypos -= 20 179 if start : 180 self.printVar(_("Since"), start, 14) 181 if end : 182 self.printVar(_("Until"), end, 14) 183 self.printVar(_("Edited on"), time.strftime("%c", time.localtime()), 14) 184 185 self.ypos -= 20 186 # self.printVar(_("Number of bytes"), str(numberofbytes), 14) 187 self.printVar(_("Number of pages printed"), str(numberofpages), 14) 188 self.ypos -= 20 189 self.printVar(_("Amount due"), "%.3f %s" % (amount, unitname), 22) 190 if vat : 191 self.ypos += 8 192 self.printVar("%s (%.2f%%)" % (_("Included VAT"), vat), "%.3f %s" % (vatamount, unitname), 14) 193 self.canvas.showPage() 194 return 1 179 self.printVar(_("Invoice"), "#%s" % invoicenumber, 22) 180 self.printVar(_("Username"), name, 22) 181 self.ypos -= 20 182 self.printVar(_("Edited on"), time.strftime("%c", time.localtime()), 14) 183 184 self.ypos -= 20 185 self.printVar(_("Number of jobs printed"), str(values["nbjobs"]), 18) 186 self.printVar(_("Number of pages printed"), str(values["nbpages"]), 18) 187 self.ypos -= 20 188 self.printVar(_("Amount due"), "%.3f %s" % (amount, unit), 18) 189 if vat : 190 self.ypos += 8 191 self.printVar("%s (%.2f%%)" % (_("Included VAT"), vat), "%.3f %s" % (vatamount, unit), 14) 192 self.canvas.showPage() 193 return 1 195 194 return 0 196 195 … … 202 201 pageCompression=1) 203 202 204 c.setAuthor( pwd.getpwuid(os.geteuid())[0])203 c.setAuthor(self.originalUserName) 205 204 c.setTitle("PyKota invoices") 206 205 c.setSubject("Invoices generated with PyKota") 207 208 206 209 207 self.canvas.beginForm("background") … … 216 214 try : 217 215 imglogo = PIL.Image.open(logo) 218 except :216 except IOError : 219 217 self.printInfo("Unable to open image %s" % logo, "warn") 220 218 else : … … 249 247 sys.stdout.flush() 250 248 251 def main(self, names, options) : 249 def genInvoices(self, peruser, logo, outfname, firstnumber, unit, vat) : 250 """Generates the invoices file.""" 251 if len(peruser) : 252 percent = Percent(self) 253 percent.setSize(len(peruser)) 254 if outfname != "-" : 255 percent.display("%s...\n" % _("Generating invoices")) 256 257 self.initPDF(logo) 258 number = firstnumber 259 for (name, values) in peruser.items() : 260 number += self.pagePDF(number, name, values, unit, vat) 261 if outfname != "-" : 262 percent.oneMore() 263 264 if number > firstnumber : 265 self.endPDF(outfname) 266 267 if outfname != "-" : 268 percent.done() 269 270 def main(self, arguments, options) : 252 271 """Generate invoices.""" 253 272 if not hasRL : … … 278 297 self.printInfo(_("Invalid 'pagesize' option %s, defaulting to A4.") % options["pagesize"], "warn") 279 298 280 if not names : 281 names = [ "*" ] 299 extractonly = {} 300 for filterexp in arguments : 301 if filterexp.strip() : 302 try : 303 (filterkey, filtervalue) = [part.strip() for part in filterexp.split("=")] 304 filterkey = filterkey.lower() 305 if filterkey not in self.validfilterkeys : 306 raise ValueError 307 except ValueError : 308 raise PyKotaCommandLineError, _("Invalid filter value [%s], see help.") % filterexp 309 else : 310 extractonly.update({ filterkey : filtervalue }) 282 311 283 312 percent = Percent(self) 284 outfname = options["output"] 313 outfname = options["output"].strip() 285 314 if outfname != "-" : 286 315 percent.display("%s..." % _("Extracting datas")) 287 entries = self.storage.getMatchingUsers(",".join(names)) 288 percent.setSize(len(entries)) 289 if entries : 290 percent.display("\n%s\n" % _("Generating invoices")) 291 self.initPDF(options["logo"].strip()) 292 for entry in entries : 293 number += self.pagePDF(number, entry, vat, options["start"], options["end"], options["unit"]) 316 317 username = extractonly.get("username") 318 if username : 319 user = self.storage.getUser(username) 320 else : 321 user = None 322 323 printername = extractonly.get("printername") 324 if printername : 325 printer = self.storage.getPrinter(printername) 326 else : 327 printer = None 328 329 start = extractonly.get("start") 330 end = extractonly.get("end") 331 (start, end) = self.storage.cleanDates(start, end) 332 333 jobs = self.storage.retrieveHistory(user=user, 334 printer=printer, 335 hostname=extractonly.get("hostname"), 336 billingcode=extractonly.get("billingcode"), 337 jobid=extractonly.get("jobid"), 338 start=start, 339 end=end, 340 limit=0) 341 342 peruser = {} 343 nbjobs = 0 344 nbpages = 0 345 nbcredits = 0.0 346 percent.setSize(len(jobs)) 347 if outfname != "-" : 348 percent.display("\n") 349 for job in jobs : 350 if job.JobSize and (job.JobAction not in ("DENY", "CANCEL", "REFUND")) : 351 nbpages += job.JobSize 352 nbcredits += job.JobPrice 353 counters = peruser.setdefault(job.UserName, { "nbjobs" : 0, "nbpages" : 0, "nbcredits" : 0.0 }) 354 counters["nbpages"] += job.JobSize 355 counters["nbcredits"] += job.JobPrice 356 counters["nbjobs"] += 1 357 nbjobs += 1 294 358 if outfname != "-" : 295 359 percent.oneMore() 296 297 if number > firstnumber :298 self.endPDF(outfname)299 300 360 if outfname != "-" : 301 361 percent.done() 362 self.genInvoices(peruser, options["logo"].strip(), outfname, firstnumber, options["unit"], vat) 363 if outfname != "-" : 364 print _("Invoiced %i users for %i jobs, %i pages and %.3f credits") % (len(peruser), nbjobs, nbpages, nbcredits) 302 365 303 366 if __name__ == "__main__" : … … 311 374 "number" : "1", 312 375 } 313 short_options = "vho:u:V:p:l:n:s:e:" 314 long_options = ["help", "version", "start=", "end=", \ 315 "unit=", "output=", \ 376 short_options = "vho:u:V:p:l:n:" 377 long_options = ["help", "version", "unit=", "output=", \ 316 378 "pagesize=", "logo=", "vat=", "number="] 317 379 … … 327 389 options["version"] = options["v"] or options["version"] 328 390 329 options["start"] = options["s"] or options["start"]330 options["end"] = options["e"] or options["end"]331 391 options["vat"] = options["V"] or options["vat"] or defaults["vat"] 332 392 options["unit"] = options["u"] or options["unit"] or defaults["unit"]