emile 1 year ago
parent 661aef2a0d
commit 657a6641a1

@ -6,6 +6,7 @@ from django.template.loader import get_template
from django.conf import settings
import os
from weasyprint import HTML, CSS
from django.core.files.base import ContentFile
@ -110,7 +111,6 @@ def add_order (request, *args, **kwargs):
def add_invoice_pdf(request, order_id):
order = get_object_or_404(Order, id=order_id)
@ -160,15 +160,10 @@ 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
invoice.pdf = pdf_file_path
invoice.save()
pdf_content = ContentFile(pdf)
filename = f'invoice_{invoice.invoice_number}.pdf'
invoice.pdf.save(filename, pdf_content, save=True)
# Return PDF
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="my_pdf.pdf"'

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-04-24 18:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('billing', '0042_order_due_date'),
]
operations = [
migrations.AlterField(
model_name='invoice',
name='pdf',
field=models.FileField(blank=True, null=True, upload_to='generated_invoices'),
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-04-24 18:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('billing', '0043_alter_invoice_pdf'),
]
operations = [
migrations.AlterField(
model_name='orderitem',
name='active',
field=models.BooleanField(blank=True, null=True),
),
]

@ -58,7 +58,7 @@ class Order(models.Model):
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
active = models.BooleanField(default=False, null=True)
active = models.BooleanField(null=True, blank=True)
purchased_at = models.DateField(null=True, blank=True)
end_at = models.DateField(blank=True, null=True)
terminated_at = models.DateField(blank=True, null=True)
@ -98,7 +98,7 @@ class Invoice(models.Model):
invoice_number = models.CharField(max_length=100, null=True, blank=True)
order = models.OneToOneField(Order, on_delete=models.SET_NULL, null=True)
date_created = models.DateField()
pdf = models.FileField(upload_to='uploaded_images', null=True, blank=True)
pdf = models.FileField(upload_to='generated_invoices', null=True, blank=True)
def __str__(self):
return self.invoice_number
def save(self, *args, **kwargs):

@ -135,7 +135,7 @@
<body>
<div class="mainContainer">
<div class="logoContainer">
<img src="https://newosina.osinode.com/static/images/ositcom_logos/full-logo.png">
<img src="https://osina.ositcom.com/static/images/ositcom_logos/full-logo.png">
</div>

@ -77,14 +77,18 @@
<p class="text-slate-800">{{invoice.date_created}}</p>
</td>
<td class="px-6 py-4">
<div class="w-full flex justify-center items-center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-[18px] text-blue-500">
<path fill-rule="evenodd" d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm5.845 17.03a.75.75 0 0 0 1.06 0l3-3a.75.75 0 1 0-1.06-1.06l-1.72 1.72V12a.75.75 0 0 0-1.5 0v4.19l-1.72-1.72a.75.75 0 0 0-1.06 1.06l3 3Z" clip-rule="evenodd" />
<path d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z" />
</svg>
</div>
<a href="{{invoice.pdf.url}}">
<div class="w-full flex justify-center items-center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-[18px] text-blue-500">
<path fill-rule="evenodd" d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm5.845 17.03a.75.75 0 0 0 1.06 0l3-3a.75.75 0 1 0-1.06-1.06l-1.72 1.72V12a.75.75 0 0 0-1.5 0v4.19l-1.72-1.72a.75.75 0 0 0-1.06 1.06l3 3Z" clip-rule="evenodd" />
<path d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z" />
</svg>
</div>
</a>
</td>
</tr>
{% endfor %}
</tbody>

@ -95,10 +95,12 @@
{% endif %}
{% if order.invoice %}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-[18px] text-blue-500">
<path fill-rule="evenodd" d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm5.845 17.03a.75.75 0 0 0 1.06 0l3-3a.75.75 0 1 0-1.06-1.06l-1.72 1.72V12a.75.75 0 0 0-1.5 0v4.19l-1.72-1.72a.75.75 0 0 0-1.06 1.06l3 3Z" clip-rule="evenodd" />
<path d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z" />
</svg>
<a href="{{order.invoice.pdf.url}}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-[18px] text-blue-500">
<path fill-rule="evenodd" d="M5.625 1.5H9a3.75 3.75 0 0 1 3.75 3.75v1.875c0 1.036.84 1.875 1.875 1.875H16.5a3.75 3.75 0 0 1 3.75 3.75v7.875c0 1.035-.84 1.875-1.875 1.875H5.625a1.875 1.875 0 0 1-1.875-1.875V3.375c0-1.036.84-1.875 1.875-1.875Zm5.845 17.03a.75.75 0 0 0 1.06 0l3-3a.75.75 0 1 0-1.06-1.06l-1.72 1.72V12a.75.75 0 0 0-1.5 0v4.19l-1.72-1.72a.75.75 0 0 0-1.06 1.06l3 3Z" clip-rule="evenodd" />
<path d="M14.25 5.25a5.23 5.23 0 0 0-1.279-3.434 9.768 9.768 0 0 1 6.963 6.963A5.23 5.23 0 0 0 16.5 7.5h-1.875a.375.375 0 0 1-.375-.375V5.25Z" />
</svg>
</a>
{% endif %}

@ -0,0 +1,59 @@
# Generated by Django 4.2.5 on 2024-04-24 19:30
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('osinacore', '0075_remove_ticketattachment_ticket_and_more'),
('billing', '0044_alter_orderitem_active'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Ticket',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=400)),
('description', models.TextField(blank=True, null=True)),
('regarding', models.CharField(choices=[('General/Account/Billing', 'General/Account/Billing'), ('Project/Product', 'Project/Product')], max_length=50, null=True)),
('opened_date', models.DateTimeField()),
('department', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='osinacore.department')),
('opened_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
('product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='billing.item')),
('project', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='osinacore.project')),
],
),
migrations.CreateModel(
name='TicketUpdate',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('description', models.TextField(blank=True, null=True)),
('date_added', models.DateTimeField()),
('added_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='customercore.ticket')),
],
),
migrations.CreateModel(
name='TicketReaction',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ticket_update', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='customercore.ticketupdate')),
],
),
migrations.CreateModel(
name='TicketAttachment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to='')),
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='customercore.ticket')),
('ticket_update', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='customercore.ticketupdate')),
],
),
]

@ -1,3 +1,39 @@
from django.db import models
from billing.models import *
# Create your models here.
class Ticket(models.Model):
REGARDING_CHOICES = (
('General/Account/Billing', 'General/Account/Billing'),
('Project/Product', 'Project/Product'),
)
title = models.CharField(max_length=400)
description = models.TextField(null=True, blank=True)
regarding = models.CharField(max_length=50, choices=REGARDING_CHOICES, null=True)
project = models.ForeignKey(Project, on_delete=models.SET_NULL, blank=True, null=True)
product = models.ForeignKey(Item, on_delete=models.SET_NULL, blank=True, null=True)
department = models.ForeignKey(Department, on_delete=models.SET_NULL,null=True)
opened_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
opened_date = models.DateTimeField()
class TicketUpdate(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
description = models.TextField(null=True, blank=True)
added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
date_added = models.DateTimeField()
class TicketAttachment(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
ticket_update = models.ForeignKey(TicketUpdate, on_delete=models.CASCADE)
file = models.FileField()
class TicketReaction(models.Model):
REGARDING_CHOICES = (
('Happy', 'Happy'),
('Indifferent', 'Indifferent'),
('Sad', 'Sad'),
)
ticket_update = models.ForeignKey(TicketUpdate, on_delete=models.CASCADE)

@ -6,14 +6,14 @@
<div class="w-full px-5 s:px-9 flex flex-col gap-3">
<div class="w-full bg-white rounded-md h-fit shadow-md p-5">
<h1 class="text-3xl text-secondosiblue text-center font-semibold">
Open Ticket
Create Ticket
</h1>
<form class="w-full flex flex-col gap-5 justify-center items-center mt-5" method="POST" action="">
{% csrf_token %}
<div class="w-full">
<label class="text-gray-500">Ticket Title:</label>
<label class="text-gray-500">Title:</label>
<input required name="title" type="text"
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md mt-1">
</div>
@ -21,12 +21,18 @@
<div class="w-full">
<label class="text-gray-500">What is this regarding?</label>
<select class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md mt-1">
<option value="">General Accounting</option>
<option value="General/Account/Billing">General/Account/Billing</option>
{% for customer_product in customer_products %}
<option value="">{{customer_product.item.title}}</option>
{% endfor %}
{% for customer_project in customer_projects %}
<option value="">{{customer_project.title}}</option>
{% endfor %}
</select>
</div>
<div class="w-full">
<label class="text-gray-500">Desceription:</label>
<label class="text-gray-500">Description:</label>
<textarea required name="description"
class="w-full py-1 px-3 border border-gray-300 outline-none rounded-md mt-1 resize-none"
rows="8"></textarea>

@ -69,14 +69,17 @@
<td class="px-6 py-4">
<div class="w-full flex justify-center items-center gap-3">
<button
class="w-fit px-3 py-2 rounded-md bg-gray-100 border border-gray-100 shadow-md cursor-pointer hover:scale-105 duration-300 transition-transform">
<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="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
</svg>
</button>
<a href="{{invoice.pdf.url}}">
<button
class="w-fit px-3 py-2 rounded-md bg-gray-100 border border-gray-100 shadow-md cursor-pointer hover:scale-105 duration-300 transition-transform">
<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="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
</svg>
</button>
</a>
{% if not invoice.order.status == 'Completed' %}

@ -59,12 +59,14 @@
</td>
<td class="px-6 py-4">
<div class="w-full flex justify-center items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-[25px] text-blue-500">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
</svg>
</div>
<a href="{{order.invoice.pdf.url}}">
<div class="w-full flex justify-center items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-[25px] text-blue-500">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
</svg>
</div>
</a>
</td>
</tr>
{% endfor %}

@ -18,7 +18,7 @@
<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">
Open Ticket
Create Ticket
</button>
</a>
</div>

@ -31,8 +31,12 @@ def redirect_osicard(request):
# ADD
@customer_login_required
def customer_add_ticket(request, *args, **kwargs):
customer_products = OrderItem.objects.filter(order__status='Completed', active__in=[True, None], item__type = 'Product', order__customer = request.user.customerprofile)
customer_projects = Project.objects.filter(customer=request.user.customerprofile)
context = {
'customer_products': customer_products,
'customer_projects': customer_projects,
}
@ -160,6 +164,15 @@ def dedicated_servers_plans(request, *args, **kwargs):
#Products Payment views
@customer_login_required
def payment(request, item_id):
item = get_object_or_404(Item, id=item_id)
@ -305,7 +318,7 @@ def check_order_status(request, merchant_id, order_id):
item.save()
order_item.save()
add_invoice_pdf(request, order_id=order.id)
return redirect('orders')
return redirect('customerorders')
error_message = 'Failed to retrieve order details: ' + response.text
return JsonResponse({'error': error_message}, status=500)
except Exception as e:
@ -399,6 +412,20 @@ def buy_free_osicard(request):
return redirect('customerorders')
#Invoice Payment views
@customer_login_required
def invoice_payment(request, invoice_id):
invoice = get_object_or_404(Invoice, id = invoice_id)

Binary file not shown.

@ -31,6 +31,7 @@ class PointAdmin(admin.ModelAdmin):
admin.site.register(Reference)
admin.site.register(Business)
admin.site.register(CustomerProfile)
admin.site.register(Department)
admin.site.register(StaffProfile)
admin.site.register(ProjectType)
admin.site.register(Project, ProjectAdmin)

@ -0,0 +1,31 @@
# Generated by Django 4.2.5 on 2024-04-24 18:31
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0069_alter_business_logo_alter_projectfile_file_and_more'),
]
operations = [
migrations.CreateModel(
name='Department',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
],
),
migrations.AlterField(
model_name='staffprofile',
name='staff_position',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='osinacore.staffposition'),
),
migrations.AddField(
model_name='staffposition',
name='department',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='osinacore.department'),
),
]

@ -0,0 +1,33 @@
# Generated by Django 4.2.5 on 2024-04-24 18:36
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('osinacore', '0070_department_alter_staffprofile_staff_position_and_more'),
]
operations = [
migrations.AddField(
model_name='projecttype',
name='department',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='osinacore.department'),
),
migrations.CreateModel(
name='Ticket',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=400)),
('description', models.TextField(blank=True, null=True)),
('regarding', models.CharField(choices=[('General/Account/Billing', 'General/Account/Billing'), ('Service/Product', 'Service/Product')], max_length=50, null=True)),
('opened_date', models.DateTimeField()),
('department', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='osinacore.department')),
('opened_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
],
),
]

@ -0,0 +1,42 @@
# Generated by Django 4.2.5 on 2024-04-24 18:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('osinacore', '0071_projecttype_department_ticket'),
]
operations = [
migrations.CreateModel(
name='TicketUpdate',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('description', models.TextField(blank=True, null=True)),
('dare_added', models.DateTimeField()),
('added_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='osinacore.ticket')),
],
),
migrations.CreateModel(
name='TicketReaction',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ticket_update', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='osinacore.ticketupdate')),
],
),
migrations.CreateModel(
name='TicketAttachment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to='')),
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='osinacore.ticket')),
('ticket_update', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='osinacore.ticketupdate')),
],
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-04-24 19:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0072_ticketupdate_ticketreaction_ticketattachment'),
]
operations = [
migrations.AlterField(
model_name='ticket',
name='regarding',
field=models.CharField(choices=[('General/Account/Billing', 'General/Account/Billing'), ('Project/Product', 'Project/Product')], max_length=50, null=True),
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-04-24 19:14
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0073_alter_ticket_regarding'),
]
operations = [
migrations.RenameField(
model_name='ticketupdate',
old_name='dare_added',
new_name='date_added',
),
]

@ -0,0 +1,45 @@
# Generated by Django 4.2.5 on 2024-04-24 19:29
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0074_rename_dare_added_ticketupdate_date_added'),
]
operations = [
migrations.RemoveField(
model_name='ticketattachment',
name='ticket',
),
migrations.RemoveField(
model_name='ticketattachment',
name='ticket_update',
),
migrations.RemoveField(
model_name='ticketreaction',
name='ticket_update',
),
migrations.RemoveField(
model_name='ticketupdate',
name='added_by',
),
migrations.RemoveField(
model_name='ticketupdate',
name='ticket',
),
migrations.DeleteModel(
name='Ticket',
),
migrations.DeleteModel(
name='TicketAttachment',
),
migrations.DeleteModel(
name='TicketReaction',
),
migrations.DeleteModel(
name='TicketUpdate',
),
]

