Fixes flake8 errors
This commit is contained in:
		
							parent
							
								
									c2400c4695
								
							
						
					
					
						commit
						224878a10c
					
				
					 14 changed files with 125 additions and 152 deletions
				
			
		|  | @ -6,7 +6,6 @@ import nested_admin | |||
| from registrasion import models as rego | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Inventory admin | ||||
| 
 | ||||
| class ProductInline(admin.TabularInline): | ||||
|  |  | |||
|  | @ -1,9 +1,8 @@ | |||
| import datetime | ||||
| import itertools | ||||
| 
 | ||||
| from django.core.exceptions import ObjectDoesNotExist | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.db.models import Avg, Min, Max, Sum | ||||
| from django.db.models import Max, Sum | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
|  | @ -33,7 +32,6 @@ class CartController(object): | |||
|             existing.save() | ||||
|         return CartController(existing) | ||||
| 
 | ||||
| 
 | ||||
|     def extend_reservation(self): | ||||
|         ''' Updates the cart's time last updated value, which is used to | ||||
|         determine whether the cart has reserved the items and discounts it | ||||
|  | @ -56,7 +54,6 @@ class CartController(object): | |||
|         self.cart.time_last_updated = timezone.now() | ||||
|         self.cart.reservation_duration = max(reservations) | ||||
| 
 | ||||
| 
 | ||||
|     def add_to_cart(self, product, quantity): | ||||
|         ''' Adds _quantity_ of the given _product_ to the cart. Raises | ||||
|         ValidationError if constraints are violated.''' | ||||
|  | @ -91,7 +88,6 @@ class CartController(object): | |||
|         self.cart.revision += 1 | ||||
|         self.cart.save() | ||||
| 
 | ||||
| 
 | ||||
|     def apply_voucher(self, voucher): | ||||
|         ''' Applies the given voucher to this cart. ''' | ||||
| 
 | ||||
|  | @ -110,7 +106,6 @@ class CartController(object): | |||
|         self.cart.revision += 1 | ||||
|         self.cart.save() | ||||
| 
 | ||||
| 
 | ||||
|     def validate_cart(self): | ||||
|         ''' Determines whether the status of the current cart is valid; | ||||
|         this is normally called before generating or paying an invoice ''' | ||||
|  | @ -121,13 +116,15 @@ class CartController(object): | |||
| 
 | ||||
|         items = rego.ProductItem.objects.filter(cart=self.cart) | ||||
|         for item in items: | ||||
|             # per-user limits are tested at add time, and are unliklely to change | ||||
|             # NOTE: per-user limits are tested at add time | ||||
|             # and are unliklely to change | ||||
|             prod = ProductController(item.product) | ||||
| 
 | ||||
|             # If the cart is not reserved, we need to see if we can re-reserve | ||||
|             quantity = 0 if is_reserved else item.quantity | ||||
| 
 | ||||
|             if not prod.can_add_with_enabling_conditions(self.cart.user, quantity): | ||||
|             if not prod.can_add_with_enabling_conditions( | ||||
|                     self.cart.user, quantity): | ||||
|                 raise ValidationError("Products are no longer available") | ||||
| 
 | ||||
|         # Validate the discounts | ||||
|  | @ -139,7 +136,8 @@ class CartController(object): | |||
|             if discount in seen_discounts: | ||||
|                 continue | ||||
|             seen_discounts.add(discount) | ||||
|             real_discount = rego.DiscountBase.objects.get_subclass(pk=discount.pk) | ||||
|             real_discount = rego.DiscountBase.objects.get_subclass( | ||||
|                 pk=discount.pk) | ||||
|             cond = ConditionController.for_condition(real_discount) | ||||
| 
 | ||||
|             quantity = 0 if is_reserved else discount_item.quantity | ||||
|  | @ -147,8 +145,6 @@ class CartController(object): | |||
|             if not cond.is_met(self.cart.user, quantity): | ||||
|                 raise ValidationError("Discounts are no longer available") | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     def recalculate_discounts(self): | ||||
|         ''' Calculates all of the discounts available for this product. | ||||
|         NB should be transactional, and it's terribly inefficient. | ||||
|  | @ -160,11 +156,10 @@ class CartController(object): | |||
|         for item in self.cart.productitem_set.all(): | ||||
|             self._add_discount(item.product, item.quantity) | ||||
| 
 | ||||
| 
 | ||||
|     def _add_discount(self, product, quantity): | ||||
|         ''' Calculates the best available discounts for this product. | ||||
|         NB this will be super-inefficient in aggregate because discounts will be | ||||
|         re-tested for each product. We should work on that.''' | ||||
|         NB this will be super-inefficient in aggregate because discounts will | ||||
|         be re-tested for each product. We should work on that.''' | ||||
| 
 | ||||
|         prod = ProductController(product) | ||||
|         discounts = prod.available_discounts(self.cart.user) | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| from django.db.models import F, Q | ||||
| from django.db.models import Q | ||||
| from django.db.models import Sum | ||||
| from django.utils import timezone | ||||
| 
 | ||||
|  | @ -15,15 +15,15 @@ class ConditionController(object): | |||
|     @staticmethod | ||||
|     def for_condition(condition): | ||||
|         CONTROLLERS = { | ||||
|             rego.CategoryEnablingCondition : CategoryConditionController, | ||||
|             rego.IncludedProductDiscount : ProductConditionController, | ||||
|             rego.ProductEnablingCondition : ProductConditionController, | ||||
|             rego.TimeOrStockLimitDiscount : | ||||
|             rego.CategoryEnablingCondition: CategoryConditionController, | ||||
|             rego.IncludedProductDiscount: ProductConditionController, | ||||
|             rego.ProductEnablingCondition: ProductConditionController, | ||||
|             rego.TimeOrStockLimitDiscount: | ||||
|                 TimeOrStockLimitConditionController, | ||||
|             rego.TimeOrStockLimitEnablingCondition : | ||||
|             rego.TimeOrStockLimitEnablingCondition: | ||||
|                 TimeOrStockLimitConditionController, | ||||
|             rego.VoucherDiscount : VoucherConditionController, | ||||
|             rego.VoucherEnablingCondition : VoucherConditionController, | ||||
|             rego.VoucherDiscount: VoucherConditionController, | ||||
|             rego.VoucherEnablingCondition: VoucherConditionController, | ||||
|         } | ||||
| 
 | ||||
|         try: | ||||
|  | @ -31,7 +31,6 @@ class ConditionController(object): | |||
|         except KeyError: | ||||
|             return ConditionController() | ||||
| 
 | ||||
| 
 | ||||
|     def is_met(self, user, quantity): | ||||
|         return True | ||||
| 
 | ||||
|  | @ -48,7 +47,8 @@ class CategoryConditionController(ConditionController): | |||
|         carts = rego.Cart.objects.filter(user=user) | ||||
|         enabling_products = rego.Product.objects.filter( | ||||
|             category=self.condition.enabling_category) | ||||
|         products = rego.ProductItem.objects.filter(cart=carts, | ||||
|         products = rego.ProductItem.objects.filter( | ||||
|             cart=carts, | ||||
|             product=enabling_products) | ||||
|         return len(products) > 0 | ||||
| 
 | ||||
|  | @ -65,7 +65,8 @@ class ProductConditionController(ConditionController): | |||
|         condition in one of their carts ''' | ||||
| 
 | ||||
|         carts = rego.Cart.objects.filter(user=user) | ||||
|         products = rego.ProductItem.objects.filter(cart=carts, | ||||
|         products = rego.ProductItem.objects.filter( | ||||
|             cart=carts, | ||||
|             product=self.condition.enabling_products.all()) | ||||
|         return len(products) > 0 | ||||
| 
 | ||||
|  | @ -77,7 +78,6 @@ class TimeOrStockLimitConditionController(ConditionController): | |||
|     def __init__(self, ceiling): | ||||
|         self.ceiling = ceiling | ||||
| 
 | ||||
| 
 | ||||
|     def is_met(self, user, quantity): | ||||
|         ''' returns True if adding _quantity_ of _product_ will not vioilate | ||||
|         this ceiling. ''' | ||||
|  | @ -93,7 +93,6 @@ class TimeOrStockLimitConditionController(ConditionController): | |||
|         # All limits have been met | ||||
|         return True | ||||
| 
 | ||||
| 
 | ||||
|     def test_date_range(self): | ||||
|         now = timezone.now() | ||||
| 
 | ||||
|  | @ -107,7 +106,6 @@ class TimeOrStockLimitConditionController(ConditionController): | |||
| 
 | ||||
|         return True | ||||
| 
 | ||||
| 
 | ||||
|     def _products(self): | ||||
|         ''' Abstracts away the product list, becuase enabling conditions | ||||
|         list products differently to discounts. ''' | ||||
|  | @ -125,7 +123,6 @@ class TimeOrStockLimitConditionController(ConditionController): | |||
|                 Q(category=categories.all()) | ||||
|             ) | ||||
| 
 | ||||
| 
 | ||||
|     def test_limits(self, quantity): | ||||
|         if self.ceiling.limit is None: | ||||
|             return True | ||||
|  | @ -155,6 +152,7 @@ class VoucherConditionController(ConditionController): | |||
| 
 | ||||
|     def is_met(self, user, quantity): | ||||
|         ''' returns True if the user has the given voucher attached. ''' | ||||
|         carts = rego.Cart.objects.filter(user=user, | ||||
|         carts = rego.Cart.objects.filter( | ||||
|             user=user, | ||||
|             vouchers=self.condition.voucher) | ||||
|         return len(carts) > 0 | ||||
|  |  | |||
|  | @ -1,11 +1,12 @@ | |||
| from decimal import Decimal | ||||
| from django.core.exceptions import ObjectDoesNotExist | ||||
| from django.db.models import Avg, Min, Max, Sum | ||||
| from django.db.models import Sum | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| 
 | ||||
| from cart import CartController | ||||
| 
 | ||||
| 
 | ||||
| class InvoiceController(object): | ||||
| 
 | ||||
|     def __init__(self, invoice): | ||||
|  | @ -22,12 +23,11 @@ class InvoiceController(object): | |||
|                 cart=cart, cart_revision=cart.revision) | ||||
|         except ObjectDoesNotExist: | ||||
|             cart_controller = CartController(cart) | ||||
|             cart_controller.validate_cart() # Raises ValidationError on fail. | ||||
|             cart_controller.validate_cart()  # Raises ValidationError on fail. | ||||
|             invoice = cls._generate(cart) | ||||
| 
 | ||||
|         return InvoiceController(invoice) | ||||
| 
 | ||||
| 
 | ||||
|     @classmethod | ||||
|     def resolve_discount_value(cls, item): | ||||
|         try: | ||||
|  | @ -46,7 +46,6 @@ class InvoiceController(object): | |||
|             value = condition.price | ||||
|         return value | ||||
| 
 | ||||
| 
 | ||||
|     @classmethod | ||||
|     def _generate(cls, cart): | ||||
|         ''' Generates an invoice for the given cart. ''' | ||||
|  | @ -89,7 +88,6 @@ class InvoiceController(object): | |||
| 
 | ||||
|         return invoice | ||||
| 
 | ||||
| 
 | ||||
