Skip to content

Commit

Permalink
Merge pull request #43 from openimis/feature/OM-344
Browse files Browse the repository at this point in the history
OM-344: Group of Worker feature - backend
  • Loading branch information
malinowskikam authored Oct 22, 2024
2 parents 54da3af + b806958 commit 9d33b5c
Show file tree
Hide file tree
Showing 17 changed files with 1,096 additions and 10 deletions.
8 changes: 8 additions & 0 deletions worker_voucher/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"gql_worker_voucher_acquire_unassigned_perms": ["204006"],
"gql_worker_voucher_acquire_assigned_perms": ["204007"],
"gql_worker_voucher_assign_vouchers_perms": ["204008"],
"gql_group_of_worker_search_perms": ["205001"],
"gql_group_of_worker_create_perms": ["205002"],
"gql_group_of_worker_update_perms": ["205003"],
"gql_group_of_worker_delete_perms": ["205004"],
"unassigned_voucher_enabled": True,
"price_per_voucher": "100.00",
"max_generic_vouchers": 1000,
Expand Down Expand Up @@ -42,6 +46,10 @@ class WorkerVoucherConfig(AppConfig, ConfigUtilMixin):
gql_worker_voucher_acquire_unassigned_perms = None
gql_worker_voucher_acquire_assigned_perms = None
gql_worker_voucher_assign_vouchers_perms = None
gql_group_of_worker_search_perms = None
gql_group_of_worker_create_perms = None
gql_group_of_worker_update_perms = None
gql_group_of_worker_delete_perms = None

unassigned_voucher_enabled = None
price_per_voucher = None
Expand Down
94 changes: 93 additions & 1 deletion worker_voucher/gql_mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from policyholder.services import PolicyHolderInsuree as PolicyHolderInsureeService
from worker_voucher.apps import WorkerVoucherConfig
from worker_voucher.models import WorkerVoucher
from worker_voucher.services import WorkerVoucherService, validate_acquire_unassigned_vouchers, \
from worker_voucher.services import WorkerVoucherService, GroupOfWorkerService, validate_acquire_unassigned_vouchers, \
validate_acquire_assigned_vouchers, validate_assign_vouchers, create_assigned_voucher, create_voucher_bill, \
create_unassigned_voucher, assign_voucher, economic_unit_user_filter, check_existing_active_vouchers

Expand Down Expand Up @@ -379,3 +379,95 @@ def _mutate(cls, user, count=None, economic_unit_code=None, workers=None, date_r

class Input(AssignVouchersMutationInput):
pass


class CreateOrUpdateGroupOfWorkerMutation(BaseMutation):
"""
Create a new group of worker or update existing group
"""
_mutation_module = "worker_voucher"
_mutation_class = "CreateOrUpdateGroupOfWorkerMutation"

class Input(OpenIMISMutation.Input):
id = graphene.UUID(required=False)
name = graphene.String(required=True, max_length=50)
economic_unit_code = graphene.String(required=True)
insurees_chf_id = graphene.List(graphene.String, required=True)

@classmethod
def _validate_mutation(cls, user, **data):
if type(user) is AnonymousUser or not user.id or not user.has_perms(
WorkerVoucherConfig.gql_worker_voucher_acquire_assigned_perms):
raise ValidationError("mutation.authentication_required")

@classmethod
def _mutate(cls, user, **data):
try:
data.pop('client_mutation_id', None)
data.pop('client_mutation_label', None)
eu_code = data.pop('economic_unit_code', None)
eu_uuid = (PolicyHolder.objects
.filter(economic_unit_user_filter(user), code=eu_code)
.values_list('uuid', flat=True)
.first())
if not eu_uuid:
return [{"message": _("worker_voucher.validation.economic_unit_not_exists")}]
with transaction.atomic():
data['policyholder_id'] = eu_uuid
service = GroupOfWorkerService(user)
result = service.create_or_update(data, eu_code)
if not result.get("success"):
return result
return None
except Exception as exc:
return [
{
'message': "worker_voucher.mutation.failed_to_create_or_update_group_of_worker",
'detail': str(exc)
}]


class DeleteGroupOfWorkerMutation(BaseMutation):
"""
Delete a chosen group of worker
"""
_mutation_module = "worker_voucher"
_mutation_class = "DeleteGroupOfWorkerMutation"

class Input(OpenIMISMutation.Input):
uuid = graphene.String(required=False)
uuids = graphene.List(graphene.String, required=False)
economic_unit_code = graphene.String(required=True)

@classmethod
def _validate_mutation(cls, user, **data):
if type(user) is AnonymousUser or not user.id or not user.has_perms(
WorkerVoucherConfig.gql_group_of_worker_delete_perms):
raise ValidationError("mutation.authentication_required")

@classmethod
def _mutate(cls, user, uuid=None, uuids=None, economic_unit_code=None, **data):
uuids_to_delete = [uuid] if uuid else uuids
if not uuids_to_delete:
return [{"message": _("workers.validation.no_group_of_workers_to_delete")}]

eu_uuid = (PolicyHolder.objects
.filter(economic_unit_user_filter(user), code=economic_unit_code)
.values_list('uuid', flat=True)
.first())

if not eu_uuid:
return [{"message": _("worker_voucher.validation.economic_unit_not_exists")}]

errors = []
service = GroupOfWorkerService(user)
try:
with transaction.atomic():
for group_id in uuids_to_delete:
errors += service.delete(group_id, eu_uuid)
if errors:
raise ValueError("Errors during mutation")
except ValueError:
pass

return errors
38 changes: 37 additions & 1 deletion worker_voucher/gql_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from insuree.models import Insuree
from invoice.models import Bill
from policyholder.gql import PolicyHolderGQLType
from worker_voucher.models import WorkerVoucher
from worker_voucher.models import WorkerVoucher, GroupOfWorker, WorkerGroup
from worker_voucher.services import get_worker_yearly_voucher_count_counts


Expand Down Expand Up @@ -89,3 +89,39 @@ class OnlineWorkerDataGQLType(graphene.ObjectType):
other_names = graphene.String()
last_name = graphene.String()
photo = graphene.String()


class GroupOfWorkerGQLType(DjangoObjectType):
uuid = graphene.String(source='uuid')

class Meta:
model = GroupOfWorker
interfaces = (graphene.relay.Node,)
filter_fields = {
"id": ["exact"],
"name": ["exact", "istartswith", "icontains", "iexact"],
**prefix_filterset("policyholder__", PolicyHolderGQLType._meta.filter_fields),

"date_created": ["exact", "lt", "lte", "gt", "gte"],
"date_updated": ["exact", "lt", "lte", "gt", "gte"],
"is_deleted": ["exact"],
}
connection_class = ExtendedConnection


class WorkerGroupGQLType(DjangoObjectType):
uuid = graphene.String(source='uuid')

class Meta:
model = WorkerGroup
interfaces = (graphene.relay.Node,)
filter_fields = {
"id": ["exact"],
"insuree_id": ["exact"],
**prefix_filterset("group__", GroupOfWorkerGQLType._meta.filter_fields),

"date_created": ["exact", "lt", "lte", "gt", "gte"],
"date_updated": ["exact", "lt", "lte", "gt", "gte"],
"is_deleted": ["exact"],
}
connection_class = ExtendedConnection
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Generated by Django 4.2.15 on 2024-10-15 13:05

import core.fields
import datetime
import dirtyfields.dirtyfields
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import simple_history.models


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('insuree', '0023_alter_family_head_insuree'),
('worker_voucher', '0009_alter_historicalworkerupload_status_and_more'),
]

operations = [
migrations.CreateModel(
name='GroupOfWorker',
fields=[
('id', models.UUIDField(db_column='UUID', default=None, editable=False, primary_key=True, serialize=False)),
('is_deleted', models.BooleanField(db_column='isDeleted', default=False)),
('json_ext', models.JSONField(blank=True, db_column='Json_ext', null=True)),
('date_created', core.fields.DateTimeField(db_column='DateCreated', default=datetime.datetime.now, null=True)),
('date_updated', core.fields.DateTimeField(db_column='DateUpdated', default=datetime.datetime.now, null=True)),
('version', models.IntegerField(default=1)),
('name', models.CharField(max_length=50)),
('user_created', models.ForeignKey(db_column='UserCreatedUUID', on_delete=django.db.models.deletion.DO_NOTHING, related_name='%(class)s_user_created', to=settings.AUTH_USER_MODEL)),
('user_updated', models.ForeignKey(db_column='UserUpdatedUUID', on_delete=django.db.models.deletion.DO_NOTHING, related_name='%(class)s_user_updated', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
bases=(dirtyfields.dirtyfields.DirtyFieldsMixin, models.Model),
),
migrations.CreateModel(
name='WorkerGroup',
fields=[
('id', models.UUIDField(db_column='UUID', default=None, editable=False, primary_key=True, serialize=False)),
('is_deleted', models.BooleanField(db_column='isDeleted', default=False)),
('json_ext', models.JSONField(blank=True, db_column='Json_ext', null=True)),
('date_created', core.fields.DateTimeField(db_column='DateCreated', default=datetime.datetime.now, null=True)),
('date_updated', core.fields.DateTimeField(db_column='DateUpdated', default=datetime.datetime.now, null=True)),
('version', models.IntegerField(default=1)),
('group', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='group_workers', to='worker_voucher.groupofworker')),
('insuree', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='insuree.insuree')),
('user_created', models.ForeignKey(db_column='UserCreatedUUID', on_delete=django.db.models.deletion.DO_NOTHING, related_name='%(class)s_user_created', to=settings.AUTH_USER_MODEL)),
('user_updated', models.ForeignKey(db_column='UserUpdatedUUID', on_delete=django.db.models.deletion.DO_NOTHING, related_name='%(class)s_user_updated', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
bases=(dirtyfields.dirtyfields.DirtyFieldsMixin, models.Model),
),
migrations.CreateModel(
name='HistoricalWorkerGroup',
fields=[
('id', models.UUIDField(db_column='UUID', db_index=True, default=None, editable=False)),
('is_deleted', models.BooleanField(db_column='isDeleted', default=False)),
('json_ext', models.JSONField(blank=True, db_column='Json_ext', null=True)),
('date_created', core.fields.DateTimeField(db_column='DateCreated', default=datetime.datetime.now, null=True)),
('date_updated', core.fields.DateTimeField(db_column='DateUpdated', default=datetime.datetime.now, null=True)),
('version', models.IntegerField(default=1)),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField(db_index=True)),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('group', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='worker_voucher.groupofworker')),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('insuree', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='insuree.insuree')),
('user_created', models.ForeignKey(blank=True, db_column='UserCreatedUUID', db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
('user_updated', models.ForeignKey(blank=True, db_column='UserUpdatedUUID', db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical worker group',
'verbose_name_plural': 'historical worker groups',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalGroupOfWorker',
fields=[
('id', models.UUIDField(db_column='UUID', db_index=True, default=None, editable=False)),
('is_deleted', models.BooleanField(db_column='isDeleted', default=False)),
('json_ext', models.JSONField(blank=True, db_column='Json_ext', null=True)),
('date_created', core.fields.DateTimeField(db_column='DateCreated', default=datetime.datetime.now, null=True)),
('date_updated', core.fields.DateTimeField(db_column='DateUpdated', default=datetime.datetime.now, null=True)),
('version', models.IntegerField(default=1)),
('name', models.CharField(max_length=50)),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField(db_index=True)),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('user_created', models.ForeignKey(blank=True, db_column='UserCreatedUUID', db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
('user_updated', models.ForeignKey(blank=True, db_column='UserUpdatedUUID', db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical group of worker',
'verbose_name_plural': 'historical group of workers',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Generated by Django 4.2.15 on 2024-10-15 14:30

import core.fields
import datetime
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('worker_voucher', '0010_groupofworker_workergroup_historicalworkergroup_and_more'),
]

operations = [
migrations.AddField(
model_name='historicalworkergroup',
name='date_valid_from',
field=core.fields.DateTimeField(db_column='DateValidFrom', default=datetime.datetime.now),
),
migrations.AddField(
model_name='historicalworkergroup',
name='date_valid_to',
field=core.fields.DateTimeField(blank=True, db_column='DateValidTo', null=True),
),
migrations.AddField(
model_name='historicalworkergroup',
name='replacement_uuid',
field=models.UUIDField(blank=True, db_column='ReplacementUUID', null=True),
),
migrations.AddField(
model_name='workergroup',
name='date_valid_from',
field=core.fields.DateTimeField(db_column='DateValidFrom', default=datetime.datetime.now),
),
migrations.AddField(
model_name='workergroup',
name='date_valid_to',
field=core.fields.DateTimeField(blank=True, db_column='DateValidTo', null=True),
),
migrations.AddField(
model_name='workergroup',
name='replacement_uuid',
field=models.UUIDField(blank=True, db_column='ReplacementUUID', null=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.2.15 on 2024-10-17 09:25

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


class Migration(migrations.Migration):

dependencies = [
('policyholder', '0018_alter_historicalpolicyholder_date_created_and_more'),
('worker_voucher', '0011_historicalworkergroup_date_valid_from_and_more'),
]

operations = [
migrations.AddField(
model_name='groupofworker',
name='policyholder',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='policyholder.policyholder'),
),
migrations.AddField(
model_name='historicalgroupofworker',
name='policyholder',
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='policyholder.policyholder'),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.15 on 2024-10-17 17:20

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('worker_voucher', '0012_groupofworker_policyholder_and_more'),
]

operations = [
migrations.AlterField(
model_name='groupofworker',
name='name',
field=models.CharField(max_length=50, unique=True),
),
migrations.AlterField(
model_name='historicalgroupofworker',
name='name',
field=models.CharField(db_index=True, max_length=50),
),
]
Loading

0 comments on commit 9d33b5c

Please sign in to comment.