main
parent
cd3e4e5f68
commit
b276d45da8
@ -0,0 +1,20 @@
|
||||
from django.urls import path
|
||||
from billing.add import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('product', views.add_product, name='addproduct'),
|
||||
path('service', views.add_service, name='addservice'),
|
||||
path('order/<int:customer_id>/', views.add_order, name='addorder'),
|
||||
|
||||
path('invoice-pdf/<int:order_id>/', views.add_invoice_pdf, name='addinvoice'),
|
||||
path('payment-pdf/<int:order_id>/', views.add_payment_pdf, name='addpayment'),
|
||||
|
||||
path('service/<int:service_id>/<int:order_id>/', views.add_service_in_order, name='addserviceinorder'),
|
||||
|
||||
path('payment_method_modal/', views.add_payment_method_modal, name='add_payment_method_modal'),
|
||||
path('payment/<int:order_id>/', views.add_payment_modal, name='add_payment_modal'),
|
||||
path('payment_comment/', views.add_payment_comment_modal, name='add_payment_comment_modal'),
|
||||
|
||||
|
||||
]
|
@ -0,0 +1,349 @@
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from osinacore.models import *
|
||||
from billing.models import *
|
||||
from django.http import JsonResponse, HttpResponse
|
||||
from django.template.loader import get_template
|
||||
from django.conf import settings
|
||||
import os
|
||||
from osinacore.decorators import *
|
||||
from django.core.files.base import ContentFile
|
||||
from django.db.models import Q
|
||||
from weasyprint import HTML, CSS
|
||||
|
||||
|
||||
@staff_login_required
|
||||
def add_product(request, *args, **kwargs):
|
||||
item_types = ProjectType.objects.all().order_by('name')
|
||||
if request.method == 'POST':
|
||||
title = request.POST.get('title')
|
||||
description = request.POST.get('description')
|
||||
|
||||
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='Product',
|
||||
title=title,
|
||||
description = description,
|
||||
item_type = item_type,
|
||||
amount = amount,
|
||||
recurring = recurring,
|
||||
)
|
||||
return redirect('items')
|
||||
context = {
|
||||
'item_types' : item_types,
|
||||
|
||||
}
|
||||
return render(request, 'add_templates/add-product.html', context)
|
||||
|
||||
|
||||
@staff_login_required
|
||||
def add_service (request, *args, **kwargs):
|
||||
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)
|
||||
|
||||
|
||||
@staff_login_required
|
||||
def add_order(request, customer_id):
|
||||
customer= get_object_or_404(CustomerProfile, id=customer_id)
|
||||
businesses = Business.objects.filter(customer=customer)
|
||||
services = Item.objects.filter(Q(type='Service') & (Q(customer=customer) | Q(customer__isnull=True)))
|
||||
|
||||
if request.method == 'POST':
|
||||
business_id = request.POST.get('business')
|
||||
date = request.POST.get('date')
|
||||
if business_id:
|
||||
business = get_object_or_404(Business, id=business_id)
|
||||
else:
|
||||
business = None
|
||||
|
||||
|
||||
order = Order.objects.create(
|
||||
customer=customer,
|
||||
business=business,
|
||||
date=date
|
||||
)
|
||||
|
||||
selected_services_ids = request.POST.getlist('service')
|
||||
for service_id in selected_services_ids:
|
||||
service = get_object_or_404(Item, id=service_id)
|
||||
order_item = OrderItem.objects.create(
|
||||
order=order,
|
||||
item=service,
|
||||
purchased_at=datetime.now()
|
||||
)
|
||||
|
||||
return redirect('orderdetails', order_id=order.order_id)
|
||||
|
||||
context = {
|
||||
'customer' : customer,
|
||||
'businesses' : businesses,
|
||||
'services' : services,
|
||||
}
|
||||
|
||||
return render(request, 'add_templates/add-order.html', context)
|
||||
|
||||
|
||||
|
||||
@staff_login_required
|
||||
def add_service_in_order(request, service_id, order_id):
|
||||
service =get_object_or_404(Item, id=service_id)
|
||||
order= get_object_or_404(Order, id=order_id)
|
||||
|
||||
order_item = OrderItem.objects.create(
|
||||
order = order,
|
||||
item = service,
|
||||
purchased_at = datetime.now()
|
||||
)
|
||||
order_item.save()
|
||||
return redirect('orderdetails', order_id=order.order_id)
|
||||
|
||||
|
||||
|
||||
|
||||
@staff_login_required
|
||||
def add_payment_method_modal(request, *args, **kwargs):
|
||||
if request.method == 'POST':
|
||||
name = request.POST.get('name')
|
||||
description = request.POST.get('description')
|
||||
image = request.FILES.get('image')
|
||||
|
||||
payment_method = PaymentType(
|
||||
name = name,
|
||||
description = description,
|
||||
image = image
|
||||
)
|
||||
payment_method.save()
|
||||
|
||||
# Reload the parent page
|
||||
return HttpResponse('<script>window.top.location.reload();</script>')
|
||||
return render(request, 'add_templates/add-payment-method-modal.html')
|
||||
|
||||
|
||||
|
||||
|
||||
@staff_login_required
|
||||
def add_payment_modal(request, order_id):
|
||||
order = get_object_or_404(Order, id=order_id)
|
||||
methods = PaymentType.objects.all().order_by('name')
|
||||
if request.method == 'POST':
|
||||
amount = request.POST.get('amount')
|
||||
|
||||
if request.POST.get('date_paid'):
|
||||
date_paid = request.POST.get('date_paid')
|
||||
else:
|
||||
date_paid = None
|
||||
|
||||
if request.POST.get('date_due'):
|
||||
date_due = request.POST.get('date_due')
|
||||
else:
|
||||
date_due = None
|
||||
|
||||
comment = request.POST.get('comment')
|
||||
selected_methods = request.POST.getlist('methods')
|
||||
|
||||
payment = OrderPayment(
|
||||
order = order,
|
||||
amount = amount,
|
||||
date_paid = date_paid,
|
||||
date_due = date_due,
|
||||
comment = comment
|
||||
)
|
||||
payment.save()
|
||||
|
||||
for method_id in selected_methods:
|
||||
method = get_object_or_404(PaymentType, id=method_id)
|
||||
payment.type.add(method)
|
||||
|
||||
|
||||
# Reload the parent page
|
||||
return HttpResponse('<script>window.top.location.reload();</script>')
|
||||
|
||||
context = {
|
||||
'methods': methods,
|
||||
'order': order
|
||||
}
|
||||
|
||||
return render(request, 'add_templates/add-payment-modal.html', context)
|
||||
|
||||
|
||||
|
||||
|
||||
@staff_login_required
|
||||
def add_payment_comment_modal(request):
|
||||
|
||||
context = {
|
||||
|
||||
}
|
||||
|
||||
return render(request, 'add_templates/add-payment-comment-modal.html', context)
|
||||
|
||||
|
||||
|
||||
def add_invoice_pdf(request, order_id):
|
||||
order = get_object_or_404(Order, id=order_id)
|
||||
|
||||
current_year = str(timezone.now().year)[-2:]
|
||||
last_invoice = Invoice.objects.all().last()
|
||||
if last_invoice:
|
||||
last_invoice_number = int(last_invoice.invoice_number.split('-')[1].split('+')[0])
|
||||
new_invoice_number = f"$0{current_year}-{last_invoice_number + 1}"
|
||||
else:
|
||||
new_invoice_number = f"$0{current_year}-1425"
|
||||
|
||||
|
||||
|
||||
invoice = Invoice.objects.create(
|
||||
invoice_number = new_invoice_number,
|
||||
order=order,
|
||||
date_created=datetime.now(),
|
||||
)
|
||||
|
||||
template = get_template('details_templates/invoice-details.html')
|
||||
context = {'order': order}
|
||||
html_string = template.render(context)
|
||||
|
||||
# Define the CSS string with Poppins font
|
||||
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=html_string).write_pdf(
|
||||
stylesheets=[
|
||||
CSS(string=css_string),
|
||||
CSS(string='@page { margin: 30px; }')
|
||||
],
|
||||
presentational_hints=True
|
||||
)
|
||||
|
||||
filename = f'invoice_{invoice.invoice_number}.pdf'
|
||||
pdf_content = ContentFile(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"'
|
||||
return response
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def add_payment_pdf(request, order_id):
|
||||
order = get_object_or_404(Order, id=order_id)
|
||||
payments = OrderPayment.objects.filter(order = order)
|
||||
paid_amount = OrderPayment.objects.filter(order=order, date_paid__isnull=False).aggregate(total_paid=Sum('amount'))['total_paid'] or 0
|
||||
cart_total = order.get_cart_total
|
||||
remaining_amount = cart_total - paid_amount
|
||||
|
||||
|
||||
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, 'remaining_amount':remaining_amount,})
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue