Changeset 3413 for pykota/trunk/bin/pkinvoice
- Timestamp:
- 09/27/08 22:02:37 (16 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/bin/pkinvoice
r3411 r3413 9 9 # the Free Software Foundation, either version 3 of the License, or 10 10 # (at your option) any later version. 11 # 11 # 12 12 # This program is distributed in the hope that it will be useful, 13 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 # GNU General Public License for more details. 16 # 16 # 17 17 # You should have received a copy of the GNU General Public License 18 18 # along with this program. If not, see <http://www.gnu.org/licenses/>. … … 34 34 from reportlab.lib import pagesizes 35 35 from reportlab.lib.units import cm 36 except ImportError : 36 except ImportError : 37 37 hasRL = False 38 else : 38 else : 39 39 hasRL = True 40 40 41 41 try : 42 import PIL.Image 43 except ImportError : 42 import PIL.Image 43 except ImportError : 44 44 hasPIL = False 45 else : 45 else : 46 46 hasPIL = True 47 47 … … 56 56 from pykota.tool import Percent, PyKotaTool 57 57 58 class PKInvoice(PyKotaTool) : 58 class PKInvoice(PyKotaTool) : 59 59 """A class for invoice generator.""" 60 60 validfilterkeys = [ "username", … … 66 66 "end", 67 67 ] 68 68 69 69 def printVar(self, label, value, size) : 70 70 """Outputs a variable onto the PDF canvas. 71 71 72 72 Returns the number of points to substract to current Y coordinate. 73 """ 73 """ 74 74 xcenter = (self.pagesize[0] / 2.0) - 1*cm 75 75 self.canvas.saveState() … … 82 82 self.canvas.restoreState() 83 83 self.ypos -= (size + 4) 84 84 85 85 def pagePDF(self, invoicenumber, name, values, unit, vat) : 86 86 """Generates a new page in the PDF document.""" … … 96 96 datetime = time.strftime("%c", time.localtime()).decode(self.charset, "replace") 97 97 self.printVar(_("Edited on"), datetime, 14) 98 98 99 99 self.ypos -= 20 100 100 self.printVar(_("Number of jobs printed"), str(values["nbjobs"]), 18) … … 107 107 self.canvas.showPage() 108 108 return 1 109 return 0 110 109 return 0 110 111 111 def initPDF(self, logo) : 112 112 """Initializes the PDF document.""" 113 self.pdfDocument = cStringIO.StringIO() 113 self.pdfDocument = cStringIO.StringIO() 114 114 self.canvas = c = canvas.Canvas(self.pdfDocument, \ 115 115 pagesize=self.pagesize, \ 116 116 pageCompression=1) 117 117 118 118 c.setAuthor(self.effectiveUserName) 119 119 c.setTitle(_("PyKota invoices")) 120 120 c.setSubject(_("Invoices generated with PyKota")) 121 121 122 122 self.canvas.beginForm("background") 123 123 self.canvas.saveState() 124 125 self.ypos = self.pagesize[1] - (2 * cm) 126 124 125 self.ypos = self.pagesize[1] - (2 * cm) 126 127 127 xcenter = self.pagesize[0] / 2.0 128 128 if logo : 129 try : 129 try : 130 130 imglogo = PIL.Image.open(logo) 131 except IOError : 131 except IOError : 132 132 self.printInfo("Unable to open image %s" % logo, "warn") 133 133 else : 134 134 (width, height) = imglogo.size 135 multi = float(width) / (8 * cm) 135 multi = float(width) / (8 * cm) 136 136 width = float(width) / multi 137 137 height = float(height) / multi … … 140 140 self.ypos, \ 141 141 width, height) 142 142 143 143 self.ypos -= (cm + 20) 144 144 self.canvas.setFont("Helvetica-Bold", 14) … … 146 146 msg = _("Here's the invoice for your printouts") 147 147 self.canvas.drawCentredString(xcenter, self.ypos, "%s :" % msg) 148 148 149 149 self.yorigine = self.ypos 150 150 self.canvas.restoreState() 151 151 self.canvas.endForm() 152 153 def endPDF(self, fname) : 152 153 def endPDF(self, fname) : 154 154 """Flushes the PDF generator.""" 155 155 self.canvas.save() 156 if fname != "-" : 156 if fname != "-" : 157 157 outfile = open(fname, "w") 158 158 outfile.write(self.pdfDocument.getvalue()) 159 159 outfile.close() 160 else : 160 else : 161 161 sys.stdout.write(self.pdfDocument.getvalue()) 162 162 sys.stdout.flush() 163 163 164 164 def genInvoices(self, peruser, logo, outfname, firstnumber, unit, vat) : 165 165 """Generates the invoices file.""" … … 168 168 if outfname != "-" : 169 169 percent.display("%s...\n" % _("Generating invoices")) 170 170 171 171 self.initPDF(logo) 172 172 number = firstnumber … … 175 175 if outfname != "-" : 176 176 percent.oneMore() 177 177 178 178 if number > firstnumber : 179 179 self.endPDF(outfname) 180 180 181 181 if outfname != "-" : 182 182 percent.done() 183 183 184 184 def main(self, arguments, options) : 185 185 """Generate invoices.""" … … 188 188 if not hasPIL : 189 189 raise PyKotaToolError, "The Python Imaging Library is missing. Download it from http://www.pythonware.com/downloads" 190 190 191 191 self.adminOnly() 192 192 193 193 self.pagesize = getPageSize(options.pagesize) 194 194 195 195 extractonly = {} 196 196 for filterexp in arguments : … … 200 200 filterkey = filterkey.lower() 201 201 if filterkey not in self.validfilterkeys : 202 raise ValueError 203 except ValueError : 202 raise ValueError 203 except ValueError : 204 204 raise PyKotaCommandLineError, _("Invalid filter value [%s], see help.") % filterexp 205 else : 205 else : 206 206 extractonly.update({ filterkey : filtervalue }) 207 207 208 208 percent = Percent(self) 209 209 outfname = options.output.strip().encode(sys.getfilesystemencoding()) 210 210 if outfname != "-" : 211 211 percent.display("%s..." % _("Extracting datas")) 212 213 username = extractonly.get("username") 212 213 username = extractonly.get("username") 214 214 if username : 215 215 user = self.storage.getUser(username) 216 216 else : 217 217 user = None 218 219 printername = extractonly.get("printername") 218 219 printername = extractonly.get("printername") 220 220 if printername : 221 221 printer = self.storage.getPrinter(printername) 222 else : 222 else : 223 223 printer = None 224 224 225 225 start = extractonly.get("start") 226 226 end = extractonly.get("end") 227 227 (start, end) = self.storage.cleanDates(start, end) 228 229 jobs = self.storage.retrieveHistory(user=user, 230 printer=printer, 228 229 jobs = self.storage.retrieveHistory(user=user, 230 printer=printer, 231 231 hostname=extractonly.get("hostname"), 232 232 billingcode=extractonly.get("billingcode"), … … 235 235 end=end, 236 236 limit=0) 237 238 peruser = {} 239 nbjobs = 0 240 nbpages = 0 237 238 peruser = {} 239 nbjobs = 0 240 nbpages = 0 241 241 nbcredits = 0.0 242 242 percent.setSize(len(jobs)) 243 243 if outfname != "-" : 244 244 percent.display("\n") 245 for job in jobs : 245 for job in jobs : 246 246 if job.JobSize and (job.JobAction not in ("DENY", "CANCEL", "REFUND")) : 247 247 nbpages += job.JobSize … … 256 256 if outfname != "-" : 257 257 percent.done() 258 self.genInvoices(peruser, 259 options.logo.strip().encode(sys.getfilesystemencoding()), 260 outfname, 261 options.number, 262 options.unit or _("Credits"), 258 self.genInvoices(peruser, 259 options.logo.strip().encode(sys.getfilesystemencoding()), 260 outfname, 261 options.number, 262 options.unit or _("Credits"), 263 263 options.vat) 264 if outfname != "-" : 264 if outfname != "-" : 265 265 nbusers = len(peruser) 266 266 print _("Invoiced %(nbusers)i users for %(nbjobs)i jobs, %(nbpages)i pages and %(nbcredits).3f credits") \ 267 267 % locals() 268 269 if __name__ == "__main__" : 268 269 if __name__ == "__main__" : 270 270 parser = PyKotaOptionParser(description=_("Invoice generator for PyKota."), 271 271 usage="pkinvoice [options] [filterexpr]") … … 281 281 default=u"A4", 282 282 help=_("Set the size of the page. Most well known page sizes are recognized, like 'A4' or 'Letter' to name a few. The default page size is %default.")) 283 parser.add_option("-n", "--number", 283 parser.add_option("-n", "--number", 284 284 dest="number", 285 285 type="int", … … 293 293 default=u"-", 294 294 help=_("The name of the file to which the PDF invoices will be written. If not set or set to '%default', the PDF document will be sent to the standard output.")) 295 295 296 296 # TODO : due to Python's optparse.py bug #1498146 fixed in rev 46861 297 297 # TODO : we can't use 'default=_("Credits")' for this option 298 parser.add_option("-u", "--unit", 298 parser.add_option("-u", "--unit", 299 299 dest="unit", 300 300 type="string", 301 301 help=_("The name of the unit to use on the invoices. The default value is 'Credits' or its locale translation.")) 302 303 parser.add_option("-V", "--vat", 302 303 parser.add_option("-V", "--vat", 304 304 dest="vat", 305 305 type="float", … … 308 308 default=0.0, 309 309 help=_("The value in percent of the applicable VAT to be exposed. The default is %default, meaning no VAT.")) 310 311 parser.add_filterexpression("username", _("User's name")) 312 parser.add_filterexpression("printername", _("Printer's name")) 313 parser.add_filterexpression("hostname", _("Host's name")) 314 parser.add_filterexpression("jobid", _("Job's id")) 310 311 parser.add_filterexpression("username", _("User's name")) 312 parser.add_filterexpression("printername", _("Printer's name")) 313 parser.add_filterexpression("hostname", _("Host's name")) 314 parser.add_filterexpression("jobid", _("Job's id")) 315 315 parser.add_filterexpression("billingcode", _("Job's billing code")) 316 parser.add_filterexpression("start", _("Job's date of printing")) 317 parser.add_filterexpression("end", _("Job's date of printing")) 318 319 parser.add_example('--unit EURO --output /tmp/invoices.pdf start=now-30', 316 parser.add_filterexpression("start", _("Job's date of printing")) 317 parser.add_filterexpression("end", _("Job's date of printing")) 318 319 parser.add_example('--unit EURO --output /tmp/invoices.pdf start=now-30', 320 320 _("This would generate a PDF document containing invoices for all users who have spent some credits last month. Amounts would be in EURO and not VAT information would be included.")) 321 322 run(parser, PKInvoice) 321 322 run(parser, PKInvoice)