Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OM-77 https://openimis.atlassian.net/browse/OM-77 #1

Merged
merged 4 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
9 changes: 4 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ on:
jobs:
call:
name: Default CI Flow
uses: openimis/openimis-be_py/.github/workflows/ci_module.yml@develop
uses: openimis/openimis-be_py/.github/workflows/ci_module.yml@moldova
secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
SONAR_PROJECT_KEY: openimis_openimis-be-tasks_management_py
SONAR_PROJECT_KEY: openimis_openimis-be-worker_voucher_py
SONAR_ORGANIZATION: openimis-1
SONAR_PROJECT_NAME: openimis-be-tasks_management_py
SONAR_PROJECT_NAME: openimis-be-worker_voucher_py
SONAR_PROJECT_VERSION: 1.0
SONAR_SOURCES: tasks_management
SONAR_SOURCES: worker_voucher
SONAR_EXCLUSIONS: "**/migrations/**,**/static/**,**/media/**,**/tests/**"

4 changes: 2 additions & 2 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
jobs:
deploy:

runs-on: ubuntu-20.04
runs-on: ubuntu-latest

steps:
- uses: olegtarasov/get-tag@v2.1
Expand All @@ -24,7 +24,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine jq
- name: update setup.py
run: |
echo "tag to use $GIT_TAG_NAME"
Expand Down
7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
'django',
'django-db-signals',
'djangorestframework',
'openimis-be-core'
'openimis-be-insuree'
''
'openimis-be-core',
'openimis-be-insuree',
'openimis-be-policyholder',
'openimis-be-msystems'
],
classifiers=[
'Environment :: Web Environment',
Expand Down
27 changes: 27 additions & 0 deletions worker_voucher/apps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
from django.apps import AppConfig

DEFAULT_CONFIG = {
"gql_worker_voucher_search_perms": ["204001"],
"gql_worker_voucher_create_perms": ["204002"],
"gql_worker_voucher_update_perms": ["204003"],
"gql_worker_voucher_delete_perms": ["204004"],
}
malinowskikam marked this conversation as resolved.
Show resolved Hide resolved


class WorkerVoucherConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'worker_voucher'

gql_worker_voucher_search_perms = None
gql_worker_voucher_create_perms = None
gql_worker_voucher_update_perms = None
gql_worker_voucher_delete_perms = None

def ready(self):
from core.models import ModuleConfiguration

cfg = ModuleConfiguration.get_or_default(self.name, DEFAULT_CONFIG)
self._load_config(cfg)

@classmethod
def _load_config(cls, cfg):
"""
Load all config fields that match current AppConfig class fields, all custom fields have to be loaded separately
"""
for field in cfg:
if hasattr(cls, field):
setattr(cls, field, cfg[field])
32 changes: 32 additions & 0 deletions worker_voucher/gql_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import graphene

from graphene_django import DjangoObjectType
from core import ExtendedConnection, prefix_filterset
from insuree.gql_queries import InsureeGQLType
from policyholder.gql import PolicyHolderGQLType
from worker_voucher.models import WorkerVoucher


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

class Meta:
model = WorkerVoucher
interfaces = (graphene.relay.Node,)
filter_fields = {
"id": ["exact"],

"code": ["exact", "iexact", "istartswith", "icontains"],
"status": ["exact", "iexact", "istartswith", "icontains"],
"assigned_date": ["exact", "lt", "lte", "gt", "gte"],
"expiry_date": ["exact", "lt", "lte", "gt", "gte"],

**prefix_filterset("insuree__", InsureeGQLType._meta.filter_fields),
**prefix_filterset("policyholder__", PolicyHolderGQLType._meta.filter_fields),

"date_created": ["exact", "lt", "lte", "gt", "gte"],
"date_updated": ["exact", "lt", "lte", "gt", "gte"],
"is_deleted": ["exact"],
"version": ["exact"],
}
connection_class = ExtendedConnection
78 changes: 78 additions & 0 deletions worker_voucher/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Generated by Django 3.2.22 on 2023-11-24 08:36

import core.fields
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):

initial = True

