Fakultas Ilmu Komputer UI

Commit 8ab2c376 authored by Ade Azurat's avatar Ade Azurat
Browse files

Merge branch 'PBI-25-pencatatan_transaksi' into 'testing'

PBI 25 Pencatatan Transaksi

See merge request !14
parents e9f8fe95 a61b02a7
Pipeline #51366 passed with stages
in 17 minutes and 32 seconds
......@@ -11,4 +11,6 @@ then
echo "PostgreSQL started"
fi
python manage.py migrate
exec "$@"
......@@ -8,13 +8,17 @@ from .mustahik.mutations import (
DataSourcePekerjaMutation, DeleteDataSource
)
from .mustahik.query import MustahikQuery
from .transaction.query import TransactionQuery
from .transaction.mutations import (
MuzakkiMutation, TransactionMutation, ZakatTransactionMutation
)
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):
class Query(MustahikQuery, TransactionQuery, graphene.ObjectType):
about = graphene.String()
def resolve_about(self, info):
......@@ -30,5 +34,9 @@ class Mutation(graphene.ObjectType):
data_source_pekerja_mutation = DataSourcePekerjaMutation.Field()
delete_data_source = DeleteDataSource.Field()
muzakki_mutation = MuzakkiMutation.Field()
transaction_mutation = TransactionMutation.Field()
zakat_transaction_mutation = ZakatTransactionMutation.Field()
schema = graphene.Schema(query=Query, mutation=Mutation)
......@@ -40,6 +40,7 @@ INSTALLED_APPS = [
'graphene_django',
'corsheaders',
'sizakat.mustahik',
'sizakat.transaction',
]
GRAPHENE = {
......
from django.contrib import admin
from .models import ZakatType
admin.site.register([
ZakatType
])
from django.apps import AppConfig
class TransactionConfig(AppConfig):
name = 'transaction'
from django import forms
from .models import Muzakki, Transaction, ZakatTransaction
class MuzakkiForm(forms.ModelForm):
class Meta:
model = Muzakki
fields = [
'no_ktp',
'name',
'phone',
]
class TransactionForm(forms.ModelForm):
class Meta:
model = Transaction
fields = [
'payment_type',
'goods_delivery_type',
'pick_up_address',
'transfer_receipt',
'payment_confirmation',
'goods_confirmation',
]
class ZakatTransactionForm(forms.ModelForm):
class Meta:
model = ZakatTransaction
fields = [
'value',
'zakat_type',
'muzakki',
'transaction',
]
# Generated by Django 3.0.7 on 2020-08-05 04:58
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='Muzakki',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('no_ktp', models.CharField(max_length=32, unique=True, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
('name', models.CharField(max_length=150)),
('phone', models.CharField(blank=True, max_length=32, null=True, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])),
],
),
migrations.CreateModel(
name='Transaction',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('payment_type', models.CharField(blank=True, choices=[('CASH', 'Tunai'), ('TRANSFER', 'Transfer')], max_length=32, null=True)),
('goods_delivery_type', models.CharField(blank=True, choices=[('PICKUP', 'Dijemput'), ('DELIVER', 'Diantar')], max_length=32, null=True)),
('pick_up_address', models.TextField(blank=True, null=True)),
('transfer_receipt', models.FileField(blank=True, null=True, upload_to='images/transaction')),
('payment_confirmation', models.BooleanField(default=False)),
('goods_confirmation', models.BooleanField(default=False)),
],
),
migrations.CreateModel(
name='ZakatType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('item_type', models.CharField(choices=[('MONEY', 'Uang'), ('RICE', 'Beras'), ('GOLD', 'Emas'), ('CHECK', 'Cek')], max_length=32)),
],
),
migrations.CreateModel(
name='ZakatTransaction',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('value', models.DecimalField(decimal_places=2, max_digits=15)),
('muzakki', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='transaction.Muzakki')),
('transaction', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='transaction.Transaction')),
('zakat_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='transaction.ZakatType')),
],
),
]
import os
from django.db import models
from sizakat.validators import validate_numeric_character
class Muzakki(models.Model):
no_ktp = models.CharField(
max_length=32, unique=True,
validators=[validate_numeric_character]
)
name = models.CharField(max_length=150)
phone = models.CharField(
max_length=32, blank=True, null=True,
validators=[validate_numeric_character]
)
class ZakatType(models.Model):
class ItemType(models.TextChoices):
MONEY = ('MONEY', 'Uang')
RICE = ('RICE', 'Beras')
GOLD = ('GOLD', 'Emas')
CHECK = ('CHECK', 'Cek')
name = models.CharField(max_length=50)
item_type = models.CharField(max_length=32, choices=ItemType.choices)
def __str__(self):
return '%s - %s' % (self.name, self.ItemType[self.item_type].label)
class Transaction(models.Model):
class PaymentType(models.TextChoices):
CASH = ('CASH', 'Tunai')
TRANSFER = ('TRANSFER', 'Transfer')
class GoodsDeliveryType(models.TextChoices):
PICKUP = ('PICKUP', 'Dijemput')
DELIVER = ('DELIVER', 'Diantar')
payment_type = models.CharField(
max_length=32, choices=PaymentType.choices, blank=True, null=True
)
goods_delivery_type = models.CharField(
max_length=32, choices=GoodsDeliveryType.choices, blank=True, null=True
)
pick_up_address = models.TextField(blank=True, null=True)
transfer_receipt = models.FileField(
upload_to=os.path.join('images', 'transaction'), blank=True, null=True
)
payment_confirmation = models.BooleanField(default=False)
goods_confirmation = models.BooleanField(default=False)
# TODO: foreign key to user
class ZakatTransaction(models.Model):
value = models.DecimalField(max_digits=15, decimal_places=2)
zakat_type = models.ForeignKey(ZakatType, on_delete=models.CASCADE)
muzakki = models.ForeignKey(Muzakki, on_delete=models.CASCADE)
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE)
import graphene
from graphene_django.forms.mutation import DjangoModelFormMutation
from graphene_django.types import ErrorType
from sizakat.validators import validate_photo
from .forms import MuzakkiForm, TransactionForm, ZakatTransactionForm
from .types import MuzakkiType, TransactionType, ZakatTransactionType
class MuzakkiMutation(DjangoModelFormMutation):
muzakki = graphene.Field(MuzakkiType)
class Meta:
form_class = MuzakkiForm
class TransactionMutation(DjangoModelFormMutation):
transaction = graphene.Field(TransactionType)
class Meta:
form_class = TransactionForm
@classmethod
def mutate_and_get_payload(cls, root, info, **input):
form = cls.get_form(root, info, **input)
transfer_receipt = info.context.FILES.get('transfer_receipt', None)
if transfer_receipt and not validate_photo(transfer_receipt):
form.add_error('transfer_receipt', 'invalid format')
if form.is_valid():
transaction = form.save(commit=False)
if transfer_receipt:
transaction.transfer_receipt = transfer_receipt
transaction.save()
kwargs = {cls._meta.return_field_name: transaction}
return cls(errors=[], **kwargs)
else:
errors = ErrorType.from_errors(form.errors)
return cls(errors=errors)
class ZakatTransactionMutation(DjangoModelFormMutation):
zakat_trasaction = graphene.Field(ZakatTransactionType)
class Meta:
form_class = ZakatTransactionForm
import graphene
from .models import Transaction, ZakatType as ZakatTypeModel
from .types import TransactionType, ZakatType
class TransactionQuery(graphene.ObjectType):
transactions = graphene.List(TransactionType)
transaction = graphene.Field(
TransactionType, transaction_id=graphene.ID(required=True)
)
zakat_types = graphene.List(ZakatType)
def resolve_transactions(self, info, **kwargs):
return Transaction.objects.all()
def resolve_transaction(self, info, transaction_id):
return Transaction.objects.get(pk=transaction_id)
def resolve_zakat_types(self, info, **kwargs):
return ZakatTypeModel.objects.all()
import json
from django.test import TestCase
from graphene_django.utils.testing import GraphQLTestCase
from sizakat.schema import schema
from .models import Muzakki, Transaction, ZakatType, ZakatTransaction
class TransactionModelTestCase(TestCase):
def setUp(self):
muzakki = Muzakki.objects.create(
no_ktp='1234567890',
name='tester',
phone='081234567890'
)
zakat_type = ZakatType.objects.create(
name='Zakat Fitrah',
item_type=ZakatType.ItemType.MONEY
)
transaction = Transaction.objects.create(
payment_type=Transaction.PaymentType.CASH,
)
ZakatTransaction.objects.create(
value=50000,
zakat_type=zakat_type,
muzakki=muzakki,
transaction=transaction
)
def test_muzakki_creation(self):
muzakki = Muzakki.objects.get(no_ktp='1234567890')
self.assertTrue(isinstance(muzakki, Muzakki))
def test_zakat_type_creation(self):
zakat_type = ZakatType.objects.get(name='Zakat Fitrah')
self.assertTrue(isinstance(zakat_type, ZakatType))
def test_transaction_creation(self):
transactions = Transaction.objects.all()
transaction = Transaction.objects.get(pk=transactions[0].pk)
self.assertTrue(isinstance(transaction, Transaction))
def test_zakat_transaction_creation(self):
zakat_transactions = ZakatTransaction.objects.all()
zakat_transaction = ZakatTransaction.objects.get(
pk=zakat_transactions[0].pk
)
self.assertTrue(isinstance(zakat_transaction, ZakatTransaction))
class TransactionGraphQLTest(GraphQLTestCase):
GRAPHQL_SCHEMA = schema
def setUp(self):
self.muzakki = Muzakki.objects.create(
no_ktp='1234567890',
name='tester',
phone='081234567890'
)
self.zakat_type = ZakatType.objects.create(
name='Zakat Fitrah',
item_type=ZakatType.ItemType.MONEY
)
self.transaction = Transaction.objects.create(
payment_type=Transaction.PaymentType.CASH,
)
self.zakat_transaction = ZakatTransaction.objects.create(
value=50000,
zakat_type=self.zakat_type,
muzakki=self.muzakki,
transaction=self.transaction
)
def test_zakat_type_query_return_list_of_zakat_type(self):
response = self.query(
'''
{
zakatTypes {
id
name
itemType
}
}
'''
)
self.assertResponseNoErrors(response)
content = json.loads(response.content)['data']['zakatTypes']
self.assertTrue(isinstance(content, list))
def test_transactions_query_return_list_of_transaction(self):
response = self.query('{ transactions { id } }')
self.assertResponseNoErrors(response)
content = json.loads(response.content)['data']['transactions']
self.assertTrue(isinstance(content, list))
def test_transaction_query_with_id_return_specific_transaction(self):
response = self.query(
'''
{
transaction(transactionId: %d) {
id
paymentType
}
}
''' % (self.transaction.pk)
)
transaction = json.loads(response.content)['data']['transaction']
self.assertEqual(str(transaction['id']), str(self.transaction.pk))
self.assertEqual(transaction['paymentType'], self.transaction.payment_type)
def test_create_muzakki_mutation(self):
count_muzakki = Muzakki.objects.all().count()
self.query(
'''
mutation {
muzakkiMutation(input: {
noKtp: "1234",
name: "test create muzakki",
}) {
muzakki {
id
noKtp
name
}
errors {
field
messages
}
}
}
'''
)
self.assertEqual(count_muzakki + 1, Muzakki.objects.all().count())
def test_create_transaction_mutation(self):
count_transaction = Transaction.objects.all().count()
response = self.query(
'''
mutation {
transactionMutation(input: {
paymentType: "CASH"
}) {
transaction {
id
paymentType
paymentConfirmation
}
errors {
field
messages
}
}
}
'''
)
self.assertResponseNoErrors(response)
self.assertEqual(count_transaction + 1, Transaction.objects.all().count())
def test_update_transaction_mutation(self):
transaction = Transaction.objects.get(pk=self.transaction.pk)
self.query(
'''
mutation {
transactionMutation(input: {
id: %d,
paymentType: "%s",
paymentConfirmation: true
}) {
transaction {
id
paymentType
paymentConfirmation
}
errors {
field
messages
}
}
}
''' % (self.transaction.pk, self.transaction.payment_type)
)
updated_transaction = Transaction.objects.get(pk=self.transaction.pk)
self.assertFalse(transaction.payment_confirmation)
self.assertTrue(updated_transaction.payment_confirmation)
def test_create_zakat_transaction_mutation(self):
count_zakat_transaction = ZakatTransaction.objects.all().count()
self.query(
'''
mutation {
zakatTransactionMutation(input: {
value: 50000,
zakatType: %d,
muzakki: %d,
transaction: %d
}) {
zakatTransaction {
id
value
}
errors {
field
messages
}
}
}
''' % (self.zakat_type.pk, self.muzakki.pk, self.transaction.pk)
)
self.assertEqual(
count_zakat_transaction + 1,
ZakatTransaction.objects.all().count()
)
import graphene
from graphene_django.types import DjangoObjectType
from .models import (
Muzakki, Transaction, ZakatTransaction, ZakatType as ZakatTypeModel
)
class MuzakkiType(DjangoObjectType):
class Meta:
model = Muzakki
class TransactionType(DjangoObjectType):
class Meta:
model = Transaction
class ZakatTransactionType(DjangoObjectType):
class Meta:
model = ZakatTransaction
class ZakatType(DjangoObjectType):
class Meta:
model = ZakatTypeModel
exclude = ('zakattransaction_set', )
from django.shortcuts import render
# Create your views here.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment