Fakultas Ilmu Komputer UI

Commit 729160b3 authored by Muhammad Ashlah Shinfain's avatar Muhammad Ashlah Shinfain Committed by Ade Azurat
Browse files

PBI 15 Pencatatan Mustahik

parent e2128f28
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/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")