Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c77e25c
extract zipfile inside zipfile in sample data lesson
sumandari May 17, 2021
d09aeb5
update unit test for download sample data lesson
sumandari May 17, 2021
0092fff
update unit test
sumandari May 17, 2021
7de9b96
fixed dockerfile for development and the documentation
Nov 23, 2021
a35044f
modified delete convener mechanism
sumandari Nov 26, 2021
d5427d7
add unit test
sumandari Nov 26, 2021
745b191
fix typo flake8
sumandari Nov 26, 2021
547869c
fixed raising ValidationError in validate_email_address
sumandari Nov 26, 2021
79e0987
fixed typo flake8
sumandari Nov 26, 2021
bfab4ac
Merge pull request #1374 from sumandari/fix_dev_docker_and_readme
Nov 26, 2021
f4b45d3
Merge branch 'develop' of https://github.com/kartoza/prj.app into 137…
sumandari Nov 26, 2021
0e1a285
Merge branch 'develop' of https://github.com/kartoza/prj.app into 137…
sumandari Nov 26, 2021
7f837e5
Merge pull request #1376 from sumandari/1372_fix_update_sustaining_me…
Dec 2, 2021
c1a2cb5
Merge pull request #1341 from sumandari/1328_lesson_extract_zip_in_zi…
Dec 2, 2021
613dbe7
added CertificateType model
sumandari Dec 3, 2021
a1c5b72
added admin class
sumandari Dec 3, 2021
3fb6b64
added CertificateType as foreign key in Certificate models and update…
sumandari Dec 3, 2021
af6b582
updated unittest
sumandari Dec 3, 2021
ec6763c
added project certificate_type
sumandari Dec 10, 2021
1f76a37
part#2: enable certification manager to manage certificate type list
sumandari Dec 10, 2021
935b99a
fixed typo flake8
sumandari Dec 11, 2021
45ca0e3
Part#3: added certificate_type in courseform
sumandari Dec 11, 2021
5c798d9
removed certificate_type in certificate model
sumandari Dec 11, 2021
22db5b5
updated queryset in courseform
sumandari Dec 16, 2021
2adf94e
Part#4 update template
sumandari Dec 16, 2021
5aeacd6
fixed typo flake8
sumandari Dec 16, 2021
85bd0b4
updated unit test and fix failed test
sumandari Dec 24, 2021
cf89c41
updated unit test and fix failed test
sumandari Dec 24, 2021
b2895c7
Merge pull request #1375 from sumandari/1373_delete_converner_mechanism
Feb 11, 2022
13f8c1a
fix typo
sumandari Feb 11, 2022
75fe979
wrap CertificateType query in try catch block
sumandari Feb 11, 2022
6560b4c
added unit test
sumandari Feb 12, 2022
4398bef
Merge branch 'develop' of https://github.com/kartoza/prj.app into 137…
sumandari Feb 12, 2022
f2254ea
fixed typo flake8
sumandari Feb 12, 2022
bdb45db
Merge pull request #1383 from sumandari/1371_certification_type
Feb 14, 2022
b26edd3
bump to version 2.3.0
Feb 14, 2022
5685092
Update version parameter
dominicschaff Feb 14, 2022
d2582d5
Merge pull request #1396 from kartoza/feature/fix-github-action-failure
Feb 14, 2022
28560c6
bump to version 2.3.1
Feb 14, 2022
f783770
certifications dev
sumandari Dec 3, 2021
eb639d1
Merge branch 'develop' of https://github.com/kartoza/prj.app into cer…
sumandari Feb 15, 2022
f0fcd05
fix merge conflict
sumandari Feb 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-push-images-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
with:
images: ${{ secrets.DOCKERHUB_REPO }}/projecta-uwsgi
tags: |
type=semver,pattern=\d.\d.\d
type=semver,pattern={{version}}
type=ref,event=branch
type=ref,event=pr

Expand Down
3 changes: 2 additions & 1 deletion README-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ When it's done, you can continue with this command:
Linux and MacOS:

