New changes.

main
emile 1 year ago
parent 5ea2208ba9
commit 7dbffeb7d9

@ -7,6 +7,7 @@ urlpatterns = [
path('service', views.add_service, name='addservice'),
path('order/<int:customer_id>/', views.add_order, name='addorder'),
path('invoice/<int:order_id>/', views.add_invoice_pdf, name='addinvoice'),
path('payment/<int:order_id>/', views.add_payment_pdf, name='addpayment'),
path('service/<int:service_id>/<int:order_id>/', views.add_service_in_order, name='addserviceinorder'),

@ -203,5 +203,51 @@ def add_invoice_pdf(request, order_id):
def add_payment_pdf(request, order_id):
order = get_object_or_404(Order, id=order_id)
payments = OrderPayment.objects.filter(order = order)
invoice = order.invoice
# Render both invoice and payment details templates to HTML
invoice_template = get_template('details_templates/invoice-details.html')
payment_template = get_template('details_templates/payment-details.html')
invoice_html = invoice_template.render({'order': order})
payment_html = payment_template.render({'order': order, 'payments':payments})
# Combine the HTML content of both templates
combined_html = f"{invoice_html}<div style='page-break-before: always;'></div>{payment_html}"
# Define CSS
css_string = '''
@font-face {
font-family: 'Poppins';
src: url('path_to_poppins_font_file.ttf') format('truetype'); /* Update the path to the font file */
}
body {
font-family: 'Poppins', sans-serif; /* Use Poppins font for the entire document */
}
/* Your existing CSS styles */
/* Add or modify styles as needed */
'''
# Generate PDF
pdf = HTML(string=combined_html).write_pdf(
stylesheets=[
CSS(string=css_string),
CSS(string='@page { margin: 30px; }')
],
presentational_hints=True
)
# Return PDF
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="my_pdf.pdf"'
return response

@ -0,0 +1,23 @@
# Generated by Django 4.2.5 on 2024-05-09 12:11
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('billing', '0045_orderpayment_date_due_alter_orderpayment_date_paid'),
]
operations = [
migrations.RemoveField(
model_name='orderpayment',
name='order',
),
migrations.AddField(
model_name='orderpayment',
name='order',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='billing.order'),
),
]