@ -8,6 +8,8 @@ from django.db.models import Sum, F
from datetime import timedelta
# Create your models here.
class Reference(models.Model):
@ -93,9 +95,15 @@ class Business(models.Model):
class Department(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class StaffPosition(models.Model):
name = models.CharField(max_length=100)
department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.name
@ -106,7 +114,7 @@ class StaffProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(upload_to='uploaded_images', null=True, blank=True)
mobile_number = models.CharField(max_length=50)
staff_position = models.ForeignKey(StaffPosition, on_delete=models.CASCADE, null=True, blank=True)
staff_position = models.ForeignKey(StaffPosition, on_delete=models.SET_NULL, null=True, blank=True)
intern = models.BooleanField(default=False)
active = models.BooleanField(default=True)
staff_id = models.CharField(max_length=20, null=True, blank=True) # Allow null and blank for initial creation
@ -126,6 +134,7 @@ class StaffProfile(models.Model):
class ProjectType(models.Model):
name = models.CharField(max_length=50)
department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.name
@ -310,10 +319,6 @@ class PointActivity(models.Model):
return 0, 0, 0
class Status(models.Model):
text = models.TextField(blank=True)
date = models.CharField(max_length=40)
@ -346,4 +351,6 @@ class Connection(models.Model):
)
status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
date = models.DateTimeField(null=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)

@ -22,8 +22,8 @@
<label class="text-gray-500">Client:</label>
<select required name="customer"
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md text-gray-500 mt-1">
{% for customer in customers %}
<option value="" selected disabled>Select Client</option>
{% for customer in customers %}
<option value="{{customer.id}}">{{customer.user.first_name}} {{customer.user.last_name}}
</option>
{% endfor %}

@ -59,7 +59,7 @@
<!-- TICKETS -->
<div class="w-full h-fit bg-white rounded-md shadow-md p-5">
<h1 class="text-secondosiblue text-[25px]">Tickets</h1>
<div class="overflow-x-auto border border-gray-300 rounded-md">
<div class="overflow-x-auto border border-gray-300 rounded-md mt-3">
<table class="min-w-full divide-y">
<!-- TABLE HEADER -->
<thead class="bg-gray-50">

@ -86,14 +86,14 @@
<div class="w-full">
<label class="text-gray-500">Description:</label>
<textarea required name="details" type="text" rows="5" cols="5"
class="w-full py-3 px-3 border border-gray-300 outline-none rounded-md resize-none mt-1">Lorem ipsum dolor sit amet consectetur adipisicing elit. Illum magnam ea temporibus commodi aspernatur culpa totam similique voluptate veritatis? Odit, excepturi? Itaque suscipit libero iure corrupti consequatur soluta expedita quod?
class="w-full py-3 px-3 border border-gray-300 outline-none rounded-md resize-none mt-1">{{project.description}}
</textarea>
</div>
<div class="w-full">
<label class="text-gray-500">Start Date:</label>
<input required name="start_date" type="date" id="date" name="date"
value="2023-09-22"
value='{{project.start_date|date:"Y-m-d"}}'
class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-1">
</div>
@ -101,7 +101,7 @@
<div class="w-full">
<label class="text-gray-500">End Date:</label>
<input required name="end_date" type="date" id="date" name="date"
value="2023-10-22"
value='{{project.end_date|date:"Y-m-d"}}'
class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-2">
</div>

Loading…
Cancel
Save