```
cp docker-compose.override.example.yml docker-compose.override.yml
make build-devweb
make devweb
cp docker-compose.override.example.yml docker-compose.override.yml
```

In case you don't get some not installed packages, you can run this
Expand All @@ -54,6 +54,7 @@ repeatable steps:
Windows:

```
copy docker-compose.override.example.yml docker-compose.override.yml
make-devbuild.bat
make-devweb.bat
```
Expand Down
6 changes: 3 additions & 3 deletions deployment/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ MAINTAINER Tim Sutton<tim@kartoza.com>
#RUN ln -s /bin/true /sbin/initctl

# Pandoc needed to generate rst dumps, uic compressor needed for django-pipeline
RUN apt-get update -y; apt-get -y --force-yes install yui-compressor gettext
RUN apt-get update -y && apt-get -y --force-yes install yui-compressor gettext
RUN wget https://github.com/jgm/pandoc/releases/download/1.17.1/pandoc-1.17.1-2-amd64.deb
RUN dpkg -i pandoc-1.17.1-2-amd64.deb && rm pandoc-1.17.1-2-amd64.deb

Expand All @@ -18,7 +18,7 @@ ENV CRYPTOGRAPHY_DONT_BUILD_RUST=1
ADD deployment/docker/REQUIREMENTS.txt /REQUIREMENTS.txt
ADD deployment/docker/uwsgi.conf /uwsgi.conf
ADD django_project /home/web/django_project
RUN pip install -r /REQUIREMENTS.txt
RUN pip install --upgrade pip && pip install -r /REQUIREMENTS.txt
RUN pip install uwsgi


Expand Down Expand Up @@ -50,7 +50,7 @@ RUN echo "export VISIBLE=now" >> /etc/profile
# End of cut & paste section

ADD deployment/docker/REQUIREMENTS-dev.txt /REQUIREMENTS-dev.txt
RUN pip install -r /REQUIREMENTS-dev.txt
RUN pip install --upgrade pip && pip install -r /REQUIREMENTS-dev.txt
ADD deployment/docker/bashrc /root/.bashrc

# --------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions deployment/docker/REQUIREMENTS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ pinax-notifications==5.0.3
pinax-templates==2.0.2
# rich text editor
django-tinymce==3.2.0
django-sorting-bootstrap==2.8.0
2 changes: 1 addition & 1 deletion django_project/.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.2.0
2.3.1
11 changes: 11 additions & 0 deletions django_project/certification/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.contrib.gis import admin
from simple_history.admin import SimpleHistoryAdmin
from certification.models.certificate import Certificate
from certification.models.certificate_type import CertificateType
from certification.models.course import Course
from certification.models.training_center import TrainingCenter
from certification.models.course_convener import CourseConvener
Expand Down Expand Up @@ -34,6 +35,15 @@ def queryset(self, request):
return query_set


class CertificateTypeAdmin(admin.ModelAdmin):
"""CertificateType admin model."""

list_display = ('name', 'wording', 'order')
list_editable = ('order', )
search_fields = ('name', 'wording')
ordering = ('order', )


class AttendeeAdmin(admin.ModelAdmin):
"""Attendee admin model."""
list_display = ('firstname', 'surname', 'email', 'certifying_organisation')
Expand Down Expand Up @@ -163,6 +173,7 @@ class StatusAdmin(admin.ModelAdmin):


