Index: /pykota/trunk/pykota/storages/sql.py
===================================================================
--- /pykota/trunk/pykota/storages/sql.py (revision 2374)
+++ /pykota/trunk/pykota/storages/sql.py (revision 2388)
@@ -495,9 +495,9 @@
         self.doModify("UPDATE billingcodes SET description=%s WHERE id=%s" % (self.doQuote(self.userCharsetToDatabase(code.Description or "")), self.doQuote(code.ident)))
        
-    def setBillingCodeValues(self, code, newbalance, newpagecounter) :    
+    def setBillingCodeValues(self, code, newpagecounter, newbalance) :    
         """Sets the new page counter and balance for a billing code."""
         self.doModify("UPDATE billingcodes SET balance=%s, pagecounter=%s WHERE id=%s" % (self.doQuote(newbalance), self.doQuote(newpagecounter), self.doQuote(code.ident)))
        
-    def consumeBillingCode(self, code, balance, pagecounter) :
+    def consumeBillingCode(self, code, pagecounter, balance) :
         """Consumes from a billing code."""
         self.doModify("UPDATE billingcodes SET balance=balance + %s, pagecounter=pagecounter + %s WHERE id=%s" % (self.doQuote(balance), self.doQuote(pagecounter), self.doQuote(code.ident)))
Index: /pykota/trunk/pykota/storages/ldapstorage.py
===================================================================
--- /pykota/trunk/pykota/storages/ldapstorage.py (revision 2386)
+++ /pykota/trunk/pykota/storages/ldapstorage.py (revision 2388)
@@ -1420,5 +1420,5 @@
         """Returns the list of all billing codes which match a certain pattern."""
         codes = []
-        result = self.doSearch("(&(objectClass=pykotaBilling)%s)" % "".join(["(pykotaBillingCode=%s)" % self.userCharsetToDatabase(bcode) for bcode in billingcodepattern.split(",")]), \
+        result = self.doSearch("(&(objectClass=pykotaBilling)(|%s))" % "".join(["(pykotaBillingCode=%s)" % self.userCharsetToDatabase(bcode) for bcode in billingcodepattern.split(",")]), \
                                 ["pykotaBillingCode", "description", "pykotaPageCounter", "pykotaBalance"], \
                                 base=self.info["billingcodebase"])
@@ -1437,5 +1437,5 @@
         return codes        
         
-    def setBillingCodeValues(self, code, newbalance, newpagecounter) :    
+    def setBillingCodeValues(self, code, newpagecounter, newbalance) :
         """Sets the new page counter and balance for a billing code."""
         fields = {
@@ -1445,5 +1445,5 @@
         return self.doModify(code.ident, fields)         
        
-    def consumeBillingCode(self, code, balance, pagecounter) :
+    def consumeBillingCode(self, code, pagecounter, balance) :
         """Consumes from a billing code."""
         fields = {
Index: /pykota/trunk/pykota/storage.py
===================================================================
--- /pykota/trunk/pykota/storage.py (revision 2342)
+++ /pykota/trunk/pykota/storage.py (revision 2388)
@@ -304,5 +304,4 @@
                     upq.PageCounter = int(upq.PageCounter or 0) + jobsize
                     upq.LifePageCounter = int(upq.LifePageCounter or 0) + jobsize
-                # TODO : consume from the billing code as well
             except PyKotaStorageError, msg :    
                 self.parent.rollbackTransaction()
@@ -433,5 +432,5 @@
     def reset(self, balance=0.0, pagecounter=0) :    
         """Resets the pagecounter and balance for this billing code."""
-        self.parent.setBillingCodeValues(self, balance, pagecounter)
+        self.parent.setBillingCodeValues(self, pagecounter, balance)
         self.Balance = balance
         self.PageCounter = pagecounter
Index: /pykota/trunk/bin/cupspykota
===================================================================
--- /pykota/trunk/bin/cupspykota (revision 2314)
+++ /pykota/trunk/bin/cupspykota (revision 2388)
@@ -220,15 +220,15 @@
                 (chtype, clienthost) = ippmessage.operation_attributes.get("job-originating-host-name", \
                                           ippmessage.job_attributes.get("job-originating-host-name", (None, None)))
-                (jbtype, billingcode) = ippmessage.job_attributes.get("job-billing", (None, None))
+                (jbtype, bcode) = ippmessage.job_attributes.get("job-billing", (None, None))
             except AttributeError :    
                 clienthost = None
-                billingcode = None
+                bcode = None
             if clienthost is None :
-                (billingcode, clienthost) = self.getJobInfosFromPageLog(cupsdconf, printer.Name, user.Name, self.jobid)
+                (bcode, clienthost) = self.getJobInfosFromPageLog(cupsdconf, printer.Name, user.Name, self.jobid)
             self.logdebug("Client Hostname : %s" % (clienthost or "Unknown"))    
-            self.logdebug("Billing Code : %s" % (billingcode or "None"))    
+            self.logdebug("Billing Code : %s" % (bcode or "None"))    
             
             os.environ["PYKOTAJOBORIGINATINGHOSTNAME"] = str(clienthost or "")
-            os.environ["PYKOTAJOBBILLING"] = str(billingcode or "")
+            os.environ["PYKOTAJOBBILLING"] = str(bcode or "")
             
             # enters first phase
@@ -269,8 +269,32 @@
                     else :    
                         self.printMoreInfo(user, printer, _("Job is a duplicate. Printing is allowed by subprocess."), "warn")
-                        action = "ALLOW" # just to be sure, in the case the external command returns something else...
+                        action = self.warnUserPQuota(userpquota)
             else :    
                 # checks the user's quota
                 action = self.warnUserPQuota(userpquota)
+            
+            # Now handle the billing code
+            if bcode is not None :
+                billingcode = self.storage.getBillingCode(bcode)
+                if billingcode.Exists :
+                    self.logdebug("Billing code [%s] exists in database." % bcode)
+                else :
+                    msg = "Unknown billing code [%s] : " % bcode
+                    (newaction, script) = self.config.getUnknownBillingCode(printer.Name)
+                    if newaction == "CREATE" :
+                        self.logdebug(msg + "will be created.")
+                        billingcode = self.storage.addBillingCode(bcode)
+                        if billingcode.Exists :
+                            self.logdebug(msg + "has been created.")
+                        else :    
+                            self.printInfo(msg + "couldn't be created.", "error")
+                    else :    
+                        self.logdebug(msg + "job will be denied.")
+                        action = newaction
+                        if script is not None : 
+                            self.logdebug(msg + "launching subprocess [%s] to notify user." % script)
+                            os.system(script)
+            else :    
+                billingcode = None
             
             # exports some new environment variables
@@ -386,7 +410,11 @@
                                     action, jobsize, jobprice, self.preserveinputfile, \
                                     self.title, self.copies, self.options, clienthost, \
-                                    self.jobSizeBytes, self.checksum, None, billingcode)
+                                    self.jobSizeBytes, self.checksum, None, bcode)
             self.printMoreInfo(user, printer, _("Job added to history."))
             
+            if billingcode and billingcode.Exists :
+                billingcode.consume(jobsize, jobprice)
+                self.printMoreInfo(user, printer, _("Billing code %s was updated.") % billingcode.BillingCode)
+                
             # exports some new environment variables
             os.environ["PYKOTAJOBSIZE"] = str(jobsize)
