mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-01 09:02:26 +00:00
214 lines
6.7 KiB
Python
214 lines
6.7 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.utils import re2o_paginator
|
|
from . import settings
|
|
|
|
from .utils import pdfinfo, send_mail_printer
|
|
|
|
from .models import (
|
|
JobWithOptions,
|
|
PrintOperation
|
|
)
|
|
from .forms import (
|
|
JobWithOptionsForm,
|
|
PrintAgainForm
|
|
)
|
|
|
|
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
|
|
"""
|
|
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())
|
|
job_instance.pages = metadata["Pages"]
|
|
job_instance.save()
|
|
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 = 'Running'
|
|
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(
|
|
'users:profil',
|
|
kwargs={'userid': str(request.user.id)}
|
|
))
|
|
|
|
@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')\
|
|
.order_by('starttime').reverse()
|
|
jobs_list = re2o_paginator(request, jobs, pagination_number)
|
|
return render(request, 'printer/index_jobs.html', {'jobs_list': jobs_list})
|