From 0bd6e0d2ab8f81721402aad84dba3c6f7c895f6f Mon Sep 17 00:00:00 2001 From: Piotr Gawron <piotr.gawron@uni.lu> Date: Fri, 1 Jun 2018 10:48:30 +0200 Subject: [PATCH] voucher partner is obligatory in voucher, voucher number is generated using schema --- smash/web/forms/voucher_forms.py | 19 ++++----- smash/web/forms/worker_form.py | 5 ++- .../web/migrations/0110_auto_20180601_0754.py | 41 +++++++++++++++++++ smash/web/models/voucher.py | 5 +-- smash/web/models/worker.py | 5 +++ smash/web/tests/forms/test_voucher_forms.py | 14 ------- smash/web/tests/functions.py | 20 ++++++++- smash/web/tests/view/test_voucher.py | 18 ++++++-- 8 files changed, 94 insertions(+), 33 deletions(-) create mode 100644 smash/web/migrations/0110_auto_20180601_0754.py diff --git a/smash/web/forms/voucher_forms.py b/smash/web/forms/voucher_forms.py index 7067d0d9..681f7bad 100644 --- a/smash/web/forms/voucher_forms.py +++ b/smash/web/forms/voucher_forms.py @@ -57,28 +57,27 @@ class VoucherForm(ModelForm): 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) + voucher_types=instance.voucher_type) if instance.status != VOUCHER_STATUS_NEW: 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) + 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) + 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 instance.status == VOUCHER_STATUS_USED and not instance.use_date: instance.use_date = timezone.now() diff --git a/smash/web/forms/worker_form.py b/smash/web/forms/worker_form.py index 8d5fdc67..1237b46b 100644 --- a/smash/web/forms/worker_form.py +++ b/smash/web/forms/worker_form.py @@ -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: diff --git a/smash/web/migrations/0110_auto_20180601_0754.py b/smash/web/migrations/0110_auto_20180601_0754.py new file mode 100644 index 00000000..2c878270 --- /dev/null +++ b/smash/web/migrations/0110_auto_20180601_0754.py @@ -0,0 +1,41 @@ +# -*- 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'), + ), + ] diff --git a/smash/web/models/voucher.py b/smash/web/models/voucher.py index 340b7876..7cf9a64e 100644 --- a/smash/web/models/voucher.py +++ b/smash/web/models/voucher.py @@ -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, @@ -48,8 +48,7 @@ class Voucher(models.Model): usage_partner = models.ForeignKey( Worker, on_delete=models.CASCADE, - null=True, - blank=True + null=False ) def __str__(self): diff --git a/smash/web/models/worker.py b/smash/web/models/worker.py index ab5ec2c1..b3dde9b8 100644 --- a/smash/web/models/worker.py +++ b/smash/web/models/worker.py @@ -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())): diff --git a/smash/web/tests/forms/test_voucher_forms.py b/smash/web/tests/forms/test_voucher_forms.py index c95063e2..003cf6c3 100644 --- a/smash/web/tests/forms/test_voucher_forms.py +++ b/smash/web/tests/forms/test_voucher_forms.py @@ -62,17 +62,3 @@ class VoucherFormTests(LoggedInWithWorkerTestCase): for key, value in voucher_form.initial.items(): form_data[key] = format_form_field(value) return form_data - - def test_valid_status(self): - study_subject = create_study_subject() - voucher = create_voucher(study_subject) - self.voucher_partner.voucher_types.add(voucher.voucher_type) - voucher.usage_partner = self.voucher_partner - voucher.save() - - form_data = self.get_voucher_form_data(voucher) - - voucher_form = VoucherForm(instance=voucher, data=form_data) - - self.assertFalse(voucher_form.is_valid()) - self.assertTrue("status" in voucher_form.errors) diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py index 0bebd3af..f7da4add 100644 --- a/smash/web/tests/functions.py +++ b/smash/web/tests/functions.py @@ -10,7 +10,7 @@ from web.models import Location, AppointmentType, StudySubject, Worker, Visit, A from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, REDCAP_BASE_URL_CONFIGURATION_TYPE, \ SEX_CHOICES_MALE, SUBJECT_TYPE_CHOICES_CONTROL, CONTACT_TYPES_PHONE, \ MONDAY_AS_DAY_OF_WEEK, COUNTRY_AFGHANISTAN_ID, VOUCHER_STATUS_NEW, GLOBAL_STUDY_ID -from web.models.worker_study_role import ROLE_CHOICES_DOCTOR +from web.models.worker_study_role import ROLE_CHOICES_DOCTOR, WORKER_VOUCHER_PARTNER from web.redcap_connector import RedcapSubject from web.views.notifications import get_today_midnight_date @@ -78,15 +78,18 @@ def get_test_id(): return result -def create_voucher(study_subject=None): +def create_voucher(study_subject=None, partner=None): if study_subject is None: study_subject = create_study_subject() + if partner is None: + partner = create_voucher_partner() number = str(get_test_id()) return Voucher.objects.create(number=number, study_subject=study_subject, issue_date=get_today_midnight_date(), expiry_date=get_today_midnight_date(), voucher_type=create_voucher_type(), + usage_partner=partner, status=VOUCHER_STATUS_NEW) @@ -229,6 +232,19 @@ def create_worker(user=None, with_test_location=False): return worker +def create_voucher_partner(): + worker = Worker.objects.create( + first_name='piotr', + last_name="gawron", + email='jacob@bla.com', + specialization="spec", + unit="LCSB", + phone_number="0123456789" + ) + WorkerStudyRole.objects.create(worker=worker, study_id=GLOBAL_STUDY_ID, role=WORKER_VOUCHER_PARTNER) + return worker + + def create_availability(worker=None): if worker is None: worker = create_worker() diff --git a/smash/web/tests/view/test_voucher.py b/smash/web/tests/view/test_voucher.py index f8c71ab9..891c4232 100644 --- a/smash/web/tests/view/test_voucher.py +++ b/smash/web/tests/view/test_voucher.py @@ -3,12 +3,15 @@ import logging import datetime from django.urls import reverse +from web.models import Worker +from web.models.worker_study_role import WORKER_VOUCHER_PARTNER from web.views.notifications import get_today_midnight_date from web.views.voucher import ExpireVouchersJob from web.forms import VoucherForm from web.models import Voucher from web.models.constants import VOUCHER_STATUS_NEW, VOUCHER_STATUS_USED, VOUCHER_STATUS_EXPIRED -from web.tests.functions import create_voucher, create_study_subject, format_form_field, create_voucher_type +from web.tests.functions import create_voucher, create_study_subject, format_form_field, create_voucher_type, \ + create_voucher_partner from .. import LoggedInTestCase logger = logging.getLogger(__name__) @@ -30,8 +33,14 @@ class VoucherTypeViewTests(LoggedInTestCase): voucher_type = create_voucher_type() study_subject = create_study_subject() study_subject.voucher_types.add(voucher_type) + + usage_partner = create_voucher_partner() + usage_partner.voucher_types.add(voucher_type) + usage_partner.save() + visit_detail_form = VoucherForm() form_data = { + "usage_partner": usage_partner.id, "status": VOUCHER_STATUS_NEW, "voucher_type": voucher_type.id } @@ -46,13 +55,16 @@ class VoucherTypeViewTests(LoggedInTestCase): def test_edit_voucher(self): voucher = create_voucher() + usage_partner = create_voucher_partner() + usage_partner.voucher_types.add(voucher.voucher_type) + usage_partner.save() voucher_form = VoucherForm(instance=voucher) form_data = {} for key, value in voucher_form.initial.items(): form_data[key] = format_form_field(value) - form_data["usage_partner"] = "" - form_data["use_date"] = "" + form_data["usage_partner"] = usage_partner.id + form_data["use_date"] = "2011-01-01" url = reverse('web.views.voucher_edit', kwargs={'pk': voucher.id}) response = self.client.post(url, data=form_data) -- GitLab