8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-25 04:43:10 +00:00
re2o/printer/views.py
2018-12-06 17:57:57 +01:00

276 lines
8.2 KiB
Python

# -*- mode: python; coding: utf-8 -*-
"""printer.views
The views for the printer app
Author : Maxime Bombar <bombar@crans.org>.
"""
from __future__ import unicode_literals
from django.urls import reverse
from django.shortcuts import render, redirect
from django.forms import modelformset_factory, formset_factory
from django.forms.models import model_to_dict
from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext as _
from re2o.views import form
from users.models import User
from re2o.base import (
re2o_paginator,
SortTable
)
from .utils import pdfinfo, send_mail_printer, printer_enabled
from re2o.acl import (
can_create,
can_edit,
can_delete_set,
can_delete,
can_view,
can_view_all,
can_change
)
from .models import (
JobWithOptions,
PrintOperation,
Digicode
)
from .forms import (
JobWithOptionsForm,
PrintAgainForm,
CreateCodeForm,
)
from preferences.models import GeneralOption
from cotisations.models import(
Paiement,
Facture,
Vente,
)
from cotisations.utils import find_payment_method
from cotisations.payment_methods.balance.models import BalancePayment
from django.core.exceptions import ValidationError
from re2o.acl import (
can_edit
)
@login_required
def new_job(request):
"""
View to create a new printing job
"""
if not printer_enabled():
return render(request, 'printer/printer_disabled.html', {})
print_operation = PrintOperation(user=request.user)
job_formset = formset_factory(JobWithOptionsForm)(
request.POST or None,
request.FILES or None,
form_kwargs={'user': request.user},
)
if job_formset.is_valid():
job_form = job_formset
print_operation.save()
for count, job in enumerate(job_form):
### Fails if one of the forms is submitted without a file.
try:
filename = job.cleaned_data['file'].name
job_instance = job.save(commit=False)
job_instance.filename = filename
job_instance.print_operation = print_operation
job_instance.user=request.user
metadata = pdfinfo(request.FILES['form-%s-file' % count].temporary_file_path())
if "Pages" in metadata:
job_instance.pages = metadata["Pages"]
job_instance.save()
else:
job_form.erros[count] = {'file': ['Invalid PDF']}
except KeyError:
job_form.errors[count] = {'file': ['This field is required.']}
if job_formset.total_error_count() == 0:
return redirect(reverse(
'printer:print-job',
kwargs={'printoperationid': print_operation.id}
))
return form(
{
'jobform': job_formset,
'action_name': _('Next'),
},
'printer/newjob.html',
request
)
@login_required
@can_edit(PrintOperation)
def print_job(request, printoperation, **_kwargs):
"""Print a job, confirm after new job step"""
jobs_to_edit = JobWithOptions.objects.filter(print_operation=printoperation)
job_modelformset = modelformset_factory(
JobWithOptions,
extra=0,
fields=('color', 'disposition', 'count', 'stapling', 'perforation'),
max_num=jobs_to_edit.count()
)
job_formset = job_modelformset(
request.POST or None,
queryset=jobs_to_edit
)
if job_formset.is_valid():
job_formset.save()
for job_form in job_formset:
job = job_form.instance
job.status = 'Printable'
job.save()
return payment(request, jobs_to_edit)
return form(
{
'jobform': job_formset,
'action_name': _('Print'),
},
'printer/print.html',
request
)
@login_required
@can_edit(JobWithOptions)
def print_job_again(request, jobwithoptions, **_kwargs):
"""Print a job again"""
jobwithoptionsform = formset_factory(PrintAgainForm)(
request.POST or None,
request.FILES or None,
form_kwargs={'user': request.user, 'instance': jobwithoptions},
)
if jobwithoptionsform.is_valid():
for job_form in jobwithoptionsform:
jobwithoptions = job_form.instance
jobwithoptions.pk = None
jobwithoptions.print_operation = PrintOperation.objects.create(user=jobwithoptions.print_operation.user)
jobwithoptions.status = 'Printable'
jobwithoptions.save()
return payment(request, [jobwithoptions])
return form(
{
'jobform': jobwithoptionsform,
'action_name': _('Print'),
},
'printer/print.html',
request
)
def payment(request, jobs):
"""
View used to create a new invoice and make the payment
"""
success = 0
users = {}
for job in jobs:
try:
users[job.printAs or job.user][0]+=job.price
users[job.printAs or job.user][1].append(job.id)
except KeyError:
users[job.printAs or job.user]=[job.price, [job.id]]
balancePayment = BalancePayment.objects.get()
minimum_balance = balancePayment.minimum_balance
for user in users:
### If payment_method balance doesn't exist, then you're not allowed to print.
try:
balance = find_payment_method(Paiement.objects.get(is_balance=True))
except Paiement.DoesNotExist:
messages.error(
request,
_("You are not allowed to print")
)
return redirect(reverse(
'users:profil',
kwargs={'userid': request.user.id}
))
invoice = Facture(user=user)
invoice.paiement = balance.payment
invoice.save()
Vente.objects.create(
facture=invoice,
name='Impressions',
prix=users[user][0],
number=1,
)
invoice.paiement.end_payment(invoice, request)
### If we are here, then either we were able to pay and it's ok,
### Either we weren't able to pay and we need to cancel the jobs.
jobs = JobWithOptions.objects.filter(id__in=users[user][1])
if float(user.solde) - float(users[user][0]) < 0:
for job in jobs:
job.status = 'Cancelled'
job.save()
else:
for job in jobs:
job.paid = True
job.save()
success=1
if success:
send_mail_printer(request.user)
return redirect(reverse('printer:index-digicodes',))
@login_required
def index_jobs(request):
""" Display jobs"""
pagination_number = GeneralOption.get_cached_value('pagination_number')
jobs = JobWithOptions.objects.select_related('user')\
.select_related('print_operation')
jobs_list = SortTable.sort(
jobs,
request.GET.get('col'),
request.GET.get('order'),
SortTable.PRINTER_INDEX_JOB
)
jobs_list = re2o_paginator(request, jobs_list, pagination_number)
return render(request, 'printer/index_jobs.html', {'jobs_list': jobs_list})
@login_required
def index_digicodes(request):
"""Display available digicodes"""
pagination_number = GeneralOption.get_cached_value('pagination_number')
digicodes = Digicode.active_codes()
digicodes_list = SortTable.sort(
digicodes,
request.GET.get('col'),
request.GET.get('order'),
SortTable.PRINTER_INDEX_CODE
)
digicodes_list = re2o_paginator(request, digicodes_list, pagination_number)
return render(request,
'printer/index_digicodes.html',
{'digicodes_list': digicodes_list},
)
@login_required
@can_create(Digicode)
def create_code(request):
"""Generate a digicode"""
code = CreateCodeForm(
request.POST or None,
user = request.user,
)
if code.is_valid():
user = code.cleaned_data['user']
Digicode._gen_code(user)
return redirect(reverse('printer:index-digicodes',))
return form(
{
'codeform': code,
'action_name': _("Create Code"),
},
'printer/create_code.html',
request
)