admin.site.register(Certificate, CertificateAdmin)
admin.site.register(CertificateType, CertificateTypeAdmin)
admin.site.register(Attendee, AttendeeAdmin)
admin.site.register(Course, CourseAdmin)
admin.site.register(CourseType, CourseTypeAdmin)
Expand Down
Empty file.
67 changes: 65 additions & 2 deletions django_project/certification/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@
Fieldset,
Submit,
Field,
HTML
)
from .models import (
CertifyingOrganisation,
CertifyingOrganisationChecklist,
CertificateType,
CertificateChecklist,
CourseConvener,
CourseType,
TrainingCenter,
Expand Down Expand Up @@ -68,6 +72,27 @@ def __init__(self, *args, **kwargs):
form_title = 'New Certifying Organisation for %s' % self.project.name
self.helper = FormHelper()
self.helper.include_media = False
self.RESPONSE_NAME_PREFIX = 'checklist-response'

# additional layout for checklist questions
self.certificate_checklists = CertificateChecklist.objects.filter(
is_archived=False, is_additional_response_enabled=True).all()
checklist_questions = []
if CertificateChecklist.objects.filter(
is_archived=False,
is_additional_response_enabled=True).exists():
checklist_questions.append(
HTML('<legend>Please answer the following questions</legend>')
)
for _ in self.certificate_checklists:
checklist_questions.append(
Field(
f'{self.RESPONSE_NAME_PREFIX}_{_.id}',
css_class='form-control',
label=f'{_.question}'
)
)

layout = Layout(
Fieldset(
form_title,
Expand All @@ -79,8 +104,9 @@ def __init__(self, *args, **kwargs):
Field('organisation_phone', css_class='form-control'),
Field('logo', css_class='form-control'),
Field('organisation_owners', css_class='form-control'),
*checklist_questions,
Field('project', css_class='form-control'),
css_id='project-form')
css_id='project-form'),
)
self.helper.layout = layout
self.helper.html5_required = False
Expand All @@ -90,12 +116,40 @@ def __init__(self, *args, **kwargs):
self.fields['organisation_owners'].initial = [self.user]
self.fields['project'].initial = self.project
self.fields['project'].widget = forms.HiddenInput()
# additional fields for checklist questions
for cl in self.certificate_checklists:
field_name = f'{self.RESPONSE_NAME_PREFIX}_{cl.id}'
self.fields[field_name] = forms.CharField(
widget=forms.Textarea(),
label=f'{cl.question}'
)
if (self.instance and
cl.certifyingorganisationchecklist_set.filter(
certifying_organisation=self.instance).exists()):
applicant_resp = cl.certifyingorganisationchecklist_set.filter(
certifying_organisation=self.instance
).last().applicant_response
self.fields[field_name].initial = applicant_resp
self.helper.add_input(Submit('submit', 'Submit'))

def save(self, commit=True):
instance = super(CertifyingOrganisationForm, self).save(commit=False)
instance.save()
self.save_m2m()
# save the checklist_response
for cl in self.certificate_checklists:
cert_org_cl, _ = (
CertifyingOrganisationChecklist.objects.get_or_create(
question=cl, certifying_organisation=instance
)
)
if cl.is_additional_response_enabled:
field_name = f'{self.RESPONSE_NAME_PREFIX}_{cl.id}'
response_text = None
if self.cleaned_data[field_name]:
response_text = self.cleaned_data[field_name]
cert_org_cl.applicant_response = response_text
cert_org_cl.save()
return instance


Expand Down Expand Up @@ -156,6 +210,7 @@ class Meta:
'user',
'degree',
'signature',
'is_active',
)

def __init__(self, *args, **kwargs):
Expand All @@ -171,6 +226,7 @@ def __init__(self, *args, **kwargs):
Field('user', css_class='form-control chosen-select'),
Field('degree', css_class='form-control'),
Field('signature', css_class='form-control'),
Field('is_active', css_class='checkbox-primary'),
)
)
self.helper.layout = layout
Expand Down Expand Up @@ -303,6 +359,7 @@ class Meta:
'end_date',
'template_certificate',
'certifying_organisation',
'certificate_type',
)

def __init__(self, *args, **kwargs):
Expand All @@ -322,14 +379,16 @@ def __init__(self, *args, **kwargs):
Field('start_date', css_class='form-control'),
Field('end_date', css_class='form-control'),
Field('template_certificate', css_class='form-control'),
Field('certificate_type', css_class='form-control'),
)
)
self.helper.layout = layout
self.helper.html5_required = False
super(CourseForm, self).__init__(*args, **kwargs)
self.fields['course_convener'].queryset = \
CourseConvener.objects.filter(
certifying_organisation=self.certifying_organisation)
certifying_organisation=self.certifying_organisation,
is_active=True)
self.fields['course_convener'].label_from_instance = \
lambda obj: "%s <%s>" % (obj.user.get_full_name(), obj)
self.fields['course_type'].queryset = \
Expand All @@ -342,6 +401,10 @@ def __init__(self, *args, **kwargs):
self.certifying_organisation
self.fields['certifying_organisation'].widget = forms.HiddenInput()
self.helper.add_input(Submit('submit', 'Submit'))
self.fields['certificate_type'].queryset = \
CertificateType.objects.filter(
projectcertificatetype__project=
self.certifying_organisation.project)

def save(self, commit=True):
instance = super(CourseForm, self).save(commit=False)
Expand Down
34 changes: 34 additions & 0 deletions django_project/certification/migrations/0007_certificatetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 2.2.18 on 2021-12-03 00:56

from django.db import migrations, models


def add_certification_type_as_existing_value(apps, schema_editor):
CertificateType = apps.get_model('certification', 'CertificateType')
CertificateType.objects.create(
name='attendance and completion',
wording='Has attended and completed the course:',
order=0
)


class Migration(migrations.Migration):

dependencies = [
('certification', '0006_auto_20210730_0615'),
]

operations = [
migrations.CreateModel(
name='CertificateType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='Certificate type.', max_length=200, unique=True)),
('description', models.TextField(blank=True, help_text='Certificate type description - 1000 characters limit.', max_length=1000, null=True)),
('wording', models.CharField(help_text='Wording that will be placed on certificate. e.g. "Has attended and completed".', max_length=500)),
('order', models.IntegerField(blank=True, null=True, unique=True)),
],
),

migrations.RunPython(add_certification_type_as_existing_value, reverse_code=migrations.RunPython.noop),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.18 on 2021-11-26 04:51

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('certification', '0006_auto_20210730_0615'),
]

operations = [
migrations.AddField(
model_name='courseconvener',
name='is_active',
field=models.BooleanField(default=True, help_text='Inactive Convener will not be available in your organisation list.'),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 2.2.18 on 2021-12-10 02:23

from django.db import migrations, models
import django.db.models.deletion

def create_existing_project_certificate_type(apps, schema_editor):
CertificateType = apps.get_model('certification', 'CertificateType')
ProjectCertificateType = apps.get_model('certification', 'ProjectCertificateType')
Project = apps.get_model('base', 'Project')
certificate_type = CertificateType.objects.filter(
name='attendance and completion').first()
projects = Project.objects.all()

for project in projects:
ProjectCertificateType.objects.create(
project=project,
certificate_type=certificate_type
)

class Migration(migrations.Migration):

dependencies = [
('base', '0006_auto_20210308_0244'),
('certification', '0007_certificatetype'),
]

operations = [
migrations.CreateModel(
name='ProjectCertificateType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('certificate_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='certification.CertificateType')),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='base.Project')),
],
),

migrations.RunPython(create_existing_project_certificate_type, reverse_code=migrations.RunPython.noop),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 2.2.18 on 2021-12-10 08:31

from django.db import migrations, models
import django.db.models.deletion

def set_existing_certificate_type_value(apps, shcema_editor):
CertificateType = apps.get_model('certification', 'CertificateType')
Course = apps.get_model('certification', 'Course')
certificate_type = CertificateType.objects.filter(
name='attendance and completion').first()
courses = Course.objects.all()

for course in courses:
course.certificate_type = certificate_type
course.save(update_fields=['certificate_type'])


class Migration(migrations.Migration):

dependencies = [
('certification', '0008_projectcertificatetype'),
]

operations = [
migrations.AddField(
model_name='course',
name='certificate_type',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='certification.CertificateType'),
),

migrations.RunPython(set_existing_certificate_type_value, reverse_code=migrations.RunPython.noop),

migrations.AlterField(
model_name='course',
name='certificate_type',
field=models.ForeignKey(null=False, on_delete=django.db.models.deletion.PROTECT,
to='certification.CertificateType'),
preserve_default=False,
),

]
Loading