Fakultas Ilmu Komputer UI

Commit e9f8fe95 authored by Ade Azurat's avatar Ade Azurat
Browse files

Merge branch 'PBI-15-pencatatan_mustahik' into 'testing'

PBI 15 Pencatatan Mustahik

See merge request !4
parents e2128f28 729160b3
Pipeline #51268 passed with stages
in 10 minutes and 27 seconds
from django.db import models
# Create your models here.
from django.test import TestCase
# Create your tests here.
from django import forms
from .models import Mustahik, DataSource, DataSourceWarga, DataSourceInstitusi, DataSourcePekerja
class MustahikForm(forms.ModelForm):
class Meta:
model = Mustahik
fields = [
'name',
'no_ktp',
'phone',
'address',
'birthdate',
'status',
'gender',
'data_source',
'photo',
]
class DataSourceForm(forms.ModelForm):
class Meta:
model = DataSource
fields = [
'category',
]
class DataSourceWargaForm(forms.ModelForm):
class Meta:
model = DataSourceWarga
fields = [
'pic_name',
'pic_ktp',
'pic_phone',
'pic_position',
'province',
'regency',
'sub_district',
'village',
'rt',
'rw',
'data_source',
]
class DataSourceInstitusiForm(forms.ModelForm):
class Meta:
model = DataSourceInstitusi
fields = [
'pic_name',
'pic_ktp',
'pic_phone',
'pic_position',
'name',
'province',
'sub_district',
'village',
'rt',
'rw',
'address',
'data_source',
]
class DataSourcePekerjaForm(forms.ModelForm):
class Meta:
model = DataSourcePekerja
fields = [
'pic_name',
'pic_ktp',
'pic_phone',
'pic_position',
'profession',
'location',
'data_source',
]
# Generated by Django 3.0.7 on 2020-07-29 08:26
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='DataSource',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('category', models.CharField(choices=[('WARGA', 'Warga'), ('INSTITUSI', 'Institusi'), ('PEKERJA', 'Pekerja')], max_length=32)),
],
),
migrations.CreateModel(
name='Mustahik',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=150)),
('no_ktp', models.CharField(max_length=32, unique=True, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('phone', models.CharField(blank=True, max_length=32, null=True, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('address', models.CharField(max_length=255)),
('birthdate', models.DateField()),
('status', models.CharField(choices=[('FAKIR', 'Fakir'), ('MISKIN', 'Miskin'), ('AMIL', 'Amil'), ('MUALAF', 'Mualaf'), ('GHARIM', 'Gharim'), ('FISABILILLAH', 'Fisabilillah'), ('MUSAFIR', 'Musafir')], max_length=32)),
('gender', models.CharField(choices=[('L', 'Laki-Laki'), ('P', 'Perempuan')], max_length=1)),
('photo', models.FileField(default='images/default_photo.jpg', upload_to='images/mustahik')),
('data_source', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')),
],
),
migrations.CreateModel(
name='DataSourceWarga',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('pic_name', models.CharField(max_length=150)),
('pic_ktp', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('pic_phone', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('pic_position', models.CharField(max_length=50)),
('province', models.CharField(max_length=50)),
('regency', models.CharField(max_length=50)),
('sub_district', models.CharField(max_length=50)),
('village', models.CharField(max_length=50)),
('rt', models.CharField(max_length=3, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('rw', models.CharField(max_length=3, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('data_source', models.OneToOneField(limit_choices_to={'category': 'WARGA'}, on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='DataSourcePekerja',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('pic_name', models.CharField(max_length=150)),
('pic_ktp', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('pic_phone', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('pic_position', models.CharField(max_length=50)),
('profession', models.CharField(max_length=50)),
('location', models.CharField(max_length=50)),
('data_source', models.OneToOneField(limit_choices_to={'category': 'PEKERJA'}, on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='DataSourceInstitusi',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('pic_name', models.CharField(max_length=150)),
('pic_ktp', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('pic_phone', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('pic_position', models.CharField(max_length=50)),
('name', models.CharField(max_length=150)),
('province', models.CharField(max_length=50)),
('regency', models.CharField(max_length=50)),
('sub_district', models.CharField(max_length=50)),
('village', models.CharField(max_length=50)),
('rt', models.CharField(max_length=3, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('rw', models.CharField(max_length=3, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('address', models.CharField(max_length=255)),
('data_source', models.OneToOneField(limit_choices_to={'category': 'INSTITUSI'}, on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')),
],
options={
'abstract': False,
},
),
]
import os
from django.db import models
from django.utils import timezone
from sizakat.validators import validate_numeric_character
class Mustahik(models.Model):
class Status(models.TextChoices):
FAKIR = ('FAKIR', 'Fakir')
MISKIN = ('MISKIN', 'Miskin')
AMIL = ('AMIL', 'Amil')
MUALAF = ('MUALAF', 'Mualaf')
GHARIM = ('GHARIM', 'Gharim')
FISABILILLAH = ('FISABILILLAH', 'Fisabilillah')
MUSAFIR = ('MUSAFIR', 'Musafir')
class Gender(models.TextChoices):
LAKILAKI = ('L', 'Laki-Laki')
PEREMPUAN = ('P', 'Perempuan')
name = models.CharField(max_length=150)
no_ktp = models.CharField(
max_length=32, unique=True,
validators=[validate_numeric_character]
)
phone = models.CharField(
max_length=32, blank=True, null=True,
validators=[validate_numeric_character]
)
address = models.CharField(max_length=255)
birthdate = models.DateField()
status = models.CharField(max_length=32, choices=Status.choices)
gender = models.CharField(max_length=1, choices=Gender.choices)
photo = models.FileField(
upload_to=os.path.join('images', 'mustahik'),
default=os.path.join('images', 'default_photo.jpg')
)
data_source = models.ForeignKey('DataSource', on_delete=models.CASCADE)
def calculate_age(self):
return timezone.now().year - self.birthdate.year
class DataSource(models.Model):
class Category(models.TextChoices):
WARGA = ('WARGA', 'Warga')
INSTITUSI = ('INSTITUSI', 'Institusi')
PEKERJA = ('PEKERJA', 'Pekerja')
category = models.CharField(max_length=32, choices=Category.choices)
def get_source_detail(self):
if self.category == DataSource.Category.INSTITUSI:
return DataSourceInstitusi.objects.get(data_source=self)
if self.category == DataSource.Category.PEKERJA:
return DataSourcePekerja.objects.get(data_source=self)
if self.category == DataSource.Category.WARGA:
return DataSourceWarga.objects.get(data_source=self)
class DataSourceDetail(models.Model):
class Meta:
abstract = True
pic_name = models.CharField(max_length=150)
pic_ktp = models.CharField(
max_length=32,
validators=[validate_numeric_character]
)
pic_phone = models.CharField(
max_length=32,
validators=[validate_numeric_character]
)
pic_position = models.CharField(max_length=50)
class DataSourceWarga(DataSourceDetail):
province = models.CharField(max_length=50)
regency = models.CharField(max_length=50)
sub_district = models.CharField(max_length=50)
village = models.CharField(max_length=50)
rt = models.CharField(
max_length=3, validators=[validate_numeric_character]
)
rw = models.CharField(
max_length=3, validators=[validate_numeric_character]
)
data_source = models.OneToOneField(
'DataSource', on_delete=models.CASCADE,
limit_choices_to={'category': DataSource.Category.WARGA}
)
class DataSourceInstitusi(DataSourceDetail):
name = models.CharField(max_length=150)
province = models.CharField(max_length=50)
regency = models.CharField(max_length=50)
sub_district = models.CharField(max_length=50)
village = models.CharField(max_length=50)
rt = models.CharField(
max_length=3, validators=[validate_numeric_character]
)
rw = models.CharField(
max_length=3, validators=[validate_numeric_character]
)
address = models.CharField(max_length=255)
data_source = models.OneToOneField(
'DataSource', on_delete=models.CASCADE,
limit_choices_to={'category': DataSource.Category.INSTITUSI}
)
class DataSourcePekerja(DataSourceDetail):
profession = models.CharField(max_length=50)
location = models.CharField(max_length=50)
data_source = models.OneToOneField(
'DataSource', on_delete=models.CASCADE,
limit_choices_to={'category': DataSource.Category.PEKERJA}
)
import graphene
from graphene_django.forms.mutation import DjangoModelFormMutation
from graphene_django.types import ErrorType
from sizakat.validators import validate_photo
from .forms import (
MustahikForm, DataSourceForm, DataSourceWargaForm,
DataSourceInstitusiForm, DataSourcePekerjaForm
)
from .models import Mustahik, DataSource
from .types import (
MustahikType, DataSourceInstitusiType,
DataSourcePekerjaType, DataSourceWargaType, DataSourceType
)
class MustahikMutation(DjangoModelFormMutation):
mustahik = graphene.Field(MustahikType)
class Meta:
form_class = MustahikForm
@classmethod
def mutate_and_get_payload(cls, root, info, **input):
form = cls.get_form(root, info, **input)
photo = info.context.FILES.get('photo', None)
if photo and not validate_photo(photo):
form.add_error('photo', 'invalid photo format')
if form.is_valid():
mustahik = form.save(commit=False)
if photo:
mustahik.photo = photo
mustahik.save()
kwargs = {cls._meta.return_field_name: mustahik}
return cls(errors=[], **kwargs)
else:
errors = ErrorType.from_errors(form.errors)
return cls(errors=errors)
class DeleteMustahik(graphene.Mutation):
class Arguments:
id = graphene.ID(required=True)
deleted = graphene.Boolean()
def mutate(self, info, id):
Mustahik.objects.get(pk=id).delete()
return DeleteMustahik(deleted=True)
class DataSourceMutation(DjangoModelFormMutation):
dataSource = graphene.Field(DataSourceType)
class Meta:
form_class = DataSourceForm
class DeleteDataSource(graphene.Mutation):
class Arguments:
id = graphene.ID(required=True)
deleted = graphene.Boolean()
def mutate(self, info, id):
DataSource.objects.get(pk=id).delete()
return DeleteDataSource(deleted=True)
class DataSourceWargaMutation(DjangoModelFormMutation):
dataSourceWarga = graphene.Field(DataSourceWargaType)
class Meta:
form_class = DataSourceWargaForm
class DataSourceInstitusiMutation(DjangoModelFormMutation):
dataSourceInstitusi = graphene.Field(DataSourceInstitusiType)
class Meta:
form_class = DataSourceInstitusiForm
class DataSourcePekerjaMutation(DjangoModelFormMutation):
dataSourcePekerja = graphene.Field(DataSourcePekerjaType)
class Meta:
form_class = DataSourcePekerjaForm
import graphene
from django.db.models import Q
from functools import reduce
from .models import Mustahik, DataSource
from .types import MustahikType, DataSourceType
class MustahikQuery(graphene.ObjectType):
mustahiks = graphene.List(
MustahikType,
statuses=graphene.List(graphene.String),
name_contains=graphene.String()
)
mustahik = graphene.Field(MustahikType, id=graphene.ID(required=True))
data_sources = graphene.List(DataSourceType, category=graphene.String())
data_source = graphene.Field(DataSourceType, id=graphene.ID(required=True))
def resolve_mustahiks(self, info, **kwargs):
statuses = kwargs.get('statuses', None)
name_contains = kwargs.get('name_contains', None)
filter_query = Q()
if statuses and len(statuses) > 0:
filter_query |= reduce(
lambda a, b: a | b,
[Q(status=status) for status in statuses]
)
if name_contains:
filter_query &= Q(name__icontains=name_contains)
return Mustahik.objects.filter(filter_query)
def resolve_mustahik(self, info, id):
return Mustahik.objects.get(pk=id)
def resolve_data_sources(self, info, **kwargs):
category = kwargs.get('category')
filter_query = Q()
if category:
filter_query &= Q(category=category)
return DataSource.objects.filter(filter_query)
def resolve_data_source(self, info, id):
return DataSource.objects.get(pk=id)
This diff is collapsed.
import graphene
from graphene_django.types import DjangoObjectType
from .models import (
Mustahik, DataSource, DataSourceInstitusi,
DataSourcePekerja, DataSourceWarga
)
class MustahikType(DjangoObjectType):
class Meta:
model = Mustahik
age = graphene.Int(source='calculate_age')
class DataSourceInstitusiType(DjangoObjectType):
class Meta:
model = DataSourceInstitusi
class DataSourcePekerjaType(DjangoObjectType):
class Meta:
model = DataSourcePekerja
class DataSourceWargaType(DjangoObjectType):
class Meta:
model = DataSourceWarga
class DataSourceDetailType(graphene.Union):
class Meta:
types = (
DataSourceInstitusiType, DataSourcePekerjaType,
DataSourceWargaType
)
my_attr = True
class DataSourceType(DjangoObjectType):
class Meta:
model = DataSource
exclude = (
'datasourceinstitusi', 'datasourcepekerja', 'datasourcewarga'
)
data_source_detail = graphene.Field(
DataSourceDetailType, source='get_source_detail'
)
from graphene_django import DjangoObjectType
import graphene
ABOUT = 'Si Zakat merupakan sistem informasi untuk membantu masjid dalam \
mengelola transaksi zakat. Sistem ini dibuat oleh tim lab 1231, \
yang dipimpin oleh Prof. Dr. Wisnu Jatmiko.'
class Query(graphene.ObjectType):
about = graphene.String()
def resolve_about(self, info):
return ABOUT
schema = graphene.Schema(query=Query)
import graphene
from graphene_django import DjangoObjectType
from .mustahik.mutations import (
MustahikMutation, DeleteMustahik, DataSourceMutation,
DataSourceWargaMutation, DataSourceInstitusiMutation,
DataSourcePekerjaMutation, DeleteDataSource
)
from .mustahik.query import MustahikQuery
ABOUT = ('Si Zakat merupakan sistem informasi untuk membantu masjid dalam '
'mengelola transaksi zakat. Sistem ini dibuat oleh tim lab 1231, '
'yang dipimpin oleh Prof. Dr. Wisnu Jatmiko.')
class Query(MustahikQuery, graphene.ObjectType):
about = graphene.String()
def resolve_about(self, info):
return ABOUT
class Mutation(graphene.ObjectType):
mustahik_mutation = MustahikMutation.Field()
delete_mustahik = DeleteMustahik.Field()
data_source_mutation = DataSourceMutation.Field()
data_source_warga_mutation = DataSourceWargaMutation.Field()
data_source_institusi_mutation = DataSourceInstitusiMutation.Field()
data_source_pekerja_mutation = DataSourcePekerjaMutation.Field()
delete_data_source = DeleteDataSource.Field()
schema = graphene.Schema(query=Query, mutation=Mutation)
......@@ -38,6 +38,8 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'graphene_django',
'corsheaders',
'sizakat.mustahik',
]
GRAPHENE = {
......@@ -47,6 +49,7 @@ GRAPHENE = {
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
......@@ -54,6 +57,9 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ORIGIN_WHITELIST = os.environ.get(
'CORS_ORIGIN_WHITELIST', 'http://localhost:3000').split()
ROOT_URLCONF = 'sizakat.urls'
TEMPLATES = [
......@@ -86,7 +92,7 @@ DATABASES = {
if 'SQL_DATABASE' in os.environ:
DATABASES = {
'default': {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('SQL_DATABASE'),
'USER': os.environ.get('SQL_USER'),
......@@ -133,4 +139,6 @@ USE_TZ = True
# https://docs.djangoproject.com/en/3.0/howto/static-files/