diff --git a/osinaweb/billing/__pycache__/models.cpython-310.pyc b/osinaweb/billing/__pycache__/models.cpython-310.pyc index c7c0d551..1a834899 100644 Binary files a/osinaweb/billing/__pycache__/models.cpython-310.pyc and b/osinaweb/billing/__pycache__/models.cpython-310.pyc differ diff --git a/osinaweb/billing/__pycache__/urls.cpython-310.pyc b/osinaweb/billing/__pycache__/urls.cpython-310.pyc index 50de5028..5855b97f 100644 Binary files a/osinaweb/billing/__pycache__/urls.cpython-310.pyc and b/osinaweb/billing/__pycache__/urls.cpython-310.pyc differ diff --git a/osinaweb/billing/__pycache__/views.cpython-310.pyc b/osinaweb/billing/__pycache__/views.cpython-310.pyc index 9d21722b..66fe0c6e 100644 Binary files a/osinaweb/billing/__pycache__/views.cpython-310.pyc and b/osinaweb/billing/__pycache__/views.cpython-310.pyc differ diff --git a/osinaweb/billing/add/__pycache__/urls.cpython-310.pyc b/osinaweb/billing/add/__pycache__/urls.cpython-310.pyc index 0092be93..22099650 100644 Binary files a/osinaweb/billing/add/__pycache__/urls.cpython-310.pyc and b/osinaweb/billing/add/__pycache__/urls.cpython-310.pyc differ diff --git a/osinaweb/billing/add/__pycache__/views.cpython-310.pyc b/osinaweb/billing/add/__pycache__/views.cpython-310.pyc index 2860681e..1900e620 100644 Binary files a/osinaweb/billing/add/__pycache__/views.cpython-310.pyc and b/osinaweb/billing/add/__pycache__/views.cpython-310.pyc differ diff --git a/osinaweb/billing/add/urls.py b/osinaweb/billing/add/urls.py index c29906c6..304ba24f 100644 --- a/osinaweb/billing/add/urls.py +++ b/osinaweb/billing/add/urls.py @@ -6,4 +6,5 @@ urlpatterns = [ path('product', views.add_product, name='addproduct'), path('service', views.add_service, name='addservice'), path('order', views.add_order, name='addorder'), + path('invoice//', views.add_invoice_pdf, name='addinvoice'), ] diff --git a/osinaweb/billing/add/views.py b/osinaweb/billing/add/views.py index 48cff91f..29dfe06c 100644 --- a/osinaweb/billing/add/views.py +++ b/osinaweb/billing/add/views.py @@ -4,6 +4,8 @@ from billing.models import * from django.http import JsonResponse, HttpResponse from django.template.loader import get_template from weasyprint import HTML +from django.conf import settings +import os def add_product (request, *args, **kwargs): @@ -36,14 +38,61 @@ def add_product (request, *args, **kwargs): def add_service (request, *args, **kwargs): - context = { + item_types = ProjectType.objects.all().order_by('name') + customers = CustomerProfile.objects.all().order_by('user__first_name') + if request.method == 'POST': + title = request.POST.get('title') + description = request.POST.get('description') + customer_id = request.POST.get('customer') + customer = get_object_or_404(CustomerProfile, id=customer_id) + + item_type_id = request.POST.get('item_type') + item_type = get_object_or_404(ProjectType, id=item_type_id) + + amount = request.POST.get('amount') + recurring = request.POST.get('recurring') + + Item.objects.create( + type='Service', + title=title, + description = description, + customer = customer, + item_type = item_type, + amount = amount, + recurring = recurring, + ) + return redirect('items') + context = { + 'item_types' : item_types, + 'customers' : customers } return render(request, 'add_templates/add-service.html', context) def add_order (request, *args, **kwargs): customers = CustomerProfile.objects.all().order_by('-id') + if request.method == 'POST': + customer_id = request.POST.get('customer') + customer = get_object_or_404(CustomerProfile, id=customer_id) + + status = request.POST.get('status') + + customer_id = request.POST.get('customer') + customer = get_object_or_404(CustomerProfile, id=customer_id) + + selected_items = request.POST.getlist('items') + + order = Order.objects.create( + customer=customer, + status=status + ) + + for item_id in selected_items: + item = Item.objects.get(id=item_id) + OrderItem.objects.create(order=order, item=item, purchased_at=datetime.now()) + return redirect('orders') + context = { 'customers': customers, @@ -52,12 +101,35 @@ def add_order (request, *args, **kwargs): return render(request, 'add_templates/add-order.html', context) -def add_invoice_pdf(request): + +def add_invoice_pdf(request, order_id): + order = get_object_or_404(Order, id=order_id) + template = get_template('details_templates/invoice-details.html') - context = {} + context = {'order': order} html_string = template.render(context) + # Generate PDF pdf = HTML(string=html_string).write_pdf() + + invoice = Invoice.objects.create( + invoice_number='111', + order=order, + date_created=datetime.now(), + ) + + # 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() + + # Return PDF response = HttpResponse(pdf, content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename="my_pdf.pdf"' - return response \ No newline at end of file + + return response + diff --git a/osinaweb/billing/migrations/0028_remove_order_due_date.py b/osinaweb/billing/migrations/0028_remove_order_due_date.py new file mode 100644 index 00000000..4dba5ca4 --- /dev/null +++ b/osinaweb/billing/migrations/0028_remove_order_due_date.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.5 on 2024-04-13 09:41 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0027_item_type'), + ] + + operations = [ + migrations.RemoveField( + model_name='order', + name='due_date', + ), + ] diff --git a/osinaweb/billing/migrations/0029_invoice_pdf.py b/osinaweb/billing/migrations/0029_invoice_pdf.py new file mode 100644 index 00000000..8850af53 --- /dev/null +++ b/osinaweb/billing/migrations/0029_invoice_pdf.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-04-13 10:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0028_remove_order_due_date'), + ] + + operations = [ + migrations.AddField( + model_name='invoice', + name='pdf', + field=models.FileField(blank=True, null=True, upload_to=''), + ), + ] diff --git a/osinaweb/billing/migrations/0030_alter_invoice_order.py b/osinaweb/billing/migrations/0030_alter_invoice_order.py new file mode 100644 index 00000000..6af90a6a --- /dev/null +++ b/osinaweb/billing/migrations/0030_alter_invoice_order.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.5 on 2024-04-13 10:25 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0029_invoice_pdf'), + ] + + operations = [ + migrations.AlterField( + model_name='invoice', + name='order', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='billing.order'), + ), + ] diff --git a/osinaweb/billing/migrations/0031_alter_invoice_invoice_number.py b/osinaweb/billing/migrations/0031_alter_invoice_invoice_number.py new file mode 100644 index 00000000..3890eb47 --- /dev/null +++ b/osinaweb/billing/migrations/0031_alter_invoice_invoice_number.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-04-13 10:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('billing', '0030_alter_invoice_order'), + ] + + operations = [ + migrations.AlterField( + model_name='invoice', + name='invoice_number', + field=models.CharField(max_length=100, null=True), + ), + ] diff --git a/osinaweb/billing/migrations/__pycache__/0028_remove_order_due_date.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0028_remove_order_due_date.cpython-310.pyc new file mode 100644 index 00000000..9010c15b Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0028_remove_order_due_date.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0029_invoice_pdf.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0029_invoice_pdf.cpython-310.pyc new file mode 100644 index 00000000..a7c3c738 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0029_invoice_pdf.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0030_alter_invoice_order.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0030_alter_invoice_order.cpython-310.pyc new file mode 100644 index 00000000..a783736f Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0030_alter_invoice_order.cpython-310.pyc differ diff --git a/osinaweb/billing/migrations/__pycache__/0031_alter_invoice_invoice_number.cpython-310.pyc b/osinaweb/billing/migrations/__pycache__/0031_alter_invoice_invoice_number.cpython-310.pyc new file mode 100644 index 00000000..30963540 Binary files /dev/null and b/osinaweb/billing/migrations/__pycache__/0031_alter_invoice_invoice_number.cpython-310.pyc differ diff --git a/osinaweb/billing/models.py b/osinaweb/billing/models.py index 0df4aa70..47f5e312 100644 --- a/osinaweb/billing/models.py +++ b/osinaweb/billing/models.py @@ -38,7 +38,6 @@ class Order(models.Model): customer = models.ForeignKey(CustomerProfile, on_delete=models.CASCADE) status = models.CharField(max_length=200, choices=STATUS, default='None') order_id = models.CharField(max_length=100, null=True, blank=True) - due_date = models.DateField(null=True) @property def get_cart_total(self): orderitems = self.orderitem_set.all() @@ -88,9 +87,10 @@ class OrderItem(models.Model): class Invoice(models.Model): - invoice_number = models.CharField(max_length=100) - order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True) + invoice_number = models.CharField(max_length=100, null=True) + order = models.OneToOneField(Order, on_delete=models.SET_NULL, null=True) date_created = models.DateField() + pdf = models.FileField(null=True, blank=True) def __str__(self): return self.invoice_number diff --git a/osinaweb/billing/templates/add_templates/add-order.html b/osinaweb/billing/templates/add_templates/add-order.html index 313ee4c8..4016b0bc 100644 --- a/osinaweb/billing/templates/add_templates/add-order.html +++ b/osinaweb/billing/templates/add_templates/add-order.html @@ -13,16 +13,17 @@

Add Order

+ -
+ {% csrf_token %}
-
-
- - -
-
-
-
- - -
@@ -64,7 +50,7 @@
diff --git a/osinaweb/billing/templates/add_templates/add-product.html b/osinaweb/billing/templates/add_templates/add-product.html index 00551e91..aaaacfe8 100644 --- a/osinaweb/billing/templates/add_templates/add-product.html +++ b/osinaweb/billing/templates/add_templates/add-product.html @@ -49,7 +49,7 @@
diff --git a/osinaweb/billing/templates/add_templates/add-service.html b/osinaweb/billing/templates/add_templates/add-service.html index 8635a7e8..a05f106c 100644 --- a/osinaweb/billing/templates/add_templates/add-service.html +++ b/osinaweb/billing/templates/add_templates/add-service.html @@ -8,19 +8,19 @@ Add Service - + {% csrf_token %}
-
-
@@ -28,35 +28,39 @@
-
-
-
-
diff --git a/osinaweb/billing/templates/details_templates/invoice-details.html b/osinaweb/billing/templates/details_templates/invoice-details.html index 3d84361c..cd9c52f3 100644 --- a/osinaweb/billing/templates/details_templates/invoice-details.html +++ b/osinaweb/billing/templates/details_templates/invoice-details.html @@ -16,7 +16,7 @@
-

Bill To: Winabig

+

Bill To: {{order.customer}}

Customer Details: 036466464

diff --git a/osinaweb/billing/templates/listing_pages/invoices.html b/osinaweb/billing/templates/listing_pages/invoices.html index a628b223..8c2a6720 100644 --- a/osinaweb/billing/templates/listing_pages/invoices.html +++ b/osinaweb/billing/templates/listing_pages/invoices.html @@ -79,10 +79,10 @@
- + + + +
diff --git a/osinaweb/billing/templates/listing_pages/items.html b/osinaweb/billing/templates/listing_pages/items.html index 1c1cee9d..2b18a490 100644 --- a/osinaweb/billing/templates/listing_pages/items.html +++ b/osinaweb/billing/templates/listing_pages/items.html @@ -126,22 +126,24 @@ + {% for service in services %} -

Item 2

+

{{service.title}}

-

Salim

+

{{service.customer.user.first_name}} {{service.customer.user.last_name}}

-

Type

+

{{service.item_type}}

-

222

+

${{service.amount}}

+ @@ -162,6 +164,7 @@
+ {% endfor %} diff --git a/osinaweb/billing/templates/listing_pages/orders.html b/osinaweb/billing/templates/listing_pages/orders.html index d76197d9..128aba41 100644 --- a/osinaweb/billing/templates/listing_pages/orders.html +++ b/osinaweb/billing/templates/listing_pages/orders.html @@ -42,7 +42,7 @@ - Due Date + Cart Total @@ -56,28 +56,51 @@ + + {% for order in orders %} -

1

+

{{order.order_id}}

-

Nataly

+

{{order.customer.user.first_name}} {{order.customer.user.last_name}}

-

10-2-2014

+

${{order.get_cart_total}}

- -

Paid

+ +

{{order.status}}

- + + +
+ +
+
+ + + {% if order.status == 'Completed' and not order.invoice %} + + + + + + + {% endif %} + + {% if order.invoice %} + + + + + {% endif %} +
@@ -90,6 +113,7 @@
+ {% endfor %}
diff --git a/osinaweb/billing/urls.py b/osinaweb/billing/urls.py index 36de696f..67d72391 100644 --- a/osinaweb/billing/urls.py +++ b/osinaweb/billing/urls.py @@ -12,7 +12,7 @@ urlpatterns = [ path('invoices', views.invoices, name='invoices'), # DETAILS - path('invoice-details//', views.invoice_details, name='invoicedetails'), + path('invoice-details//', views.invoice_details, name='invoicedetails'), path('fetch-customer-items//', views.fetch_customer_items, name='fetch_customer_items'), diff --git a/osinaweb/billing/views.py b/osinaweb/billing/views.py index 918ad6eb..7c9bfb66 100644 --- a/osinaweb/billing/views.py +++ b/osinaweb/billing/views.py @@ -8,23 +8,26 @@ from weasyprint import HTML # LISTING -def items (request, *args, **kwargs): +def items(request, *args, **kwargs): products = Item.objects.filter(type='Product').order_by('-id') + services = Item.objects.filter(type='Service').order_by('-id') context = { 'products': products, + 'services': services, } return render(request, 'listing_pages/items.html', context) -def orders (request, *args, **kwargs): +def orders(request, *args, **kwargs): + orders = Order.objects.all().order_by('-id') context = { - + 'orders': orders, } return render(request, 'listing_pages/orders.html', context) -def invoices (request, *args, **kwargs): +def invoices(request, *args, **kwargs): invoices = Invoice.objects.all().order_by('-id') context = { @@ -35,11 +38,11 @@ def invoices (request, *args, **kwargs): #DETAILS -def invoice_details (request, invoice_id): - invoice = get_object_or_404(Invoice, id=invoice_id) +def invoice_details(request, order_id): + order = get_object_or_404(Order, id=order_id) context = { - 'invoice' : invoice, + 'order' : order, } return render(request, 'invoice-details.html', context) diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index 5cccc217..1f4e9d83 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/osinacore/templates/add-edit-main.html b/osinaweb/osinacore/templates/add-edit-main.html index 2433a634..d7543513 100644 --- a/osinaweb/osinacore/templates/add-edit-main.html +++ b/osinaweb/osinacore/templates/add-edit-main.html @@ -46,7 +46,9 @@ class="w-full bg-transparent border border-white border-opacity-10 py-2 px-3 text-white outline-none rounded-md" placeholder="Search...">
- + + +
@@ -60,7 +62,9 @@