New changes.

main
nataly 1 year ago
parent 79ddd0dc7f
commit 406d89696e

@ -6,5 +6,6 @@ urlpatterns = [
path('product', views.add_product, name='addproduct'), path('product', views.add_product, name='addproduct'),
path('service', views.add_service, name='addservice'), path('service', views.add_service, name='addservice'),
path('order/<int:customer_id>/', views.add_order, name='addorder'), path('order/<int:customer_id>/', views.add_order, name='addorder'),
path('invoice/<int:order_id>/', views.add_invoice_pdf, name='addinvoice'), path('invoice/<int:order_id>/', views.add_invoice_pdf, name='addinvoice'),
] ]

@ -114,6 +114,7 @@ def add_order (request, customer_id):
def add_invoice_pdf(request, order_id): def add_invoice_pdf(request, order_id):
order = get_object_or_404(Order, id=order_id) order = get_object_or_404(Order, id=order_id)
@ -163,19 +164,20 @@ def add_invoice_pdf(request, order_id):
) )
# Save PDF to a file
pdf_file_path = os.path.join(settings.MEDIA_ROOT, f'invoice_{invoice.id}.pdf')
with open(pdf_file_path, 'wb') as pdf_file:
pdf_file.write(pdf)
# Associate PDF file path with the Invoice object # Associate PDF file path with the Invoice object
pdf_content = ContentFile(pdf) invoice.pdf = pdf_file_path
filename = f'invoice_{invoice.invoice_number}.pdf' invoice.save()
invoice.pdf.save(filename, pdf_content, save=True)
# Return PDF # Return PDF
response = HttpResponse(pdf, content_type='application/pdf') response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="my_pdf.pdf"' response['Content-Disposition'] = 'attachment; filename="my_pdf.pdf"'
return response return response