@ -109,7 +109,7 @@ class PaymentType(models.Model):
class OrderPayment(models.Model):
order = models.ManyToManyField(Order, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
amount = models.DecimalField(decimal_places=3, max_digits = 5)
date_paid = models.DateField(null=True,blank=True)
date_due = models.DateField(null=True, blank=True)

@ -129,14 +129,14 @@
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Amount
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Date Paid
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap ">
Date Due
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Date Paid
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Payment Method
@ -154,58 +154,71 @@
<!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200">
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">$20.0</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">02-12-2024</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">02-12-2024</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">Cash</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<div class="w-full flex justify-center items-center">
<div class="w-[30px] h-[30px] bg-gray-100 rounded-full flex justify-center items-center p-1 text-secondosiblue cursor-pointer hover:bg-secondosiblue hover:text-gray-100 duration-300 addPaymentCommentButton"
title="Add Comment" data-modal-url="{% url 'add_payment_comment_modal' %}">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round"
d="M12 4.5v15m7.5-7.5h-15" />
</svg>
{% for payment in payments %}
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">${{payment.amount}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{payment.date_due}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{payment.date_paid}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{payment.type}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<div class="w-full flex justify-center items-center">
<div class="w-[30px] h-[30px] bg-gray-100 rounded-full flex justify-center items-center p-1 text-secondosiblue cursor-pointer hover:bg-secondosiblue hover:text-gray-100 duration-300 addPaymentCommentButton"
title="Add Comment" data-modal-url="{% url 'add_payment_comment_modal' %}">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round"
d="M12 4.5v15m7.5-7.5h-15" />
</svg>
</div>
</div>
</div>
<!-- <p class="text-secondosiblue">Comment</p> -->
</td>
<!-- <p class="text-secondosiblue">Comment</p> -->
</td>
<td class="px-6 py-4 text-center text-sm">
<div class="flex justify-center items-center gap-3">
<div data-modal-url="{% url 'edit_payment_modal' %}" class="editPaymentButton">
<td class="px-6 py-4 text-center text-sm">
<div class="flex justify-center items-center gap-3">
<a href="{% url 'addpayment' order.id %}">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor"
class="w-[18px] text-fifthosiblue hover:scale-110 duration-500 transition-transform cursor-pointer">
<path stroke-linecap="round" stroke-linejoin="round"
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
</svg>
</div>
stroke-width="1.5" stroke="currentColor"
class="w-[18px] text-fifthosiblue hover:scale-110 duration-500 transition-transform cursor-pointer">
<path stroke-linecap="round" stroke-linejoin="round"
d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m3.75 9v6m3-3H9m1.5-12H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
</svg>
</a>
<div data-modal-url="{% url 'edit_payment_modal' %}" class="editPaymentButton">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor"
class="w-[18px] text-fifthosiblue hover:scale-110 duration-500 transition-transform cursor-pointer">
<path stroke-linecap="round" stroke-linejoin="round"
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
</svg>
</div>
<div data-modal-url="{% url 'deletepaymentmodal' %}" class="deletePaymentButton">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor"
class="w-[18px] text-red-500 hover:scale-110 duration-500 transition-transform cursor-pointer">
<path stroke-linecap="round" stroke-linejoin="round"
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
</svg>
<div data-modal-url="{% url 'deletepaymentmodal' %}" class="deletePaymentButton">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor"
class="w-[18px] text-red-500 hover:scale-110 duration-500 transition-transform cursor-pointer">
<path stroke-linecap="round" stroke-linejoin="round"
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
</svg>
</div>
</div>
</div>
</td>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

@ -0,0 +1,202 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Invoice Details</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
color: #20336b;
font-size: 16px;
margin-bottom: 10px;
}
p {
color: #374a7a;
margin-bottom: 5px;
font-size: 13px;
}
.mainContainer {
width: 100%;
display: block;
}
.logoContainer {
width: 100%;
text-align: center;
}
.logoContainer img {
width: 150px;
}
.invoiceNumberBar {
width: 100%;
background-color: #374a7a;
padding: 10px 20px;
color: white;
font-weight: 600;
text-align: start;
font-size: 18px;
margin: 30px 0px;
}
.invoiceNumberBar p {
color: white;
font-size: 15px;
}
.tableContainer {
border: 1px solid rgb(230, 230, 230);
border-radius: 5px;
}
.tableContainer table {
width: 100%;
}
.payment-header {
padding: 10px 10px;
font-size: 15px;
font-weight: lighter;
color: rgb(161, 161, 161);
border-right: 1px solid rgb(230, 230, 230);
white-space: nowrap;
width: 25%;
}
.payment-body {
width: 100%;
}
.payment-cell {
width: 25%;
padding: 10px 10px;
text-align: center;
font-size: 0.875rem;
border-right: 1px solid rgb(230, 230, 230);
color: #374a7a;
background-color: #fff;
border-top: 1px solid rgb(230, 230, 230);
}
.tableContainer {
width: 100%;
margin: 0 auto;
text-align: center;
}
.remainingAmountContainer {
width: 100%;
text-align: end;
margin-top: 50px;
color: #20336b;
font-weight: 600;
}
.remainingAmountContainer p {
font-size: 16px;
}
.payment-header-last, .payment-cell-last {
border-right: 0px !important;
}
.footer {
width: 100%;
bottom: 0;
position: absolute;
}
.footer div {
margin-top: 20px;
}
.footer p {
color: rgb(151, 151, 151);
margin-bottom: 5px;
}
.footer span {
font-weight: 600;
color: #20336b;
font-size: 13px;
}
</style>
</head>
<body>
<div class="mainContainer">
<div class="logoContainer">
<img src="https://osina.ositcom.com/static/images/ositcom_logos/full-logo.png">
</div>
<div class="invoiceNumberBar">
<p>Payment</p>
</div>
<div class="tableContainer">
<table>
<thead>
<th class="payment-header">Amount</th>
<th class="payment-header">Date Due</th>
<th class="payment-header">Date Paid</th>
<th class="payment-header payment-header-last">Payment Method</th>
</thead>
<tbody class="payment-body">
{% for payment in payments %}
<tr>
<td class="payment-cell">${{payment.amount}}</td>
<td class="payment-cell">{{payment.date_due}}</td>
<td class="payment-cell">{{payment.date_paid}}</td>
<td class="payment-cell payment-cell-last">{{payment.type}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="remainingAmountContainer">
<p>Remaining Amount: <span>$0.00</span></p>
</div>
</div>
<div class="footer">
<p>Thank you for choosing us, we hope to satisfy all your IT Requirements.</p>
<p>OSITCOM ltd</p>
<p>Optimal Solutions for IT and Communication Lebanon Jounieh Highway, Doueihy Building, 7th Floor </p>
<p>Phone: +961 (9) 918 718 - Fax: +961 (9) 918 718 - Mobile: +961 (70) 918 718</p>
<p>Box: 90-1246</p>
<p>Email: billing@ositcom.net</p>
<div >
<p>If you have any questions, please feel free to contact us at billing@ositcom.net.</p>
<span>You can now pay your invoice online through <a>https://osina.ositcom.com</a></span>
</div>
</div>
</body>
</html>

@ -17,4 +17,5 @@ urlpatterns = [
# DETAILS
path('invoices/<int:order_id>/', views.invoice_details, name='invoicedetails'),
path('orders/<int:order_id>/', views.order_details, name='orderdetails'),
path('paymyent/<int:order_id>/', views.payment_details, name='paymentdetails'),
]

@ -52,13 +52,27 @@ def order_details(request, order_id):
services = Item.objects.filter(Q(type='Service') & (Q(customer=order.customer) | Q(customer__isnull=True))).exclude(id__in=order_item_ids).order_by('-id')
products = Item.objects.filter(Q(type='Product') & (Q(customer=order.customer) | Q(customer__isnull=True))).exclude(id__in=order_item_ids).order_by('-id')
payments = OrderPayment.objects.filter(order = order).order_by('-id')
context = {
'order' : order,
'order_items' : order_items,
'services': services,
'payments' : payments,
}
return render(request, 'details_templates/order-details.html', context)
def payment_details(request, order_id):
order = get_object_or_404(Order, id=order_id)
payments = OrderPayment.objects.filter(order = order).order_by('-id')
context = {
'payments' : payments,
}
return render(request, 'details_templates/payment-details.html', context)

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save