diff --git a/api/migrations/0001_initial.py b/api/migrations/0001_initial.py index 4eaad886774517d3a170ad3e3278f16172d938c3..e61302d4dab20087b7304b5ee29ee7e322a1b7af 100644 --- a/api/migrations/0001_initial.py +++ b/api/migrations/0001_initial.py @@ -1,19 +1,20 @@ -# Generated by Django 3.0.7 on 2020-10-22 09:08 +# Generated by Django 3.0.7 on 2021-06-06 13:02 -import api.utils +import re +import uuid from decimal import Decimal -from django.conf import settings -from django.contrib.postgres import operations as postgres_operations + +import api.utils import django.contrib.auth.models import django.contrib.auth.validators import django.contrib.postgres.fields.citext import django.core.validators -from django.db import migrations, models import django.db.models.deletion import django.utils.timezone import phonenumber_field.modelfields -import re -import uuid +from django.conf import settings +from django.contrib.postgres import operations as postgres_operations +from django.db import migrations, models class Migration(migrations.Migration): @@ -75,6 +76,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='ID')), ('bank_name', models.CharField(max_length=100, verbose_name='bank name')), + ('bank_code_number', models.CharField(default='000', max_length=100, verbose_name='bank code number')), ('bank_account_number', models.CharField(max_length=100, verbose_name='bank account number')), ('bank_account_name', models.CharField(max_length=200, verbose_name='bank account name')), ], @@ -133,8 +135,15 @@ class Migration(migrations.Migration): ('description', models.TextField(verbose_name='description')), ('price', models.DecimalField(decimal_places=2, max_digits=12, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='price')), ('stock', models.PositiveIntegerField(blank=True, null=True, verbose_name='stock')), - ('pre_order', models.BooleanField(default=False, verbose_name='pre-order')), + ('modal', models.DecimalField(decimal_places=2, default=Decimal('0'), max_digits=12, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='modal')), + ('profit', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='profit')), ('image', models.ImageField(blank=True, null=True, upload_to=api.utils.get_upload_file_path, verbose_name='image')), + ('total_profit', models.DecimalField(blank=True, decimal_places=2, default=Decimal('0'), max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='total profit')), + ('is_hampers', models.BooleanField(default=False, verbose_name='the product is hampers package')), + ('hampers_price', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=12, validators=[django.core.validators.MinValueValidator(Decimal('0.00'))], verbose_name='hampers price')), + ('unit', models.CharField(default='buah', max_length=200, verbose_name='unit')), + ('preorder', models.BooleanField(blank=True, default=False, null=True, verbose_name='preorder')), + ('preorder_duration', models.PositiveIntegerField(blank=True, default=0, null=True, verbose_name='preorder duration')), ], options={ 'verbose_name': 'product', @@ -202,6 +211,7 @@ class Migration(migrations.Migration): ('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')), + ('transfer_destination_bank_code_number', models.CharField(blank=True, max_length=100, null=True, verbose_name='transfer destination bank code 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')), @@ -222,7 +232,8 @@ class Migration(migrations.Migration): ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='ID')), ('product_name', models.CharField(max_length=200, verbose_name='product name')), ('product_price', models.DecimalField(decimal_places=2, max_digits=12, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='product price')), - ('product_pre_order', models.BooleanField(verbose_name='product pre-order')), + ('hampers_price', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=12, validators=[django.core.validators.MinValueValidator(Decimal('0.00'))], verbose_name='hampers price')), + ('hampers_messages', models.CharField(default='', max_length=100, verbose_name='hampers messages')), ('quantity', models.PositiveIntegerField(verbose_name='quantity')), ('product', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transaction_items', to='api.Product', verbose_name='product')), ('transaction', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='transaction_items', to='api.Transaction', verbose_name='transaction')), @@ -259,6 +270,21 @@ class Migration(migrations.Migration): 'ordering': ['user', 'id'], }, ), + migrations.CreateModel( + name='ProgramProgress', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField(verbose_name='date')), + ('description', django.contrib.postgres.fields.citext.CICharField(max_length=200, verbose_name='description')), + ('image', models.ImageField(blank=True, null=True, upload_to=api.utils.get_upload_file_path, verbose_name='image')), + ('program', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='program', to='api.Program', verbose_name='program')), + ], + options={ + 'verbose_name': 'program progress', + 'verbose_name_plural': 'program progress', + 'ordering': ['-date', 'id'], + }, + ), migrations.CreateModel( name='ProgramDonation', fields=[ @@ -276,6 +302,7 @@ class Migration(migrations.Migration): ('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')), + ('transfer_destination_bank_code_number', models.CharField(blank=True, max_length=100, null=True, verbose_name='transfer destination bank code 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')), @@ -302,6 +329,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.PositiveIntegerField(default=0, verbose_name='quantity')), + ('hampers_messages', models.CharField(default='', max_length=100, verbose_name='hampers messages')), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cart_items', to='api.Product', verbose_name='product')), ('shopping_cart', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cart_items', to='api.ShoppingCart', verbose_name='shopping cart')), ], diff --git a/api/migrations/0002_auto_20201229_1028.py b/api/migrations/0002_auto_20201229_1028.py deleted file mode 100644 index cfff94743344f0a16ba79e60d19b424fa7ba9fe0..0000000000000000000000000000000000000000 --- a/api/migrations/0002_auto_20201229_1028.py +++ /dev/null @@ -1,57 +0,0 @@ -# Generated by Django 3.0.7 on 2020-12-29 03:28 - -import api.utils -from decimal import Decimal -import django.contrib.postgres.fields.citext -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='product', - name='pre_order', - ), - migrations.RemoveField( - model_name='transactionitem', - name='product_pre_order', - ), - migrations.AddField( - model_name='product', - name='modal', - field=models.DecimalField(decimal_places=2, default=Decimal('0'), max_digits=12, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='modal'), - ), - migrations.AddField( - model_name='product', - name='profit', - field=models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='profit'), - ), - migrations.AddField( - model_name='product', - name='total_profit', - field=models.DecimalField(blank=True, decimal_places=2, default=Decimal('0'), max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='total profit'), - ), - migrations.CreateModel( - name='ProgramProgress', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False, verbose_name='ID')), - ('date', models.DateField(verbose_name='date')), - ('description', django.contrib.postgres.fields.citext.CICharField(max_length=200, verbose_name='description')), - ('image', models.ImageField(blank=True, null=True, upload_to=api.utils.get_upload_file_path, verbose_name='image')), - ('program', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='program', to='api.Program', verbose_name='program')), - ], - options={ - 'verbose_name': 'program progress', - 'verbose_name_plural': 'program progress', - 'ordering': ['-date', 'id'], - }, - ), - ] diff --git a/api/migrations/0003_product_unit.py b/api/migrations/0003_product_unit.py deleted file mode 100644 index 2c9236546417e6fa7467bdbebbdcf5b78cbf42c6..0000000000000000000000000000000000000000 --- a/api/migrations/0003_product_unit.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.0.7 on 2021-03-27 05:42 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0002_auto_20201229_1028'), - ] - - operations = [ - migrations.AddField( - model_name='product', - name='unit', - field=models.CharField(default='buah', max_length=200, verbose_name='unit'), - ), - ] diff --git a/api/migrations/0004_product_preorder.py b/api/migrations/0004_product_preorder.py deleted file mode 100644 index f9f3cd5f211baca2b5466ca6ce62b94138e4b2c5..0000000000000000000000000000000000000000 --- a/api/migrations/0004_product_preorder.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.0.7 on 2021-05-21 15:02 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0003_product_unit'), - ] - - operations = [ - migrations.AddField( - model_name='product', - name='preorder', - field=models.BooleanField(blank=True, default=False, null=True, verbose_name='preorder'), - ), - ] diff --git a/api/migrations/0005_product_preorder_duration.py b/api/migrations/0005_product_preorder_duration.py deleted file mode 100644 index a231557d88f5019ab36533a69c1013bcb3fe4aa7..0000000000000000000000000000000000000000 --- a/api/migrations/0005_product_preorder_duration.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 3.0.7 on 2021-05-21 16:37 - -from decimal import Decimal -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0004_product_preorder'), - ] - - operations = [ - migrations.AddField( - model_name='product', - name='preorder_duration', - field=models.DecimalField(blank=True, decimal_places=2, default=Decimal('0'), max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0.01'))], verbose_name='preorder duration'), - ), - ] diff --git a/api/migrations/0006_auto_20210603_1954.py b/api/migrations/0006_auto_20210603_1954.py deleted file mode 100644 index 1da8d351134935fa3b9087aab32bedf002f479f2..0000000000000000000000000000000000000000 --- a/api/migrations/0006_auto_20210603_1954.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 3.0.7 on 2021-06-03 12:54 - -from decimal import Decimal -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0005_product_preorder_duration'), - ] - - operations = [ - migrations.AlterField( - model_name='product', - name='preorder_duration', - field=models.DecimalField(blank=True, decimal_places=2, default=Decimal('0'), max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(Decimal('1'))], verbose_name='preorder duration'), - ), - ] diff --git a/api/migrations/0007_auto_20210603_2001.py b/api/migrations/0007_auto_20210603_2001.py deleted file mode 100644 index af9d337f85084db44e5595af4bca25a7bce2e2f9..0000000000000000000000000000000000000000 --- a/api/migrations/0007_auto_20210603_2001.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.0.7 on 2021-06-03 13:01 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0006_auto_20210603_1954'), - ] - - operations = [ - migrations.AlterField( - model_name='product', - name='preorder_duration', - field=models.PositiveIntegerField(blank=True, default=0, null=True, verbose_name='preorder duration'), - ), - ] diff --git a/api/migrations/0008_auto_20210605_2241.py b/api/migrations/0008_auto_20210605_2241.py deleted file mode 100644 index d73c378becde009d9980ba65e798cd6472c7a410..0000000000000000000000000000000000000000 --- a/api/migrations/0008_auto_20210605_2241.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 3.0.7 on 2021-06-05 15:41 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0007_auto_20210603_2001'), - ] - - operations = [ - migrations.AddField( - model_name='bankaccounttransferdestination', - name='bank_code_number', - field=models.CharField(default='000', max_length=100, verbose_name='bank code number'), - ), - migrations.AddField( - model_name='programdonation', - name='transfer_destination_bank_code_number', - field=models.CharField(blank=True, max_length=100, null=True, verbose_name='transfer destination bank code number'), - ), - migrations.AddField( - model_name='transaction', - name='transfer_destination_bank_code_number', - field=models.CharField(blank=True, max_length=100, null=True, verbose_name='transfer destination bank code number'), - ), - ] diff --git a/api/models.py b/api/models.py index e1875492aa6f7a957f2a17316f4f3e93ec2b1e04..468aab004f2052b0dbf84979d27f6a6fdd0eafae 100644 --- a/api/models.py +++ b/api/models.py @@ -165,6 +165,14 @@ class Product(db_models.Model): validators=[validators.MinValueValidator(decimal.Decimal('0.01'))], verbose_name=_('total profit') ) + is_hampers = db_models.BooleanField(default=False, verbose_name=_('the product is hampers package')) + hampers_price = db_models.DecimalField( + decimal_places=2, + default=decimal.Decimal('0.00'), + max_digits=12, + validators=[validators.MinValueValidator(decimal.Decimal('0.00'))], + verbose_name=_('hampers price') + ) unit = db_models.CharField(default='buah', max_length=200, verbose_name=_('unit')) preorder = db_models.BooleanField(blank=True, null=True, default=False, verbose_name=_('preorder')) preorder_duration = db_models.PositiveIntegerField( @@ -210,6 +218,7 @@ class CartItem(db_models.Model): verbose_name=_('product') ) quantity = db_models.PositiveIntegerField(default=0, verbose_name=_('quantity')) + hampers_messages = db_models.CharField(default='', max_length=100, verbose_name=_('hampers messages')) class Meta: ordering = ['shopping_cart', 'product', 'id'] @@ -385,7 +394,14 @@ class TransactionItem(db_models.Model): validators=[validators.MinValueValidator(decimal.Decimal('0.01'))], verbose_name=_('product price') ) - + hampers_price = db_models.DecimalField( + default=decimal.Decimal('0.00'), + decimal_places=2, + max_digits=12, + validators=[validators.MinValueValidator(decimal.Decimal('0.00'))], + verbose_name=_('hampers price') + ) + hampers_messages = db_models.CharField(default='', max_length=100, verbose_name=_('hampers messages')) quantity = db_models.PositiveIntegerField(verbose_name=_('quantity')) class Meta: diff --git a/api/reports_writer.py b/api/reports_writer.py index 788e4ab61b494ec9f4a8abdfeb505b9d601a1922..2b650f0c171f1c7f9aa258abefe48b1bd39d21ae 100644 --- a/api/reports_writer.py +++ b/api/reports_writer.py @@ -122,8 +122,8 @@ def transaction_or_donation_user_username_with_hyperlink(worksheet, row, col, ob def transaction_transaction_item_subtotal(worksheet, row, col, obj, cell_format): worksheet.write_number(row, col, sum( - transaction_item.product_price * transaction_item.quantity - for transaction_item in obj.transaction_items.all() + (transaction_item.product_price + transaction_item.hampers_price) + * transaction_item.quantity for transaction_item in obj.transaction_items.all() ), cell_format=cell_format) @@ -246,6 +246,8 @@ def create_transaction_report(filter_params): # pylint: disable=too-many-locals (transaction_item_transaction_transaction_number_with_hyperlink, _('Transaction Number')), ('product_name', _('Product Name')), ('product_price', _('Product Price')), + ('hampers_price', _('Hampers Price')), + ('hampers_messages', _('Hampers Messages')), ('quantity', _('Quantity')), ] write_queryset_data_to_worksheet( @@ -253,7 +255,10 @@ def create_transaction_report(filter_params): # pylint: disable=too-many-locals models.TransactionItem.objects.filter(transaction__in=transactions), transaction_item_fields, header_format=header_format, - data_format={'product_price': money_format}, + data_format={ + 'product_price': money_format, + 'hampers_price': money_format + }, col_width=32 ) product_order_summary_worksheet = workbook.add_worksheet(str(_('Product Order Summary'))) diff --git a/api/seeds.py b/api/seeds.py index 25123029c9bf032e87c87130cff5b3c1e8a3991a..3cfa3fe8e1d15b032e4649f733775e81c29d991e 100644 --- a/api/seeds.py +++ b/api/seeds.py @@ -38,6 +38,8 @@ PRODUCT_DATA = { 'stock': 10, 'modal': '1000', 'unit': 'kg', + 'is_hampers': True, + 'hampers_price': '500', 'preorder' : True, 'preorder_duration' : 5, } diff --git a/api/serializers.py b/api/serializers.py index 222a0d1a621b94a2059babe1029a7974b0c6a338..8ac79f507a5e5be7fc04681ec0485cde5dbf18d8 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -20,6 +20,11 @@ class OTPSerializer(serializers.Serializer): # pylint: disable=abstract-method class CartUpdateSerializer(serializers.Serializer): # pylint: disable=abstract-method product = serializers.UUIDField(label=_('Product')) quantity = serializers.IntegerField(label=_('Quantity'), min_value=0) + hampers_messages = serializers.CharField( + label=_('Hampers Messages'), + max_length=100, + required=False + ) class CartCheckoutSerializer(serializers.Serializer): # pylint: disable=abstract-method @@ -266,6 +271,8 @@ class ProductSerializer(serializers.ModelSerializer): 'image', 'total_profit', 'unit', + 'is_hampers', + 'hampers_price', 'preorder', 'preorder_duration' ] @@ -279,7 +286,7 @@ class CartItemSerializer(serializers.ModelSerializer): product = ProductSerializer(read_only=True) class Meta: - fields = ['id', 'product', 'quantity'] + fields = ['id', 'product', 'quantity', 'hampers_messages'] model = models.CartItem read_only_fields = ['id', 'quantity'] @@ -296,7 +303,8 @@ class ShoppingCartSerializer(serializers.ModelSerializer): def get_cart_item_subtotal(self, obj): # pylint: disable=no-self-use cart_item_subtotal = sum( - cart_item.product.price * cart_item.quantity for cart_item in obj.cart_items.all() + (cart_item.product.price + cart_item.product.hampers_price) + * cart_item.quantity for cart_item in obj.cart_items.all() ) return str(cart_item_subtotal) @@ -311,6 +319,8 @@ class TransactionItemSerializer(serializers.ModelSerializer): 'product_code', 'product_name', 'product_price', + 'hampers_price', + 'hampers_messages', 'quantity', ] model = models.TransactionItem @@ -319,6 +329,7 @@ class TransactionItemSerializer(serializers.ModelSerializer): 'product', 'product_name', 'product_price', + 'hampers_price', 'quantity', ] @@ -407,8 +418,8 @@ class TransactionSerializer(serializers.ModelSerializer): def get_transaction_item_subtotal(self, obj): # pylint: disable=no-self-use transaction_item_subtotal = sum( - transaction_item.product_price * transaction_item.quantity - for transaction_item in obj.transaction_items.all() + (transaction_item.product_price + transaction_item.hampers_price) + * transaction_item.quantity for transaction_item in obj.transaction_items.all() ) return str(transaction_item_subtotal) diff --git a/api/signals.py b/api/signals.py index 6340fe60c31b773370fdbc71a5c09d8e5f7dfaaa..2f93db7681d6bba30ed04aab89129ca550c6ecb0 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: @@ -40,6 +41,7 @@ def fill_dependent_transaction_fields(sender, instance, **_kwargs): 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_code_number = None instance.transfer_destination_bank_account_number = None else: instance.transfer_destination_bank_name = ( @@ -51,6 +53,9 @@ def fill_dependent_transaction_fields(sender, instance, **_kwargs): instance.transfer_destination_bank_account_number = ( instance.bank_account_transfer_destination.bank_account_number ) + instance.transfer_destination_bank_code_number = ( + instance.bank_account_transfer_destination.bank_code_number + ) if (instance.transaction_status == '002'): if instance.batch is None: @@ -71,10 +76,14 @@ def fill_dependent_transaction_item_fields(sender, instance, **_kwargs): if instance.product is None: instance.product_name = None instance.product_price = None + instance.hampers_price = None + instance.hampers_messages = None else: instance.product_name = instance.product.name instance.product_price = instance.product.price + instance.hampers_price = instance.hampers_price + instance.hampers_messages = instance.hampers_messages diff --git a/api/tests.py b/api/tests.py index 2d296aa763f5bbedbf77e80f6ffc43e1da2c9519..9b198e8b77b2df18e28575f10132dafef4bd130b 100644 --- a/api/tests.py +++ b/api/tests.py @@ -1,17 +1,21 @@ +import datetime import decimal -from os import name import tempfile +import uuid +from os import name from unittest import mock -import datetime + import jwt -from django import conf, test as django_test, urls +from django import conf +from django import test as django_test +from django import 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 -import uuid +from PIL import Image +from rest_framework import exceptions, status +from rest_framework import test as rest_framework_test +from api import models, seeds, utils, views def create_tmp_image(): @@ -299,6 +303,7 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst data = { 'product': self.product.id, 'quantity': 1, + 'hampers_messages': 'Selamat Lebaran', } response = request( 'POST', @@ -333,6 +338,7 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst data = { 'product': self.product.id, 'quantity': 1, + 'hampers_messages': 'Selamat Lebaran', } response = request( 'POST', @@ -387,6 +393,7 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst data = { 'product': self.product.id, 'quantity': 20, + 'hampers_messages': 'Selamat Lebaran', } request( 'POST', @@ -411,6 +418,7 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst data = { 'product': self.product.id, 'quantity': 1, + 'hampers_messages': 'Selamat Lebaran', } request( 'POST', @@ -455,6 +463,7 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst data = { 'product': self.product.id, 'quantity': 1, + 'hampers_messages': 'Selamat Lebaran', } request( 'POST', @@ -540,6 +549,7 @@ class CartTest(rest_framework_test.APITestCase): # pylint: disable=too-many-inst data = { 'product': self.product.id, 'quantity': 20, + 'hampers_messages': 'Selamat Lebaran', } request( 'POST', @@ -1228,7 +1238,9 @@ class ProductTest(rest_framework_test.APITestCase): 'name': 'Dummy', 'price':'4000', 'modal':'2000', - 'unit': 'gram' + 'unit': 'gram', + 'is_hampers': True, + 'hampers_price': '500', } response = request( 'PATCH', @@ -1241,6 +1253,7 @@ class ProductTest(rest_framework_test.APITestCase): self.assertEqual(models.Product.objects.get(id=product.id).profit,2000) self.assertEqual(models.Product.objects.get(id=product.id).name, data['name']) self.assertEqual(models.Product.objects.get(id=product.id).unit, data['unit']) + self.assertEqual(models.Product.objects.get(id=product.id).is_hampers, data['is_hampers']) data = dict(seeds.PRODUCT_DATA, subcategory=self.subcategory.id) response = request( 'PUT', diff --git a/api/views/cart.py b/api/views/cart.py index ddd75459f7661bae66daf13a107ceb77b8a24193..b9d72e42eb3f47e48e2cd7da4079852d7b4e897f 100644 --- a/api/views/cart.py +++ b/api/views/cart.py @@ -36,9 +36,15 @@ class CartUpdate(rest_framework_views.APIView): product=product, shopping_cart=shopping_cart ) + validated_hampers_messages = '' + try: + validated_hampers_messages = serializer.validated_data['hampers_messages'] + except KeyError: + pass if serializer.validated_data['quantity'] == 0: cart_item.delete() else: + cart_item.hampers_messages = validated_hampers_messages cart_item.quantity = serializer.validated_data['quantity'] cart_item.save() return response.Response(status=status.HTTP_204_NO_CONTENT) @@ -51,8 +57,8 @@ class CartOverview(rest_framework_views.APIView): user = request.user shopping_cart = models.ShoppingCart.objects.get(user=user) item_subtotal = sum( - cart_item.product.price * cart_item.quantity - for cart_item in shopping_cart.cart_items.all() + (cart_item.product.price + cart_item.product.hampers_price) + * cart_item.quantity for cart_item in shopping_cart.cart_items.all() ) shipping_costs = api_utils.get_shipping_costs(user) if shipping_costs is None: @@ -121,7 +127,9 @@ class CartCheckout(rest_framework_views.APIView): models.TransactionItem.objects.create( transaction=transaction, product=product, - quantity=cart_item.quantity + quantity=cart_item.quantity, + hampers_price=product.hampers_price, + hampers_messages=cart_item.hampers_messages ) cart_item.delete() if not is_success: diff --git a/api/views/product.py b/api/views/product.py index 97009f4a314529aeaa37a91a1cb0f91deb1cf10a..a15004f8abeb08ff7db5817a3c7e9dafd58f6aaf 100644 --- a/api/views/product.py +++ b/api/views/product.py @@ -106,8 +106,12 @@ class ProductList(generics.ListCreateAPIView): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) validated_image = None + validated_is_hampers = False + validated_hampers_price = 0 try: validated_image = serializer.validated_data['image'] + validated_is_hampers=serializer.validated_data['is_hampers'] + validated_hampers_price = serializer.validated_data['hampers_price'] except KeyError: pass if serializer.validated_data['preorder']: @@ -119,6 +123,8 @@ class ProductList(generics.ListCreateAPIView): subcategory=models.Subcategory.objects.get(name=serializer.validated_data['subcategory']), total_profit=0, unit=serializer.validated_data['unit'], + is_hampers=validated_is_hampers, + hampers_price=validated_hampers_price, image=validated_image, preorder=serializer.validated_data['preorder'], preorder_duration=serializer.validated_data['preorder_duration'], @@ -133,6 +139,8 @@ class ProductList(generics.ListCreateAPIView): subcategory=models.Subcategory.objects.get(name=serializer.validated_data['subcategory']), total_profit=0, unit=serializer.validated_data['unit'], + is_hampers=validated_is_hampers, + hampers_price=validated_hampers_price, image=validated_image, ) product.profit = (product.price - product.modal)