From 565b2263f9e1a62b7a8d0f8070715e486d596f17 Mon Sep 17 00:00:00 2001 From: Wan Muhammad Rayhan Arwindra <wan.muhammad81@ui.ac.id> Date: Thu, 29 Oct 2020 14:44:52 +0700 Subject: [PATCH] Revert "Merge branch 'pbi3' into 'master'" This reverts merge request !80 --- .idea/.gitignore | 2 - .idea/backend.iml | 9 - .idea/codeStyles/codeStyleConfig.xml | 5 - .idea/encodings.xml | 4 - .idea/misc.xml | 6 - .idea/modules.xml | 8 - .idea/vcs.xml | 6 - .vscode/launch.json | 15 - .vscode/settings.json | 3 - api/constants.py | 10 - api/filters.py | 9 - api/migrations/0001_initial.py | 33 +- api/models.py | 95 +----- api/schemas.py | 15 - api/seeds.py | 27 +- api/serializers.py | 83 +---- api/signals.py | 22 +- api/tests.py | 440 +++++++++++---------------- api/urls.py | 19 +- api/utils.py | 34 +-- api/views.py | 193 ++---------- home_industry/settings/local.py | 2 +- manage.py | 0 23 files changed, 229 insertions(+), 811 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/backend.iml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json mode change 100644 => 100755 manage.py diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 5c98b428..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Default ignored files -/workspace.xml \ No newline at end of file diff --git a/.idea/backend.iml b/.idea/backend.iml deleted file mode 100644 index d6ebd480..00000000 --- a/.idea/backend.iml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$" /> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - </component> -</module> \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index a55e7a17..00000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ -<component name="ProjectCodeStyleConfiguration"> - <state> - <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" /> - </state> -</component> \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 15a15b21..00000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="Encoding" addBOMForNewFiles="with NO BOM" /> -</project> \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 28a804d8..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="JavaScriptSettings"> - <option name="languageLevel" value="ES6" /> - </component> -</project> \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index e066844e..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="ProjectModuleManager"> - <modules> - <module fileurl="file://$PROJECT_DIR$/.idea/backend.iml" filepath="$PROJECT_DIR$/.idea/backend.iml" /> - </modules> - </component> -</project> \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="VcsDirectoryMappings"> - <mapping directory="" vcs="Git" /> - </component> -</project> \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 7a9dfa04..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "pwa-chrome", - "request": "launch", - "name": "Launch Chrome against localhost", - "url": "http://localhost:8080", - "webRoot": "${workspaceFolder}" - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index daa22838..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "python.pythonPath": "env/bin/python3" -} \ No newline at end of file diff --git a/api/constants.py b/api/constants.py index 17d1bf71..38b00b71 100644 --- a/api/constants.py +++ b/api/constants.py @@ -7,16 +7,6 @@ DONATION_STATUS_CHOICES = [ ('004', _('Waiting for reupload of proof of bank transfer')), ] -DONATION_TYPE_CHOICES = [ - ('CSH', _('Cash')), - ('GDS', _('Goods')), -] - -DONATION_GOODS_DELIVERY_METHOD_CHOICES = [ - ('PCK', _('Pick Up')), - ('DLV', _('Delivered')), -] - PAYMENT_METHOD_CHOICES = [ ('TRF', _('Transfer')), ('COD', _('Cash on delivery')), diff --git a/api/filters.py b/api/filters.py index 404d3868..67bfb5db 100644 --- a/api/filters.py +++ b/api/filters.py @@ -29,8 +29,6 @@ class TransactionFilter(django_filters.FilterSet): 'payment_method', 'transaction_status', 'updated_at_date_range', - 'batch_name', - 'end_date' ] model = models.Transaction @@ -46,10 +44,3 @@ class ProgramDonationFilter(django_filters.FilterSet): 'updated_at_date_range', ] model = models.ProgramDonation - -class BatchFilter(django_filters.FilterSet): - created_at_date_range = django_filters.DateFromToRangeFilter(field_name='created_at') - - class Meta: - fields = ['id', 'batch_name', 'start_date', 'end_date', 'shipping_cost'] - model = models.Batch diff --git a/api/migrations/0001_initial.py b/api/migrations/0001_initial.py index 4eaad886..573f92fd 100644 --- a/api/migrations/0001_initial.py +++ b/api/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.7 on 2020-10-22 09:08 +# Generated by Django 3.0.7 on 2020-06-06 19:07 import api.utils from decimal import Decimal @@ -85,21 +85,6 @@ class Migration(migrations.Migration): 'unique_together': {('bank_name', 'bank_account_number')}, }, ), - migrations.CreateModel( - name='Batch', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='ID')), - ('batch_name', models.CharField(max_length=200, verbose_name='name')), - ('start_date', models.DateField(verbose_name='start date')), - ('end_date', models.DateField(verbose_name='end date')), - ('shipping_cost', models.IntegerField(blank=True, null=True, verbose_name='shipping cost')), - ], - options={ - 'verbose_name': 'batch', - 'verbose_name_plural': 'batches', - 'ordering': ['-start_date', '-end_date', 'batch_name', 'id'], - }, - ), migrations.CreateModel( name='Category', fields=[ @@ -204,10 +189,7 @@ class Migration(migrations.Migration): ('transfer_destination_bank_account_number', models.CharField(blank=True, max_length=100, null=True, verbose_name='transfer destination bank account number')), ('created_at', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='created at')), ('updated_at', models.DateTimeField(auto_now=True, db_index=True, verbose_name='updated at')), - ('batch_name', models.CharField(max_length=200, verbose_name='batch name')), - ('end_date', models.DateField(null=True, verbose_name='end date')), ('bank_account_transfer_destination', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transactions', to='api.BankAccountTransferDestination', verbose_name='bank account transfer destination')), - ('batch', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transaction', to='api.Batch', verbose_name='batch')), ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transactions', to=settings.AUTH_USER_MODEL, verbose_name='user')), ], options={ @@ -267,22 +249,17 @@ class Migration(migrations.Migration): ('user_full_name', models.CharField(max_length=200, verbose_name='user full name')), ('user_phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region=None, verbose_name='user phone number')), ('program_name', models.CharField(max_length=200, verbose_name='program name')), - ('amount', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='amount')), + ('amount', models.DecimalField(decimal_places=2, max_digits=12, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='amount')), ('donation_status', models.CharField(choices=[('001', 'Waiting for admin confirmation'), ('002', 'Completed'), ('003', 'Canceled'), ('004', 'Waiting for reupload of proof of bank transfer')], default='001', max_length=3, verbose_name='donation status')), - ('donation_type', models.CharField(choices=[('CSH', 'Cash'), ('GDS', 'Goods')], default='CSH', max_length=3, verbose_name='donation type')), - ('proof_of_bank_transfer', models.ImageField(blank=True, null=True, upload_to=api.utils.get_upload_file_path, verbose_name='proof of bank transfer')), + ('proof_of_bank_transfer', models.ImageField(upload_to=api.utils.get_upload_file_path, verbose_name='proof of bank transfer')), ('user_bank_name', models.CharField(blank=True, max_length=100, null=True, verbose_name='user bank name')), - ('user_bank_account_name', models.CharField(blank=True, max_length=200, null=True, verbose_name='user bank account name')), + ('user_bank_account_name', models.CharField(max_length=200, verbose_name='user bank account name')), ('transfer_destination_bank_name', models.CharField(blank=True, max_length=100, null=True, verbose_name='transfer destination bank name')), ('transfer_destination_bank_account_name', models.CharField(blank=True, max_length=200, null=True, verbose_name='transfer destination bank account name')), ('transfer_destination_bank_account_number', models.CharField(blank=True, max_length=100, null=True, verbose_name='transfer destination bank account number')), - ('goods_quantity', models.DecimalField(blank=True, decimal_places=0, max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(Decimal('1'))], verbose_name='goods quantity')), - ('goods_description', models.CharField(blank=True, max_length=200, null=True, verbose_name='goods description')), - ('delivery_method', models.CharField(blank=True, choices=[('PCK', 'Pick Up'), ('DLV', 'Delivered')], max_length=3, null=True, verbose_name='goods delivery method')), - ('delivery_address', models.CharField(blank=True, max_length=200, null=True, verbose_name='goods delivery address')), ('created_at', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='created at')), ('updated_at', models.DateTimeField(auto_now=True, db_index=True, verbose_name='updated at')), - ('bank_account_transfer_destination', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='program_donations', to='api.BankAccountTransferDestination', verbose_name='bank account transfer destination')), + ('bank_account_transfer_destination', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='program_donations', to='api.BankAccountTransferDestination', verbose_name='bank account transfer destination')), ('program', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='program_donations', to='api.Program', verbose_name='program')), ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='program_donations', to=settings.AUTH_USER_MODEL, verbose_name='user')), ], diff --git a/api/models.py b/api/models.py index 2f56883f..c493722d 100644 --- a/api/models.py +++ b/api/models.py @@ -13,8 +13,6 @@ from api import constants, utils class User(auth_models.AbstractUser): - REQUIRED_FIELDS=['phone_number'] - id = db_models.UUIDField(default=uuid.uuid4, primary_key=True, verbose_name=_('ID')) first_name = None last_name = None @@ -305,22 +303,6 @@ class Transaction(db_models.Model): ) updated_at = db_models.DateTimeField(auto_now=True, db_index=True, verbose_name=_('updated at')) - batch = db_models.ForeignKey( - 'api.Batch', - null=True, - blank=True, - on_delete=db_models.CASCADE, - related_name='transaction', - verbose_name=_('batch') - ) - - batch_name = db_models.CharField(max_length=200, verbose_name=_('batch name')) - - end_date = db_models.DateField( - null=True, - verbose_name=_('end date') - ) - class Meta: ordering = ['-updated_at', '-created_at', 'transaction_number', 'id'] verbose_name = _('transaction') @@ -443,8 +425,6 @@ class ProgramDonation(db_models.Model): user_phone_number = modelfields.PhoneNumberField(verbose_name=_('user phone number')) program_name = db_models.CharField(max_length=200, verbose_name=_('program name')) amount = db_models.DecimalField( - blank=True, - null=True, decimal_places=2, max_digits=12, validators=[validators.MinValueValidator(decimal.Decimal('0.01'))], @@ -456,33 +436,22 @@ class ProgramDonation(db_models.Model): max_length=3, verbose_name=_('donation status') ) - donation_type = db_models.CharField( - choices=constants.DONATION_TYPE_CHOICES, - default='CSH', - max_length=3, - verbose_name=_('donation type') - ) proof_of_bank_transfer = db_models.ImageField( - blank=True, - null=True, upload_to=utils.get_upload_file_path, verbose_name=_('proof of bank transfer') ) user_bank_name = db_models.CharField( blank=True, - null=True, max_length=100, + null=True, verbose_name=_('user bank name') ) user_bank_account_name = db_models.CharField( - blank=True, - null=True, max_length=200, verbose_name=_('user bank account name') ) bank_account_transfer_destination = db_models.ForeignKey( 'api.BankAccountTransferDestination', - blank=True, null=True, on_delete=db_models.SET_NULL, related_name='program_donations', @@ -490,48 +459,21 @@ class ProgramDonation(db_models.Model): ) transfer_destination_bank_name = db_models.CharField( blank=True, - null=True, max_length=100, + null=True, verbose_name=_('transfer destination bank name') ) transfer_destination_bank_account_name = db_models.CharField( blank=True, - null=True, max_length=200, + null=True, verbose_name=_('transfer destination bank account name') ) transfer_destination_bank_account_number = db_models.CharField( blank=True, - null=True, max_length=100, - verbose_name=_('transfer destination bank account number') - ) - goods_quantity = db_models.DecimalField( - blank=True, - null=True, - decimal_places=0, - max_digits=12, - validators=[validators.MinValueValidator(decimal.Decimal('1'))], - verbose_name=_('goods quantity') - ) - goods_description = db_models.CharField( - blank=True, - null=True, - max_length=200, - verbose_name=_('goods description') - ) - delivery_method = db_models.CharField( - choices=constants.DONATION_GOODS_DELIVERY_METHOD_CHOICES, - blank=True, null=True, - max_length=3, - verbose_name=_('goods delivery method') - ) - delivery_address = db_models.CharField( - blank=True, - null=True, - max_length=200, - verbose_name=_('goods delivery address') + verbose_name=_('transfer destination bank account number') ) created_at = db_models.DateTimeField( auto_now_add=True, @@ -617,32 +559,3 @@ class ShipmentConfig(solo_models.SingletonModel): def __str__(self): return 'Shipment Configuration' - - -class Batch(db_models.Model): - id = db_models.UUIDField(default=uuid.uuid4, primary_key=True, verbose_name=_('ID')) - - batch_name = db_models.CharField(max_length=200, verbose_name=_('name')) - - start_date = db_models.DateField( - blank=False, - verbose_name=_('start date') - ) - end_date = db_models.DateField( - blank=False, - verbose_name=_('end date') - ) - - shipping_cost = db_models.IntegerField( - blank=True, - verbose_name=_('shipping cost'), - null=True - ) - - class Meta: - ordering = ['-start_date', '-end_date', 'batch_name', 'id'] - verbose_name = _('batch') - verbose_name_plural = _('batches') - - def __str__(self): - return self.batch_name diff --git a/api/schemas.py b/api/schemas.py index e91a3cbf..1fb99dcf 100644 --- a/api/schemas.py +++ b/api/schemas.py @@ -31,17 +31,6 @@ class AutoSchemaWithDateRange(schemas.AutoSchema): class ReportTransactionSchema(AutoSchemaWithDateRange): date_range_fields = ['created_at_date_range'] - def get_filter_fields(self, path, method): - filter_fields = super().get_filter_fields(path, method) - filter_fields += [ - coreapi.Field( - 'batch_name', - location='query', - required=False, - schema=coreschema.String() - ) - ] - return filter_fields class ReportProgramDonationSchema(AutoSchemaWithDateRange): @@ -54,7 +43,3 @@ class TransactionListSchema(AutoSchemaWithDateRange): class ProgramDonationListSchema(AutoSchemaWithDateRange): date_range_fields = ['updated_at_date_range'] - - -class BatchListSchema(AutoSchemaWithDateRange): - date_range_fields = ['updated_at_date_range'] \ No newline at end of file diff --git a/api/seeds.py b/api/seeds.py index ee45fadb..aff4d005 100644 --- a/api/seeds.py +++ b/api/seeds.py @@ -57,24 +57,10 @@ PROGRAM_DATA = { 'link': 'https://example.com', } -PROGRAM_DONATION_CASH_DATA = { +PROGRAM_DONATION_DATA = { 'amount': '1000', - 'user_bank_name': 'Dummy Bank Name', - 'user_bank_account_name': 'Dummy Bank Account Name', -} - -PROGRAM_DONATION_GOODS_DATA = { - 'goods_quantity': '10', - 'goods_description': 'Dummy Goods', - 'delivery_address': 'Dummy Address', - 'delivery_method': 'PCK', -} - -PROGRAM_DONATION_GOODS_DATA_DLV = { - 'goods_quantity': '10', - 'goods_description': 'Dummy Goods', - 'delivery_address': None, - 'delivery_method': 'DLV', + 'user_bank_name': 'Dummy User Bank Name', + 'user_bank_account_name': 'Dummy User Bank Account Name', } HELP_CONTACT_CONFIG_DATA = { @@ -89,10 +75,3 @@ SHIPMENT_CONFIG_DATA = { 'same_urban_village_different_hamlet_costs': '2000', 'same_sub_district_different_urban_village_costs': '3000', } - -BATCH_DATA = { - 'batch_name': 'Batch 1', - 'start_date': '2020-10-08', - 'end_date': '2020-10-15', - 'shipping_cost': '60000', -} \ No newline at end of file diff --git a/api/serializers.py b/api/serializers.py index 290967f2..157f7aa4 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -58,53 +58,23 @@ class CartCompleteOrCancelTransactionSerializer(serializers.Serializer): # pylin class DonationCreateSerializer(serializers.Serializer): # pylint: disable=abstract-method program = serializers.UUIDField(label=_('Program')) - donation_type = serializers.ChoiceField( - choices=constants.DONATION_TYPE_CHOICES, - label=_('Donation type') - ) amount = serializers.DecimalField( decimal_places=2, label=_('Amount'), max_digits=12, - min_value=decimal.Decimal('0.01'), - required=False + min_value=decimal.Decimal('0.01') ) proof_of_bank_transfer = serializers.ImageField(label=_('Proof of bank transfer')) user_bank_name = serializers.CharField( label=_('User bank name'), - max_length=100, - required=False + max_length=100 ) user_bank_account_name = serializers.CharField( label=_('User bank account name'), - max_length=200, - required=False + max_length=200 ) bank_account_transfer_destination = serializers.UUIDField( - label=_('Bank account transfer destination'), - required=False - ) - goods_quantity = serializers.DecimalField( - decimal_places=0, - label=_('Goods quantity'), - max_digits=12, - min_value=decimal.Decimal('1'), - required=False - ) - goods_description = serializers.CharField( - label=_('Goods description'), - max_length=200, - required=False - ) - delivery_method = serializers.ChoiceField( - choices=constants.DONATION_GOODS_DELIVERY_METHOD_CHOICES, - label=_('Goods delivery method'), - required=False - ) - delivery_address = serializers.CharField( - label=_('Goods delivery address'), - max_length=200, - required=False + label=_('Bank account transfer destination') ) @@ -329,11 +299,10 @@ class TransactionSerializer(serializers.ModelSerializer): readable_transaction_status = serializers.SerializerMethodField( 'get_readable_transaction_status' ) - transaction_items = TransactionItemSerializer(many=True, read_only=True) transaction_item_subtotal = serializers.SerializerMethodField('get_transaction_item_subtotal') subtotal = serializers.SerializerMethodField('get_subtotal') - + class Meta: fields = [ 'id', @@ -365,9 +334,6 @@ class TransactionSerializer(serializers.ModelSerializer): 'transaction_items', 'transaction_item_subtotal', 'subtotal', - 'batch', - 'batch_name', - 'end_date' ] model = models.Transaction read_only_fields = [ @@ -393,9 +359,6 @@ class TransactionSerializer(serializers.ModelSerializer): 'transfer_destination_bank_account_number', 'created_at', 'updated_at', - 'batch', - 'batch_name', - 'end_date' ] def get_readable_payment_method(self, obj): # pylint: disable=no-self-use @@ -451,8 +414,7 @@ class ProgramSerializer(serializers.ModelSerializer): def get_total_donation_amount(self, obj): # pylint: disable=no-self-use total_donation_amount = sum( program_donation.amount for program_donation in obj.program_donations.filter( - donation_status='002', - donation_type='CSH' + donation_status='002' ) ) return str(total_donation_amount) @@ -488,9 +450,8 @@ class ProgramDonationSerializer(serializers.ModelSerializer): 'user_full_name', 'user_phone_number', 'program_name', - 'donation_type', - 'donation_status', 'amount', + 'donation_status', 'readable_donation_status', 'proof_of_bank_transfer', 'user_bank_name', @@ -499,10 +460,6 @@ class ProgramDonationSerializer(serializers.ModelSerializer): 'transfer_destination_bank_name', 'transfer_destination_bank_account_name', 'transfer_destination_bank_account_number', - 'goods_quantity', - 'goods_description', - 'delivery_method', - 'delivery_address', 'created_at', 'updated_at', ] @@ -515,7 +472,6 @@ class ProgramDonationSerializer(serializers.ModelSerializer): 'user_full_name', 'user_phone_number', 'program_name', - 'donation_type', 'amount', 'proof_of_bank_transfer', 'user_bank_name', @@ -555,28 +511,3 @@ class ShipmentConfigSerializer(serializers.ModelSerializer): 'same_sub_district_different_urban_village_costs', ] model = models.ShipmentConfig - -class BatchSerializer(serializers.ModelSerializer): - class Meta: - fields = [ - 'id', - 'batch_name', - 'start_date', - 'end_date', - 'shipping_cost' - ] - model = models.Batch - -class BatchCreateSerializer(serializers.Serializer): # pylint: disable=abstract-method - batch_name = serializers.CharField( - label=_('Batch name'), - max_length=200 - ) - start_date = serializers.DateField(label=_('Start Date')) - end_date = serializers.DateField(label=_('End Date')) - shipping_cost = serializers.DecimalField( - decimal_places=2, - label=_('Amount'), - max_digits=12, - min_value=decimal.Decimal('0.01') - ) diff --git a/api/signals.py b/api/signals.py index 528d5ce2..fe0a2e28 100644 --- a/api/signals.py +++ b/api/signals.py @@ -3,6 +3,7 @@ from django.db.models import signals from api import models, utils + @dispatch.receiver(signals.post_save, sender=models.User) def create_shopping_cart(sender, created, instance, **_kwargs): # pylint: disable=unused-argument if created: @@ -51,12 +52,6 @@ def fill_dependent_transaction_fields(sender, instance, **_kwargs): instance.transfer_destination_bank_account_number = ( instance.bank_account_transfer_destination.bank_account_number ) - - if (obj is not None) and (instance.transaction_status == '002'): - if instance.batch is None: - instance.batch = utils.get_batch_transaction(instance) - instance.batch_name = instance.batch.batch_name - instance.end_date = instance.batch.end_date @dispatch.receiver(signals.pre_save, sender=models.TransactionItem) @@ -100,11 +95,14 @@ def fill_dependent_program_donation_fields(sender, instance, **_kwargs): else: instance.user_full_name = instance.user.full_name instance.user_phone_number = instance.user.phone_number - - if (obj is not None) and (instance.donation_type != None): - if (instance.donation_type=='CSH'): - if (instance.bank_account_transfer_destination is None): - instance.bank_account_transfer_destination= utils.get_transfer_destination(instance) + if ((obj is None) or + (obj.bank_account_transfer_destination != instance.bank_account_transfer_destination) + or (getattr(instance, 'update_bank_account_transfer_destination', False))): + if instance.bank_account_transfer_destination is None: + instance.transfer_destination_bank_name = None + instance.transfer_destination_bank_account_name = None + instance.transfer_destination_bank_account_number = None + else: instance.transfer_destination_bank_name = ( instance.bank_account_transfer_destination.bank_name ) @@ -113,4 +111,4 @@ def fill_dependent_program_donation_fields(sender, instance, **_kwargs): ) instance.transfer_destination_bank_account_number = ( instance.bank_account_transfer_destination.bank_account_number - ) \ No newline at end of file + ) diff --git a/api/tests.py b/api/tests.py index d5f35df0..a0e3dc04 100644 --- a/api/tests.py +++ b/api/tests.py @@ -1,13 +1,13 @@ import decimal import tempfile from unittest import mock -import datetime + import jwt from django import conf, test as django_test, urls from django.core import management from PIL import Image from rest_framework import exceptions, status, test as rest_framework_test -from django.utils import timezone + from api import models, seeds, utils, views @@ -148,22 +148,6 @@ class UtilsTest(django_test.TestCase): self.assertIsInstance(mapped_choices, list) self.assertEqual(len(mapped_choices), len(choices)) - def get_batch_transaction_success(self): - transaction = models.Transaction.objects.create(**seeds.TRANSACTION_DATA) - transaction.created_at= datetime.datetime.now() - batch = models.Batch.objects.create(**seeds.BATCH_DATA) - batch_transaction=utils.get_batch_transaction(transaction) - self.assertEqual(batch.batch_name,batch_transaction.batch_name) - - def get_batch_transaction_fail(self): - transaction = models.Transaction.objects.create(**seeds.TRANSACTION_DATA) - transaction.created_at= datetime.datetime.now() - batch = models.Batch.objects.create('Batch 2','2020-10-08','2020-10-08',19000) - batch_transaction=utils.get_batch_transaction(transaction) - self.assertEqual(None,batch_transaction.batch_name) - - - class AuthTest(rest_framework_test.APITestCase): def setUp(self): @@ -401,7 +385,7 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(models.Transaction.objects.count(), 0) - + def test_cart_complete_transaction(self): data = { 'product': self.product.id, @@ -443,8 +427,6 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst http_authorization=self.user_http_authorization ) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - self.assertEqual(transaction.batch, None) - def test_cart_cancel_transaction(self): data = { @@ -485,6 +467,44 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst ) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + def test_cart_upload_pop_success(self): + data = { + 'product': self.product.id, + 'quantity': 1, + } + request( + 'POST', + 'cart-update', + data, + http_authorization=self.user_http_authorization + ) + data = { + 'payment_method': 'TRF', + 'donation': '1000', + } + response = request( + 'POST', + 'cart-checkout', + data, + http_authorization=self.user_http_authorization + ) + with open(self.proof_of_payment_file.name, 'rb') as proof_of_payment: + data = { + 'transaction': response.data['transaction'], + 'proof_of_payment': proof_of_payment, + 'user_bank_name': 'Dummy User Bank Name', + 'user_bank_account_name': 'Dummy User Bank Account Name', + 'bank_account_transfer_destination': self.bank_account_transfer_destination.id, + } + response = request( + 'POST', + 'cart-upload-pop', + data, + format='multipart', + http_authorization=self.user_http_authorization + ) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + def test_cart_upload_pop_fail(self): data = { 'product': self.product.id, @@ -506,6 +526,22 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst data, http_authorization=self.user_http_authorization ) + with open(self.proof_of_payment_file.name, 'rb') as proof_of_payment: + data = { + 'transaction': response.data['transaction'], + 'proof_of_payment': proof_of_payment, + 'user_bank_name': 'Dummy User Bank Name', + 'user_bank_account_name': 'Dummy User Bank Account Name', + 'bank_account_transfer_destination': self.bank_account_transfer_destination.id, + } + response = request( + 'POST', + 'cart-upload-pop', + data, + format='multipart', + http_authorization=self.user_http_authorization + ) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) data = { 'product': self.product.id, 'quantity': 1, @@ -529,6 +565,22 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst transaction = models.Transaction.objects.get(id=response.data['transaction']) transaction.transaction_status = '003' transaction.save() + with open(self.proof_of_payment_file.name, 'rb') as proof_of_payment: + data = { + 'transaction': response.data['transaction'], + 'proof_of_payment': proof_of_payment, + 'user_bank_name': 'Dummy User Bank Name', + 'user_bank_account_name': 'Dummy User Bank Account Name', + 'bank_account_transfer_destination': self.bank_account_transfer_destination.id, + } + response = request( + 'POST', + 'cart-upload-pop', + data, + format='multipart', + http_authorization=self.user_http_authorization + ) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) @mock.patch('api.utils.validate_product_stock', return_value=None) def test_cart_checkout_race_condition(self, mock_validate_product_stock): @@ -556,7 +608,7 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst self.assertEqual(mock_validate_product_stock.call_count, 1) -class DonationCashTest(rest_framework_test.APITestCase): +class DonationTest(rest_framework_test.APITestCase): def setUp(self): self.user = create_user(seeds.USER_DATA) self.user_http_authorization = get_http_authorization( @@ -569,67 +621,102 @@ class DonationCashTest(rest_framework_test.APITestCase): ) ) self.proof_of_bank_transfer_file = create_tmp_image() - - - def test_donation_reupload_proof_of_bank_transfer_success(self): + + def test_donation_create_success(self): program = models.Program.objects.create(**seeds.PROGRAM_DATA) - program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_CASH_DATA, - user=self.user, - program=program - )) - program_donation.save() + with open(self.proof_of_bank_transfer_file.name, 'rb') as proof_of_bank_transfer: + data = { + 'program': program.id, + 'amount': '1000', + 'proof_of_bank_transfer': proof_of_bank_transfer, + 'user_bank_name': 'Dummy User Bank Name', + 'user_bank_account_name': 'Dummy User Bank Account Name', + 'bank_account_transfer_destination': self.bank_account_transfer_destination.id, + } + response = request( + 'POST', + 'donation-create', + data, + format='multipart', + http_authorization=self.user_http_authorization + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(models.ProgramDonation.objects.count(), 1) - def test_donation_reupload_proof_of_bank_transfer_fail(self): + def test_donation_create_fail(self): program = models.Program.objects.create(**seeds.PROGRAM_DATA) - program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_CASH_DATA, - user=self.user, - program=program - )) - program_donation.donation_status = '002' - program_donation.save() + program.open_donation = False + program.save() + with open(self.proof_of_bank_transfer_file.name, 'rb') as proof_of_bank_transfer: + data = { + 'program': program.id, + 'amount': '1000', + 'proof_of_bank_transfer': proof_of_bank_transfer, + 'user_bank_name': 'Dummy User Bank Name', + 'user_bank_account_name': 'Dummy User Bank Account Name', + 'bank_account_transfer_destination': self.bank_account_transfer_destination.id, + } + response = request( + 'POST', + 'donation-create', + data, + format='multipart', + http_authorization=self.user_http_authorization + ) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertEqual(models.ProgramDonation.objects.count(), 0) -class DonationDeliveryTest(rest_framework_test.APITestCase): - def setUp(self): - self.user = create_user(seeds.USER_DATA) - self.user_http_authorization = get_http_authorization( - seeds.USER_DATA['username'], - seeds.USER_DATA['password'] - ) - - - def test_donation_goods_create_success(self): + def test_donation_reupload_proof_of_bank_transfer_success(self): program = models.Program.objects.create(**seeds.PROGRAM_DATA) program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_GOODS_DATA, + seeds.PROGRAM_DONATION_DATA, user=self.user, - program=program, + program=program )) - program_donation.donation_type='GDS' - program_donation.save() + with open(self.proof_of_bank_transfer_file.name, 'rb') as proof_of_bank_transfer: + data = { + 'amount': '1000', + 'program_donation': program_donation.id, + 'proof_of_bank_transfer': proof_of_bank_transfer, + 'user_bank_name': 'Dummy User Bank Name', + 'user_bank_account_name': 'Dummy User Bank Account Name', + 'bank_account_transfer_destination': self.bank_account_transfer_destination.id, + } + response = request( + 'POST', + 'donation-reupload-proof-of-bank-transfer', + data, + format='multipart', + http_authorization=self.user_http_authorization + ) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - def test_donation_goods_create_fail(self): + def test_donation_reupload_proof_of_bank_transfer_fail(self): program = models.Program.objects.create(**seeds.PROGRAM_DATA) program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_GOODS_DATA, + seeds.PROGRAM_DONATION_DATA, user=self.user, - program=program, + program=program )) - program_donation.donation_type='GDS' program_donation.donation_status = '002' program_donation.save() - - def test_delivery_method(self): - program = models.Program.objects.create(**seeds.PROGRAM_DATA) - program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_GOODS_DATA_DLV, - user=self.user, - program=program, - )) - program_donation.donation_type='GDS' - self.assertEqual(program_donation.delivery_address,None) - self.assertEqual(program_donation.delivery_method,'DLV') + with open(self.proof_of_bank_transfer_file.name, 'rb') as proof_of_bank_transfer: + data = { + 'amount': '1000', + 'program_donation': program_donation.id, + 'proof_of_bank_transfer': proof_of_bank_transfer, + 'user_bank_name': 'Dummy User Bank Name', + 'user_bank_account_name': 'Dummy User Bank Account Name', + 'bank_account_transfer_destination': self.bank_account_transfer_destination.id, + } + response = request( + 'POST', + 'donation-reupload-proof-of-bank-transfer', + data, + format='multipart', + http_authorization=self.user_http_authorization + ) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) class ReportViewsTest(rest_framework_test.APITestCase): @@ -640,8 +727,6 @@ class ReportViewsTest(rest_framework_test.APITestCase): seeds.SUPERUSER_DATA['password'] ) models.ShipmentConfig.objects.create(**seeds.SHIPMENT_CONFIG_DATA) - models.Batch.objects.create(**seeds.BATCH_DATA) - models.BankAccountTransferDestination.objects.create(**seeds.BANK_ACCOUNT_TRANSFER_DESTINATION) def test_get_filename_not_implemented_error(self): with self.assertRaises(NotImplementedError): @@ -686,7 +771,7 @@ class ReportViewsTest(rest_framework_test.APITestCase): user = create_user(seeds.USER_DATA) program = models.Program.objects.create(**seeds.PROGRAM_DATA) program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_CASH_DATA, + seeds.PROGRAM_DONATION_DATA, user=user, program=program )) @@ -1275,8 +1360,6 @@ class TransactionTest(rest_framework_test.APITestCase): seeds.USER_DATA['username'], seeds.USER_DATA['password'] ) - self.batch = models.Batch.objects.create(**seeds.BATCH_DATA) - def test_transaction_model_string_representation(self): transaction = models.Transaction.objects.create(**dict( @@ -1369,7 +1452,6 @@ class TransactionItemTest(rest_framework_test.APITestCase): seeds.SUPERUSER_DATA['username'], seeds.SUPERUSER_DATA['password'] ) - models.Batch.objects.create(**seeds.BATCH_DATA) models.ShipmentConfig.objects.create(**seeds.SHIPMENT_CONFIG_DATA) self.user = create_user(seeds.USER_DATA) self.category = models.Category.objects.create(**seeds.CATEGORY_DATA) @@ -1385,7 +1467,6 @@ class TransactionItemTest(rest_framework_test.APITestCase): seeds.TRANSACTION_DATA, user=self.user )) - def test_transaction_item_model_string_representation(self): transaction_item = models.TransactionItem.objects.create(**dict( @@ -1485,6 +1566,20 @@ class ProgramTest(rest_framework_test.APITestCase): url_args=[program.id] ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + program_minutes_file = create_tmp_image() + with open(program_minutes_file.name, 'rb') as program_minutes_file: + data = { + 'program_minutes': program_minutes_file, + } + response = request( + 'PATCH', + 'program-detail', + data, + format='multipart', + http_authorization=self.superuser_http_authorization, + url_args=[program.id] + ) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) class ProgramDonationTest(rest_framework_test.APITestCase): @@ -1500,16 +1595,15 @@ class ProgramDonationTest(rest_framework_test.APITestCase): seeds.USER_DATA['password'] ) self.program = models.Program.objects.create(**seeds.PROGRAM_DATA) - models.BankAccountTransferDestination.objects.create(**seeds.BANK_ACCOUNT_TRANSFER_DESTINATION) def test_program_donation_model_string_representation(self): program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_CASH_DATA, + seeds.PROGRAM_DONATION_DATA, user=self.user, program=self.program )) self.assertEqual(len(str(program_donation)), 6) - + def test_program_donation_list_success(self): response = request( 'GET', @@ -1517,27 +1611,16 @@ class ProgramDonationTest(rest_framework_test.APITestCase): http_authorization=self.superuser_http_authorization, ) self.assertEqual(response.status_code, status.HTTP_200_OK) - - - def test_program_donation_csh_list_success(self): response = request( 'GET', - 'program-donation-csh-list', - http_authorization=self.superuser_http_authorization, - ) - self.assertEqual(response.status_code, status.HTTP_200_OK) - - def test_program_donation_gds_list_success(self): - response = request( - 'GET', - 'program-donation-gds-list', + 'program-donation-list', http_authorization=self.user_http_authorization, ) self.assertEqual(response.status_code, status.HTTP_200_OK) def test_program_donation_detail_success(self): program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_CASH_DATA, + seeds.PROGRAM_DONATION_DATA, user=self.user, program=self.program )) @@ -1551,10 +1634,10 @@ class ProgramDonationTest(rest_framework_test.APITestCase): def test_update_program_donation_success(self): program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_CASH_DATA, + seeds.PROGRAM_DONATION_DATA, user=self.user, program=self.program - )) + )) data = { 'donation_status': '002', } @@ -1573,7 +1656,7 @@ class ProgramDonationTest(rest_framework_test.APITestCase): def test_update_program_donation_fail(self): program_donation = models.ProgramDonation.objects.create(**dict( - seeds.PROGRAM_DONATION_CASH_DATA, + seeds.PROGRAM_DONATION_DATA, user=self.user, program=self.program )) @@ -1772,172 +1855,3 @@ class ShipmentConfigTest(rest_framework_test.APITestCase): http_authorization=self.superuser_http_authorization ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - -class CategoryTest(rest_framework_test.APITestCase): - def setUp(self): - self.superuser = models.User.objects.create_superuser(**seeds.SUPERUSER_DATA) - self.superuser_http_authorization = get_http_authorization( - seeds.SUPERUSER_DATA['username'], - seeds.SUPERUSER_DATA['password'] - ) - - def test_category_model_string_representation(self): - category = models.Category.objects.create(**seeds.CATEGORY_DATA) - self.assertEqual(str(category), seeds.CATEGORY_DATA['name']) - - def test_category_list_success(self): - response = request( - 'GET', - 'category-list', - http_authorization=self.superuser_http_authorization - ) - self.assertEqual(response.status_code, status.HTTP_200_OK) - - def test_category_detail_success(self): - category = models.Category.objects.create(**seeds.CATEGORY_DATA) - response = request( - 'GET', - 'category-detail', - http_authorization=self.superuser_http_authorization, - url_args=[category.id] - ) - self.assertEqual(response.status_code, status.HTTP_200_OK) - - def test_create_category_success(self): - data = seeds.CATEGORY_DATA - response = request( - 'POST', - 'category-list', - data, - http_authorization=self.superuser_http_authorization - ) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertEqual(models.Category.objects.count(), 1) - self.assertEqual(models.Category.objects.get(id=response.data['id']).name, data['name']) - - def test_create_category_fail(self): - response = request( - 'POST', - 'category-list', - http_authorization=self.superuser_http_authorization - ) - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(models.Category.objects.count(), 0) - - def test_delete_category_success(self): - category = models.Category.objects.create(**seeds.CATEGORY_DATA) - response = request( - 'DELETE', - 'category-detail', - http_authorization=self.superuser_http_authorization, - url_args=[category.id] - ) - self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - self.assertEqual(models.Category.objects.count(), 0) - - def test_delete_category_fail(self): - category = models.Category.objects.create(**seeds.CATEGORY_DATA) - subcategory = models.Subcategory.objects.create(**dict( - seeds.SUBCATEGORY_DATA, category=category - )) - models.Product.objects.create(**dict(seeds.PRODUCT_DATA, subcategory=subcategory)) - response = request( - 'DELETE', - 'category-detail', - http_authorization=self.superuser_http_authorization, - url_args=[category.id] - ) - self.assertEqual(response.status_code, status.HTTP_409_CONFLICT) - self.assertEqual(models.Category.objects.count(), 1) - -class BatchTest(rest_framework_test.APITestCase): - def setUp(self): - self.superuser = models.User.objects.create_superuser(**seeds.SUPERUSER_DATA) - self.superuser_http_authorization = get_http_authorization( - seeds.SUPERUSER_DATA['username'], - seeds.SUPERUSER_DATA['password'] - ) - - def test_batch_model_string_representation(self): - batch = models.Batch.objects.create(**seeds.BATCH_DATA) - self.assertEqual(str(batch), seeds.BATCH_DATA['batch_name']) - - def test_batch_list_success(self): - response = request( - 'GET', - 'batch-list', - http_authorization=self.superuser_http_authorization - ) - self.assertEqual(response.status_code, status.HTTP_200_OK) - - def test_create_batch_success(self): - data = seeds.BATCH_DATA - response = request( - 'POST', - 'batch-list', - data, - http_authorization=self.superuser_http_authorization - ) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertEqual(models.Batch.objects.count(), 1) - self.assertEqual(models.Batch.objects.get(id=response.data['id']).batch_name, data['batch_name']) - - def test_create_batch_fail(self): - data = { - 'batch_name': 'Batch 1', - 'start_date': '2020-10-15', - 'end_date': '', - 'shipping_cost': '60000', - } - response = request( - 'POST', - 'batch-list', - data, - http_authorization=self.superuser_http_authorization - ) - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertEqual(models.Batch.objects.count(), 0) - - def test_create_batch_wrong_date(self): - data = { - 'batch_name': 'Batch 1', - 'start_date': '2020-10-15', - 'end_date': '2020-10-8', - 'shipping_cost': '60000', - } - response = request( - 'POST', - 'batch-list', - data, - http_authorization=self.superuser_http_authorization - ) - self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - self.assertEqual(models.Batch.objects.count(), 0) - - def test_edit_batch_success(self): - batch = models.Batch.objects.create(**seeds.BATCH_DATA) - data = seeds.BATCH_DATA - data['shipping_cost'] = 30000 - response = request( - 'PATCH', - 'batch-detail', - data, - url_args=[batch.id], - http_authorization=self.superuser_http_authorization - ) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(models.Batch.objects.get(id=batch.id).shipping_cost, data['shipping_cost']) - - def test_edit_batch_fail(self): - batch = models.Batch.objects.create(**seeds.BATCH_DATA) - data = seeds.BATCH_DATA - data['shipping_cost'] = 30000 - response = request( - 'PATCH', - 'batch-detail', - data, - url_args=[0], - http_authorization=self.superuser_http_authorization - ) - self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - self.assertEqual(models.Batch.objects.get(id=batch.id).shipping_cost, 60000) diff --git a/api/urls.py b/api/urls.py index 9d3412f4..bfe3cc10 100644 --- a/api/urls.py +++ b/api/urls.py @@ -37,9 +37,9 @@ urlpatterns = [ ), urls.path( 'reports/transaction/', - api_views.ReportTransaction.as_view(), - name='transaction-report' - ), + api_views.ReportTransaction.as_view(), + name='transaction-report' + ), urls.path( 'reports/program-donation/', api_views.ReportProgramDonation.as_view(), @@ -81,16 +81,6 @@ urlpatterns = [ ), urls.path('programs/', api_views.ProgramList.as_view(), name='program-list'), urls.path('programs/<str:pk>/', api_views.ProgramDetail.as_view(), name='program-detail'), - urls.path( - 'program-donations/csh', - api_views.ProgramDonationListCSH.as_view(), - name='program-donation-csh-list' - ), - urls.path( - 'program-donations/gds', - api_views.ProgramDonationListGDS.as_view(), - name='program-donation-gds-list' - ), urls.path( 'program-donations/', api_views.ProgramDonationList.as_view(), @@ -127,7 +117,4 @@ urlpatterns = [ api_views.ShipmentConfigDetail.as_view(), name='shipment-config-detail' ), - urls.path('batch/', api_views.BatchList.as_view(), name='batch-list'), - urls.path('batch/<str:pk>/', api_views.BatchDetail.as_view(), name='batch-detail'), - urls.path('batch/create/', api_views.BatchCreate.as_view(), name='batch-create'), ] diff --git a/api/utils.py b/api/utils.py index d269b5cf..20d8b163 100644 --- a/api/utils.py +++ b/api/utils.py @@ -1,15 +1,13 @@ import datetime -from datetime import timedelta + import jwt import shortuuid from jwt import exceptions as jwt_exceptions from django import conf -from django.utils import timezone from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions as rest_framework_exceptions from home_industry import utils -from api import models def generate_bearer_token(user): @@ -117,33 +115,3 @@ def validate_product_stock(cart_items): 'Failed to checkout because the purchased quantity of certain items exceeds the ' 'available stock.' )) - - -def get_batch_transaction(transaction): - today = timezone.now().date() - transaction_batch = models.Batch.objects.filter(start_date__lte=date, end_date__gt=date).first() - if transaction_batch is None: - days_to_saturday = 5 - today.weekday() - if days_to_saturday == -1: - end_date = today + timedelta(days=6) - start_date = end_date - timedelta(days=7) - else: - end_date = today + timedelta(days=days_to_saturday) - start_date = end_date - timedelta(days=7) - transaction_batch = models.Batch.objects.create( - batch_name='Auto Batch', - start_date=start_date, - end_date=end_date, - shipping_cost=0 - ) - transaction_batch.save() - return transaction_batch - -def get_transfer_destination(program_donation): - bank_name= program_donation.user_bank_name - bank_account_name= program_donation.user_bank_account_name - transfer_destination=None - for bank_destination in models.BankAccountTransferDestination.objects.all(): - if (bank_destination.bank_name== bank_name) and (bank_destination.bank_account_name== bank_account_name): - transfer_destination= bank_destination - return transfer_destination diff --git a/api/views.py b/api/views.py index 3c0e09eb..cfcfecdc 100644 --- a/api/views.py +++ b/api/views.py @@ -1,4 +1,3 @@ - from django import http, shortcuts from django.contrib import auth from django.db import transaction as db_transaction, utils as db_utils @@ -172,17 +171,12 @@ class CartCheckout(rest_framework_views.APIView): transaction_status = ( '001' if serializer.validated_data['payment_method'] == 'TRF' else '002' ) - batch = ( - None if serializer.validated_data['payment_method'] == 'TRF' - else models.Batch.objects.filter(start_date__lte=timezone.now().date(), end_date__gte=timezone.now().date()).first() - ) transaction = models.Transaction.objects.create( user=user, payment_method=serializer.validated_data['payment_method'], donation=serializer.validated_data['donation'], - transaction_status=transaction_status, + transaction_status=transaction_status ) - is_success = True for cart_item in cart_items: product = cart_item.product @@ -240,7 +234,6 @@ class CartUploadPOP(rest_framework_views.APIView): transaction.bank_account_transfer_destination = bank_account_transfer_destination transaction.update_bank_account_transfer_destination = True transaction.transaction_status = '002' - transaction.batch = models.Batch.objects.filter(start_date__lte=timezone.now().date(), end_date__gte=timezone.now().date()).first() transaction.save() return response.Response(status=status.HTTP_204_NO_CONTENT) @@ -266,7 +259,6 @@ class CartCompleteTransaction(rest_framework_views.APIView): 'Transaction cannot be completed unless the status is "Being shipped".' )) transaction.transaction_status = '005' - transaction.save() return response.Response(status=status.HTTP_204_NO_CONTENT) @@ -309,6 +301,10 @@ class DonationCreate(rest_framework_views.APIView): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = request.user + bank_account_transfer_destination = shortcuts.get_object_or_404( + models.BankAccountTransferDestination, + id=serializer.validated_data['bank_account_transfer_destination'] + ) program = shortcuts.get_object_or_404( models.Program, id=serializer.validated_data['program'] @@ -317,45 +313,15 @@ class DonationCreate(rest_framework_views.APIView): raise rest_framework_exceptions.PermissionDenied(_( 'This program is currently not accepting donations.' )) - program_donation = None - if serializer.validated_data['donation_type'] == 'CSH': - bank_account_transfer_destination = shortcuts.get_object_or_404( - models.BankAccountTransferDestination, - id=serializer.validated_data['bank_account_transfer_destination'] - ) - program_donation = models.ProgramDonation.objects.create( - user=user, - program=program, - donation_type='CSH', - amount=serializer.validated_data['amount'], - proof_of_bank_transfer=serializer.validated_data['proof_of_bank_transfer'], - user_bank_name=serializer.validated_data['user_bank_name'], - user_bank_account_name=serializer.validated_data['user_bank_account_name'], - bank_account_transfer_destination=bank_account_transfer_destination - ) - - else: - if serializer.validated_data['delivery_method'] == 'DLV': - program_donation = models.ProgramDonation.objects.create( - user=user, - program=program, - donation_type='GDS', - goods_quantity=serializer.validated_data['goods_quantity'], - goods_description=serializer.validated_data['goods_description'], - delivery_method=serializer.validated_data['delivery_method'], - delivery_address=None - ) - else: - program_donation = models.ProgramDonation.objects.create( - user=user, - program=program, - donation_type='GDS', - goods_quantity=serializer.validated_data['goods_quantity'], - goods_description=serializer.validated_data['goods_description'], - delivery_method=serializer.validated_data['delivery_method'], - delivery_address=serializer.validated_data['delivery_address'] - ) - + program_donation = models.ProgramDonation.objects.create( + user=user, + program=program, + amount=serializer.validated_data['amount'], + proof_of_bank_transfer=serializer.validated_data['proof_of_bank_transfer'], + user_bank_name=serializer.validated_data['user_bank_name'], + user_bank_account_name=serializer.validated_data['user_bank_account_name'], + bank_account_transfer_destination=bank_account_transfer_destination + ) return response.Response( {'program_donation': program_donation.id}, status=status.HTTP_200_OK @@ -386,10 +352,6 @@ class DonationReuploadProofOfBankTransfer(rest_framework_views.APIView): raise rest_framework_exceptions.PermissionDenied(_( 'Cannot reupload proof of bank transfer at this stage.' )) - if program_donation.donation_type != 'CSH': - raise rest_framework_exceptions.PermissionDenied(_( - 'Cannot proof of bank transfer foor good donation.' - )) program_donation.amount = serializer.validated_data['amount'] program_donation.proof_of_bank_transfer = ( serializer.validated_data['proof_of_bank_transfer'] @@ -437,11 +399,10 @@ class ReportTransaction(ReportAPIView): def get_filename(self, query_params): filename = '{}.xlsx'.format(_( # pylint: disable=no-member - 'Transaction Report from {date_from} to {date_to} for {batch_name}' + 'Transaction Report from {date_from} to {date_to}' ).format( date_from=query_params.get('created_at_date_range_after', '_'), - date_to=query_params.get('created_at_date_range_before', str(timezone.now())[:10]), - batch_name=query_params.get('batch_name', '_') + date_to=query_params.get('created_at_date_range_before', str(timezone.now())[:10]) )) return filename @@ -705,6 +666,7 @@ class ProgramDetail(generics.RetrieveUpdateDestroyAPIView): queryset = models.Program.objects.all() serializer_class = api_serializers.ProgramSerializer + class ProgramDonationList(generics.ListAPIView): filter_backends = [ rest_framework.DjangoFilterBackend, @@ -717,29 +679,7 @@ class ProgramDonationList(generics.ListAPIView): permission_classes = [rest_framework_permissions.IsAuthenticated] queryset = models.ProgramDonation.objects.all() schema = schemas.ProgramDonationListSchema() - search_fields = ['donation_number', 'user_full_name', 'program_name', 'donation_type'] - serializer_class = api_serializers.ProgramDonationSerializer - - def filter_queryset(self, queryset): - queryset = super().filter_queryset(queryset) - if not self.request.user.is_staff: - return queryset.filter(user=self.request.user) - return queryset - - -class ProgramDonationListCSH(generics.ListAPIView): - filter_backends = [ - rest_framework.DjangoFilterBackend, - rest_framework_filters.OrderingFilter, - rest_framework_filters.SearchFilter, - ] - filterset_class = api_filters.ProgramDonationFilter - ordering_fields = ['created_at', 'updated_at'] - pagination_class = paginations.SmallResultsSetPagination - permission_classes = [rest_framework_permissions.IsAuthenticated] - queryset = models.ProgramDonation.objects.filter(donation_type='CSH') - schema = schemas.ProgramDonationListSchema() - search_fields = ['donation_number', 'user_full_name', 'program_name', 'donation_type'] + search_fields = ['donation_number', 'user_full_name', 'program_name'] serializer_class = api_serializers.ProgramDonationSerializer def filter_queryset(self, queryset): @@ -748,26 +688,6 @@ class ProgramDonationListCSH(generics.ListAPIView): return queryset.filter(user=self.request.user) return queryset -class ProgramDonationListGDS(generics.ListAPIView): - filter_backends = [ - rest_framework.DjangoFilterBackend, - rest_framework_filters.OrderingFilter, - rest_framework_filters.SearchFilter, - ] - filterset_class = api_filters.ProgramDonationFilter - ordering_fields = ['created_at', 'updated_at'] - pagination_class = paginations.SmallResultsSetPagination - permission_classes = [rest_framework_permissions.IsAuthenticated] - queryset = models.ProgramDonation.objects.filter(donation_type='GDS') - schema = schemas.ProgramDonationListSchema() - search_fields = ['donation_number', 'user_full_name', 'program_name', 'donation_type'] - serializer_class = api_serializers.ProgramDonationSerializer - - def filter_queryset(self, queryset): - queryset = super().filter_queryset(queryset) - if not self.request.user.is_staff: - return queryset.filter(user=self.request.user) - return queryset class ProgramDonationDetail(generics.RetrieveUpdateAPIView): permission_classes = [ @@ -839,80 +759,3 @@ class ShipmentConfigDetail(generics.RetrieveUpdateAPIView): def get_object(self): obj = shortcuts.get_object_or_404(models.ShipmentConfig) return obj - -class BatchList(generics.ListCreateAPIView): - filter_backends = [ - rest_framework.DjangoFilterBackend, - rest_framework_filters.OrderingFilter, - rest_framework_filters.SearchFilter, - ] - - filterset_class = api_filters.BatchFilter - ordering_fields = ['created_at', 'updated_at'] - pagination_class = paginations.SmallResultsSetPagination - permission_classes = [rest_framework_permissions.IsAuthenticated] - queryset = models.Batch.objects.all() - schema = schemas.BatchListSchema() - search_fields = ['batch_name'] - serializer_class = api_serializers.BatchSerializer - - def post(self, request, _format=None): - serializer = self.get_serializer(data=request.data) - serializer.is_valid(raise_exception=True) - - if(serializer.validated_data['start_date']<serializer.validated_data['end_date']): - batch = models.Batch.objects.create( - batch_name=serializer.validated_data['batch_name'], - start_date=serializer.validated_data['start_date'], - end_date=serializer.validated_data['end_date'], - shipping_cost=serializer.validated_data['shipping_cost'], - ) - else: - raise rest_framework_exceptions.PermissionDenied(_( - 'Start Date must be earlier than End Date.' - )) - return response.Response( - {'id': batch.id}, - status=status.HTTP_201_CREATED - ) - - def filter_queryset(self, queryset): - queryset = super().filter_queryset(queryset) - if not self.request.user.is_staff: - return queryset.filter(user=self.request.user) - return queryset - -class BatchDetail(generics.RetrieveUpdateDestroyAPIView): - permission_classes = [ - api_permissions.IsAdminUserOrReadOnly, - rest_framework_permissions.IsAuthenticated, - ] - queryset = models.Batch.objects.all() - serializer_class = api_serializers.BatchSerializer - -class BatchCreate(rest_framework_views.APIView): - permission_classes = [rest_framework_permissions.IsAuthenticated] - serializer_class = api_serializers.BatchCreateSerializer - - def get_serializer(self, *args, **kwargs): - return self.serializer_class(*args, **kwargs) - - def post(self, request, _format=None): - serializer = self.get_serializer(data=request.data) - serializer.is_valid(raise_exception=True) - - if(serializer.validate_data['start_date']<serializer.validate_date['end_date']): - batch = models.Batch.objects.create( - batch_name=serializer.validated_data['batch_name'], - start_date=serializer.validated_data['start_date'], - end_date=serializer.validated_data['end_date'], - shipping_cost=serializer.validated_data['shipping_cost'], - ) - else: - raise rest_framework_exceptions.PermissionDenied(_( - 'Start Date must be earlier than End Date.' - )) - return response.Response( - {'id': batch.id}, - status=status.HTTP_201_CREATED - ) diff --git a/home_industry/settings/local.py b/home_industry/settings/local.py index fe04e340..81f7d36c 100644 --- a/home_industry/settings/local.py +++ b/home_industry/settings/local.py @@ -11,7 +11,7 @@ SECRET_KEY = os.environ['SECRET_KEY'] DEBUG = os.environ.get('DEBUG', True) != 'False' -ALLOWED_HOSTS = ['127.0.0.1', 'localhost', '10.0.2.2'] +ALLOWED_HOSTS = ['127.0.0.1', 'localhost'] # Application definition diff --git a/manage.py b/manage.py old mode 100644 new mode 100755 -- GitLab