@ -9,9 +9,30 @@
<p class="text-secondosiblue text-xl">Ticket <span class="font-semibold">{{ticket.ticket_number}}</span></p> <p class="text-secondosiblue text-xl">Ticket <span class="font-semibold">{{ticket.ticket_number}}</span></p>
<div class="flex justify-start items-center gap-1"> <div class="flex justify-start items-center gap-1">
<div class="w-[16px] h-[16px] rounded-full bg-red-200 border shadow-md"></div> <div class="w-[16px] h-[16px] rounded-full bg-red-200 shadow-md"></div>
<p class="text-secondosiblue font-light">Closed by Linode at 20-4-24 16:30</p> <p class="text-secondosiblue font-light">Closed by Linode at 20-4-24 16:30</p>
</div> </div>
<div class="w-full mt-3">
<p class="text-gray-500 font-light text-sm leading-7">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sagittis, risus id sollicitudin
maximus, diam velit tempus est, pulvinar cursus arcu nisi nec ligula. Nunc eleifend, est eget
lacinia semper, ligula purus scelerisque nunc, a molestie elit magna quis sem. Curabitur eget auctor
mi, vel sodales purus. Nullam odio erat, convallis sit amet feugiat molestie, fermentum sit amet
purus. Proin eget nunc eget risus tristique tempus. Donec egestas bibendum ligula sit amet porta.
</p>
</div>
<div class="w-full flex flex-wrap justify-end items-center gap-3">
<a>
<div class="flex items-center gap-1 text-secondosiblue hover:text-gray-500 duration-300 cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 text-secondosiblue">
<path stroke-linecap="round" stroke-linejoin="round" d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.699-9.941-7.81 7.81a1.5 1.5 0 0 0 2.112 2.13" />
</svg>
<p>Filename.docx</p>
</div>
</a>
</div>
</div> </div>
@ -23,25 +44,25 @@
<div> <div>
<div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100"> <div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100">
{% if update.added_by.customerprofile %} {% if update.added_by.customerprofile %}
{% if update.added_by.customerprofile.image %} {% if update.added_by.customerprofile.image %}
<img src="{{update.added_by.customerprofile.image.url}}" <img src="{{update.added_by.customerprofile.image.url}}"
class="w-full h-full rounded-full object-cover"> class="w-full h-full rounded-full object-cover">
{% else %} {% else %}
<div <div
class="w-full h-full border border-secondosiblue bg-secondosiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md"> class="w-full h-full border border-secondosiblue bg-secondosiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ update.added_by.first_name.0 }}{{ update.added_by.last_name.0 }} {{ update.added_by.first_name.0 }}{{ update.added_by.last_name.0 }}
</div> </div>
{% endif %} {% endif %}
{% elif update.added_by.staffprofile %} {% elif update.added_by.staffprofile %}
{% if update.added_by.staffprofile.image %} {% if update.added_by.staffprofile.image %}
<img src="{{update.added_by.staffprofile.image.url}}" <img src="{{update.added_by.staffprofile.image.url}}"
class="w-full h-full rounded-full object-cover"> class="w-full h-full rounded-full object-cover">
{% else %} {% else %}
<div <div
class="w-full h-full border border-osiblue bg-osiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md"> class="w-full h-full border border-osiblue bg-osiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ update.added_by.first_name.0 }}{{ update.added_by.last_name.0 }} {{ update.added_by.first_name.0 }}{{ update.added_by.last_name.0 }}
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -50,7 +71,8 @@
<div class="w-full replyContainer shadow-md"> <div class="w-full replyContainer shadow-md">
<div <div
class="w-full bg-gray-100 flex justify-between items-center gap-3 px-3 py-3 cursor-pointer rounded-t-md toggleReply"> class="w-full bg-gray-100 flex justify-between items-center gap-3 px-3 py-3 cursor-pointer rounded-t-md toggleReply">
<p class="text-secondosiblue font-light text-sm s:text-base"><span class="font-semibold">{{update.added_by.first_name}}</span> <p class="text-secondosiblue font-light text-sm s:text-base"><span
class="font-semibold">{{update.added_by.first_name}}</span>
replied {{update.date_added}}</p> replied {{update.date_added}}</p>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
@ -67,9 +89,20 @@
<div class="w-full bg-white p-5 flex flex-col gap-3 reply"> <div class="w-full bg-white p-5 flex flex-col gap-3 reply">
<p class="text-gray-500 font-light leading-8 text-[15px]"> <p class="text-gray-500 font-light leading-8 text-[15px]">
{{update.description}} {{update.description}}
</p> </p>
<div class="w-full flex flex-wrap justify-end items-center gap-3">
<a>
<div class="flex items-center gap-1 text-secondosiblue hover:text-gray-500 duration-300 cursor-pointer text-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 text-secondosiblue">
<path stroke-linecap="round" stroke-linejoin="round" d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.699-9.941-7.81 7.81a1.5 1.5 0 0 0 2.112 2.13" />
</svg>
<p>Filename.docx</p>
</div>
</a>
</div>
</div> </div>
{% if update.added_by.staffprofile %} {% if update.added_by.staffprofile %}
@ -79,15 +112,18 @@
<div class="flex justify-start items-center gap-2"> <div class="flex justify-start items-center gap-2">
<div class="w-fit h-fit rounded-full border-2 border-secondosiblue"> <div class="w-fit h-fit rounded-full border-2 border-secondosiblue">
<img src="{% static 'images/icons/happy-icon.png' %}" class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform"> <img src="{% static 'images/icons/happy-icon.png' %}"
class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform">
</div> </div>
<div class="w-fit h-fit rounded-full"> <div class="w-fit h-fit rounded-full">
<img src="{% static 'images/icons/neutral-icon.png' %}" class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform"> <img src="{% static 'images/icons/neutral-icon.png' %}"
class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform">
</div> </div>
<div class="w-fit h-fit rounded-full"> <div class="w-fit h-fit rounded-full">
<img src="{% static 'images/icons/unhappy-icon.png' %}" class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform"> <img src="{% static 'images/icons/unhappy-icon.png' %}"
class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform">
</div> </div>
</div> </div>
</div> </div>
@ -100,30 +136,31 @@
<!-- REPLYING SECTION --> <!-- REPLYING SECTION -->
<form class="flex gap-3" method="POST" action="{% url 'customeraddticketupdate' ticket.id %}" enctype="multipart/form-data"> <form class="flex gap-3" method="POST" action="{% url 'customeraddticketupdate' ticket.id %}"
enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<div> <div>
<div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100"> <div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100">
{% if request.user.customerprofile %} {% if request.user.customerprofile %}
{% if request.user.customerprofile.image %} {% if request.user.customerprofile.image %}
<img src="{{request.user.customerprofile.image.url}}" <img src="{{request.user.customerprofile.image.url}}"
class="w-full h-full rounded-full object-cover"> class="w-full h-full rounded-full object-cover">
{% else %} {% else %}
<div <div
class="w-full h-full border border-secondosiblue bg-secondosiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md"> class="w-full h-full border border-secondosiblue bg-secondosiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }} {{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div> </div>
{% endif %} {% endif %}
{% elif request.user.staffprofile %} {% elif request.user.staffprofile %}
{% if request.user.staffprofile.image %} {% if request.user.staffprofile.image %}
<img src="{{request.user.staffprofile.image.url}}" <img src="{{request.user.staffprofile.image.url}}"
class="w-full h-full rounded-full object-cover"> class="w-full h-full rounded-full object-cover">
{% else %} {% else %}
<div <div
class="w-full h-full border border-osiblue bg-osiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md"> class="w-full h-full border border-osiblue bg-osiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }} {{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -136,14 +173,18 @@
<div class="w-full flex flex-col s:flex-row justify-end items-center gap-3"> <div class="w-full flex flex-col s:flex-row justify-end items-center gap-3">
<div class="w-full s:w-[50px] h-[50px] rounded-md bg-gray-50 shadow-md border border-gray-100 flex justify-center items-center p-2 cursor-pointer relative hover:scale-105 duration-300 transition-transform"> <div
class="w-full s:w-[50px] h-[50px] rounded-md bg-gray-50 shadow-md border border-gray-100 flex justify-center items-center p-2 cursor-pointer relative hover:scale-105 duration-300 transition-transform">
<input type="file" name="file" id="fileInput" class="opacity-0"> <input type="file" name="file" id="fileInput" class="opacity-0">
<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 text-secondosiblue z-10 absolute pointer-events-none"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
<path stroke-linecap="round" stroke-linejoin="round" d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.699-9.941-7.81 7.81a1.5 1.5 0 0 0 2.112 2.13" /> stroke="currentColor"
class="w-5 h-5 text-secondosiblue z-10 absolute pointer-events-none">
<path stroke-linecap="round" stroke-linejoin="round"
d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.699-9.941-7.81 7.81a1.5 1.5 0 0 0 2.112 2.13" />
</svg> </svg>
</div> </div>
<button <button
class="w-full s:w-fit bg-secondosiblue border border-secondosiblue text-white rounded-md cursor-pointer hover:bg-white hover:text-secondosiblue duration-300 px-9 py-3"> class="w-full s:w-fit bg-secondosiblue border border-secondosiblue text-white rounded-md cursor-pointer hover:bg-white hover:text-secondosiblue duration-300 px-9 py-3">
Send Send

@ -11,20 +11,21 @@
<div class="w-full flex flex-col gap-3 mt-4"> <div class="w-full flex flex-col gap-3 mt-4">
<div class="w-full bg-gray-200 rounded-md shadow-md h-fit p-3 flex items-center justify-between gap-5"> <div class="w-full bg-gray-200 rounded-md shadow-md h-fit p-3 flex items-center justify-between gap-5">
<div class="flex items-center gap-5 text-[17px]"> <div class="flex items-center gap-5 text-[17px]">
<p class="text-secondosiblue font-semibold cursor-pointer">Open Tickets</p> <p class="text-secondosiblue font-semibold cursor-pointer" id="openTicketsLink">Open Tickets</p>
<p class="text-gray-500 cursor-pointer">Closed Tickets</p> <p class="text-gray-500 cursor-pointer" id="closedTicketsLink">Closed Tickets</p>
</div> </div>
<a href="{% url 'customeraddticket' %}"> <a href="{% url 'customeraddticket' %}">
<button class="w-fit px-5 py-2 bg-osiblue border border-osiblue text-white rounded-md cursor-pointer hover:bg-white hover:text-secondosiblue duration-300"> <button
class="w-fit px-5 py-2 bg-osiblue border border-osiblue text-white rounded-md cursor-pointer hover:bg-white hover:text-secondosiblue duration-300">
Create Ticket Create Ticket
</button> </button>
</a> </a>
</div> </div>
<div class="overflow-x-auto border border-gray-300 rounded-md"> <!-- OPEN TICKETS -->
<div class="overflow-x-auto border border-gray-300 rounded-md" id="openTickets">
<table class="min-w-full divide-y"> <table class="min-w-full divide-y">
<!-- TABLE HEADER --> <!-- TABLE HEADER -->
<thead class="bg-gray-50"> <thead class="bg-gray-50">
@ -45,51 +46,143 @@
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap"> class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Date Created Date Created
</th> </th>
<th scope="col" class="px-6 py-3 text-sm font-medium text-gray-500 border-r border-gray-300 uppercase whitespace-nowrap"> <th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 border-r border-gray-300 uppercase whitespace-nowrap">
Last Updated Last Updated
</th> </th>
<th scope="col" class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap"> <th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 border-r border-gray-300 uppercase whitespace-nowrap">
Updated By Updated By
</th> </th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
Unread
</th>
</tr> </tr>
</thead> </thead>
<!-- TABLE BODY --> <!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200"> <tbody class="bg-white divide-y divide-gray-200">
{% for ticket in open_tickets %}
<tr> <tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300"> <td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<a href=""> <a href="{% url 'customerticketdetails' ticket.ticket_number %}">
<p class="text-secondosiblue cursor-pointer hover:text-gray-500 duration-300">My Account Balance</p> <p class="text-secondosiblue cursor-pointer hover:text-gray-500 duration-300">{{ticket.title }}</p>
</a> </a>
</td> </td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300"> <td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">22666766</p> <p class="text-secondosiblue">{{ ticket.ticket_number }}</p>
</td> </td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300"> <td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">Django</p> <p class="text-secondosiblue">{{ ticket.regarding }}</p>
</td> </td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300"> <td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">20-2-2024</p> <p class="text-secondosiblue">{{ ticket.opened_date }}</p>
</td> </td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300"> <td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">20-2-2024</p> <p class="text-secondosiblue">{{ ticket.last_updated }}</p>
</td> </td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{ ticket.updated_by }}</p>
</td>
<td class="px-6 py-4 text-center text-sm"> <td class="px-6 py-4 text-center text-sm">
<p class="text-secondosiblue">Ositcom Ltd</p> <div class="w-full flex justify-center items-center">
<div class="w-[40px] h-[40px] rounded-full border-2 border-secondosiblue flex justify-center items-center">
<p class="text-secondosiblue">2</p>
</div>
</div>
</td> </td>
</tr> </tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
</div>
<!-- CLOSED TICKETS -->
<div class="overflow-x-auto border border-gray-300 rounded-md hidden" id="closedTickets">
<table class="min-w-full divide-y">
<!-- TABLE HEADER -->
<thead class="bg-gray-50">
<tr>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Subject
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Ticket ID
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Regarding
</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 Created
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 border-r border-gray-300 uppercase whitespace-nowrap">
Last Updated
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
Updated By
</th>
</tr>
</thead>
<!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200">
{% for ticket in closed_tickets %}
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<a href="{% url 'customerticketdetails' ticket.ticket_number %}">
<p class="text-secondosiblue cursor-pointer hover:text-gray-500 duration-300">{{ticket.title }}</p>
</a>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{ ticket.ticket_number }}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{ ticket.regarding }}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{ ticket.opened_date }}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{ ticket.last_updated }}</p>
</td>
<td class="px-6 py-4 text-center text-sm">
<p class="text-secondosiblue">{{ ticket.updated_by }}</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div> </div>
</div> </div>
<!---------------------- JS SCRIPTS -------------------->
<script type="text/javascript" src='{% static "js/customer_dashboard/tickets-filtering.js" %}'></script>
{% endblock %} {% endblock %}

Binary file not shown.

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

Loading…
Cancel
Save