1
0
Parcourir la source

Improved invoice template
Prevent invoice to be downloaded by anyone
Accept invoice id or number in url

Fabs il y a 11 ans
Parent
commit
9a9409856d

+ 1 - 0
coin/billing/generate_invoices.py

@@ -10,6 +10,7 @@ from coin.billing.models import Invoice, InvoiceDetail
 
 
 def generate_missing_invoices(request):
 def generate_missing_invoices(request):
 	"""
 	"""
+	TODO
 	Pour chaque abonnement (OfferSubscription):
 	Pour chaque abonnement (OfferSubscription):
 		Vérifie pour chaque période de facturation si elle a été facturée
 		Vérifie pour chaque période de facturation si elle a été facturée
 		Sinon génère la facture correspondante
 		Sinon génère la facture correspondante

+ 4 - 0
coin/billing/models.py

@@ -40,6 +40,10 @@ class Invoice(models.Model):
         total += detail.total()
         total += detail.total()
       return total.quantize(Decimal('0.01'))
       return total.quantize(Decimal('0.01'))
 
 
+    def has_owner(self, uid):
+      "Check if passed uid is owner of the invoice"
+      return self.member.ldap_cn == uid
+
     @staticmethod
     @staticmethod
     def next_invoice_number():
     def next_invoice_number():
       "Détermine un numéro de facture aléatoire"
       "Détermine un numéro de facture aléatoire"

+ 34 - 28
coin/billing/templates/billing/invoice.html

@@ -8,12 +8,10 @@
 		        size: a4 portrait;
 		        size: a4 portrait;
 		        @frame header_frame {          
 		        @frame header_frame {          
 		            -pdf-frame-content: header_content;
 		            -pdf-frame-content: header_content;
-		            -pdf-frame-border: 1;
-		            left: 50pt; width: 512pt; top: 50pt; height: 50pt;
+		            left: 50pt; width: 512pt; top: 50pt; height: 70pt;
 		        }
 		        }
 		        @frame content_frame {
 		        @frame content_frame {
-		        	-pdf-frame-border: 1;
-		            left: 50pt; width: 512pt; top: 120pt; height: 632pt;
+		            left: 50pt; width: 512pt; top: 150pt; height: 632pt;
 		        }
 		        }
 		        @frame footer_frame { 
 		        @frame footer_frame { 
 		            -pdf-frame-content: footer_content;
 		            -pdf-frame-content: footer_content;
@@ -21,13 +19,20 @@
 		            left: 50pt; width: 512pt; top: 772pt; height: 20pt;
 		            left: 50pt; width: 512pt; top: 772pt; height: 20pt;
 		        }
 		        }
 		    }
 		    }
-		    table#details {
-		    	border:1px solid black;
+		    body {
+		    	font-size: 10pt;
 		    }
 		    }
-		    table td {
-		    	padding-top:5pt;
-		    	border:1px solid red;
+		    table#details {
+		    	-pdf-keep-with-next: true;
+		    	width:100%;
 		    }
 		    }
+		    th.cell {border:0px;}
+		    .cell.result {border:0px; font-weight: bold}
+		    .cell { padding:2pt; border:1px solid #DDD; }
+		    .cell.label { width:400pt;}
+		    .cell.quantity {width:50pt;}
+		    .cell.amount {width:50pt;}
+		    .cell.total {width:50pt;}
 		</style>
 		</style>
 
 
 	</head>
 	</head>
@@ -67,29 +72,30 @@
 	<hr />
 	<hr />
 	Facture N°{{ invoice.number }}
 	Facture N°{{ invoice.number }}
 
 
-	<table id="details">
+	<table id="details" repeat="1">
 		<thead>
 		<thead>
 			<tr>
 			<tr>
-				<th></th>
-				<th>Quantité</th>
-				<th>Prix unitaire</th>
-				<th>Total</th>
+				<th class="cell label"></th>
+				<th class="cell quantity">Quantité</th>
+				<th class="cell amount">PU</th>
+				<th class="cell total">Total</th>
 			</tr>
 			</tr>
 		</thead>
 		</thead>
-		{% for detail in invoice.details.all %}
-		<tr>
-			<td>{{ detail.label }}</td>
-			<td>{{ detail.quantity }}</td>
-			<td>{{ detail.amount }}€</td>
-			<td>{{ detail.total }}€</td>
-		</tr>
-		{% endfor %}
-		<tr>
-			<td></td>
-			<td></td>
-			<td>Total TTC</td>
-			<td>{{ invoice.amount }}€</td>
-		</tr>
+		<tbody>
+			{% for detail in invoice.details.all %}
+			<tr>
+				<td class="cell label">{{ detail.label }}</td>
+				<td class="cell quantity">{{ detail.quantity }}</td>
+				<td class="cell amount">{{ detail.amount }}€</td>
+				<td class="cell total">{{ detail.total }}€</td>
+			</tr>
+			{% endfor %}
+			<tr>
+				<td class="cell result"></td>
+				<td class="cell result total_ttc" colspan="2">Total TTC</td>
+				<td class="cell result invoice_amount">{{ invoice.amount }}€</td>
+			</tr>
+		</tbody>
 	</table>
 	</table>
 
 
 
 

+ 1 - 1
coin/billing/urls.py

@@ -4,5 +4,5 @@ from coin.billing import views
 
 
 urlpatterns = patterns(
 urlpatterns = patterns(
     '',
     '',
-    url(r'^invoice/(?P<pk>\d+)/pdf$', views.invoice_pdf)
+    url(r'^invoice/(?P<id>.+)/pdf$', views.invoice_pdf)
 )
 )

+ 14 - 4
coin/billing/views.py

@@ -1,14 +1,25 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 from django.http import HttpResponse
 from django.http import HttpResponse
 from django.shortcuts import render, get_object_or_404
 from django.shortcuts import render, get_object_or_404
+from django.core.exceptions import PermissionDenied
 from coin.billing.models import Invoice
 from coin.billing.models import Invoice
 from coin.members.models import Member
 from coin.members.models import Member
 from coin.html2pdf import render_as_pdf
 from coin.html2pdf import render_as_pdf
 
 
 
 
-def invoice_pdf(request, pk):
-
-    invoice = get_object_or_404(Invoice, pk=pk)
+def invoice_pdf(request, id):
+    """
+    Renvoi une facture générée en format pdf
+    id peut être soit la pk d'une facture, soit le numero de facture
+    """
+    try:
+        invoice = Invoice.objects.get(pk=id)
+    except:
+        invoice = get_object_or_404(Invoice, number=id)   
+    
+    if not invoice.has_owner(request.user) and not request.user.is_superuser:
+        raise PermissionDenied
+    
     member = invoice.member
     member = invoice.member
 
 
     context = {"invoice": invoice, 'member':member}
     context = {"invoice": invoice, 'member':member}
@@ -20,5 +31,4 @@ def invoice_pdf(request, pk):
 
 
     response.write(pdf)
     response.write(pdf)
 
 
-    #response.write(process_latex('billing/invoice.html', context))
     return response
     return response