added competence models
This commit is contained in:
parent
d4e6778259
commit
3de2c1a2c8
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 3.2.12 on 2022-04-26 12:15
|
||||
# Generated by Django 3.2.12 on 2022-05-04 15:52
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
|
@ -20,12 +20,35 @@ class Migration(migrations.Migration):
|
|||
name='Circle',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
|
||||
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
|
||||
('description', models.TextField(blank=True, default='')),
|
||||
('goals', models.TextField(blank=True, default='')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Circle',
|
||||
},
|
||||
bases=('wagtailcore.page', models.Model),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Competence',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
|
||||
('category_short', models.CharField(default='', max_length=3)),
|
||||
('name', models.CharField(max_length=2048)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Competence',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CompetencePage',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Learning Path',
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
|
|
@ -39,15 +62,17 @@ class Migration(migrations.Migration):
|
|||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LearningUnit',
|
||||
name='LearningSequence',
|
||||
fields=[
|
||||
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
|
||||
('contents', wagtail.core.fields.StreamField([('web_based_training', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('video', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())]))], blank=True, null=True)),
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
|
||||
('title', models.CharField(default='', max_length=256)),
|
||||
('category', models.CharField(choices=[('INCIRCLE', 'In Circle'), ('START', 'Start'), ('END', 'End')], default='INCIRCLE', max_length=16)),
|
||||
('circle', modelcluster.fields.ParentalKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='learning_sequences', to='learnpath.circle')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Learning Unit',
|
||||
'verbose_name': 'Learning Sequence',
|
||||
},
|
||||
bases=('wagtailcore.page',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Topic',
|
||||
|
|
@ -63,17 +88,33 @@ class Migration(migrations.Migration):
|
|||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LearningSequence',
|
||||
name='LearningUnit',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
|
||||
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
|
||||
('title', models.CharField(default='', max_length=256)),
|
||||
('category', models.CharField(choices=[('INCIRCLE', 'In Circle'), ('START', 'Start'), ('END', 'End')], default='INCIRCLE', max_length=16)),
|
||||
('circle', modelcluster.fields.ParentalKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='learning_sequences', to='learnpath.circle')),
|
||||
('contents', wagtail.core.fields.StreamField([('web_based_training', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('video', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())]))], blank=True, null=True)),
|
||||
('learning_sequence', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='learning_units', to='learnpath.learningsequence')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Learning Sequence',
|
||||
'verbose_name': 'Learning Unit',
|
||||
},
|
||||
bases=('wagtailcore.page', models.Model),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FullfillmentCriteria',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=2048)),
|
||||
('competence', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='learnpath.competence')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Fullfillment Criteria',
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='competence',
|
||||
name='competence_page',
|
||||
field=modelcluster.fields.ParentalKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='competences', to='learnpath.competencepage'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='circle',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 3.2.12 on 2022-04-27 08:58
|
||||
# Generated by Django 3.2.12 on 2022-05-04 16:00
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
|
@ -11,12 +11,7 @@ class Migration(migrations.Migration):
|
|||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='circle',
|
||||
name='sort_order',
|
||||
field=models.IntegerField(blank=True, editable=False, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='learningunit',
|
||||
model_name='fullfillmentcriteria',
|
||||
name='sort_order',
|
||||
field=models.IntegerField(blank=True, editable=False, null=True),
|
||||
),
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# Generated by Django 3.2.12 on 2022-05-03 11:03
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('learnpath', '0002_auto_20220427_1058'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='learningunit',
|
||||
name='learning_sequence',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='circles', to='learnpath.learningsequence'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# Generated by Django 3.2.12 on 2022-05-03 11:22
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('learnpath', '0003_learningunit_learning_sequence'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='learningunit',
|
||||
name='learning_sequence',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='learning_units', to='learnpath.learningsequence'),
|
||||
),
|
||||
]
|
||||
|
|
@ -9,7 +9,9 @@ from wagtail.core.models import Page, Orderable
|
|||
from django.utils.text import slugify
|
||||
|
||||
|
||||
|
||||
from vbv_lernwelt.learnpath.models_learning_unit_content import WebBasedTrainingBlock, VideoBlock
|
||||
from vbv_lernwelt.learnpath.models_competences import *
|
||||
|
||||
|
||||
class LearningPath(Page):
|
||||
|
|
@ -119,6 +121,7 @@ class LearningSequence(Orderable):
|
|||
on_delete=models.CASCADE,
|
||||
related_name='learning_sequences',
|
||||
)
|
||||
icon = ""
|
||||
|
||||
panels = [FieldPanel('title'), FieldPanel('category')]
|
||||
|
||||
|
|
@ -130,14 +133,14 @@ class LearningSequence(Orderable):
|
|||
|
||||
|
||||
class LearningUnit(Page, Orderable):
|
||||
# TODO: Review model architecture, is the stream fiel the right thing here?
|
||||
# TODO: Review model architecture, is the stream field the right thing here?
|
||||
parent_page_types = ['learnpath.Circle']
|
||||
learning_sequence = models.ForeignKey(
|
||||
'learnpath.LearningSequence',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='learning_units'
|
||||
related_name='learning_units',
|
||||
)
|
||||
|
||||
content_blocks = [
|
||||
|
|
@ -150,8 +153,8 @@ class LearningUnit(Page, Orderable):
|
|||
|
||||
content_panels = [
|
||||
FieldPanel('title', classname="full title"),
|
||||
FieldPanel('learning_sequence'),
|
||||
StreamFieldPanel('contents'),
|
||||
FieldPanel('learning_sequence')
|
||||
]
|
||||
|
||||
subpage_types = []
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
from django.db import models
|
||||
from wagtail.core.models import Page, Orderable
|
||||
from modelcluster.fields import ParentalKey
|
||||
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel, InlinePanel
|
||||
|
||||
|
||||
class CompetencePage(Page):
|
||||
"""This is the page where the competences and Fullfillment criterias are manged
|
||||
For one Learning Path"""
|
||||
|
||||
|
||||
content_panels = Page.content_panels + [
|
||||
InlinePanel('competences', label="Competences"),
|
||||
]
|
||||
|
||||
subpage_types = ['learnpath.Circle']
|
||||
|
||||
parent_page_types = ['learnpath.LearningPath']
|
||||
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Learning Path"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.title}"
|
||||
|
||||
|
||||
class Competence(Orderable):
|
||||
""" In VBV Terms this is a "Handlungskompetenz"""
|
||||
category_short = models.CharField(max_length=3, default='')
|
||||
name = models.CharField(max_length=2048)
|
||||
|
||||
|
||||
competence_page = ParentalKey('learnpath.CompetencePage',
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='competences',
|
||||
)
|
||||
|
||||
|
||||
|
||||
def get_short_info(self):
|
||||
return f"{self.category_short}{self.sort_order}"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.get_short_info()}: {self.name}"
|
||||
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Competence"
|
||||
|
||||
|
||||
class FullfillmentCriteria(Orderable):
|
||||
""" VBV Term Leistungskriterium"""
|
||||
name = models.CharField(max_length=2048)
|
||||
competence = models.ForeignKey(Competence, on_delete=models.CASCADE, null=True)
|
||||
|
||||
def get_short_info(self):
|
||||
return f"{self.competence.get_short_info()}.{self.sort_order}"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.get_short_info()}: {self.name}"
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Fullfillment Criteria"
|
||||
|
|
@ -31,3 +31,11 @@ class WebBasedTrainingBlock(blocks.StructBlock):
|
|||
|
||||
class Meta:
|
||||
icon = 'media'
|
||||
|
||||
# 'Transver Task'
|
||||
class TranverTaskBlock(blocks.StructBlock):
|
||||
title = models.CharField(max_length=128, default="")
|
||||
description = models.TextField(default="")
|
||||
|
||||
class Meta:
|
||||
icon = 'media'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
{
|
||||
"competences": [
|
||||
{
|
||||
"name": "Weiterempfehlung für Neukunden generieren",
|
||||
"category_short": "A",
|
||||
"fullfillment_criteria": [
|
||||
{
|
||||
"name": "bestehende Kunden so zu beraten, dass sie von diesen weiterempfohlen werden"
|
||||
},
|
||||
{
|
||||
"name": "geeignete Personen wie z.B. Garagisten, Architekten, Treuhänder auf die Vermittlung/Zusammenarbeit anzusprechen"
|
||||
},
|
||||
{
|
||||
"name": "verschiedene Datenquellen wie Internet, Telefonbuch, Handelszeitung, Baugesuche etc. gezielt für die Gewinnung von Neukunden zu benützen"
|
||||
},
|
||||
{
|
||||
"name": "ein beliebiges Gespräch resp. einen bestehenden Kontakt in die Richtung «Versicherung» zu lenken"
|
||||
},
|
||||
{
|
||||
"name": "das Thema Risiko und Sicherheit in einem Gespräch gezielt und auf die Situation des jeweiligen Gesprächspartners bezogen einfliessen zu lassen"
|
||||
},
|
||||
{
|
||||
"name": "im täglichen Kontakt potentielle Kundinnen und Kunden zu erkennen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Kundengespräche vereinbaren",
|
||||
"category_short": "A",
|
||||
"fullfillment_criteria": [
|
||||
{
|
||||
"name": "je nach (Neu-) Kunde Form und Ort für das Gespräch festzulegen"
|
||||
},
|
||||
{
|
||||
"name": "sich intern und extern die nötigen Informationen über den (Neu-) Kunde zu beschaffen"
|
||||
},
|
||||
{
|
||||
"name": "die Terminierung auf ein bestimmtes Thema wie z.B. Rechtsschutz, Vorsorge, Krankenversicherung etc. auszurichten"
|
||||
},
|
||||
{
|
||||
"name": "für das zu führende Gespräch eine Agenda zu erstellen"
|
||||
},
|
||||
{
|
||||
"name": "für das zu führende Gespräch geeignete Hilfsmittel und Unterlagen zusammenzustellen"
|
||||
}, {
|
||||
"name": "eine Kaltakquise durchzuführen und auf mögliche Einwände reagieren zu können"
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
"name": "Auftritt in den sozialen Medien zeitgemäss halten",
|
||||
"category_short": "A",
|
||||
"fullfillment_criteria": [ {
|
||||
"name": "in Zusammenarbeit mit den IT-Spezialisten und der Marketingabteilung die Inhalte für den zu realisierenden Medienauftritt zielgruppengerecht festzulegen"
|
||||
},
|
||||
{
|
||||
"name": "für die verschiedenen Kundensegmente die passenden sozialen Medien zu definieren"
|
||||
},
|
||||
{
|
||||
"name": "die Inhalte compliant zu halten"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Kundendaten erfassen",
|
||||
"category_short": "A",
|
||||
"fullfillment_criteria": []
|
||||
},
|
||||
{
|
||||
"name": "Wünsche, Ziele und Bedürfnisse der Kunden im Gespräch ermitteln",
|
||||
"category_short": "B",
|
||||
"fullfillment_criteria": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import factory
|
||||
import wagtail_factories
|
||||
|
||||
from vbv_lernwelt.learnpath.models_competences import Competence, FullfillmentCriteria, CompetencePage
|
||||
from vbv_lernwelt.learnpath.tests.learningpath_factories import LearningPathFactory
|
||||
|
||||
|
||||
class CompetencePageFactory(wagtail_factories.PageFactory):
|
||||
# learning_path = factory.SubFactory(LearningPathFactory)
|
||||
|
||||
class Meta:
|
||||
model = CompetencePage
|
||||
|
||||
|
||||
class CompetenceFactory(factory.django.DjangoModelFactory):
|
||||
category_short = 'A'
|
||||
name = "Weiterempfehung für neukunden generieren"
|
||||
competence_page = factory.SubFactory(CompetencePageFactory)
|
||||
|
||||
class Meta:
|
||||
model = Competence
|
||||
|
||||
|
||||
class FullfilmentCriteriaFactory(factory.django.DjangoModelFactory):
|
||||
name = 'Bestehende Kunden so zu beraten, dass sie von diesen weiterempfohlen werden'
|
||||
competence = factory.SubFactory(CompetenceFactory)
|
||||
|
||||
class Meta:
|
||||
model = FullfillmentCriteria
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import json
|
||||
|
||||
|
||||
import os.path
|
||||
|
||||
from vbv_lernwelt.learnpath.tests.competences_factories import CompetenceFactory, FullfilmentCriteriaFactory
|
||||
|
||||
competences_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'competences.json')
|
||||
|
||||
|
||||
def create_default_competences(competences_json=competences_file):
|
||||
with open(competences_json) as f:
|
||||
competences_json = json.load(f)
|
||||
|
||||
for index, compentence in enumerate(competences_json['competences']):
|
||||
|
||||
competence_model = CompetenceFactory(name=compentence['name'], category_short=compentence['category_short'], sort_order=index)
|
||||
print(competence_model)
|
||||
|
||||
for criteria_index, criteria in enumerate(compentence['fullfillment_criteria']):
|
||||
criteria_model = FullfilmentCriteriaFactory(name=criteria['name'], competence=competence_model, sort_order=criteria_index)
|
||||
print(criteria_model)
|
||||
|
||||
|
|
@ -2,16 +2,22 @@ import wagtail_factories
|
|||
from wagtail.core.models import Site
|
||||
|
||||
from vbv_lernwelt.learnpath.models import LearningPath, Topic, Circle, LearningSequence, LearningUnit
|
||||
from vbv_lernwelt.learnpath.tests.create_default_competences import create_default_competences
|
||||
from vbv_lernwelt.learnpath.tests.learningpath_factories import LearningPathFactory, TopicFactory, CircleFactory, \
|
||||
LearningSequenceFactory, LearningUnitFactory, VideoBlockFactory, WebBasedTrainingBlockFactory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def create_default_learning_path():
|
||||
site = Site.objects.filter(is_default_site=True).first()
|
||||
|
||||
if not site:
|
||||
site = wagtail_factories.SiteFactory(is_default_site=True)
|
||||
|
||||
create_default_competences()
|
||||
|
||||
lp = LearningPathFactory(title="Versicherungsvermittler/in", parent=site.root_page)
|
||||
|
||||
tp = TopicFactory(title="Basis", is_visible=False, learning_path=lp)
|
||||
|
|
@ -129,6 +135,9 @@ von Neukunden zu benützen
|
|||
circle_7 = CircleFactory.create(title="Prüfungsvorbereitung", parent=lp, topic=tp)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def delete_default_learning_path():
|
||||
LearningUnit.objects.all().delete()
|
||||
LearningSequence.objects.all().delete()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
from django.test import TestCase
|
||||
|
||||
from vbv_lernwelt.learnpath.models_competences import Competence, FullfillmentCriteria
|
||||
from vbv_lernwelt.learnpath.tests.competences_factories import CompetencePageFactory, CompetenceFactory, \
|
||||
FullfilmentCriteriaFactory
|
||||
|
||||
|
||||
class TestCompetencesFactories(TestCase):
|
||||
def test_create_competences_page(self):
|
||||
CompetencePageFactory()
|
||||
|
||||
def test_create_competence(self):
|
||||
CompetenceFactory(name='Boogie Woogie')
|
||||
self.assertEqual(Competence.objects.filter(name='Boogie Woogie').count(), 1)
|
||||
|
||||
def test_create_fullfillment_criteria(self):
|
||||
FullfilmentCriteriaFactory(name='shuffle like ...')
|
||||
self.assertEqual(FullfillmentCriteria.objects.filter(name='shuffle like ...').count(), 1)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
from django.conf import settings
|
||||
from django.test import TestCase
|
||||
from wagtail.core.models import Locale
|
||||
|
||||
from vbv_lernwelt.learnpath.models import LearningPath
|
||||
from vbv_lernwelt.learnpath.tests.create_default_competences import create_default_competences
|
||||
from vbv_lernwelt.learnpath.tests.create_default_learning_path import create_default_learning_path
|
||||
|
||||
|
||||
class TestCreateDefaultCompetences(TestCase):
|
||||
def test_create_default_competeneces(self):
|
||||
create_default_competences()
|
||||
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
from django.test import TestCase
|
||||
|
||||
from server.vbv_lernwelt.core.models import User
|
||||
|
||||
|
||||
class TestWhatever(TestCase):
|
||||
def test_print(self):
|
||||
print("hallo " * 80)
|
||||
|
||||
def test_user(self):
|
||||
|
||||
User.objects.get_or_create(name='hallo ')
|
||||
|
||||
Loading…
Reference in New Issue