Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • smasch/scheduling-system
1 result
Show changes
Commits on Source (17)
Showing
with 521 additions and 39 deletions
......@@ -16,7 +16,7 @@ Including another URLconf
from django.conf.urls import url
from web.api_views import worker, location, subject, appointment_type, appointment, configuration, daily_planning, \
redcap, flying_team, visit
redcap, flying_team, visit, voucher, voucher_type
urlpatterns = [
# appointments
......@@ -53,8 +53,14 @@ urlpatterns = [
# worker data
url(r'^specializations$', worker.specializations, name='web.api.specializations'),
url(r'^units$', worker.units, name='web.api.units'),
url(r'^workers$', worker.workers_for_daily_planning, name='web.api.workers'),
url(r'^workers/availabilities$', worker.availabilities, name='web.api.workers.availabilities$'),
# workers
url(r'^workers/(?P<worker_role>[A-z]+)/$', worker.get_workers, name='web.api.workers'),
# daily planning data
url(r'^daily_planning/workers/$', worker.workers_for_daily_planning, name='web.api.workers.daily_planning'),
url(r'^daily_planning/workers/availabilities$', worker.availabilities,
name='web.api.workers.daily_planning.availabilities$'),
# daily planning events
url(r'^events/(?P<date>\d{4}-\d{2}-\d{2})/$', daily_planning.events, name='web.api.events'),
......@@ -67,4 +73,14 @@ urlpatterns = [
url(r'^redcap/missing_subjects/(?P<missing_subject_id>\d+):unignore$', redcap.unignore_missing_subject,
name='web.api.redcap.unignore_missing_subject'),
# vouchers data
url(r'^vouchers/$', voucher.get_vouchers, name='web.api.vouchers'),
url(r'^vouchers:columns$', voucher.get_voucher_columns,
name='web.api.vouchers.columns'),
# voucher types data
url(r'^voucher_types/$', voucher_type.get_voucher_types, name='web.api.voucher_types'),
url(r'^vouchers:columns$', voucher.get_voucher_columns,
name='web.api.vouchers.columns'),
]
import logging
from django.http import JsonResponse
from web.api_views.serialization_utils import get_filters_for_data_table_request, add_column, \
serialize_date
from web.models import Voucher
logger = logging.getLogger(__name__)
def get_vouchers_order(vouchers_to_be_ordered, order_column, order_direction):
result = vouchers_to_be_ordered
if order_direction == "asc":
order_direction = ""
else:
order_direction = "-"
if order_column == "first_name":
result = vouchers_to_be_ordered.order_by(order_direction + 'study_subject__subject__first_name')
elif order_column == "last_name":
result = vouchers_to_be_ordered.order_by(order_direction + 'study_subject__subject__last_name')
elif order_column == "number":
result = vouchers_to_be_ordered.order_by(order_direction + 'number')
elif order_column == "expiry_date":
result = vouchers_to_be_ordered.order_by(order_direction + 'expiry_date')
elif order_column == "issue_date":
result = vouchers_to_be_ordered.order_by(order_direction + 'issue_date')
elif order_column == "id":
result = vouchers_to_be_ordered.order_by(order_direction + 'id')
elif order_column == "type":
result = vouchers_to_be_ordered.order_by(order_direction + 'voucher_type__code')
elif order_column == "status":
result = vouchers_to_be_ordered.order_by(order_direction + 'status')
else:
logger.warn("Unknown sort column: " + str(order_column))
return result
def get_vouchers_filtered(vouchers_to_be_filtered, filters):
result = vouchers_to_be_filtered
for row in filters:
column = row[0]
value = row[1]
if column == "first_name":
result = result.filter(study_subject__subject__first_name__icontains=value)
elif column == "last_name":
result = result.filter(study_subject__subject__last_name__icontains=value)
elif column == "number":
result = result.filter(number__icontains=value)
elif column == "type":
result = result.filter(voucher_type=value)
elif column == "status":
result = result.filter(status=value)
elif column == "voucher_partner":
result = result.filter(usage_partner=value)
elif column == "feedback":
result = result.filter(feedback__icontains=value)
elif column == "":
pass
else:
message = "UNKNOWN filter: "
if column is None:
message += "[None]"
else:
message += str(column)
logger.warn(message)
return result
# noinspection PyUnusedLocal
def get_voucher_columns(request):
result = []
add_column(result, "First name", "first_name", None, "string_filter")
add_column(result, "Last name", "last_name", None, "string_filter")
add_column(result, "Number", "number", None, "string_filter")
add_column(result, "Type", "type", None, "voucher_type_filter")
add_column(result, "Status", "status", None, "voucher_status_filter")
add_column(result, "Voucher partner", "voucher_partner", None, "voucher_partner_filter")
add_column(result, "Issue date", "issue_date", None, None)
add_column(result, "Expiry date", "expiry_date", None, None)
add_column(result, "Edit", "edit", None, None, sortable=False)
return JsonResponse({"columns": result})
def get_vouchers(request):
# id of the query from dataTable: https://datatables.net/manual/server-side
draw = int(request.GET.get("draw", "-1"))
start = int(request.GET.get("start", "0"))
length = int(request.GET.get("length", "10"))
order = int(request.GET.get("order[0][column]", "0"))
order_dir = request.GET.get("order[0][dir]", "asc")
order_column = request.GET.get("columns[" + str(order) + "][data]", "last_name")
filters = get_filters_for_data_table_request(request)
all_vouchers = Voucher.objects.all()
count = all_vouchers.count()
ordered_vouchers = get_vouchers_order(all_vouchers, order_column, order_dir)
filtered_vouchers = get_vouchers_filtered(ordered_vouchers, filters)
sliced_vouchers = filtered_vouchers[start:(start + length)]
result_vouchers = sliced_vouchers
count_filtered = filtered_vouchers.count()
data = []
for voucher in result_vouchers:
data.append(serialize_voucher(voucher))
return JsonResponse({
"draw": draw,
"recordsTotal": count,
"recordsFiltered": count_filtered,
"data": data,
})
def serialize_voucher(voucher):
issue_date = serialize_date(voucher.issue_date)
expiry_date = serialize_date(voucher.expiry_date)
result = {
"first_name": voucher.study_subject.subject.first_name,
"last_name": voucher.study_subject.subject.last_name,
"issue_date": issue_date,
"type": voucher.voucher_type.code,
"status": str(voucher.status),
"voucher_partner": str(voucher.usage_partner),
"feedback": voucher.feedback,
"expiry_date": expiry_date,
"number": voucher.number,
"id": voucher.id,
}
return result
import logging
from django.http import JsonResponse
from web.models import VoucherType
logger = logging.getLogger(__name__)
def get_voucher_types(request):
all_vouchers = VoucherType.objects.all()
count = all_vouchers.count()
data = []
for voucher_type in all_vouchers:
data.append(serialize_voucher_type(voucher_type))
return JsonResponse({
"recordsTotal": count,
"recordsFiltered": count,
"data": data,
})
def serialize_voucher_type(voucher_type):
result = {
"code": voucher_type.code,
"description": voucher_type.description,
"id": voucher_type.id,
}
return result
......@@ -61,3 +61,27 @@ def availabilities(request):
return JsonResponse({
"availabilities": result,
})
def get_workers(request, worker_role):
all_workers = Worker.get_workers_by_worker_type(worker_role).distinct()
count = all_workers.count()
data = []
for voucher_type in all_workers:
data.append(serialize_worker(voucher_type))
return JsonResponse({
"recordsTotal": count,
"recordsFiltered": count,
"data": data,
})
def serialize_worker(worker):
result = {
"first_name": worker.first_name,
"last_name": worker.last_name,
"id": worker.id,
}
return result
......@@ -19,3 +19,19 @@ def process_file(path_to_docx, path_to_new_docx, changes_to_apply):
paragraph.text = paragraph.text.replace(placeholder, replacement)
doc.save(path_to_new_docx)
def merge_files(files, path_to_new_docx):
merged_document = Document()
for index, input_file in enumerate(files):
sub_doc = Document(input_file)
# Don't add a page break if you've reached the last file.
if index < len(files) - 1:
sub_doc.add_page_break()
for element in sub_doc.element.body:
merged_document.element.body.append(element)
merged_document.save(path_to_new_docx)
......@@ -8,7 +8,7 @@ from django.utils import timezone
from web.algorithm import VerhoeffAlgorithm
from web.forms.forms import DATEPICKER_DATE_ATTRS
from web.models import VoucherType, VoucherTypePrice, Voucher, Worker
from web.models.constants import VOUCHER_STATUS_NEW, VOUCHER_STATUS_USED
from web.models.constants import VOUCHER_STATUS_NEW, VOUCHER_STATUS_USED, VOUCHER_STATUS_EXPIRED
from web.models.worker_study_role import WORKER_VOUCHER_PARTNER
logger = logging.getLogger(__name__)
......@@ -52,35 +52,29 @@ class VoucherForm(ModelForm):
self.fields['issue_date'].required = False
self.fields['expiry_date'].widget.attrs['readonly'] = True
self.fields['expiry_date'].required = False
self.fields['use_date'].widget.attrs['readonly'] = True
instance = getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['voucher_type'].widget.attrs['readonly'] = True
self.fields['usage_partner'].queryset = Worker.get_workers_by_worker_type(WORKER_VOUCHER_PARTNER).filter(
voucher_types = instance.voucher_type)
self.fields['hours'].widget.attrs['readonly'] = True
self.fields['usage_partner'].widget.attrs['readonly'] = True
if instance.status != VOUCHER_STATUS_NEW:
if instance.status == VOUCHER_STATUS_USED or instance.status == VOUCHER_STATUS_EXPIRED:
self.fields['status'].widget.attrs['readonly'] = True
self.fields['feedback'].widget.attrs['readonly'] = True
self.fields['usage_partner'].widget.attrs['readonly'] = True
def clean(self):
if self.cleaned_data["status"] == VOUCHER_STATUS_USED and not self.cleaned_data["usage_partner"]:
self.add_error('usage_partner', "Partner must be defined for used voucher")
if self.cleaned_data["status"] != VOUCHER_STATUS_USED and self.cleaned_data["usage_partner"]:
self.add_error('status', "Status must be used for voucher with defined partner")
def save(self, commit=True):
instance = super(VoucherForm, self).save(commit=False)
if not instance.id:
instance.issue_date = timezone.now()
instance.expiry_date = instance.issue_date + datetime.timedelta(days=92)
max_id = str(0).zfill(5)
instance.expiry_date = instance.issue_date + datetime.timedelta(days=90)
max_id = str(1).zfill(5)
if Voucher.objects.all().count() > 0:
max_id = str(Voucher.objects.latest('id').id).zfill(5)
instance.number = max_id + VerhoeffAlgorithm.calculate_verhoeff_check_sum(max_id)
if instance.status == VOUCHER_STATUS_USED and not instance.use_date:
instance.use_date = timezone.now()
max_id = str(Voucher.objects.latest('id').id + 1).zfill(5)
# number in format {ND_NUMBER}-{DATE}-{VOUCHER_TYPE_CODE}-{VOUCHER_TYPE}-{SEQ_NUMBER}{CHECKSUM}
instance.number = instance.study_subject.nd_number + "-" + \
datetime.datetime.now().strftime("%Y%m%d") + "-" + \
instance.voucher_type.code + "-" + \
instance.usage_partner.voucher_partner_code + "-" + \
max_id + VerhoeffAlgorithm.calculate_verhoeff_check_sum(max_id)
if commit:
instance.save()
import datetime
import logging
from django import forms
from django.forms import ModelForm
from web.forms.forms import DATETIMEPICKER_DATE_ATTRS
from web.models.voucher_partner_session import VoucherPartnerSession
logger = logging.getLogger(__name__)
class VoucherPartnerSessionForm(ModelForm):
date = forms.DateTimeField(widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS),
initial=datetime.datetime.now().replace(hour=8, minute=0, second=0))
class Meta:
model = VoucherPartnerSession
exclude = ['voucher']
......@@ -9,7 +9,7 @@ from django_common.auth_backends import User
from web.models import Worker, WorkerStudyRole
from web.models.constants import GLOBAL_STUDY_ID
from web.models.worker import role_choices_by_worker_type, worker_type_by_worker
from web.models.worker_study_role import WORKER_STAFF
from web.models.worker_study_role import WORKER_STAFF, WORKER_VOUCHER_PARTNER
logger = logging.getLogger(__name__)
......@@ -43,6 +43,9 @@ class WorkerForm(ModelForm):
else:
del self.fields['locations']
if worker_type != WORKER_VOUCHER_PARTNER:
del self.fields['voucher_partner_code']
fields = OrderedDict()
if worker_type == WORKER_STAFF:
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-01 07:54
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0109_missing_appointment_list_update'),
]
operations = [
migrations.AddField(
model_name='worker',
name='voucher_partner_code',
field=models.CharField(blank=True, max_length=10, verbose_name=b'Code'),
),
migrations.AlterField(
model_name='studysubjectlist',
name='type',
field=models.CharField(blank=True, choices=[(b'GENERIC', b'Generic subject list'), (b'NO_VISIT', b'Subjects without visit'), (b'REQUIRE_CONTACT', b'Subjects required contact'), (b'VOUCHER_EXPIRY', b'Subject with vouchers to be expired soon')], max_length=50, null=True, verbose_name=b'Type of list'),
),
migrations.AlterField(
model_name='studyvisitlist',
name='type',
field=models.CharField(choices=[(b'UNFINISHED', b'unfinished visits'), (b'APPROACHING_WITHOUT_APPOINTMENTS', b'approaching visits'), (b'APPROACHING_FOR_MAIL_CONTACT', b'post mail for approaching visits'), (b'GENERIC', b'Generic visit list'), (b'MISSING_APPOINTMENTS', b'visits with missing appointments'), (b'EXCEEDED_TIME', b'exceeded visit time')], max_length=50, verbose_name=b'Type of list'),
),
migrations.AlterField(
model_name='voucher',
name='number',
field=models.CharField(max_length=50, unique=True, verbose_name=b'Number'),
),
migrations.AlterField(
model_name='voucher',
name='usage_partner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Worker'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-01 13:18
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0110_auto_20180601_0754'),
]
operations = [
migrations.CreateModel(
name='VoucherPartnerSession',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('length', models.IntegerField(verbose_name=b'Length (minutes)')),
('date', models.DateTimeField(verbose_name=b'Issue date')),
],
),
migrations.RemoveField(
model_name='voucher',
name='use_date',
),
migrations.AddField(
model_name='voucher',
name='hours',
field=models.IntegerField(default=0, verbose_name=b'Hours'),
),
migrations.AlterField(
model_name='voucher',
name='status',
field=models.CharField(choices=[(b'NEW', b'New'), (b'IN_USE', b'In use'), (b'USED', b'Used'), (b'EXPIRED', b'Expired')], default=b'NEW', max_length=20, verbose_name=b'Status'),
),
migrations.AddField(
model_name='voucherpartnersession',
name='voucher',
field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='voucher_partner_sessions', to='web.Voucher'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-04 10:21
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('web', '0111_auto_20180601_1318'),
]
operations = [
migrations.AlterField(
model_name='mailtemplate',
name='context',
field=models.CharField(choices=[(b'A', b'Appointment'), (b'S', b'Subject'), (b'V', b'Visit'), (b'C', b'Voucher')], max_length=1),
),
migrations.AlterField(
model_name='mailtemplate',
name='language',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='web.Language'),
),
]
......@@ -48,14 +48,18 @@ KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE = "KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_
MAIL_TEMPLATE_CONTEXT_SUBJECT = 'S'
MAIL_TEMPLATE_CONTEXT_APPOINTMENT = 'A'
MAIL_TEMPLATE_CONTEXT_VISIT = 'V'
MAIL_TEMPLATE_CONTEXT_VOUCHER = 'C'
MAIL_TEMPLATE_CONTEXT_CHOICES = (
(MAIL_TEMPLATE_CONTEXT_APPOINTMENT, 'Appointment'),
(MAIL_TEMPLATE_CONTEXT_SUBJECT, 'Subject'),
(MAIL_TEMPLATE_CONTEXT_VISIT, 'Visit'),
(MAIL_TEMPLATE_CONTEXT_VOUCHER, 'Voucher'),
)
LOCALE_CHOICES = [(value, value) for value in sorted(locale.windows_locale.values())]
DEFAULT_LOCALE_NAME = "fr_FR"
MONDAY_AS_DAY_OF_WEEK = 1
TUESDAY_AS_DAY_OF_WEEK = 2
WEDNESDAY_AS_DAY_OF_WEEK = 3
......@@ -85,10 +89,12 @@ COUNTRY_AFGHANISTAN_ID = 2
GLOBAL_STUDY_ID = 1
VOUCHER_STATUS_NEW = "NEW"
VOUCHER_STATUS_IN_USE = "IN_USE"
VOUCHER_STATUS_USED = "USED"
VOUCHER_STATUS_EXPIRED = "EXPIRED"
VOUCHER_STATUS_CHOICES = (
(VOUCHER_STATUS_NEW, 'New'),
(VOUCHER_STATUS_IN_USE, 'In use'),
(VOUCHER_STATUS_USED, 'Used'),
(VOUCHER_STATUS_EXPIRED, 'Expired'),
)
......
......@@ -2,7 +2,7 @@
from django.db import models
from .constants import LOCALE_CHOICES
from .constants import LOCALE_CHOICES, DEFAULT_LOCALE_NAME
class Language(models.Model):
......@@ -13,7 +13,8 @@ class Language(models.Model):
name = models.CharField(max_length=20)
image = models.ImageField()
order = models.IntegerField(default=0)
locale = models.CharField(max_length=10, choices=LOCALE_CHOICES, null=False, blank=False, default="fr_FR")
locale = models.CharField(max_length=10, choices=LOCALE_CHOICES, null=False, blank=False,
default=DEFAULT_LOCALE_NAME)
windows_locale_name = models.CharField(max_length=10, choices=LOCALE_CHOICES, null=False, blank=False,
default="French")
......
......@@ -7,9 +7,9 @@ from contextlib import contextmanager
from django.db import models
from .constants import MAIL_TEMPLATE_CONTEXT_CHOICES, MAIL_TEMPLATE_CONTEXT_APPOINTMENT, \
MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VISIT
MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VISIT, MAIL_TEMPLATE_CONTEXT_VOUCHER, DEFAULT_LOCALE_NAME
from ..docx_helper import process_file
from ..models import Appointment, Visit, StudySubject, Worker
from ..models import Appointment, Visit, StudySubject, Worker, Voucher
DATE_FORMAT_FULL = "%A %d %B %Y"
......@@ -99,9 +99,26 @@ class MailTemplate(models.Model):
("##A_TYPES##", "Appointment's types", "comma separated"),
]
MAILS_TEMPLATE_VOUCHER_TAGS = [
("##C_NUMBER##", "Number", ''),
("##C_PATIENT_NAME##", "Voucher Partner name", ''),
("##C_VOUCHER_TYPE##", "Voucher type", ''),
("##C_ISSUE_DATE_SHORT##", "Issue date", get_formatted_time(DATE_FORMAT_SHORT)),
("##C_EXPIRY_START_SHORT##", "Expiry date", get_formatted_time(DATE_FORMAT_SHORT)),
("##C_PARTNER_NAME##", "Voucher Partner name", ''),
("##C_PARTNER_ADDRESS##", "Voucher Partner address", ''),
("##C_PARTNER_CITY##", "Voucher Partner city", ''),
("##C_PARTNER_POSTAL_CODE##", "Voucher Partner postal code", ''),
("##C_PARTNER_COUNTRY##", "Voucher Partner country", ''),
("##C_PARTNER_PHONE##", "Voucher Partner phone", ''),
("##C_HOURS##", "Hours", ''),
]
name = models.CharField(max_length=255)
context = models.CharField(max_length=1, choices=MAIL_TEMPLATE_CONTEXT_CHOICES)
language = models.ForeignKey("web.Language", on_delete=models.CASCADE)
language = models.ForeignKey("web.Language", on_delete=models.CASCADE, null=True)
template_file = models.FileField(upload_to='templates/')
@staticmethod
......@@ -112,6 +129,10 @@ class MailTemplate(models.Model):
def get_subject_mail_templates(languages):
return MailTemplate.get_mail_templates_for_context(languages, MAIL_TEMPLATE_CONTEXT_SUBJECT)
@staticmethod
def get_voucher_mail_templates(languages):
return MailTemplate.get_mail_templates_for_context(languages, MAIL_TEMPLATE_CONTEXT_VOUCHER)
@staticmethod
def get_visit_mail_templates(languages):
return MailTemplate.get_mail_templates_for_context(languages, MAIL_TEMPLATE_CONTEXT_VISIT)
......@@ -123,17 +144,23 @@ class MailTemplate(models.Model):
active_templates = []
disabled_templates = []
for template in templates:
if template.language.name in languages_names:
if template.language is None:
if len(languages) == 0:
active_templates.append(template)
else:
disabled_templates.append(template)
elif template.language.name in languages_names:
active_templates.append(template)
else:
disabled_templates.append(template)
active_templates.sort(key=lambda x: languages_names.index(x.language.name))
active_templates.sort(key=lambda x: languages_names.index(x.language.name) if x.language is not None else -1)
return active_templates, disabled_templates
def apply(self, instance, user, stream):
appointment = None
visit = None
study_subject = None
voucher = None
if isinstance(instance, Appointment):
appointment = instance
visit = instance.visit
......@@ -143,19 +170,29 @@ class MailTemplate(models.Model):
study_subject = visit.subject
elif isinstance(instance, StudySubject):
study_subject = instance
elif isinstance(instance, Voucher):
voucher = instance
# set locale to get correct date format
locale_name = self.language.locale
if platform.system() == 'Windows':
locale_name = self.language.windows_locale_name
locale_name = self.get_locale_name()
with setlocale(locale_name.encode('utf8')):
replacements = {}
self._add_generic_replacements(replacements, Worker.get_by_user(user))
self._add_appointment_replacements(replacements, appointment)
self._add_visit_replacements(replacements, visit)
self._add_subject_replacements(replacements, study_subject)
self._add_voucher_replacements(replacements, voucher)
process_file(self.template_file.path, stream, replacements)
return stream
def get_locale_name(self):
if self.language is None:
locale_name = DEFAULT_LOCALE_NAME
else:
locale_name = self.language.locale
if platform.system() == 'Windows':
locale_name = self.language.windows_locale_name
return locale_name
def _add_generic_replacements(self, replacements, worker):
current_datetime = datetime.datetime.now()
replacements.update({
......@@ -237,3 +274,21 @@ class MailTemplate(models.Model):
'##S_MAIL_LANGUAGE##': str(study_subject.subject.default_written_communication_language),
'##S_KNOWN_LANGUAGES##': ", ".join([l.name for l in study_subject.subject.languages.all()])
})
def _add_voucher_replacements(self, replacements, voucher):
if voucher is not None:
replacements.update({
"##C_NUMBER##": voucher.number,
"##C_PATIENT_NAME##": voucher.study_subject.subject.first_name + ' ' + voucher.study_subject.subject.last_name,
"##C_VOUCHER_TYPE##": voucher.voucher_type.description,
"##C_ISSUE_DATE_SHORT##": voucher.issue_date.strftime(DATE_FORMAT_SHORT).decode(date_format_encoding()),
"##C_EXPIRY_START_SHORT##": voucher.expiry_date.strftime(DATE_FORMAT_SHORT).decode(
date_format_encoding()),
"##C_PARTNER_NAME##": voucher.usage_partner.first_name + ' ' + voucher.usage_partner.last_name,
"##C_PARTNER_ADDRESS##": voucher.usage_partner.address,
"##C_PARTNER_POSTAL_CODE##": voucher.usage_partner.postal_code,
"##C_PARTNER_CITY##": voucher.usage_partner.city,
"##C_PARTNER_COUNTRY##": unicode(voucher.usage_partner.country),
"##C_PARTNER_PHONE##": voucher.usage_partner.phone_number,
"##C_HOURS##": str(voucher.hours),
})
......@@ -11,7 +11,7 @@ class Voucher(models.Model):
app_label = 'web'
number = models.CharField(
max_length=10,
max_length=50,
verbose_name='Number',
blank=False,
null=False,
......@@ -20,7 +20,13 @@ class Voucher(models.Model):
issue_date = models.DateField(verbose_name='Issue date', null=False)
expiry_date = models.DateField(verbose_name='Expiry date', null=False)
use_date = models.DateField(verbose_name='Use date', null=True, blank=True)
hours = models.IntegerField(
verbose_name='Hours',
default=0,
null=False
)
voucher_type = models.ForeignKey(
VoucherType,
on_delete=models.CASCADE,
......@@ -48,8 +54,7 @@ class Voucher(models.Model):
usage_partner = models.ForeignKey(
Worker,
on_delete=models.CASCADE,
null=True,
blank=True
null=False
)
def __str__(self):
......
# coding=utf-8
from django.db import models
from web.models import Voucher
class VoucherPartnerSession(models.Model):
class Meta:
app_label = 'web'
length = models.IntegerField(
verbose_name='Length (minutes)',
null=False
)
date = models.DateTimeField(verbose_name='Issue date', null=False)
voucher = models.ForeignKey(
Voucher,
on_delete=models.CASCADE,
null=False,
related_name="voucher_partner_sessions",
editable=False
)
......@@ -126,6 +126,11 @@ class Worker(models.Model):
blank=True
)
voucher_partner_code = models.CharField(max_length=10,
verbose_name='Code',
blank=True
)
def is_on_leave(self):
if len(self.holiday_set.filter(datetime_end__gt=datetime.datetime.now(),
datetime_start__lt=datetime.datetime.now())):
......
......@@ -215,6 +215,8 @@ function createTable(params) {
var flying_teams_url = params.flying_teams_url;
var appointment_types_url = params.appointment_types_url;
var subjects_url = params.subjects_url;
var voucher_types_url = params.voucher_types_url;
var voucher_partner_url = params.voucher_partner_url;
var columnsDefinition = params.columns;
tableElement.appendChild(createHeader(columnsDefinition));
......@@ -239,6 +241,15 @@ function createTable(params) {
$(this).html('<select style="width:60px" >' + options + '</select>');
});
$(tableElement).find('tfoot div[name="voucher_status_filter"]').each(function () {
$(this).html('<select style="width:60px" ><option value selected="selected">---</option>' +
'<option value="NEW">NEW</option>' +
'<option value="IN_USE">IN USE</option>' +
'<option value="USED">USED</option>' +
'<option value="EXPIRED">EXPIRED</option>' +
'</select>');
});
$(tableElement).find('tfoot div[name="visit_filter"]').each(function () {
$(this).html('<select style="width:60px" >' +
'<option value selected="selected">---</option>' +
......@@ -265,6 +276,29 @@ function createTable(params) {
});
});
$(tableElement).find('tfoot div[name="voucher_type_filter"]').each(function () {
var obj = $(this);
obj.html('<select style="width:80px"><option value selected="selected">---</option></select>');
var select = $('select', obj);
$.get(voucher_types_url, function (content) {
$.each(content.data, function (index, voucher_type) {
select.append('<option value="' + voucher_type.id + '">' + voucher_type.code + '</option>');
});
});
});
$(tableElement).find('tfoot div[name="voucher_partner_filter"]').each(function () {
var obj = $(this);
obj.html('<select style="width:80px"><option value selected="selected">---</option></select>');
var select = $('select', obj);
$.get(voucher_partner_url, function (content) {
$.each(content.data, function (index, voucher_partner) {
select.append('<option value="' + voucher_partner.id + '">' + voucher_partner.first_name + ' ' +
voucher_partner.last_name + ' ' + '</option>');
});
});
});
$(tableElement).find('tfoot div[name="flying_team_filter"]').each(function () {
var obj = $(this);
obj.html('<select style="width:80px"><option value selected="selected">---</option></select>');
......
......@@ -157,7 +157,7 @@
events: get_calendar_events_function(
"{% url 'web.api.appointments' full_list %}",
true, dayHeaders,
"{% url 'web.api.workers.availabilities$' %}")
"{% url 'web.api.workers.daily_planning.availabilities$' %}")
});
});
</script>
......
......@@ -46,7 +46,7 @@
<script src="{% static 'fullcalendar-scheduler/lib/fullcalendar.min.js' %}"></script>
<script src="{% static 'fullcalendar-scheduler/scheduler.min.js' %}"></script>
<script>
var resources_url = '{% url 'web.api.workers' %}';
var resources_url = '{% url 'web.api.workers.daily_planning' %}';
var events_url = '{% url 'web.api.events_persist' %}';
</script>
{% include "includes/datepicker.js.html" %}
......