|     def is_valid(self): | ||||
|         ''' Returns true if the attached invoice is not void and it represents | ||||
|         a valid cart. ''' | ||||
|  | @ -100,12 +98,10 @@ class InvoiceController(object): | |||
|                 return False | ||||
|         return True | ||||
| 
 | ||||
| 
 | ||||
|     def void(self): | ||||
|         ''' Voids the invoice. ''' | ||||
|         self.invoice.void = True | ||||
| 
 | ||||
| 
 | ||||
|     def pay(self, reference, amount): | ||||
|         ''' Pays the invoice by the given amount. If the payment | ||||
|         equals the total on the invoice, finalise the invoice. | ||||
|  | @ -113,7 +109,7 @@ class InvoiceController(object): | |||
|         ''' | ||||
|         if self.invoice.cart is not None: | ||||
|             cart = CartController(self.invoice.cart) | ||||
|             cart.validate_cart() # Raises ValidationError if invalid | ||||
|             cart.validate_cart()  # Raises ValidationError if invalid | ||||
| 
 | ||||
|         ''' Adds a payment ''' | ||||
|         payment = rego.Payment.objects.create( | ||||
|  | @ -127,7 +123,7 @@ class InvoiceController(object): | |||
|         agg = payments.aggregate(Sum("amount")) | ||||
|         total = agg["amount__sum"] | ||||
| 
 | ||||
|         if total==self.invoice.value: | ||||
|         if total == self.invoice.value: | ||||
|             self.invoice.paid = True | ||||
| 
 | ||||
|             cart = self.invoice.cart | ||||
|  |  | |||
|  | @ -2,12 +2,17 @@ import itertools | |||
| 
 | ||||
| from collections import namedtuple | ||||
| 
 | ||||
| from django.db.models import F, Q | ||||
| from django.db.models import Q | ||||
| from registrasion import models as rego | ||||
| 
 | ||||
| from conditions import ConditionController | ||||
| 
 | ||||
| DiscountEnabler = namedtuple("DiscountEnabler", ("discount", "condition", "value")) | ||||
| DiscountEnabler = namedtuple( | ||||
|     "DiscountEnabler", ( | ||||
|         "discount", | ||||
|         "condition", | ||||
|         "value")) | ||||
| 
 | ||||
| 
 | ||||
| class ProductController(object): | ||||
| 
 | ||||
|  | @ -19,7 +24,9 @@ class ProductController(object): | |||
|         this Product without exceeding _limit_per_user_.''' | ||||
| 
 | ||||
|         carts = rego.Cart.objects.filter(user=user) | ||||
|         items = rego.ProductItem.objects.filter(product=self.product, cart=carts) | ||||
|         items = rego.ProductItem.objects.filter( | ||||
|             product=self.product, | ||||
|             cart=carts) | ||||
| 
 | ||||
|         count = 0 | ||||
|         for item in items: | ||||
|  | @ -62,7 +69,6 @@ class ProductController(object): | |||
| 
 | ||||
|         return True | ||||
| 
 | ||||
| 
 | ||||
|     def get_enabler(self, condition): | ||||
|         if condition.percentage is not None: | ||||
|             value = condition.percentage * self.product.price | ||||
|  | @ -91,7 +97,8 @@ class ProductController(object): | |||
| 
 | ||||
|         discounts = [] | ||||
|         for discount in potential_discounts: | ||||
|             real_discount = rego.DiscountBase.objects.get_subclass(pk=discount.discount.pk) | ||||
|             real_discount = rego.DiscountBase.objects.get_subclass( | ||||
|                 pk=discount.discount.pk) | ||||
|             cond = ConditionController.for_condition(real_discount) | ||||
|             if cond.is_met(user, 0): | ||||
|                 discounts.append(discount) | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ from __future__ import unicode_literals | |||
| 
 | ||||
| import datetime | ||||
| 
 | ||||
| from django.core.exceptions import ObjectDoesNotExist | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.contrib.auth.models import User | ||||
| from django.db import models | ||||
|  | @ -13,10 +12,6 @@ from django.utils.translation import ugettext_lazy as _ | |||
| from model_utils.managers import InheritanceManager | ||||
| 
 | ||||
| 
 | ||||
| from symposion.markdown_parser import parse | ||||
| from symposion.proposals.models import ProposalBase | ||||
| 
 | ||||
| 
 | ||||
| # User models | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
|  | @ -63,9 +58,11 @@ class Category(models.Model): | |||
|     ] | ||||
| 
 | ||||
|     name = models.CharField(max_length=65, verbose_name=_("Name")) | ||||
|     description = models.CharField(max_length=255, verbose_name=_("Description")) | ||||
|     description = models.CharField(max_length=255, | ||||
|                                    verbose_name=_("Description")) | ||||
|     order = models.PositiveIntegerField(verbose_name=("Display order")) | ||||
|     render_type = models.IntegerField(choices=CATEGORY_RENDER_TYPES, verbose_name=_("Render type")) | ||||
|     render_type = models.IntegerField(choices=CATEGORY_RENDER_TYPES, | ||||
|                                       verbose_name=_("Render type")) | ||||
| 
 | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
|  | @ -76,10 +73,15 @@ class Product(models.Model): | |||
|         return self.name | ||||
| 
 | ||||
|     name = models.CharField(max_length=65, verbose_name=_("Name")) | ||||
|     description = models.CharField(max_length=255, verbose_name=_("Description")) | ||||
|     description = models.CharField(max_length=255, | ||||
|                                    verbose_name=_("Description")) | ||||
|     category = models.ForeignKey(Category, verbose_name=_("Product category")) | ||||
|     price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name=_("Price")) | ||||
|     limit_per_user = models.PositiveIntegerField(blank=True, verbose_name=_("Limit per user")) | ||||
|     price = models.DecimalField(max_digits=8, | ||||
|                                 decimal_places=2, | ||||
|                                 verbose_name=_("Price")) | ||||
|     limit_per_user = models.PositiveIntegerField( | ||||
|         blank=True, | ||||
|         verbose_name=_("Limit per user")) | ||||
|     reservation_duration = models.DurationField( | ||||
|         default=datetime.timedelta(hours=1), | ||||
|         verbose_name=_("Reservation duration")) | ||||
|  | @ -98,7 +100,9 @@ class Voucher(models.Model): | |||
|         return "Voucher for %s" % self.recipient | ||||
| 
 | ||||
|     recipient = models.CharField(max_length=64, verbose_name=_("Recipient")) | ||||
|     code = models.CharField(max_length=16, unique=True, verbose_name=_("Voucher code")) | ||||
|     code = models.CharField(max_length=16, | ||||
|                             unique=True, | ||||
|                             verbose_name=_("Voucher code")) | ||||
|     limit = models.PositiveIntegerField(verbose_name=_("Voucher use limit")) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -107,8 +111,8 @@ class Voucher(models.Model): | |||
| @python_2_unicode_compatible | ||||
| class DiscountBase(models.Model): | ||||
|     ''' Base class for discounts. Each subclass has controller code that | ||||
|     determines whether or not the given discount is available to be added to the | ||||
|     current cart. ''' | ||||
|     determines whether or not the given discount is available to be added to | ||||
|     the current cart. ''' | ||||
| 
 | ||||
|     objects = InheritanceManager() | ||||
| 
 | ||||
|  | @ -116,7 +120,7 @@ class DiscountBase(models.Model): | |||
|         return "Discount: " + self.description | ||||
| 
 | ||||
|     description = models.CharField(max_length=255, | ||||
|         verbose_name=_("Description")) | ||||
|                                    verbose_name=_("Description")) | ||||
| 
 | ||||
| 
 | ||||
| @python_2_unicode_compatible | ||||
|  | @ -156,7 +160,10 @@ class DiscountForCategory(models.Model): | |||
| 
 | ||||
|     discount = models.ForeignKey(DiscountBase, on_delete=models.CASCADE) | ||||
|     category = models.ForeignKey(Category, on_delete=models.CASCADE) | ||||
|     percentage = models.DecimalField(max_digits=4, decimal_places=1, blank=True) | ||||
|     percentage = models.DecimalField( | ||||
|         max_digits=4, | ||||
|         decimal_places=1, | ||||
|         blank=True) | ||||
|     quantity = models.PositiveIntegerField() | ||||
| 
 | ||||
| 
 | ||||
|  | @ -176,7 +183,9 @@ class VoucherDiscount(DiscountBase): | |||
|     ''' Discounts that are enabled when a voucher code is in the current | ||||
|     cart. ''' | ||||
| 
 | ||||
|     voucher = models.OneToOneField(Voucher, on_delete=models.CASCADE, | ||||
|     voucher = models.OneToOneField( | ||||
|         Voucher, | ||||
|         on_delete=models.CASCADE, | ||||
|         verbose_name=_("Voucher")) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -187,14 +196,15 @@ class IncludedProductDiscount(DiscountBase): | |||
|     class Meta: | ||||
|         verbose_name = _("Product inclusion") | ||||
| 
 | ||||
|     enabling_products = models.ManyToManyField(Product, | ||||
|     enabling_products = models.ManyToManyField( | ||||
|         Product, | ||||
|         verbose_name=_("Including product")) | ||||
| 
 | ||||
| 
 | ||||
| class RoleDiscount(object): | ||||
|     ''' Discounts that are enabled because the active user has a specific | ||||
|     role. This is for e.g. volunteers who can get a discount ticket. ''' | ||||
|     ## TODO: implement RoleDiscount | ||||
|     # TODO: implement RoleDiscount | ||||
|     pass | ||||
| 
 | ||||
| 
 | ||||
|  | @ -253,16 +263,16 @@ class VoucherEnablingCondition(EnablingConditionBase): | |||
|     enabling sponsor tickets. ''' | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         return "Enabled by voucher: %s" % voucher | ||||
|         return "Enabled by voucher: %s" % self.voucher | ||||
| 
 | ||||
|     voucher = models.OneToOneField(Voucher) | ||||
| 
 | ||||
| 
 | ||||
| #@python_2_unicode_compatible | ||||
| # @python_2_unicode_compatible | ||||
| class RoleEnablingCondition(object): | ||||
|     ''' The condition is met because the active user has a particular Role. | ||||
|     This is for e.g. enabling Team tickets. ''' | ||||
|     ## TODO: implement RoleEnablingCondition | ||||
|     # TODO: implement RoleEnablingCondition | ||||
|     pass | ||||
| 
 | ||||
| 
 | ||||
|  | @ -289,8 +299,9 @@ class Cart(models.Model): | |||
|         ''' Gets all carts that are 'reserved' ''' | ||||
|         return Cart.objects.filter( | ||||
|             (Q(active=True) & | ||||
|                 Q(time_last_updated__gt=timezone.now()-F('reservation_duration') | ||||
|             )) | | ||||
|                 Q(time_last_updated__gt=( | ||||
|                     timezone.now()-F('reservation_duration') | ||||
|                                         ))) | | ||||
|             Q(active=False) | ||||
|         ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| from django.utils import timezone | ||||
| 
 | ||||
| 
 | ||||
| class SetTimeMixin(object): | ||||
|     ''' Patches timezone.now() for the duration of a test case. Allows us to | ||||
|     test time-based conditions (ceilings etc) relatively easily. ''' | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ from decimal import Decimal | |||
| from django.contrib.auth.models import User | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.test import TestCase | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| from registrasion.controllers.cart import CartController | ||||
|  | @ -14,6 +13,7 @@ from patch_datetime import SetTimeMixin | |||
| 
 | ||||
| UTC = pytz.timezone('UTC') | ||||
| 
 | ||||
| 
 | ||||
| class RegistrationCartTestCase(SetTimeMixin, TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|  | @ -21,11 +21,15 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase): | |||
| 
 | ||||
|     @classmethod | ||||
|     def setUpTestData(cls): | ||||
|         cls.USER_1 = User.objects.create_user(username='testuser', | ||||
|             email='test@example.com', password='top_secret') | ||||
|         cls.USER_1 = User.objects.create_user( | ||||
|             username='testuser', | ||||
|             email='test@example.com', | ||||
|             password='top_secret') | ||||
| 
 | ||||
|         cls.USER_2 = User.objects.create_user(username='testuser2', | ||||
|             email='test2@example.com', password='top_secret') | ||||
|         cls.USER_2 = User.objects.create_user( | ||||
|             username='testuser2', | ||||
|             email='test2@example.com', | ||||
|             password='top_secret') | ||||
| 
 | ||||
|         cls.CAT_1 = rego.Category.objects.create( | ||||
|             name="Category 1", | ||||
|  | @ -47,8 +51,8 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase): | |||
| 
 | ||||
|         cls.PROD_1 = rego.Product.objects.create( | ||||
|             name="Product 1", | ||||
|             description= "This is a test product. It costs $10. " \ | ||||
|                 "A user may have 10 of them.", | ||||
|             description="This is a test product. It costs $10. " | ||||
|                         "A user may have 10 of them.", | ||||
|             category=cls.CAT_1, | ||||
|             price=Decimal("10.00"), | ||||
|             reservation_duration=cls.RESERVATION, | ||||
|  | @ -59,8 +63,8 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase): | |||
| 
 | ||||
|         cls.PROD_2 = rego.Product.objects.create( | ||||
|             name="Product 2", | ||||
|             description= "This is a test product. It costs $10. " \ | ||||
|                 "A user may have 10 of them.", | ||||
|             description="This is a test product. It costs $10. " | ||||
|                         "A user may have 10 of them.", | ||||
|             category=cls.CAT_1, | ||||
|             price=Decimal("10.00"), | ||||
|             limit_per_user=10, | ||||
|  | @ -70,8 +74,8 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase): | |||
| 
 | ||||
|         cls.PROD_3 = rego.Product.objects.create( | ||||
|             name="Product 3", | ||||
|             description= "This is a test product. It costs $10. " \ | ||||
|                 "A user may have 10 of them.", | ||||
|             description="This is a test product. It costs $10. " | ||||
|                         "A user may have 10 of them.", | ||||
|             category=cls.CAT_2, | ||||
|             price=Decimal("10.00"), | ||||
|             limit_per_user=10, | ||||
|  | @ -79,7 +83,6 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase): | |||
|         ) | ||||
|         cls.PROD_2.save() | ||||
| 
 | ||||
| 
 | ||||
|     @classmethod | ||||
|     def make_ceiling(cls, name, limit=None, start_time=None, end_time=None): | ||||
|         limit_ceiling = rego.TimeOrStockLimitEnablingCondition.objects.create( | ||||
|  | @ -93,9 +96,9 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase): | |||
|         limit_ceiling.products.add(cls.PROD_1, cls.PROD_2) | ||||
|         limit_ceiling.save() | ||||
| 
 | ||||
| 
 | ||||
|     @classmethod | ||||
|     def make_category_ceiling(cls, name, limit=None, start_time=None, end_time=None): | ||||
|     def make_category_ceiling( | ||||
|             cls, name, limit=None, start_time=None, end_time=None): | ||||
|         limit_ceiling = rego.TimeOrStockLimitEnablingCondition.objects.create( | ||||
|             description=name, | ||||
|             mandatory=True, | ||||
|  | @ -107,9 +110,9 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase): | |||
|         limit_ceiling.categories.add(cls.CAT_1) | ||||
|         limit_ceiling.save() | ||||
| 
 | ||||
| 
 | ||||
|     @classmethod | ||||
|     def make_discount_ceiling(cls, name, limit=None, start_time=None, end_time=None): | ||||
|     def make_discount_ceiling( | ||||
|             cls, name, limit=None, start_time=None, end_time=None): | ||||
|         limit_ceiling = rego.TimeOrStockLimitDiscount.objects.create( | ||||
|             description=name, | ||||
|             start_time=start_time, | ||||
|  | @ -141,7 +144,6 @@ class BasicCartTests(RegistrationCartTestCase): | |||
|         current_cart2 = CartController.for_user(self.USER_1) | ||||
|         self.assertEqual(current_cart.cart, current_cart2.cart) | ||||
| 
 | ||||
| 
 | ||||
|     def test_add_to_cart_collapses_product_items(self): | ||||
|         current_cart = CartController.for_user(self.USER_1) | ||||
| 
 | ||||
|  | @ -149,14 +151,14 @@ class BasicCartTests(RegistrationCartTestCase): | |||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
|         ## Count of products for a given user should be collapsed. | ||||
|         items = rego.ProductItem.objects.filter(cart=current_cart.cart, | ||||
|         # Count of products for a given user should be collapsed. | ||||
|         items = rego.ProductItem.objects.filter( | ||||
|             cart=current_cart.cart, | ||||
|             product=self.PROD_1) | ||||
|         self.assertEqual(1, len(items)) | ||||
|         item = items[0] | ||||
|         self.assertEquals(2, item.quantity) | ||||
| 
 | ||||
| 
 | ||||
|     def test_add_to_cart_per_user_limit(self): | ||||
|         current_cart = CartController.for_user(self.USER_1) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,19 +1,15 @@ | |||
| import datetime | ||||
| import pytz | ||||
| 
 | ||||
| from decimal import Decimal | ||||
| from django.contrib.auth.models import User | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.test import TestCase | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| from registrasion.controllers.cart import CartController | ||||
| 
 | ||||
| from test_cart import RegistrationCartTestCase | ||||
| 
 | ||||
| UTC = pytz.timezone('UTC') | ||||
| 
 | ||||
| 
 | ||||
| class CeilingsTestCases(RegistrationCartTestCase): | ||||
| 
 | ||||
|     def test_add_to_cart_ceiling_limit(self): | ||||
|  | @ -44,12 +40,11 @@ class CeilingsTestCases(RegistrationCartTestCase): | |||
|         # User should be able to add 5 of PROD_2 to the current cart | ||||
|         current_cart.add_to_cart(self.PROD_2, 4) | ||||
| 
 | ||||
| 
 | ||||
|     def test_add_to_cart_ceiling_date_range(self): | ||||
|         self.make_ceiling("date range ceiling", | ||||
|         self.make_ceiling( | ||||
|             "date range ceiling", | ||||
|             start_time=datetime.datetime(2015, 01, 01, tzinfo=UTC), | ||||
|             end_time=datetime.datetime(2015, 02, 01, tzinfo=UTC) | ||||
|         ) | ||||
|             end_time=datetime.datetime(2015, 02, 01, tzinfo=UTC)) | ||||
| 
 | ||||
|         current_cart = CartController.for_user(self.USER_1) | ||||
| 
 | ||||
|  | @ -74,7 +69,6 @@ class CeilingsTestCases(RegistrationCartTestCase): | |||
|         with self.assertRaises(ValidationError): | ||||
|             current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_add_to_cart_ceiling_limit_reserved_carts(self): | ||||
|         self.make_ceiling("Limit ceiling", limit=1) | ||||
| 
 | ||||
|  | @ -106,7 +100,6 @@ class CeilingsTestCases(RegistrationCartTestCase): | |||
|         with self.assertRaises(ValidationError): | ||||
|             first_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_validate_cart_fails_product_ceilings(self): | ||||
|         self.make_ceiling("Limit ceiling", limit=1) | ||||
|         self.__validation_test() | ||||
|  |  | |||
|  | @ -1,11 +1,6 @@ | |||
| import datetime | ||||
| import pytz | ||||
| 
 | ||||
| from decimal import Decimal | ||||
| from django.contrib.auth.models import User | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.test import TestCase | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| from registrasion.controllers.cart import CartController | ||||
|  | @ -14,6 +9,7 @@ from test_cart import RegistrationCartTestCase | |||
| 
 | ||||
| UTC = pytz.timezone('UTC') | ||||
| 
 | ||||
| 
 | ||||
| class DiscountTestCase(RegistrationCartTestCase): | ||||
| 
 | ||||
|     @classmethod | ||||
|  | @ -32,7 +28,6 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         ).save() | ||||
|         return discount | ||||
| 
 | ||||
| 
 | ||||
|     @classmethod | ||||
|     def add_discount_prod_1_includes_cat_2(cls, amount=Decimal(100)): | ||||
|         discount = rego.IncludedProductDiscount.objects.create( | ||||
|  | @ -49,9 +44,8 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         ).save() | ||||
|         return discount | ||||
| 
 | ||||
| 
 | ||||
|     def test_discount_is_applied(self): | ||||
|         discount = self.add_discount_prod_1_includes_prod_2() | ||||
|         self.add_discount_prod_1_includes_prod_2() | ||||
| 
 | ||||
|         cart = CartController.for_user(self.USER_1) | ||||
|         cart.add_to_cart(self.PROD_1, 1) | ||||
|  | @ -60,9 +54,8 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         # Discounts should be applied at this point... | ||||
|         self.assertEqual(1, len(cart.cart.discountitem_set.all())) | ||||
| 
 | ||||
| 
 | ||||
|     def test_discount_is_applied_for_category(self): | ||||
|         discount = self.add_discount_prod_1_includes_cat_2() | ||||
|         self.add_discount_prod_1_includes_cat_2() | ||||
| 
 | ||||
|         cart = CartController.for_user(self.USER_1) | ||||
|         cart.add_to_cart(self.PROD_1, 1) | ||||
|  | @ -71,9 +64,8 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         # Discounts should be applied at this point... | ||||
|         self.assertEqual(1, len(cart.cart.discountitem_set.all())) | ||||
| 
 | ||||
| 
 | ||||
|     def test_discount_does_not_apply_if_not_met(self): | ||||
|         discount = self.add_discount_prod_1_includes_prod_2() | ||||
|         self.add_discount_prod_1_includes_prod_2() | ||||
| 
 | ||||
|         cart = CartController.for_user(self.USER_1) | ||||
|         cart.add_to_cart(self.PROD_2, 1) | ||||
|  | @ -81,9 +73,8 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         # No discount should be applied as the condition is not met | ||||
|         self.assertEqual(0, len(cart.cart.discountitem_set.all())) | ||||
| 
 | ||||
| 
 | ||||
|     def test_discount_applied_out_of_order(self): | ||||
|         discount = self.add_discount_prod_1_includes_prod_2() | ||||
|         self.add_discount_prod_1_includes_prod_2() | ||||
| 
 | ||||
|         cart = CartController.for_user(self.USER_1) | ||||
|         cart.add_to_cart(self.PROD_2, 1) | ||||
|  | @ -92,9 +83,8 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         # No discount should be applied as the condition is not met | ||||
|         self.assertEqual(1, len(cart.cart.discountitem_set.all())) | ||||
| 
 | ||||
| 
 | ||||
|     def test_discounts_collapse(self): | ||||
|         discount = self.add_discount_prod_1_includes_prod_2() | ||||
|         self.add_discount_prod_1_includes_prod_2() | ||||
| 
 | ||||
|         cart = CartController.for_user(self.USER_1) | ||||
|         cart.add_to_cart(self.PROD_1, 1) | ||||
|  | @ -104,9 +94,8 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         # Discounts should be applied and collapsed at this point... | ||||
|         self.assertEqual(1, len(cart.cart.discountitem_set.all())) | ||||
| 
 | ||||
| 
 | ||||
|     def test_discounts_respect_quantity(self): | ||||
|         discount = self.add_discount_prod_1_includes_prod_2() | ||||
|         self.add_discount_prod_1_includes_prod_2() | ||||
| 
 | ||||
|         cart = CartController.for_user(self.USER_1) | ||||
|         cart.add_to_cart(self.PROD_1, 1) | ||||
|  | @ -117,7 +106,6 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         discount_items = list(cart.cart.discountitem_set.all()) | ||||
|         self.assertEqual(2, discount_items[0].quantity) | ||||
| 
 | ||||
| 
 | ||||
|     def test_multiple_discounts_apply_in_order(self): | ||||
|         discount_full = self.add_discount_prod_1_includes_prod_2() | ||||
|         discount_half = self.add_discount_prod_1_includes_prod_2(Decimal(50)) | ||||
|  | @ -137,9 +125,8 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         self.assertEqual(2, discount_items[1].quantity) | ||||
|         self.assertEqual(discount_full.pk, discount_items[1].discount.pk) | ||||
| 
 | ||||
| 
 | ||||
|     def test_discount_applies_across_carts(self): | ||||
|         discount_full = self.add_discount_prod_1_includes_prod_2() | ||||
|         self.add_discount_prod_1_includes_prod_2() | ||||
| 
 | ||||
|         # Enable the discount during the first cart. | ||||
|         cart = CartController.for_user(self.USER_1) | ||||
|  | @ -167,16 +154,16 @@ class DiscountTestCase(RegistrationCartTestCase): | |||
|         discount_items = list(cart.cart.discountitem_set.all()) | ||||
|         self.assertEqual(1, discount_items[0].quantity) | ||||
| 
 | ||||
| 
 | ||||
|     def test_discount_applies_only_once_enabled(self): | ||||
|         # Enable the discount during the first cart. | ||||
|         cart = CartController.for_user(self.USER_1) | ||||
|         cart.add_to_cart(self.PROD_1, 1) | ||||
|         cart.add_to_cart(self.PROD_2, 2) # This would exhaust discount if present | ||||
|         # This would exhaust discount if present | ||||
|         cart.add_to_cart(self.PROD_2, 2) | ||||
|         cart.cart.active = False | ||||
|         cart.cart.save() | ||||
| 
 | ||||
|         discount_full = self.add_discount_prod_1_includes_prod_2() | ||||
|         self.add_discount_prod_1_includes_prod_2() | ||||
|         cart = CartController.for_user(self.USER_1) | ||||
|         cart.add_to_cart(self.PROD_2, 2) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,11 +1,6 @@ | |||
| import datetime | ||||
| import pytz | ||||
| 
 | ||||
| from decimal import Decimal | ||||
| from django.contrib.auth.models import User | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.test import TestCase | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| from registrasion.controllers.cart import CartController | ||||
|  | @ -14,6 +9,7 @@ from test_cart import RegistrationCartTestCase | |||
| 
 | ||||
| UTC = pytz.timezone('UTC') | ||||
| 
 | ||||
| 
 | ||||
| class EnablingConditionTestCases(RegistrationCartTestCase): | ||||
| 
 | ||||
|     @classmethod | ||||
|  | @ -29,7 +25,6 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         enabling_condition.enabling_products.add(cls.PROD_2) | ||||
|         enabling_condition.save() | ||||
| 
 | ||||
| 
 | ||||
|     @classmethod | ||||
|     def add_product_enabling_condition_on_category(cls, mandatory=False): | ||||
|         ''' Adds a product enabling condition that operates on a category: | ||||
|  | @ -43,7 +38,6 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         enabling_condition.enabling_products.add(cls.PROD_3) | ||||
|         enabling_condition.save() | ||||
| 
 | ||||
| 
 | ||||
|     def add_category_enabling_condition(cls, mandatory=False): | ||||
|         ''' Adds a category enabling condition: adding PROD_1 to a cart is | ||||
|         predicated on adding an item from CAT_2 beforehand.''' | ||||
|  | @ -56,7 +50,6 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         enabling_condition.products.add(cls.PROD_1) | ||||
|         enabling_condition.save() | ||||
| 
 | ||||
| 
 | ||||
|     def test_product_enabling_condition_enables_product(self): | ||||
|         self.add_product_enabling_condition() | ||||
| 
 | ||||
|  | @ -68,7 +61,6 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         current_cart.add_to_cart(self.PROD_2, 1) | ||||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_product_enabled_by_product_in_previous_cart(self): | ||||
|         self.add_product_enabling_condition() | ||||
| 
 | ||||
|  | @ -81,7 +73,6 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         current_cart = CartController.for_user(self.USER_1) | ||||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_product_enabling_condition_enables_category(self): | ||||
|         self.add_product_enabling_condition_on_category() | ||||
| 
 | ||||
|  | @ -93,7 +84,6 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         current_cart.add_to_cart(self.PROD_3, 1) | ||||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_category_enabling_condition_enables_product(self): | ||||
|         self.add_category_enabling_condition() | ||||
| 
 | ||||
|  | @ -106,7 +96,6 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         current_cart.add_to_cart(self.PROD_3, 1) | ||||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_product_enabled_by_category_in_previous_cart(self): | ||||
|         self.add_category_enabling_condition() | ||||
| 
 | ||||
|  | @ -119,7 +108,6 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         current_cart = CartController.for_user(self.USER_1) | ||||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_multiple_non_mandatory_conditions(self): | ||||
|         self.add_product_enabling_condition() | ||||
|         self.add_category_enabling_condition() | ||||
|  | @ -140,7 +128,6 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         cart_2.add_to_cart(self.PROD_3, 1) | ||||
|         cart_2.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_multiple_mandatory_conditions(self): | ||||
|         self.add_product_enabling_condition(mandatory=True) | ||||
|         self.add_category_enabling_condition(mandatory=True) | ||||
|  | @ -149,13 +136,12 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         # Cannot add PROD_1 until both conditions are met | ||||
|         with self.assertRaises(ValidationError): | ||||
|             cart_1.add_to_cart(self.PROD_1, 1) | ||||
|         cart_1.add_to_cart(self.PROD_2, 1) # Meets the product condition | ||||
|         cart_1.add_to_cart(self.PROD_2, 1)  # Meets the product condition | ||||
|         with self.assertRaises(ValidationError): | ||||
|             cart_1.add_to_cart(self.PROD_1, 1) | ||||
|         cart_1.add_to_cart(self.PROD_3, 1) # Meets the category condition | ||||
|         cart_1.add_to_cart(self.PROD_3, 1)  # Meets the category condition | ||||
|         cart_1.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_mandatory_conditions_are_mandatory(self): | ||||
|         self.add_product_enabling_condition(mandatory=False) | ||||
|         self.add_category_enabling_condition(mandatory=True) | ||||
|  | @ -164,8 +150,8 @@ class EnablingConditionTestCases(RegistrationCartTestCase): | |||
|         # Cannot add PROD_1 until both conditions are met | ||||
|         with self.assertRaises(ValidationError): | ||||
|             cart_1.add_to_cart(self.PROD_1, 1) | ||||
|         cart_1.add_to_cart(self.PROD_2, 1) # Meets the product condition | ||||
|         cart_1.add_to_cart(self.PROD_2, 1)  # Meets the product condition | ||||
|         with self.assertRaises(ValidationError): | ||||
|             cart_1.add_to_cart(self.PROD_1, 1) | ||||
|         cart_1.add_to_cart(self.PROD_3, 1) # Meets the category condition | ||||
|         cart_1.add_to_cart(self.PROD_3, 1)  # Meets the category condition | ||||
|         cart_1.add_to_cart(self.PROD_1, 1) | ||||
|  |  | |||
|  | @ -2,10 +2,7 @@ import datetime | |||
| import pytz | ||||
| 
 | ||||
| from decimal import Decimal | ||||
| from django.contrib.auth.models import User | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.test import TestCase | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| from registrasion.controllers.cart import CartController | ||||
|  | @ -74,7 +71,6 @@ class InvoiceTestCase(RegistrationCartTestCase): | |||
|         new_cart = CartController.for_user(self.USER_1) | ||||
|         self.assertNotEqual(current_cart.cart, new_cart.cart) | ||||
| 
 | ||||
| 
 | ||||
|     def test_invoice_includes_discounts(self): | ||||
|         voucher = rego.Voucher.objects.create( | ||||
|             recipient="Voucher recipient", | ||||
|  | @ -105,4 +101,6 @@ class InvoiceTestCase(RegistrationCartTestCase): | |||
|         line_items = rego.LineItem.objects.filter(invoice=invoice_1.invoice) | ||||
|         self.assertEqual(2, len(line_items)) | ||||
|         # That invoice should have a value equal to 50% of the cost of PROD_1 | ||||
|         self.assertEqual(self.PROD_1.price * Decimal("0.5"), invoice_1.invoice.value) | ||||
|         self.assertEqual( | ||||
|             self.PROD_1.price * Decimal("0.5"), | ||||
|             invoice_1.invoice.value) | ||||
|  |  | |||
|  | @ -2,10 +2,7 @@ import datetime | |||
| import pytz | ||||
| 
 | ||||
| from decimal import Decimal | ||||
| from django.contrib.auth.models import User | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.test import TestCase | ||||
| from django.utils import timezone | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| from registrasion.controllers.cart import CartController | ||||
|  | @ -41,7 +38,8 @@ class VoucherTestCases(RegistrationCartTestCase): | |||
|         with self.assertRaises(ValidationError): | ||||
|             cart_2.apply_voucher(voucher) | ||||
| 
 | ||||
|         # After the reservation duration, user 2 should be able to apply voucher | ||||
|         # After the reservation duration | ||||
|         # user 2 should be able to apply voucher | ||||
|         self.add_timedelta(rego.Voucher.RESERVATION_DURATION * 2) | ||||
|         cart_2.apply_voucher(voucher) | ||||
|         cart_2.cart.active = False | ||||
|  | @ -74,7 +72,6 @@ class VoucherTestCases(RegistrationCartTestCase): | |||
|         current_cart.apply_voucher(voucher) | ||||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
| 
 | ||||
|     def test_voucher_enables_discount(self): | ||||
|         voucher = self.new_voucher() | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										3
									
								
								setup.cfg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								setup.cfg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| [flake8] | ||||
| exclude = registrasion/migrations/* | ||||
| 
 | ||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Christopher Neugebauer
						Christopher Neugebauer