From 8f10b38f9a570935dedb3eb9050ada554290262d Mon Sep 17 00:00:00 2001 From: Nathan Chapman Date: Sat, 15 Oct 2022 20:58:49 -0600 Subject: [PATCH] Stall stripe --- src/accounts/apps.py | 8 +- src/core/apps.py | 2 +- src/core/migrations/0001_initial.py | 161 ++++++++++++++---- ...ethod_price_alter_order_status_and_more.py | 36 ---- ...er_created_at_trackingnumber_updated_at.py | 25 --- src/core/migrations/0004_order_coupon.py | 19 --- ...5_alter_product_options_product_sorting.py | 22 --- ...lter_order_options_order_shipping_total.py | 22 --- src/core/migrations/0007_product_subtitle.py | 18 -- ...8_alter_order_coupon_alter_order_weight.py | 27 --- src/core/migrations/0009_coupon_users.py | 20 --- src/core/migrations/0010_product_stripe_id.py | 18 -- ...11_product_stripe_price_id_subscription.py | 29 ---- ...y_productoption_productvariant_and_more.py | 130 -------------- .../0012_alter_productvariant_product.py | 19 --- ...t_amount_order_subtotal_amount_and_more.py | 38 ----- ...4_alter_productvariant_options_and_more.py | 22 --- .../0015_productcategory_main_product.py | 18 -- ...n_product_productcategory_main_category.py | 18 -- src/core/models.py | 3 + src/core/signals.py | 58 ++++--- src/core/tasks.py | 2 + 22 files changed, 170 insertions(+), 545 deletions(-) delete mode 100644 src/core/migrations/0002_shippingmethod_price_alter_order_status_and_more.py delete mode 100644 src/core/migrations/0003_trackingnumber_created_at_trackingnumber_updated_at.py delete mode 100644 src/core/migrations/0004_order_coupon.py delete mode 100644 src/core/migrations/0005_alter_product_options_product_sorting.py delete mode 100644 src/core/migrations/0006_alter_order_options_order_shipping_total.py delete mode 100644 src/core/migrations/0007_product_subtitle.py delete mode 100644 src/core/migrations/0008_alter_order_coupon_alter_order_weight.py delete mode 100644 src/core/migrations/0009_coupon_users.py delete mode 100644 src/core/migrations/0010_product_stripe_id.py delete mode 100644 src/core/migrations/0011_product_stripe_price_id_subscription.py delete mode 100644 src/core/migrations/0011_productcategory_productoption_productvariant_and_more.py delete mode 100644 src/core/migrations/0012_alter_productvariant_product.py delete mode 100644 src/core/migrations/0013_rename_total_net_amount_order_subtotal_amount_and_more.py delete mode 100644 src/core/migrations/0014_alter_productvariant_options_and_more.py delete mode 100644 src/core/migrations/0015_productcategory_main_product.py delete mode 100644 src/core/migrations/0016_rename_main_product_productcategory_main_category.py diff --git a/src/accounts/apps.py b/src/accounts/apps.py index 734d6a1..35cfd1f 100644 --- a/src/accounts/apps.py +++ b/src/accounts/apps.py @@ -5,7 +5,7 @@ class AccountsConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'accounts' - def ready(self): - from .signals import ( - user_saved - ) + # def ready(self): + # from .signals import ( + # user_saved + # ) diff --git a/src/core/apps.py b/src/core/apps.py index ad887d3..6cb4229 100644 --- a/src/core/apps.py +++ b/src/core/apps.py @@ -7,7 +7,7 @@ class CoreConfig(AppConfig): def ready(self): from .signals import ( - product_saved, + # variant_saved, order_created, transaction_created, order_line_post_save, diff --git a/src/core/migrations/0001_initial.py b/src/core/migrations/0001_initial.py index f56f516..3774cc1 100644 --- a/src/core/migrations/0001_initial.py +++ b/src/core/migrations/0001_initial.py @@ -1,8 +1,9 @@ -# Generated by Django 4.0.2 on 2022-03-11 02:25 +# Generated by Django 4.0.2 on 2022-10-16 02:36 import core.weight from decimal import Decimal from django.conf import settings +import django.contrib.postgres.fields import django.core.validators from django.db import migrations, models import django.db.models.deletion @@ -16,46 +17,101 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('accounts', '0001_initial'), + ('accounts', '0003_user_stripe_id'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ + migrations.CreateModel( + name='Coupon', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(choices=[('entire_order', 'Entire order'), ('shipping', 'Shipping'), ('specific_product', 'Specific products, collections and categories')], default='entire_order', max_length=20)), + ('name', models.CharField(blank=True, max_length=255, null=True)), + ('code', models.CharField(db_index=True, max_length=12, unique=True)), + ('valid_from', models.DateTimeField(default=django.utils.timezone.now)), + ('valid_to', models.DateTimeField(blank=True, null=True)), + ('discount_value_type', models.CharField(choices=[('fixed', 'USD'), ('percentage', '%')], default='fixed', max_length=10)), + ('discount_value', models.DecimalField(decimal_places=2, max_digits=12)), + ], + options={ + 'ordering': ('code',), + }, + ), migrations.CreateModel( name='Order', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('status', models.CharField(choices=[('draft', 'Draft'), ('unfulfilled', 'Unfulfilled'), ('partially fulfilled', 'Partially fulfilled'), ('partially_returned', 'Partially returned'), ('returned', 'Returned'), ('fulfilled', 'Fulfilled'), ('canceled', 'Canceled')], default='unfulfilled', max_length=32)), - ('total_net_amount', models.DecimalField(decimal_places=2, default=0, max_digits=10)), - ('weight', django_measurement.models.MeasurementField(default=core.weight.zero_weight, measurement=measurement.measures.mass.Mass)), + ('status', models.CharField(choices=[('draft', 'Draft'), ('unfulfilled', 'Unfulfilled'), ('partially_fulfilled', 'Partially fulfilled'), ('partially_returned', 'Partially returned'), ('returned', 'Returned'), ('fulfilled', 'Fulfilled'), ('canceled', 'Canceled')], default='unfulfilled', max_length=32)), + ('subtotal_amount', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('coupon_amount', models.CharField(blank=True, max_length=255)), + ('shipping_total', models.DecimalField(decimal_places=2, default=0, max_digits=5)), + ('total_amount', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('weight', django_measurement.models.MeasurementField(blank=True, default=core.weight.zero_weight, measurement=measurement.measures.mass.Mass, null=True)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('billing_address', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='accounts.address')), + ('coupon', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='orders', to='core.coupon')), ('customer', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='orders', to=settings.AUTH_USER_MODEL)), ('shipping_address', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='accounts.address')), ], + options={ + 'ordering': ('-created_at',), + }, ), migrations.CreateModel( name='Product', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=250)), + ('subtitle', models.CharField(blank=True, max_length=250)), ('description', models.TextField(blank=True)), - ('sku', models.CharField(max_length=255, unique=True)), - ('price', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True)), - ('weight', django_measurement.models.MeasurementField(blank=True, measurement=measurement.measures.mass.Mass, null=True)), + ('checkout_limit', models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0)])), ('visible_in_listings', models.BooleanField(default=False)), + ('sorting', models.PositiveIntegerField(blank=True, null=True)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ], + options={ + 'ordering': ['sorting', 'name'], + }, ), migrations.CreateModel( - name='ShippingMethod', + name='ProductCategory', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100)), - ('type', models.CharField(choices=[('price', 'Price based shipping'), ('weight', 'Weight based shipping')], max_length=30)), + ('name', models.CharField(max_length=255)), + ('main_category', models.BooleanField(default=True)), ], + options={ + 'verbose_name': 'Product Category', + 'verbose_name_plural': 'Product Categories', + }, + ), + migrations.CreateModel( + name='ShippingRate', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('shipping_provider', models.CharField(choices=[('USPS', 'USPS')], default='USPS', max_length=255)), + ('name', models.CharField(max_length=255)), + ('container', models.CharField(choices=[('LG FLAT RATE BOX', 'Flate Rate Box - Large'), ('MD FLAT RATE BOX', 'Flate Rate Box - Medium'), ('REGIONALRATEBOXA', 'Regional Rate Box A'), ('REGIONALRATEBOXB', 'Regional Rate Box B'), ('VARIABLE', 'Variable')], default='VARIABLE', max_length=255)), + ('min_order_weight', models.PositiveIntegerField(blank=True, null=True)), + ('max_order_weight', models.PositiveIntegerField(blank=True, null=True)), + ], + options={ + 'ordering': ['min_order_weight'], + }, + ), + migrations.CreateModel( + name='SiteSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('usps_user_id', models.CharField(max_length=255)), + ], + options={ + 'verbose_name': 'Site Settings', + 'verbose_name_plural': 'Site Settings', + }, ), migrations.CreateModel( name='Transaction', @@ -67,6 +123,47 @@ class Migration(migrations.Migration): ('order', models.OneToOneField(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.order')), ], ), + migrations.CreateModel( + name='TrackingNumber', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tracking_id', models.CharField(max_length=256)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('order', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='tracking_numbers', to='core.order')), + ], + options={ + 'verbose_name': 'Tracking Number', + 'verbose_name_plural': 'Tracking Numbers', + }, + ), + migrations.CreateModel( + name='Subscription', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('stripe_id', models.CharField(blank=True, max_length=255)), + ('customer', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscription', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='ProductVariant', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('sku', models.CharField(max_length=255, unique=True)), + ('stripe_id', models.CharField(blank=True, max_length=255)), + ('price', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True)), + ('weight', django_measurement.models.MeasurementField(blank=True, measurement=measurement.measures.mass.Mass, null=True)), + ('track_inventory', models.BooleanField(default=False)), + ('stock', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)])), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='variants', to='core.product')), + ], + options={ + 'ordering': ['weight'], + }, + ), migrations.CreateModel( name='ProductPhoto', fields=[ @@ -75,6 +172,20 @@ class Migration(migrations.Migration): ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.product')), ], ), + migrations.CreateModel( + name='ProductOption', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('options', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=255), size=None)), + ('products', models.ManyToManyField(related_name='options', to='core.Product')), + ], + ), + migrations.AddField( + model_name='product', + name='category', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.productcategory'), + ), migrations.CreateModel( name='OrderLine', fields=[ @@ -86,29 +197,17 @@ class Migration(migrations.Migration): ('unit_price', models.DecimalField(decimal_places=2, max_digits=12)), ('tax_rate', models.DecimalField(decimal_places=2, default=Decimal('0.0'), max_digits=5)), ('order', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='lines', to='core.order')), - ('product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='order_lines', to='core.product')), + ('variant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='order_lines', to='core.productvariant')), ], ), migrations.AddField( - model_name='order', - name='shipping_method', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='orders', to='core.shippingmethod'), + model_name='coupon', + name='products', + field=models.ManyToManyField(blank=True, to='core.Product'), ), - migrations.CreateModel( - name='Coupon', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('type', models.CharField(choices=[('entire_order', 'Entire order'), ('shipping', 'Shipping'), ('specific_product', 'Specific products, collections and categories')], default='entire_order', max_length=20)), - ('name', models.CharField(blank=True, max_length=255, null=True)), - ('code', models.CharField(db_index=True, max_length=12, unique=True)), - ('valid_from', models.DateTimeField(default=django.utils.timezone.now)), - ('valid_to', models.DateTimeField(blank=True, null=True)), - ('discount_value_type', models.CharField(choices=[('fixed', 'USD'), ('percentage', '%')], default='fixed', max_length=10)), - ('discount_value', models.DecimalField(decimal_places=2, max_digits=12)), - ('products', models.ManyToManyField(blank=True, to='core.Product')), - ], - options={ - 'ordering': ('code',), - }, + migrations.AddField( + model_name='coupon', + name='users', + field=models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL), ), ] diff --git a/src/core/migrations/0002_shippingmethod_price_alter_order_status_and_more.py b/src/core/migrations/0002_shippingmethod_price_alter_order_status_and_more.py deleted file mode 100644 index 96dd6bd..0000000 --- a/src/core/migrations/0002_shippingmethod_price_alter_order_status_and_more.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 4.0.2 on 2022-03-23 16:25 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='shippingmethod', - name='price', - field=models.DecimalField(decimal_places=2, default=0, max_digits=12), - ), - migrations.AlterField( - model_name='order', - name='status', - field=models.CharField(choices=[('draft', 'Draft'), ('unfulfilled', 'Unfulfilled'), ('partially_fulfilled', 'Partially fulfilled'), ('partially_returned', 'Partially returned'), ('returned', 'Returned'), ('fulfilled', 'Fulfilled'), ('canceled', 'Canceled')], default='unfulfilled', max_length=32), - ), - migrations.CreateModel( - name='TrackingNumber', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('tracking_id', models.CharField(max_length=256)), - ('order', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='tracking_numbers', to='core.order')), - ], - options={ - 'verbose_name': 'Tracking Number', - 'verbose_name_plural': 'Tracking Numbers', - }, - ), - ] diff --git a/src/core/migrations/0003_trackingnumber_created_at_trackingnumber_updated_at.py b/src/core/migrations/0003_trackingnumber_created_at_trackingnumber_updated_at.py deleted file mode 100644 index 170c781..0000000 --- a/src/core/migrations/0003_trackingnumber_created_at_trackingnumber_updated_at.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 4.0.2 on 2022-03-23 17:04 - -from django.db import migrations, models -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0002_shippingmethod_price_alter_order_status_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='trackingnumber', - name='created_at', - field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), - preserve_default=False, - ), - migrations.AddField( - model_name='trackingnumber', - name='updated_at', - field=models.DateTimeField(auto_now=True), - ), - ] diff --git a/src/core/migrations/0004_order_coupon.py b/src/core/migrations/0004_order_coupon.py deleted file mode 100644 index f33dc45..0000000 --- a/src/core/migrations/0004_order_coupon.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.0.2 on 2022-03-23 21:30 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0003_trackingnumber_created_at_trackingnumber_updated_at'), - ] - - operations = [ - migrations.AddField( - model_name='order', - name='coupon', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='orders', to='core.coupon'), - ), - ] diff --git a/src/core/migrations/0005_alter_product_options_product_sorting.py b/src/core/migrations/0005_alter_product_options_product_sorting.py deleted file mode 100644 index a7eca60..0000000 --- a/src/core/migrations/0005_alter_product_options_product_sorting.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 4.0.2 on 2022-03-28 17:27 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0004_order_coupon'), - ] - - operations = [ - migrations.AlterModelOptions( - name='product', - options={'ordering': ['sorting', 'name']}, - ), - migrations.AddField( - model_name='product', - name='sorting', - field=models.PositiveIntegerField(blank=True, null=True), - ), - ] diff --git a/src/core/migrations/0006_alter_order_options_order_shipping_total.py b/src/core/migrations/0006_alter_order_options_order_shipping_total.py deleted file mode 100644 index 1af1363..0000000 --- a/src/core/migrations/0006_alter_order_options_order_shipping_total.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 4.0.2 on 2022-04-24 16:34 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0005_alter_product_options_product_sorting'), - ] - - operations = [ - migrations.AlterModelOptions( - name='order', - options={'ordering': ('-created_at',)}, - ), - migrations.AddField( - model_name='order', - name='shipping_total', - field=models.DecimalField(decimal_places=2, default=0, max_digits=5), - ), - ] diff --git a/src/core/migrations/0007_product_subtitle.py b/src/core/migrations/0007_product_subtitle.py deleted file mode 100644 index 2d98dce..0000000 --- a/src/core/migrations/0007_product_subtitle.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2022-04-30 15:52 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0006_alter_order_options_order_shipping_total'), - ] - - operations = [ - migrations.AddField( - model_name='product', - name='subtitle', - field=models.CharField(blank=True, max_length=250), - ), - ] diff --git a/src/core/migrations/0008_alter_order_coupon_alter_order_weight.py b/src/core/migrations/0008_alter_order_coupon_alter_order_weight.py deleted file mode 100644 index 035f81e..0000000 --- a/src/core/migrations/0008_alter_order_coupon_alter_order_weight.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 4.0.2 on 2022-04-30 23:11 - -import core.weight -from django.db import migrations, models -import django.db.models.deletion -import django_measurement.models -import measurement.measures.mass - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0007_product_subtitle'), - ] - - operations = [ - migrations.AlterField( - model_name='order', - name='coupon', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='orders', to='core.coupon'), - ), - migrations.AlterField( - model_name='order', - name='weight', - field=django_measurement.models.MeasurementField(blank=True, default=core.weight.zero_weight, measurement=measurement.measures.mass.Mass, null=True), - ), - ] diff --git a/src/core/migrations/0009_coupon_users.py b/src/core/migrations/0009_coupon_users.py deleted file mode 100644 index cb3293d..0000000 --- a/src/core/migrations/0009_coupon_users.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 4.0.2 on 2022-05-11 00:55 - -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('core', '0008_alter_order_coupon_alter_order_weight'), - ] - - operations = [ - migrations.AddField( - model_name='coupon', - name='users', - field=models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/src/core/migrations/0010_product_stripe_id.py b/src/core/migrations/0010_product_stripe_id.py deleted file mode 100644 index 98f624c..0000000 --- a/src/core/migrations/0010_product_stripe_id.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2022-07-23 17:28 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0009_coupon_users'), - ] - - operations = [ - migrations.AddField( - model_name='product', - name='stripe_id', - field=models.CharField(blank=True, max_length=255), - ), - ] diff --git a/src/core/migrations/0011_product_stripe_price_id_subscription.py b/src/core/migrations/0011_product_stripe_price_id_subscription.py deleted file mode 100644 index f05f090..0000000 --- a/src/core/migrations/0011_product_stripe_price_id_subscription.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 4.0.2 on 2022-08-07 19:40 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('core', '0010_product_stripe_id'), - ] - - operations = [ - migrations.AddField( - model_name='product', - name='stripe_price_id', - field=models.CharField(blank=True, max_length=255), - ), - migrations.CreateModel( - name='Subscription', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('stripe_id', models.CharField(blank=True, max_length=255)), - ('customer', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscription', to=settings.AUTH_USER_MODEL)), - ], - ), - ] diff --git a/src/core/migrations/0011_productcategory_productoption_productvariant_and_more.py b/src/core/migrations/0011_productcategory_productoption_productvariant_and_more.py deleted file mode 100644 index 8dce6ee..0000000 --- a/src/core/migrations/0011_productcategory_productoption_productvariant_and_more.py +++ /dev/null @@ -1,130 +0,0 @@ -# Generated by Django 4.0.2 on 2022-09-07 20:34 - -from django.conf import settings -import django.contrib.postgres.fields -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion -import django_measurement.models -import measurement.measures.mass - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('core', '0010_product_stripe_id'), - ] - - operations = [ - migrations.CreateModel( - name='ProductCategory', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ], - options={ - 'verbose_name': 'Product Category', - 'verbose_name_plural': 'Product Categories', - }, - ), - migrations.CreateModel( - name='ProductOption', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('options', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=255), size=None)), - ], - ), - migrations.CreateModel( - name='ProductVariant', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('sku', models.CharField(max_length=255, unique=True)), - ('stripe_id', models.CharField(blank=True, max_length=255)), - ('price', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True)), - ('weight', django_measurement.models.MeasurementField(blank=True, measurement=measurement.measures.mass.Mass, null=True)), - ('track_inventory', models.BooleanField(default=False)), - ('stock', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)])), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ], - ), - migrations.CreateModel( - name='ShippingRate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('shipping_provider', models.CharField(choices=[('USPS', 'USPS')], default='USPS', max_length=255)), - ('name', models.CharField(max_length=255)), - ('container', models.CharField(choices=[('LG FLAT RATE BOX', 'Flate Rate Box - Large'), ('MD FLAT RATE BOX', 'Flate Rate Box - Medium'), ('REGIONALRATEBOXA', 'Regional Rate Box A'), ('REGIONALRATEBOXB', 'Regional Rate Box B'), ('VARIABLE', 'Variable')], default='VARIABLE', max_length=255)), - ('min_order_weight', models.PositiveIntegerField(blank=True, null=True)), - ('max_order_weight', models.PositiveIntegerField(blank=True, null=True)), - ], - options={ - 'ordering': ['min_order_weight'], - }, - ), - migrations.CreateModel( - name='SiteSettings', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('usps_user_id', models.CharField(max_length=255)), - ], - options={ - 'verbose_name': 'Site Settings', - 'verbose_name_plural': 'Site Settings', - }, - ), - migrations.CreateModel( - name='Subscription', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('stripe_id', models.CharField(blank=True, max_length=255)), - ('customer', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscription', to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.RemoveField( - model_name='order', - name='shipping_method', - ), - migrations.RemoveField( - model_name='product', - name='price', - ), - migrations.RemoveField( - model_name='product', - name='sku', - ), - migrations.RemoveField( - model_name='product', - name='stripe_id', - ), - migrations.RemoveField( - model_name='product', - name='weight', - ), - migrations.AddField( - model_name='product', - name='checkout_limit', - field=models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0)]), - ), - migrations.DeleteModel( - name='ShippingMethod', - ), - migrations.AddField( - model_name='productvariant', - name='product', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.product'), - ), - migrations.AddField( - model_name='productoption', - name='product', - field=models.ManyToManyField(related_name='options', to='core.Product'), - ), - migrations.AddField( - model_name='product', - name='category', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.productcategory'), - ), - ] diff --git a/src/core/migrations/0012_alter_productvariant_product.py b/src/core/migrations/0012_alter_productvariant_product.py deleted file mode 100644 index 52796fb..0000000 --- a/src/core/migrations/0012_alter_productvariant_product.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.0.2 on 2022-09-07 21:24 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0011_productcategory_productoption_productvariant_and_more'), - ] - - operations = [ - migrations.AlterField( - model_name='productvariant', - name='product', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='variants', to='core.product'), - ), - ] diff --git a/src/core/migrations/0013_rename_total_net_amount_order_subtotal_amount_and_more.py b/src/core/migrations/0013_rename_total_net_amount_order_subtotal_amount_and_more.py deleted file mode 100644 index 975ad85..0000000 --- a/src/core/migrations/0013_rename_total_net_amount_order_subtotal_amount_and_more.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by Django 4.0.2 on 2022-10-01 18:45 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0012_alter_productvariant_product'), - ] - - operations = [ - migrations.RenameField( - model_name='order', - old_name='total_net_amount', - new_name='subtotal_amount', - ), - migrations.RemoveField( - model_name='orderline', - name='product', - ), - migrations.AddField( - model_name='order', - name='coupon_amount', - field=models.CharField(blank=True, max_length=255), - ), - migrations.AddField( - model_name='order', - name='total_amount', - field=models.DecimalField(decimal_places=2, default=0, max_digits=10), - ), - migrations.AddField( - model_name='orderline', - name='variant', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='order_lines', to='core.productvariant'), - ), - ] diff --git a/src/core/migrations/0014_alter_productvariant_options_and_more.py b/src/core/migrations/0014_alter_productvariant_options_and_more.py deleted file mode 100644 index 44602cf..0000000 --- a/src/core/migrations/0014_alter_productvariant_options_and_more.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 4.0.2 on 2022-10-13 01:23 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0013_rename_total_net_amount_order_subtotal_amount_and_more'), - ] - - operations = [ - migrations.AlterModelOptions( - name='productvariant', - options={'ordering': ['weight']}, - ), - migrations.RenameField( - model_name='productoption', - old_name='product', - new_name='products', - ), - ] diff --git a/src/core/migrations/0015_productcategory_main_product.py b/src/core/migrations/0015_productcategory_main_product.py deleted file mode 100644 index ba0d3e2..0000000 --- a/src/core/migrations/0015_productcategory_main_product.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2022-10-15 22:06 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0014_alter_productvariant_options_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='productcategory', - name='main_product', - field=models.BooleanField(default=True), - ), - ] diff --git a/src/core/migrations/0016_rename_main_product_productcategory_main_category.py b/src/core/migrations/0016_rename_main_product_productcategory_main_category.py deleted file mode 100644 index 3a6c009..0000000 --- a/src/core/migrations/0016_rename_main_product_productcategory_main_category.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.0.2 on 2022-10-15 22:15 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('core', '0015_productcategory_main_product'), - ] - - operations = [ - migrations.RenameField( - model_name='productcategory', - old_name='main_product', - new_name='main_category', - ), - ] diff --git a/src/core/models.py b/src/core/models.py index e5c8bc9..d4de40b 100644 --- a/src/core/models.py +++ b/src/core/models.py @@ -272,6 +272,9 @@ class ShippingRate(models.Model): null=True ) + def get_absolute_url(self): + return reverse('dashboard:rate-detail', kwargs={'pk': self.pk}) + def __str__(self): return f'{self.shipping_provider}: {self.name} ({self.min_order_weight}–{self.max_order_weight})' diff --git a/src/core/signals.py b/src/core/signals.py index 9786091..bdd99f4 100644 --- a/src/core/signals.py +++ b/src/core/signals.py @@ -8,7 +8,9 @@ from django.db import models from django.conf import settings from . import OrderStatus, TransactionStatus -from .models import Product, Order, OrderLine, Transaction, TrackingNumber +from .models import ( + Product, ProductVariant, Order, OrderLine, Transaction, TrackingNumber +) from .tasks import ( send_order_confirmation_email, send_order_shipped_email @@ -17,33 +19,33 @@ from .tasks import ( logger = logging.getLogger(__name__) -@receiver(post_save, sender=Product, dispatch_uid="product_created") -def product_saved(sender, instance, created, **kwargs): - logger.info('Product was saved') - if created or not instance.stripe_id: - stripe.api_key = settings.STRIPE_API_KEY - prod_response = stripe.Product.create( - name=instance.name, - description=instance.description - ) - price_response = stripe.Price.create( - unit_amount=int(instance.price * 100), - currency=settings.DEFAULT_CURRENCY, - product=prod_response['id'] - ) - instance.stripe_id = prod_response['id'] - instance.stripe_price_id = price_response['id'] - instance.save() - else: - stripe.Product.modify( - instance.stripe_id, - name=instance.name, - description=instance.description - ) - stripe.Price.modify( - instance.stripe_price_id, - unit_amount=int(instance.price * 100) - ) +# @receiver(post_save, sender=ProductVariant, dispatch_uid='variant_created') +# def variant_saved(sender, instance, created, **kwargs): +# logger.info('Product was saved') +# if created or not instance.stripe_id: +# stripe.api_key = settings.STRIPE_API_KEY +# prod_response = stripe.Product.create( +# name=instance.product.name + ': ' + instance.name, +# description=instance.product.description +# ) +# price_response = stripe.Price.create( +# unit_amount=int(instance.price * 100), +# currency=settings.DEFAULT_CURRENCY, +# product=prod_response['id'] +# ) +# instance.stripe_id = prod_response['id'] +# instance.stripe_price_id = price_response['id'] +# instance.save() +# else: +# stripe.Product.modify( +# instance.stripe_id, +# name=instance.product.name + ': ' + instance.name, +# description=instance.product.description +# ) +# stripe.Price.modify( +# instance.stripe_price_id, +# unit_amount=int(instance.price * 100) +# ) @receiver(post_save, sender=Order, dispatch_uid="order_created") diff --git a/src/core/tasks.py b/src/core/tasks.py index 91a5ac1..5d47ae4 100644 --- a/src/core/tasks.py +++ b/src/core/tasks.py @@ -15,6 +15,7 @@ SHIP_ORDER_TEMPLATE = 'storefront/order_shipped' ORDER_CANCEl_TEMPLATE = 'storefront/order_cancel' ORDER_REFUND_TEMPLATE = 'storefront/order_refund' + @shared_task(name='send_order_confirmation_email') def send_order_confirmation_email(order): send_templated_mail( @@ -26,6 +27,7 @@ def send_order_confirmation_email(order): logger.info(f"Order confirmation email sent to {order['email']}") + @shared_task(name='send_order_shipped_email') def send_order_shipped_email(data): send_templated_mail(