2016-09-01 00:45:44 +02:00
# -*- coding: utf-8 -*-
from __future__ import ( absolute_import , division ,
print_function , unicode_literals )
from builtins import *
2016-08-22 05:41:31 +02:00
from decimal import Decimal
2016-08-02 10:40:46 +02:00
from django import forms
2016-08-07 17:02:01 +02:00
from django . core . exceptions import ValidationError
2016-08-31 00:36:23 +02:00
from django . core . validators import MinLengthValidator
2016-08-21 05:51:55 +02:00
from django . contrib . auth . models import User , Group , Permission
from django . contrib . contenttypes . models import ContentType
2016-08-26 15:30:40 +02:00
from django . forms import modelformset_factory , inlineformset_factory
from django . forms . models import BaseInlineFormSet
2016-08-22 02:52:59 +02:00
from django . utils import timezone
2016-08-11 15:14:23 +02:00
from kfet . models import ( Account , Checkout , Article , OperationGroup , Operation ,
2016-08-26 15:30:40 +02:00
CheckoutStatement , ArticleCategory , Settings , AccountNegative , Transfer ,
2016-08-27 14:12:01 +02:00
TransferGroup , Supplier , Inventory , InventoryArticle )
2016-08-02 10:40:46 +02:00
from gestioncof . models import CofProfile
2016-08-04 05:21:04 +02:00
# -----
# Widgets
# -----
class DateTimeWidget ( forms . DateTimeInput ) :
def __init__ ( self , attrs = None ) :
super ( DateTimeWidget , self ) . __init__ ( attrs )
self . attrs [ ' format ' ] = ' % Y- % m- %d % H: % M '
class Media :
css = {
2016-09-02 14:50:09 +02:00
' all ' : ( ' kfet/css/bootstrap-datetimepicker.min.css ' , )
2016-08-04 05:21:04 +02:00
}
js = (
2016-09-02 14:50:09 +02:00
' kfet/js/moment.js ' ,
' kfet/js/moment-fr.js ' ,
' kfet/js/bootstrap-datetimepicker.min.js ' ,
2016-08-04 05:21:04 +02:00
)
# -----
# Account forms
# -----
2016-08-03 04:38:54 +02:00
class AccountForm ( forms . ModelForm ) :
# Surcharge pour passer data à Account.save()
def save ( self , data = { } , * args , * * kwargs ) :
obj = super ( AccountForm , self ) . save ( commit = False , * args , * * kwargs )
obj . save ( data = data )
return obj
2016-08-02 10:40:46 +02:00
class Meta :
model = Account
2016-09-03 22:52:55 +02:00
fields = [ ' trigramme ' , ' promo ' , ' nickname ' , ' is_frozen ' ]
2016-08-02 10:40:46 +02:00
widgets = {
' trigramme ' : forms . TextInput ( attrs = { ' autocomplete ' : ' off ' } ) ,
}
2016-09-05 07:31:54 +02:00
class AccountBalanceForm ( forms . ModelForm ) :
class Meta :
model = Account
fields = [ ' balance ' ]
2016-08-03 04:38:54 +02:00
class AccountTriForm ( AccountForm ) :
2016-09-03 16:41:02 +02:00
def clean_trigramme ( self ) :
trigramme = self . cleaned_data [ ' trigramme ' ]
return trigramme . upper ( )
2016-08-03 04:38:54 +02:00
class Meta ( AccountForm . Meta ) :
fields = [ ' trigramme ' ]
class AccountNoTriForm ( AccountForm ) :
class Meta ( AccountForm . Meta ) :
exclude = [ ' trigramme ' ]
class AccountRestrictForm ( AccountForm ) :
class Meta ( AccountForm . Meta ) :
2016-09-03 22:52:55 +02:00
fields = [ ' is_frozen ' ]
2016-08-02 10:40:46 +02:00
2016-09-01 16:31:18 +02:00
class AccountPwdForm ( forms . Form ) :
pwd1 = forms . CharField (
widget = forms . PasswordInput )
pwd2 = forms . CharField (
widget = forms . PasswordInput )
def clean ( self ) :
2016-09-02 14:17:11 +02:00
pwd1 = self . cleaned_data . get ( ' pwd1 ' , ' ' )
pwd2 = self . cleaned_data . get ( ' pwd2 ' , ' ' )
2016-09-01 16:31:18 +02:00
if len ( pwd1 ) < 8 :
raise ValidationError ( " Mot de passe trop court " )
if pwd1 != pwd2 :
raise ValidationError ( " Les mots de passes sont différents " )
super ( AccountPwdForm , self ) . clean ( )
2016-08-02 10:40:46 +02:00
class CofForm ( forms . ModelForm ) :
def clean_is_cof ( self ) :
instance = getattr ( self , ' instance ' , None )
if instance and instance . pk :
return instance . is_cof
else :
return False
class Meta :
model = CofProfile
fields = [ ' login_clipper ' , ' is_cof ' , ' departement ' ]
2016-08-03 04:38:54 +02:00
class CofRestrictForm ( CofForm ) :
class Meta ( CofForm . Meta ) :
fields = [ ' departement ' ]
2016-08-02 10:40:46 +02:00
class UserForm ( forms . ModelForm ) :
2016-08-31 00:36:23 +02:00
def __init__ ( self , * args , * * kwargs ) :
2016-09-01 05:01:59 +02:00
from_clipper = kwargs . pop ( ' from_clipper ' , False )
new_user = kwargs . get ( ' instance ' ) is None and not from_clipper
2016-08-31 00:36:23 +02:00
super ( UserForm , self ) . __init__ ( * args , * * kwargs )
if new_user :
self . fields [ ' username ' ] . validators = [ MinLengthValidator ( 9 ) ]
2016-08-02 10:40:46 +02:00
class Meta :
model = User
fields = [ ' username ' , ' first_name ' , ' last_name ' , ' email ' ]
help_texts = {
' username ' : ' '
}
2016-08-03 04:38:54 +02:00
class UserRestrictForm ( UserForm ) :
2016-08-21 02:53:35 +02:00
class Meta ( UserForm . Meta ) :
fields = [ ' first_name ' , ' last_name ' ]
class UserRestrictTeamForm ( UserForm ) :
2016-08-03 04:38:54 +02:00
class Meta ( UserForm . Meta ) :
fields = [ ' first_name ' , ' last_name ' , ' email ' ]
2016-08-04 05:21:04 +02:00
2016-08-21 02:53:35 +02:00
class UserGroupForm ( forms . ModelForm ) :
groups = forms . ModelMultipleChoiceField (
Group . objects . filter ( name__icontains = ' K-Fêt ' ) )
class Meta :
model = User
fields = [ ' groups ' ]
2016-08-21 05:51:55 +02:00
class GroupForm ( forms . ModelForm ) :
permissions = forms . ModelMultipleChoiceField (
queryset = Permission . objects . filter ( content_type__in =
ContentType . objects . filter ( app_label = ' kfet ' ) ) )
2016-09-03 14:06:51 +02:00
def clean_name ( self ) :
name = self . cleaned_data [ ' name ' ]
return ' K-Fêt %s ' % name
2016-08-21 05:51:55 +02:00
class Meta :
model = Group
fields = [ ' name ' , ' permissions ' ]
2016-08-22 20:07:01 +02:00
class AccountNegativeForm ( forms . ModelForm ) :
class Meta :
model = AccountNegative
fields = [ ' authz_overdraft_amount ' , ' authz_overdraft_until ' ,
' balance_offset ' , ' comment ' ]
widgets = {
' authz_overdraft_until ' : DateTimeWidget ( ) ,
}
2016-08-04 05:21:04 +02:00
# -----
# Checkout forms
# -----
class CheckoutForm ( forms . ModelForm ) :
class Meta :
2016-08-04 08:23:34 +02:00
model = Checkout
fields = [ ' name ' , ' valid_from ' , ' valid_to ' , ' balance ' , ' is_protected ' ]
2016-08-04 05:21:04 +02:00
widgets = {
' valid_from ' : DateTimeWidget ( ) ,
' valid_to ' : DateTimeWidget ( ) ,
}
class CheckoutRestrictForm ( CheckoutForm ) :
class Meta ( CheckoutForm . Meta ) :
fields = [ ' name ' , ' valid_from ' , ' valid_to ' ]
2016-08-04 08:23:34 +02:00
2016-08-23 00:15:17 +02:00
class CheckoutStatementCreateForm ( forms . ModelForm ) :
2016-08-23 02:45:49 +02:00
balance_001 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_002 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_005 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_01 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_02 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_05 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_1 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_2 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_5 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_10 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_20 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_50 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_100 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_200 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
balance_500 = forms . IntegerField ( min_value = 0 , initial = 0 , required = False )
2016-08-23 00:15:17 +02:00
class Meta :
model = CheckoutStatement
exclude = [ ' by ' , ' at ' , ' checkout ' , ' amount_error ' , ' amount_taken ' ,
' balance_old ' , ' balance_new ' ]
2016-08-23 02:45:49 +02:00
def clean ( self ) :
not_count = self . cleaned_data [ ' not_count ' ]
if not not_count and (
self . cleaned_data [ ' balance_001 ' ] is None
or self . cleaned_data [ ' balance_002 ' ] is None
or self . cleaned_data [ ' balance_005 ' ] is None
or self . cleaned_data [ ' balance_01 ' ] is None
or self . cleaned_data [ ' balance_02 ' ] is None
or self . cleaned_data [ ' balance_05 ' ] is None
or self . cleaned_data [ ' balance_1 ' ] is None
or self . cleaned_data [ ' balance_2 ' ] is None
or self . cleaned_data [ ' balance_5 ' ] is None
or self . cleaned_data [ ' balance_10 ' ] is None
or self . cleaned_data [ ' balance_20 ' ] is None
or self . cleaned_data [ ' balance_50 ' ] is None
or self . cleaned_data [ ' balance_100 ' ] is None
or self . cleaned_data [ ' balance_200 ' ] is None
or self . cleaned_data [ ' balance_500 ' ] is None ) :
raise ValidationError ( " Y ' a un problème. Si tu comptes la caisse, mets au moins des 0 stp (et t ' as pas idée de comment c ' est long de vérifier que t ' as mis des valeurs de partout...) " )
super ( CheckoutStatementCreateForm , self ) . clean ( )
2016-08-23 00:15:17 +02:00
class CheckoutStatementUpdateForm ( forms . ModelForm ) :
2016-08-11 15:14:23 +02:00
class Meta :
model = CheckoutStatement
2016-08-23 00:15:17 +02:00
exclude = [ ' by ' , ' at ' , ' checkout ' , ' amount_error ' , ' amount_taken ' ]
2016-08-11 15:14:23 +02:00
2016-08-04 08:23:34 +02:00
# -----
# Article forms
# -----
class ArticleForm ( forms . ModelForm ) :
2016-08-21 18:10:35 +02:00
category_new = forms . CharField (
max_length = 45 ,
required = False )
category = forms . ModelChoiceField (
queryset = ArticleCategory . objects . all ( ) ,
required = False )
2016-08-26 23:44:57 +02:00
suppliers = forms . ModelMultipleChoiceField (
queryset = Supplier . objects . all ( ) ,
required = False )
supplier_new = forms . CharField (
max_length = 45 ,
required = False )
def __init__ ( self , * args , * * kwargs ) :
super ( ArticleForm , self ) . __init__ ( * args , * * kwargs )
if self . instance . pk :
self . initial [ ' suppliers ' ] = self . instance . suppliers . values_list ( ' pk ' , flat = True )
2016-08-21 18:10:35 +02:00
def clean ( self ) :
category = self . cleaned_data . get ( ' category ' )
category_new = self . cleaned_data . get ( ' category_new ' )
if not category and not category_new :
raise ValidationError ( ' Sélectionnez une catégorie ou créez en une ' )
elif not category :
category , _ = ArticleCategory . objects . get_or_create ( name = category_new )
self . cleaned_data [ ' category ' ] = category
2016-08-26 23:44:57 +02:00
2016-08-21 18:10:35 +02:00
super ( ArticleForm , self ) . clean ( )
2016-08-04 08:23:34 +02:00
class Meta :
model = Article
2017-01-26 19:22:38 +01:00
fields = [ ' name ' , ' is_sold ' , ' hidden ' , ' price ' , ' stock ' , ' category ' , ' box_type ' ,
2016-08-28 05:39:34 +02:00
' box_capacity ' ]
2016-08-04 08:23:34 +02:00
class ArticleRestrictForm ( ArticleForm ) :
class Meta ( ArticleForm . Meta ) :
2017-01-26 19:22:38 +01:00
fields = [ ' name ' , ' is_sold ' , ' hidden ' , ' price ' , ' category ' , ' box_type ' ,
2016-08-28 05:39:34 +02:00
' box_capacity ' ]
2016-08-06 22:19:52 +02:00
# -----
# K-Psul forms
# -----
class KPsulOperationGroupForm ( forms . ModelForm ) :
2016-08-07 17:02:01 +02:00
checkout = forms . ModelChoiceField (
2016-08-22 02:52:59 +02:00
queryset = Checkout . objects . filter (
is_protected = False , valid_from__lte = timezone . now ( ) ,
valid_to__gte = timezone . now ( ) ) ,
2016-08-07 17:02:01 +02:00
widget = forms . HiddenInput ( ) )
2016-09-29 21:47:37 +02:00
on_acc = forms . ModelChoiceField (
queryset = Account . objects . exclude ( trigramme = ' GNR ' ) ,
widget = forms . HiddenInput ( ) )
2016-08-06 22:19:52 +02:00
class Meta :
model = OperationGroup
2016-08-23 15:43:16 +02:00
fields = [ ' on_acc ' , ' checkout ' , ' comment ' ]
2016-08-06 22:19:52 +02:00
class KPsulAccountForm ( forms . ModelForm ) :
class Meta :
model = Account
fields = [ ' trigramme ' ]
widgets = {
2016-08-16 03:36:14 +02:00
' trigramme ' : forms . TextInput (
attrs = {
' autocomplete ' : ' off ' ,
' spellcheck ' : ' false ' ,
} ) ,
2016-08-06 22:19:52 +02:00
}
class KPsulCheckoutForm ( forms . Form ) :
checkout = forms . ModelChoiceField (
2016-08-22 02:52:59 +02:00
queryset = Checkout . objects . filter (
is_protected = False , valid_from__lte = timezone . now ( ) ,
valid_to__gte = timezone . now ( ) ) ,
2016-08-06 22:19:52 +02:00
widget = forms . Select ( attrs = { ' id ' : ' id_checkout_select ' } ) )
class KPsulOperationForm ( forms . ModelForm ) :
2016-08-12 10:03:39 +02:00
article = forms . ModelChoiceField (
2016-08-14 19:59:36 +02:00
queryset = Article . objects . select_related ( ' category ' ) . all ( ) ,
2016-08-17 11:44:58 +02:00
required = False ,
widget = forms . HiddenInput ( ) )
2016-08-06 22:19:52 +02:00
class Meta :
model = Operation
fields = [ ' type ' , ' amount ' , ' is_checkout ' , ' article ' , ' article_nb ' ]
2016-08-17 11:44:58 +02:00
widgets = {
' type ' : forms . HiddenInput ( ) ,
' amount ' : forms . HiddenInput ( ) ,
' is_checkout ' : forms . HiddenInput ( ) ,
' article_nb ' : forms . HiddenInput ( ) ,
}
2016-08-06 23:44:58 +02:00
2016-08-07 17:02:01 +02:00
def clean ( self ) :
super ( KPsulOperationForm , self ) . clean ( )
type_ope = self . cleaned_data . get ( ' type ' )
amount = self . cleaned_data . get ( ' amount ' )
article = self . cleaned_data . get ( ' article ' )
article_nb = self . cleaned_data . get ( ' article_nb ' )
if type_ope and type_ope == Operation . PURCHASE :
if not article or not article_nb :
raise ValidationError (
" Un achat nécessite un article et une quantité " )
if article_nb < 1 :
raise ValidationError ( " Impossible d ' acheter moins de 1 article " )
self . cleaned_data [ ' is_checkout ' ] = True
elif type_ope and type_ope in [ Operation . DEPOSIT , Operation . WITHDRAW ] :
if not amount or article or article_nb :
raise ValidationError ( " Bad request " )
if type_ope == Operation . DEPOSIT and amount < = 0 :
raise ValidationError ( " Charge non positive " )
if type_ope == Operation . WITHDRAW and amount > = 0 :
raise ValidationError ( " Retrait non négatif " )
2016-08-07 23:41:46 +02:00
self . cleaned_data [ ' article ' ] = None
self . cleaned_data [ ' article_nb ' ] = None
2016-08-07 17:02:01 +02:00
2016-08-06 23:44:58 +02:00
KPsulOperationFormSet = modelformset_factory (
2016-08-07 23:41:46 +02:00
Operation ,
form = KPsulOperationForm ,
2016-08-17 11:44:58 +02:00
can_delete = True ,
extra = 0 ,
2016-08-07 23:41:46 +02:00
min_num = 1 , validate_min = True )
2016-08-22 03:57:13 +02:00
2016-08-22 05:41:31 +02:00
class AddcostForm ( forms . Form ) :
trigramme = forms . CharField ( required = False )
amount = forms . DecimalField (
required = False ,
max_digits = 6 , decimal_places = 2 , min_value = Decimal ( 0 ) )
def clean ( self ) :
trigramme = self . cleaned_data . get ( ' trigramme ' )
if trigramme :
try :
Account . objects . get ( trigramme = trigramme )
except Account . DoesNotExist :
raise ValidationError ( ' Compte invalide ' )
else :
self . cleaned_data [ ' amount ' ] = 0
super ( AddcostForm , self ) . clean ( )
2016-08-22 03:57:13 +02:00
# -----
# Settings forms
# -----
class SettingsForm ( forms . ModelForm ) :
class Meta :
model = Settings
fields = [ ' value_decimal ' , ' value_account ' , ' value_duration ' ]
def clean ( self ) :
name = self . instance . name
value_decimal = self . cleaned_data . get ( ' value_decimal ' )
value_account = self . cleaned_data . get ( ' value_account ' )
value_duration = self . cleaned_data . get ( ' value_duration ' )
type_decimal = [ ' SUBVENTION_COF ' , ' ADDCOST_AMOUNT ' , ' OVERDRAFT_AMOUNT ' ]
type_account = [ ' ADDCOST_FOR ' ]
type_duration = [ ' OVERDRAFT_DURATION ' , ' CANCEL_DURATION ' ]
self . cleaned_data [ ' name ' ] = name
if name in type_decimal :
if not value_decimal :
raise ValidationError ( ' Renseignez une valeur décimale ' )
self . cleaned_data [ ' value_account ' ] = None
self . cleaned_data [ ' value_duration ' ] = None
elif name in type_account :
self . cleaned_data [ ' value_decimal ' ] = None
self . cleaned_data [ ' value_duration ' ] = None
elif name in type_duration :
if not value_duration :
raise ValidationError ( ' Renseignez une durée ' )
self . cleaned_data [ ' value_decimal ' ] = None
self . cleaned_data [ ' value_account ' ] = None
super ( SettingsForm , self ) . clean ( )
2016-08-24 19:52:07 +02:00
class FilterHistoryForm ( forms . Form ) :
checkouts = forms . ModelMultipleChoiceField ( queryset = Checkout . objects . all ( ) )
accounts = forms . ModelMultipleChoiceField ( queryset = Account . objects . all ( ) )
2016-08-26 15:30:40 +02:00
# -----
# Transfer forms
# -----
class TransferGroupForm ( forms . ModelForm ) :
class Meta :
model = TransferGroup
fields = [ ' comment ' ]
class TransferForm ( forms . ModelForm ) :
from_acc = forms . ModelChoiceField (
2016-09-29 21:47:37 +02:00
queryset = Account . objects . exclude ( trigramme__in = [ ' LIQ ' , ' #13 ' , ' GNR ' ] ) ,
2016-08-26 15:30:40 +02:00
widget = forms . HiddenInput ( )
)
to_acc = forms . ModelChoiceField (
2016-09-29 21:47:37 +02:00
queryset = Account . objects . exclude ( trigramme__in = [ ' LIQ ' , ' #13 ' , ' GNR ' ] ) ,
2016-08-26 15:30:40 +02:00
widget = forms . HiddenInput ( )
)
def clean_amount ( self ) :
amount = self . cleaned_data [ ' amount ' ]
if amount < = 0 :
raise forms . ValidationError ( " Montant invalide " )
return amount
class Meta :
model = Transfer
fields = [ ' from_acc ' , ' to_acc ' , ' amount ' ]
TransferFormSet = modelformset_factory (
Transfer ,
form = TransferForm ,
min_num = 1 , validate_min = True ,
extra = 9 ,
)
2016-08-27 14:12:01 +02:00
# -----
# Inventory forms
# -----
class InventoryArticleForm ( forms . Form ) :
article = forms . ModelChoiceField (
queryset = Article . objects . all ( ) ,
widget = forms . HiddenInput ( ) ,
)
stock_new = forms . IntegerField ( required = False )
def __init__ ( self , * args , * * kwargs ) :
super ( InventoryArticleForm , self ) . __init__ ( * args , * * kwargs )
if ' initial ' in kwargs :
self . name = kwargs [ ' initial ' ] [ ' name ' ]
self . stock_old = kwargs [ ' initial ' ] [ ' stock_old ' ]
self . category = kwargs [ ' initial ' ] [ ' category ' ]
self . category_name = kwargs [ ' initial ' ] [ ' category__name ' ]
2016-08-28 05:39:34 +02:00
# -----
# Order forms
# -----
class OrderArticleForm ( forms . Form ) :
article = forms . ModelChoiceField (
queryset = Article . objects . all ( ) ,
widget = forms . HiddenInput ( ) ,
)
quantity_ordered = forms . IntegerField ( required = False )
def __init__ ( self , * args , * * kwargs ) :
super ( OrderArticleForm , self ) . __init__ ( * args , * * kwargs )
if ' initial ' in kwargs :
self . name = kwargs [ ' initial ' ] [ ' name ' ]
self . stock = kwargs [ ' initial ' ] [ ' stock ' ]
self . category = kwargs [ ' initial ' ] [ ' category ' ]
self . category_name = kwargs [ ' initial ' ] [ ' category__name ' ]
self . box_capacity = kwargs [ ' initial ' ] [ ' box_capacity ' ]
self . v_s1 = kwargs [ ' initial ' ] [ ' v_s1 ' ]
self . v_s2 = kwargs [ ' initial ' ] [ ' v_s2 ' ]
self . v_s3 = kwargs [ ' initial ' ] [ ' v_s3 ' ]
self . v_s4 = kwargs [ ' initial ' ] [ ' v_s4 ' ]
self . v_s5 = kwargs [ ' initial ' ] [ ' v_s5 ' ]
self . v_moy = kwargs [ ' initial ' ] [ ' v_moy ' ]
self . v_et = kwargs [ ' initial ' ] [ ' v_et ' ]
self . v_prev = kwargs [ ' initial ' ] [ ' v_prev ' ]
self . c_rec = kwargs [ ' initial ' ] [ ' c_rec ' ]
2016-08-30 15:35:30 +02:00
class OrderArticleToInventoryForm ( forms . Form ) :
article = forms . ModelChoiceField (
queryset = Article . objects . all ( ) ,
widget = forms . HiddenInput ( ) ,
)
price_HT = forms . DecimalField (
max_digits = 7 , decimal_places = 4 ,
required = False )
TVA = forms . DecimalField (
max_digits = 7 , decimal_places = 2 ,
required = False )
rights = forms . DecimalField (
max_digits = 7 , decimal_places = 4 ,
required = False )
quantity_received = forms . IntegerField ( )
def __init__ ( self , * args , * * kwargs ) :
super ( OrderArticleToInventoryForm , self ) . __init__ ( * args , * * kwargs )
if ' initial ' in kwargs :
self . name = kwargs [ ' initial ' ] [ ' name ' ]
self . category = kwargs [ ' initial ' ] [ ' category ' ]
self . category_name = kwargs [ ' initial ' ] [ ' category__name ' ]
self . quantity_ordered = kwargs [ ' initial ' ] [ ' quantity_ordered ' ]