dependencies = [
('policyholder', '0017_auto_20230126_0903'),
('insuree', '0019_auto_20231026_1205'),
('core', '0025_mutationlog_json_ext'),
('msystems', '0005_fix_ward'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='WorkerVoucher',
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', null=True)),
('date_updated', core.fields.DateTimeField(db_column='DateUpdated', null=True)),
('version', models.IntegerField(default=1)),
('code', models.CharField(blank=True, max_length=255, null=True)),
('status', models.CharField(blank=True, choices=[('AWAITING_PAYMENT', 'Awaiting Payment'), ('UNASSIGNED', 'Unassigned'), ('ASSIGNED', 'Assigned'), ('EXPIRED', 'Expired'), ('CANCELED', 'Canceled'), ('CLOSED', 'Closed')], default='AWAITING_PAYMENT', max_length=255, null=True)),
('assigned_date', core.fields.DateField(blank=True, null=True)),
('expiry_date', core.fields.DateField(blank=True, null=True)),
('insuree', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='insuree.insuree')),
('policyholder', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='policyholder.policyholder')),
('user_created', models.ForeignKey(db_column='UserCreatedUUID', on_delete=django.db.models.deletion.DO_NOTHING, related_name='workervoucher_user_created', to=settings.AUTH_USER_MODEL)),
('user_updated', models.ForeignKey(db_column='UserUpdatedUUID', on_delete=django.db.models.deletion.DO_NOTHING, related_name='workervoucher_user_updated', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
bases=(dirtyfields.dirtyfields.DirtyFieldsMixin, models.Model),
),
migrations.CreateModel(
name='HistoricalWorkerVoucher',
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', null=True)),
('date_updated', core.fields.DateTimeField(db_column='DateUpdated', null=True)),
('version', models.IntegerField(default=1)),
('code', models.CharField(blank=True, max_length=255, null=True)),
('status', models.CharField(blank=True, choices=[('AWAITING_PAYMENT', 'Awaiting Payment'), ('UNASSIGNED', 'Unassigned'), ('ASSIGNED', 'Assigned'), ('EXPIRED', 'Expired'), ('CANCELED', 'Canceled'), ('CLOSED', 'Closed')], default='AWAITING_PAYMENT', max_length=255, null=True)),
('assigned_date', core.fields.DateField(blank=True, null=True)),
('expiry_date', core.fields.DateField(blank=True, null=True)),
('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)),
('insuree', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='insuree.insuree')),
('policyholder', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='policyholder.policyholder')),
('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 voucher',
'verbose_name_plural': 'historical worker vouchers',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
]
46 changes: 46 additions & 0 deletions worker_voucher/migrations/0002_woucher_rights.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from django.db import migrations

rights = ['204001', '204002', '204003', '204001']
roles = ['Employer', 'Inspector', 'IMIS Administrator']


def add_rights(role_name, role_model, role_right_model):
role = role_model.objects.get(name=role_name)
for right_id in rights:
if not role_right_model.objects.filter(validity_to__isnull=True, role=role, right_id=right_id).exists():
_add_right_for_role(role, right_id, role_right_model)


def _add_right_for_role(role, right_id, role_right_model):
role_right_model.objects.create(role=role, right_id=right_id, audit_user_id=1)


def remove_rights(role_id, role_right_model):
role_right_model.objects.filter(
role__is_system=role_id,
right_id__in=rights,
validity_to__isnull=True
).delete()


def on_migration(apps, schema_editor):
role_model = apps.get_model("core", "role")
role_right_model = apps.get_model("core", "roleright")
for role in roles:
add_rights(role, role_model, role_right_model)


def on_reverse_migration(apps, schema_editor):
role_right_model = apps.get_model("core", "roleright")
for role in roles:
remove_rights(role, role_right_model)


class Migration(migrations.Migration):
dependencies = [
('worker_voucher', '0001_initial'),
]

operations = [
migrations.RunPython(on_migration, on_reverse_migration),
]
23 changes: 22 additions & 1 deletion worker_voucher/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
from django.db import models
from django.utils.translation import gettext_lazy as _

# Create your models here.
from core.models import HistoryModel
from core import fields
from insuree.models import Insuree
from policyholder.models import PolicyHolder


class WorkerVoucher(HistoryModel):
class Status(models.TextChoices):
PENDING = 'AWAITING_PAYMENT', _('Awaiting Payment')
UNASSIGNED = 'UNASSIGNED', _('Unassigned')
ASSIGNED = 'ASSIGNED', _('Assigned')
EXPIRED = 'EXPIRED', _('Expired')
CANCELED = 'CANCELED', _('Canceled')
CLOSED = 'CLOSED', _('Closed')

insuree = models.ForeignKey(Insuree, null=True, blank=True, on_delete=models.DO_NOTHING)
policyholder = models.ForeignKey(PolicyHolder, null=True, blank=True, on_delete=models.DO_NOTHING)
code = models.CharField(max_length=255, blank=True, null=True)
status = models.CharField(max_length=255, blank=True, null=True, choices=Status.choices, default=Status.PENDING)
assigned_date = fields.DateField(blank=True, null=True)
expiry_date = fields.DateField(blank=True, null=True)
36 changes: 36 additions & 0 deletions worker_voucher/schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import graphene
import graphene_django_optimizer as gql_optimizer

from django.db.models import Q
from django.contrib.auth.models import AnonymousUser
from core.schema import OrderedDjangoFilterConnectionField
from core.utils import append_validity_filter
from worker_voucher.apps import WorkerVoucherConfig
from worker_voucher.gql_queries import WorkerVoucherGQLType
from worker_voucher.models import WorkerVoucher


class Query(graphene.ObjectType):
module_name = "tasks_management"

worker_voucher = OrderedDjangoFilterConnectionField(
WorkerVoucherGQLType,
orderBy=graphene.List(of_type=graphene.String),
client_mutation_id=graphene.String(),
)

def resolve_worker_voucher(self, info, **kwargs):
Query._check_permissions(info.context.user, WorkerVoucherConfig.gql_worker_voucher_search_perms)
filters = append_validity_filter(**kwargs)

client_mutation_id = kwargs.get("client_mutation_id", None)
if client_mutation_id:
filters.append(Q(mutations__mutation__client_mutation_id=client_mutation_id))

query = WorkerVoucher.objects.filter(*filters)
return gql_optimizer.query(query, info)

@staticmethod
def _check_permissions(user, perms):
if type(user) is AnonymousUser or not user.id or not user.has_perms(perms):
raise PermissionError("Unauthorized")
27 changes: 19 additions & 8 deletions worker_voucher/services.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import logging
import warnings

from core.services import BaseService
from core.signals import register_service_signal
from worker_voucher.models import WorkerVoucher
from worker_voucher.validation import WorkerVoucherValidation

logger = logging.getLogger(__name__)

# Remove this code when implementing services
warnings.warn("The example code in service is still present.")

class WorkerVoucherService(BaseService):
OBJECT_TYPE = WorkerVoucher

def __init__(self, user, validation_class=WorkerVoucherValidation):
super().__init__(user, validation_class)

def example_service_function_job():
pass
@register_service_signal('worker_voucher_service.create')
def create(self, obj_data):
return super().create(obj_data)

@register_service_signal('worker_voucher_service.update')
def update(self, obj_data):
return super().update(obj_data)

class ExampleService:
def example_service_method_job(self):
pass
@register_service_signal('worker_voucher_service.delete')
def delete(self, obj_data):
return super().delete(obj_data)
17 changes: 0 additions & 17 deletions worker_voucher/tests.py
Original file line number Diff line number Diff line change
@@ -1,17 +0,0 @@
import warnings

from django.test import TestCase
from worker_voucher.services import example_service_function_job, ExampleService


class ExampleImisTest(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
# Remove this code when implementing tests
warnings.warn("The example code in test case is still present.")

def test_example_module_loaded_correctly(self):
example_service_function_job()
ExampleService().example_service_method_job()
self.assertTrue(True)
6 changes: 6 additions & 0 deletions worker_voucher/validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from core.validation import BaseModelValidation
from worker_voucher.models import WorkerVoucher


class WorkerVoucherValidation(BaseModelValidation):
OBJECT_TYPE = WorkerVoucher
Loading