diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index e6efb02..6e173cf 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
[bumpversion]
-current_version = 0.1.0
+current_version = 1.0.0
files = setup.py oscar_support/__init__.py docs/source/conf.py
commit = True
tag = True
diff --git a/.travis.yml b/.travis.yml
index b9b0fdc..9a488fc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,8 +3,8 @@ python:
- "2.6"
- "2.7"
env:
- - DJANGO_VERSION=">=1.4,<1.5" OSCAR_VERSION=">=0.6,<0.7"
- - DJANGO_VERSION=">=1.5,<1.6" OSCAR_VERSION=">=0.6,<0.7"
+ - DJANGO_VERSION=">=1.8,<2.0" OSCAR_VERSION=">=1.3,<1.6"
+ - DJANGO_VERSION=">=1.8,<2.0" OSCAR_VERSION=">=1.3,<1.6"
install:
- pip install Django$DJANGO_VERSION django-oscar$OSCAR_VERSION
- pip install .
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index e69de29..53e2972 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -0,0 +1,7 @@
+__CHANGELOG:__
+
+__1.0.0__
+
+- Support for insert files, orders, lines and products in `dashboard` and `admin`.
+- Add ticket types, ticket statuses and priorities in `dashboard`.
+- Create, Edit and Delete tickets.
diff --git a/README.rst b/README.rst
index 67f6956..15fafac 100644
--- a/README.rst
+++ b/README.rst
@@ -24,11 +24,11 @@ Currently it only allow very basic functionality such as:
#. Reply to a customer with a message.
#. Make a note on the ticket for internal use.
#. Assign tickets to a staff user.
+#. Relating a ticket to products, orders or order lines(User case: only staff can do it, staff take al information from attached files (invoices for example))
+#. Allow file attachments
Features currently in the making:
-#. Relating a ticket to products, orders or order lines
-#. Allow file attachments
#. Integrate with Oscar's alert system to notify the user of new replies.
#. Add templating for messages in the dashboard for quicker replies.
@@ -44,6 +44,11 @@ Longer-term direction:
are then prioritized or re-assigned according to actions related to these
SLAs.
+For to do:
+
+* Test and coverage for all features.
+* Improve styles: print only file name instead his path.
+* Not all changes in the forms have to make a new messages.
Screenshots
-----------
diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst
index 0585d28..b23c6c2 100644
--- a/docs/source/getting_started.rst
+++ b/docs/source/getting_started.rst
@@ -2,12 +2,6 @@
Getting Started
===============
-.. warning:: *django-oscar-support* has been tested with Oscar 0.6 ``master``
- (due to it's pre-release state) and only works with commit `4aea545de3`_
- or later. Due to major changes in the stock record architecture and the
- customer account templates earlier version will not work with the
- instructions below.
-
.. _`4aea545de3`: https://github.com/tangentlabs/django-oscar/commit/4aea545de3d79fb20af49c24984541873c6be89c
Installation
@@ -24,7 +18,7 @@ Start off by installing the required package either from PyPI::
or install the latest version from github using::
- pip install git+https://github.com/tangentlabs/django-oscar-support.git
+ pip install git+https://github.com/mykljohn/django-oscar-support.git
To make your Django project aware of the new package add it to your
``INSTALLED_APPS``::
@@ -57,14 +51,18 @@ a default UI for these two entry points but they need to be hooked into your
Oscar project. Let's start by adding the URL patterns to your current project
by adding the following line into your ``urls.py`` file::
- import oscar_support.urls
-
- urlpatterns = patterns(''
+ from oscar_support.app import application as support
+ from oscar_support.api.app import application as support_api
+ from oscar_support.dashboard.app import application as support_dashboard
+
+ urlpatterns = [
...
+ url(r'^dashboard/support/', include(support_dashboard.urls)),
url(r'^', include(shop.urls)), # Oscar's URL patterns
- url(r'^', include(oscar_support.urls)),
+ url(r'', include(support.urls)),
+ url(r'^api/', include(support_api.urls)), # You can use instead Oscar api urls
...
- )
+ ]
This will provide all the URLs required to interact with the support system.
The next step is to make the dashboard UI available in the navigation using
@@ -75,7 +73,7 @@ Oscar's ``OSCAR_DASHBOARD_NAVIGATION`` settings::
....
- OSCAR_DASHBOARD_NAVIGATION = OSCAR_DASHBOARD_NAVIGATION + [
+ OSCAR_DASHBOARD_NAVIGATION += [
{
'label': _("Support"),
'icon': 'icon-comments',
@@ -83,10 +81,6 @@ Oscar's ``OSCAR_DASHBOARD_NAVIGATION`` settings::
}
]
-.. note:: Make sure that you aren't using ``OSCAR_DASHBOARD_NAVIGATION +=``
- because this will cause duplicate entries due to a bug in Django that will
- only be fixed in version 1.6+
-
All that is left to do now is integrating the customer-facing part of the
support system. The templates that come with *django-oscar-support* extend
Oscar's customer account templates and should pick up the styles that are
@@ -102,11 +96,10 @@ template directory and add the following content::
{% extends "oscar/customer/baseaccountpage.html" %}
{% load i18n %}
- {% load url from future %}
{% block standard_tabs %}
{{ block.super }}
-
+
{% trans "Support" %}
{% endblock %}
diff --git a/oscar_support/__init__.py b/oscar_support/__init__.py
index b794fd4..f6c9b7b 100644
--- a/oscar_support/__init__.py
+++ b/oscar_support/__init__.py
@@ -1 +1,2 @@
-__version__ = '0.1.0'
+__version__ = '0.2.0'
+default_app_config = 'oscar_support.config.OscarSupportConfig'
diff --git a/oscar_support/abstract_models.py b/oscar_support/abstract_models.py
index 2384eb9..c4db174 100644
--- a/oscar_support/abstract_models.py
+++ b/oscar_support/abstract_models.py
@@ -1,4 +1,6 @@
from django.db import models
+from django.urls import reverse
+from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from shortuuidfield import ShortUUIDField
@@ -17,11 +19,12 @@ class Meta:
abstract = True
+@python_2_unicode_compatible
class AbstractTicketType(BaseSupportModel):
slug = AutoSlugField(_("Slug"), populate_from='name', unique=True)
name = models.CharField(_("Name"), max_length=64)
- def __unicode__(self):
+ def __str__(self):
return self.name
class Meta:
@@ -30,11 +33,12 @@ class Meta:
verbose_name_plural = _("Ticket types")
+@python_2_unicode_compatible
class AbstractTicketStatus(BaseSupportModel):
slug = AutoSlugField(_("Slug"), populate_from='name', unique=True)
name = models.CharField(_("Name"), max_length=64)
- def __unicode__(self):
+ def __str__(self):
return self.name
class Meta:
@@ -43,6 +47,7 @@ class Meta:
verbose_name_plural = _("Ticket statuses")
+@python_2_unicode_compatible
class AbstractTicket(ModificationTrackingMixin, BaseSupportModel):
number = models.CharField(
_("Number"),
@@ -93,7 +98,9 @@ class AbstractTicket(ModificationTrackingMixin, BaseSupportModel):
# main content of the (initial) ticket
subject = models.CharField(_("Subject"), max_length=255)
- body = models.TextField(_("Body"))
+ body = models.TextField(_("Body"), blank=True)
+ # TODO: In CreateForm in dashboard JS give us: An invalid form control with name='body' is not focusable,
+ # for avoid it was needed make BODY unrequired, putting "black=true" property. It doesn't happen in customer view.
priority = models.ForeignKey(
'Priority',
@@ -145,8 +152,15 @@ def save(self, *args, **kwargs):
self.subticket_id = ticket_numbers['subticket_id']
return super(AbstractTicket, self).save(*args, **kwargs)
- def __unicode__(self):
- return "Ticket #{0}".format(self.printable_number)
+ def __str__(self):
+ return _("Ticket #{0}").format(self.printable_number)
+
+ def get_absolute_url(self):
+ """
+ Return a product's absolute url
+ """
+ return reverse('support:customer-ticket-update',
+ kwargs={'pk': self.uuid})
class Meta:
abstract = True
@@ -158,17 +172,22 @@ class Meta:
unique_together = (('number', 'subticket_id'),)
+@python_2_unicode_compatible
class AbstractPriority(BaseSupportModel):
name = models.CharField(_("Name"), max_length=255)
slug = AutoSlugField(_("Slug"), populate_from='name')
comment = models.TextField(_("Comment"), blank=True)
+ def __str__(self):
+ return self.name
+
class Meta:
abstract = True
verbose_name = _("Priority")
verbose_name_plural = _("Priorities")
+@python_2_unicode_compatible
class AbstractMessage(ModificationTrackingMixin, BaseSupportModel):
PUBLIC = u'public'
INTERNAL = u'internal'
@@ -198,8 +217,8 @@ class AbstractMessage(ModificationTrackingMixin, BaseSupportModel):
def is_internal(self):
return self.type == self.INTERNAL
- def __unicode__(self):
- return "{0} from {1} for ticket #{2}".format(
+ def __str__(self):
+ return _("{0} from {1} for {2}").format(
self.type,
self.user.email,
self.ticket
@@ -212,6 +231,7 @@ class Meta:
verbose_name_plural = _("Messages")
+@python_2_unicode_compatible
class AbstractRelatedItem(ModificationTrackingMixin, BaseSupportModel):
ticket = models.ForeignKey(
'Ticket',
@@ -224,10 +244,14 @@ class AbstractRelatedItem(ModificationTrackingMixin, BaseSupportModel):
related_name="%(class)ss",
)
+ def __str__(self):
+ return _("{0} related to {1}").format(self.ticket, self.user)
+
class Meta:
abstract = True
+@python_2_unicode_compatible
class AbstractRelatedOrderLine(AbstractRelatedItem):
line = models.ForeignKey(
"order.Line",
@@ -235,8 +259,8 @@ class AbstractRelatedOrderLine(AbstractRelatedItem):
related_name="ticket_related_order_lines",
)
- def __unicode__(self):
- return "{0} related to {1}".format(self.line, self.ticket)
+ def __str__(self):
+ return _("{0} related to {1}").format(self.line, self.ticket)
class Meta:
abstract = True
@@ -244,6 +268,7 @@ class Meta:
verbose_name_plural = _("Related order lines")
+@python_2_unicode_compatible
class AbstractRelatedOrder(AbstractRelatedItem):
order = models.ForeignKey(
"order.Order",
@@ -251,8 +276,8 @@ class AbstractRelatedOrder(AbstractRelatedItem):
related_name="ticket_related_orders",
)
- def __unicode__(self):
- return "{0} related to {1}".format(self.order, self.ticket)
+ def __str__(self):
+ return _("{0} related to {1}").format(self.order, self.ticket)
class Meta:
abstract = True
@@ -260,6 +285,7 @@ class Meta:
verbose_name_plural = _("Related orders")
+@python_2_unicode_compatible
class AbstractRelatedProduct(AbstractRelatedItem):
product = models.ForeignKey(
"catalogue.Product",
@@ -267,8 +293,8 @@ class AbstractRelatedProduct(AbstractRelatedItem):
related_name="ticket_related_products",
)
- def __unicode__(self):
- return "{0} related to {1}".format(self.product, self.ticket)
+ def __str__(self):
+ return _("{0} related to {1}").format(self.product, self.ticket)
class Meta:
abstract = True
@@ -276,6 +302,7 @@ class Meta:
verbose_name_plural = _("Related products")
+@python_2_unicode_compatible
class AbstractAttachment(ModificationTrackingMixin, BaseSupportModel):
ticket = models.ForeignKey(
'Ticket',
@@ -289,11 +316,13 @@ class AbstractAttachment(ModificationTrackingMixin, BaseSupportModel):
)
file = models.FileField(
upload_to="oscar_support/%Y/%m",
- verbose_name=_("File")
+ verbose_name=_("File"),
+ help_text=_("Add documents that present important information to understand the problem, "
+ "such as: invoices, catalogs, photos, orders, etc.")
)
- def __unicode__(self):
- return "{0} attached to {1}".format(self.file.url, self.ticket)
+ def __str__(self):
+ return _("{0} attached to {1}").format(self.file.url, self.ticket)
class Meta:
abstract = True
diff --git a/oscar_support/admin.py b/oscar_support/admin.py
index 56a27fa..ba53e5f 100644
--- a/oscar_support/admin.py
+++ b/oscar_support/admin.py
@@ -1,13 +1,131 @@
from django.contrib import admin
-from django.db.models import get_model
-
-
-admin.site.register(get_model('oscar_support', 'TicketType'))
-admin.site.register(get_model('oscar_support', 'TicketStatus'))
-admin.site.register(get_model('oscar_support', 'Ticket'))
-admin.site.register(get_model('oscar_support', 'Priority'))
-admin.site.register(get_model('oscar_support', 'Message'))
-admin.site.register(get_model('oscar_support', 'RelatedOrder'))
-admin.site.register(get_model('oscar_support', 'RelatedOrderLine'))
-admin.site.register(get_model('oscar_support', 'RelatedProduct'))
-admin.site.register(get_model('oscar_support', 'Attachment'))
+from oscar.core.loading import get_model
+
+Attachment = get_model('oscar_support', 'Attachment')
+Line = get_model('order', 'Line')
+Message = get_model('oscar_support', 'Message')
+Priority = get_model("oscar_support", "Priority")
+Product = get_model('catalogue', 'Product')
+RelatedOrder = get_model("oscar_support", "RelatedOrder")
+RelatedOrderLine = get_model("oscar_support", "RelatedOrderLine")
+RelatedProduct = get_model("oscar_support", "RelatedProduct")
+Ticket = get_model('oscar_support', 'Ticket')
+TicketStatus = get_model('oscar_support', 'TicketStatus')
+TicketType = get_model('oscar_support', 'TicketType')
+
+
+class AttacmentInlineAdmin(admin.TabularInline):
+ model = Attachment
+ fields = ['user', 'file']
+
+
+class LinesInlineAdmin(admin.TabularInline):
+ model = Ticket.related_lines.through
+ fields = ['line']
+
+
+class OrderInlineAdmin(admin.TabularInline):
+ model = Ticket.related_orders.through
+ fields = ['order']
+
+
+class ProductInlineAdmin(admin.TabularInline):
+ model = Ticket.related_products.through
+ fields = ['product']
+
+
+class MessageInlineAdmin(admin.TabularInline):
+ model = Message
+ fields = ['user', 'type', 'text']
+
+
+class TicketTypeAdmin(admin.ModelAdmin):
+ list_display = ['name', 'slug']
+ fields = ['name', 'slug']
+ readonly_fields = ['slug']
+
+
+class TicketStatusAdmin(admin.ModelAdmin):
+ list_display = ['name', 'slug']
+ fields = ['name', 'slug']
+ readonly_fields = ['slug']
+
+
+class PriorityAdmin(admin.ModelAdmin):
+ list_display = ['name', 'slug', 'comment']
+ fields = ['name', 'slug', 'comment']
+ readonly_fields = ['slug']
+
+
+class TicketAdmin(admin.ModelAdmin):
+ date_hierarchy = 'date_updated'
+ inlines = [
+ AttacmentInlineAdmin,
+ LinesInlineAdmin,
+ OrderInlineAdmin,
+ ProductInlineAdmin,
+ MessageInlineAdmin
+ ]
+ list_display = ['number', 'is_internal', 'requester', 'type', 'assignee', 'priority', 'status']
+ list_filter = ['is_internal', 'requester', 'type', 'assignee', 'priority', 'status']
+ raw_id_fields = ['related_lines', 'related_orders', 'related_products']
+ readonly_fields = ['date_created', 'date_updated']
+ search_fields = [
+ 'is_internal',
+ 'requester__username',
+ 'type__name',
+ 'assignee__username',
+ 'priority__name',
+ 'status__name'
+ ]
+
+
+class MessageAdmin(admin.ModelAdmin):
+ date_hierarchy = 'date_updated'
+ list_display = ['user', 'type', 'ticket', 'text']
+ list_filter = ['user', 'type', 'ticket']
+ readonly_fields = ['date_created', 'date_updated']
+ search_fields = ['user__username', 'type', 'ticket__number']
+
+
+class RelatedOrderAdmin(admin.ModelAdmin):
+ date_hierarchy = 'date_updated'
+ list_display = ['user', 'ticket', 'order']
+ list_filter = ['user', 'ticket', ]
+ readonly_fields = ['date_created', 'date_updated']
+ search_fields = ['user__username', 'ticket__number', ]
+
+
+class RelatedOrderLineAdmin(admin.ModelAdmin):
+ date_hierarchy = 'date_updated'
+ list_display = ['user', 'ticket', 'line']
+ list_filter = ['user', 'ticket', ]
+ readonly_fields = ['date_created', 'date_updated']
+ search_fields = ['user__username', 'ticket__number', ]
+
+
+class RelatedProductAdmin(admin.ModelAdmin):
+ date_hierarchy = 'date_updated'
+ list_display = ['user', 'ticket', 'product']
+ list_filter = ['user', 'ticket', ]
+ readonly_fields = ['date_created', 'date_updated']
+ search_fields = ['user__username', 'ticket__number', ]
+
+
+class AttachmentAdmin(admin.ModelAdmin):
+ date_hierarchy = 'date_updated'
+ list_display = ['user', 'ticket', 'file']
+ list_filter = ['user', 'ticket', ]
+ readonly_fields = ['date_created', 'date_updated']
+ search_fields = ['user__username', 'ticket__number', ]
+
+
+admin.site.register(TicketType, TicketTypeAdmin)
+admin.site.register(TicketStatus, TicketStatusAdmin)
+admin.site.register(Priority, PriorityAdmin)
+admin.site.register(Ticket, TicketAdmin)
+admin.site.register(Message, MessageAdmin)
+admin.site.register(RelatedOrder, RelatedOrderAdmin)
+admin.site.register(RelatedOrderLine, RelatedOrderLineAdmin)
+admin.site.register(RelatedProduct, RelatedProductAdmin)
+admin.site.register(Attachment, AttachmentAdmin)
diff --git a/oscar_support/api/app.py b/oscar_support/api/app.py
new file mode 100644
index 0000000..b259875
--- /dev/null
+++ b/oscar_support/api/app.py
@@ -0,0 +1,20 @@
+from oscar.core.application import Application
+from oscar.views.decorators import permissions_required
+
+from .urls import urlpatterns
+
+
+class RESTApiApplication(Application):
+ def get_url_decorator(self, pattern):
+ "Fixes bug in Application.get_url_decorator which would decorate None values."
+ permissions = self.get_permissions(pattern.name)
+ if permissions is not None:
+ return permissions_required(permissions)
+
+ return None
+
+ def get_urls(self):
+ return self.post_process_urls(urlpatterns)
+
+
+application = RESTApiApplication()
diff --git a/oscar_support/api/serializers.py b/oscar_support/api/serializers.py
deleted file mode 100644
index 160d28c..0000000
--- a/oscar_support/api/serializers.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from rest_framework import serializers
-
-from oscar.core.compat import get_user_model
-
-
-class UserSerializer(serializers.ModelSerializer):
- display_text = serializers.SerializerMethodField('get_display_text')
-
- class Meta:
- model = get_user_model()
- fields = ('id', 'email', 'first_name', 'last_name', 'display_text')
-
- def get_display_text(self, obj):
- if not obj:
- return ''
- full_name = obj.get_full_name()
- if full_name:
- return "{0} <{1}>".format(full_name, obj.email)
- return obj.email
diff --git a/oscar_support/api/serializers/__init__.py b/oscar_support/api/serializers/__init__.py
new file mode 100644
index 0000000..4a3a5e8
--- /dev/null
+++ b/oscar_support/api/serializers/__init__.py
@@ -0,0 +1 @@
+from .ticket import *
diff --git a/oscar_support/api/serializers/ticket.py b/oscar_support/api/serializers/ticket.py
new file mode 100644
index 0000000..5121608
--- /dev/null
+++ b/oscar_support/api/serializers/ticket.py
@@ -0,0 +1,230 @@
+from rest_framework import serializers
+
+from oscar.core.compat import get_user_model
+from oscar.core.loading import get_model
+
+from oscarapi.utils import (
+ OscarModelSerializer,
+ overridable,
+ OscarHyperlinkedModelSerializer
+)
+
+Attachment = get_model('oscar_support', 'Attachment')
+Basket = get_model('basket', 'Basket')
+Line = get_model('order', 'Line')
+Message = get_model('oscar_support', 'Message')
+Order = get_model('order', 'Order')
+Product = get_model('catalogue', 'Product')
+Ticket = get_model('oscar_support', 'Ticket')
+TicketStatus = get_model('oscar_support', 'TicketStatus')
+TicketType = get_model('oscar_support', 'TicketType')
+
+
+class UserSerializer(serializers.ModelSerializer):
+ display_text = serializers.SerializerMethodField('get_display_text')
+
+ class Meta:
+ model = get_user_model()
+ fields = ('id', 'email', 'first_name', 'last_name', 'display_text')
+
+ def get_display_text(self, obj):
+ if not obj:
+ return ''
+ full_name = obj.get_full_name()
+ if full_name:
+ return "{0} <{1}>".format(full_name, obj.email)
+ return obj.email
+
+
+"""
+class PartnerSerializer(OscarModelSerializer):
+ class Meta:
+ model = Partner
+ fields = '__all__'
+
+
+class OptionSerializer(OscarHyperlinkedModelSerializer):
+ class Meta:
+ model = Option
+ fields = overridable('OSCARAPI_OPTION_FIELDS', default=(
+ 'url', 'id', 'name', 'code', 'type'
+ ))
+"""
+
+
+class TicketLinkSerializer(OscarHyperlinkedModelSerializer):
+ priority = serializers.StringRelatedField(required=False)
+
+ class Meta:
+ model = Ticket
+ fields = ['url', 'number', 'subject', 'priority']
+ # overridable('OSCARAPI_TICKET_FIELDS', default=())
+
+
+"""
+class ProductAttributeValueSerializer(OscarModelSerializer):
+ name = serializers.StringRelatedField(source="attribute")
+ value = serializers.StringRelatedField()
+
+ class Meta:
+ model = ProductAttributeValue
+ fields = overridable('OSCARAPI_PRODUCT_ATTRIBUTE_VALUE_FIELDS', default=('name', 'value',))
+
+
+class ProductAttributeSerializer(OscarModelSerializer):
+ productattributevalue_set = ProductAttributeValueSerializer(many=True)
+
+ class Meta:
+ model = ProductAttribute
+ fields = overridable('OSCARAPI_PRODUCT_ATTRIBUTE_FIELDS', default=('name', 'productattributevalue_set'))
+
+
+class ProductImageSerializer(OscarModelSerializer):
+ class Meta:
+ model = ProductImage
+ fields = '__all__'
+
+
+class AvailabilitySerializer(serializers.Serializer):
+ is_available_to_buy = serializers.BooleanField()
+ num_available = serializers.IntegerField(required=False)
+ message = serializers.CharField()
+
+
+class RecommmendedProductSerializer(OscarModelSerializer):
+ url = serializers.HyperlinkedIdentityField(view_name='product-detail')
+
+ class Meta:
+ model = Product
+ fields = overridable(
+ 'OSCARAPI_RECOMMENDED_PRODUCT_FIELDS', default=('url',))
+"""
+
+
+class TicketRelatedLineSerializer(OscarModelSerializer):
+ order = serializers.StringRelatedField()
+ partner = serializers.StringRelatedField()
+ product = serializers.HyperlinkedRelatedField(
+ view_name='product-detail', read_only=True)
+
+ # status = models.CharField()
+
+ class Meta:
+ model = Line
+ fields = ['url', 'order', 'partner', 'product', 'status', ]
+
+
+class TicketRelatedOrderSerializer(OscarModelSerializer):
+ basket = serializers.HyperlinkedRelatedField(
+ view_name='basket-detail', queryset=Basket.objects)
+ owner = serializers.HyperlinkedRelatedField(
+ view_name='user-detail', read_only=True, source='user')
+
+ # TODO: Status doesn't show anything
+ # status = models.CharField()
+
+ class Meta:
+ model = Order
+ fields = ['url', 'number', 'basket', 'owner', 'status', ]
+
+
+class TicketRelatedProductSerializer(OscarModelSerializer):
+ class Meta:
+ model = Product
+ fields = ['url', 'upc', 'title', 'rating']
+
+
+class TicketAttachmentSerializer(OscarModelSerializer):
+ user = serializers.HyperlinkedRelatedField(
+ view_name='user-detail', read_only=True, )
+
+ class Meta:
+ model = Attachment
+ fields = '__all__'
+
+
+class TicketMessageSerializer(OscarModelSerializer):
+ user = serializers.HyperlinkedRelatedField(
+ view_name='user-detail', read_only=True, )
+
+ class Meta:
+ model = Message
+ fields = '__all__'
+
+
+class TicketSerializer(OscarModelSerializer):
+ url = serializers.HyperlinkedIdentityField(view_name='ticket-detail')
+ requester = serializers.StringRelatedField() # TODO: It need be hyperlinked
+ status = serializers.StringRelatedField()
+ type = serializers.StringRelatedField()
+ assigned_group = serializers.StringRelatedField()
+ assignee = serializers.StringRelatedField()
+ priority = serializers.StringRelatedField(required=False)
+ # parent = serializers.StringRelatedField()
+ attachments = TicketAttachmentSerializer(many=True, required=False, )
+ related_lines = TicketRelatedLineSerializer(many=True, required=False, ) # TODO: Review it
+ related_orders = TicketRelatedOrderSerializer(many=True, required=False, )
+ related_products = TicketRelatedProductSerializer(many=True, required=False, )
+ messages = TicketMessageSerializer(many=True, required=False, )
+
+ class Meta:
+ model = Ticket
+ fields = [
+ 'url',
+ 'is_internal',
+ 'type',
+ 'number',
+ 'subject',
+ 'requester',
+ 'status',
+ 'body',
+ 'subticket_id',
+ # 'parent',
+ 'assigned_group',
+ 'assignee',
+ 'priority',
+ 'attachments',
+ 'related_lines',
+ 'related_orders',
+ 'related_products',
+ 'messages'
+ ]
+ # overridable('OSCARAPI_PRODUCTDETAIL_FIELDS', default=())
+
+
+"""
+class OptionValueSerializer(serializers.Serializer):
+ option = serializers.HyperlinkedRelatedField(
+ view_name='option-detail', queryset=Option.objects)
+ value = serializers.CharField()
+
+
+class AddProductSerializer(serializers.Serializer):
+ # Serializes and validates an add to basket request.
+ quantity = serializers.IntegerField(required=True)
+ url = serializers.HyperlinkedRelatedField(
+ view_name='product-detail', queryset=Product.objects, required=True)
+ options = OptionValueSerializer(many=True, required=False)
+
+ class Meta:
+ model = Product
+"""
+
+
+class AddTicketSerializer(serializers.HyperlinkedModelSerializer):
+ requester = serializers.StringRelatedField() # TODO: It need be hyperlinked
+ type = serializers.StringRelatedField()
+ attachments = TicketAttachmentSerializer(many=True, required=False, )
+
+ class Meta:
+ model = Ticket
+ fields = [
+ 'type',
+ 'subject',
+ 'requester',
+ 'body',
+ 'attachments',
+ ]
+
+ def create(self, validated_data):
+ return Ticket.objects.create(**validated_data)
diff --git a/oscar_support/api/urls.py b/oscar_support/api/urls.py
index 19a4975..21955d1 100644
--- a/oscar_support/api/urls.py
+++ b/oscar_support/api/urls.py
@@ -1,28 +1,21 @@
-from django.conf import settings
-from django.conf.urls import url, patterns, include
-
-from rest_framework import routers
+import django
+from django.conf.urls import url
+from rest_framework.urlpatterns import format_suffix_patterns
from . import views
+urlpatterns = [
+ # url(r'^', include(router.urls, namespace='support-api')),
+ url(r'^$', views.api_root, name='support-api'),
+ url(r'^tickets/$', views.TicketList.as_view(), name='ticket-list'),
+ url(r'^tickets/(?P[a-zA-Z0-9]+)/$', views.TicketDetail.as_view(), name='ticket-detail'),
+ url(r'^ticket/add-ticket/$', views.AddTicketView.as_view(), name='ticket-add-ticket'),
+ # url(r'^ticket/update-ticket/$', views.UpdateTicketView.as_view(), name='ticket-update-ticket'),
+]
-router = routers.DefaultRouter()
-router.register(r'customers', views.CustomerViewSet, base_name="customer")
-router.register(r'agents', views.AgentViewSet, base_name="agent")
-router.register(r'groups', views.GroupViewSet)
-
-
-urlpatterns = patterns(
- '',
- url(r'^', include(router.urls, namespace='support-api')),
-)
+urlpatterns = format_suffix_patterns(urlpatterns)
+if django.VERSION[:2] < (1, 8):
+ from django.conf.urls import patterns
-if settings.DEBUG:
- urlpatterns = urlpatterns + patterns(
- '',
- url(
- r'^api-auth/',
- include('rest_framework.urls', namespace='rest_framework')
- ),
- )
+ urlpatterns = patterns('', *urlpatterns)
diff --git a/oscar_support/api/views.py b/oscar_support/api/views.py
deleted file mode 100644
index 2d19b87..0000000
--- a/oscar_support/api/views.py
+++ /dev/null
@@ -1,31 +0,0 @@
-from django.db.models import get_model
-
-from rest_framework import viewsets
-
-from oscar.core.compat import get_user_model
-
-from . import serializers
-from .mixins import UserFilterMixin
-
-User = get_user_model()
-Group = get_model('auth', 'Group')
-
-
-class CustomerViewSet(UserFilterMixin, viewsets.ModelViewSet):
- model = User
- serializer_class = serializers.UserSerializer
-
- def get_queryset(self):
- return self.filter_queryset(self.model.objects.all())
-
-
-class AgentViewSet(UserFilterMixin, viewsets.ModelViewSet):
- model = User
- serializer_class = serializers.UserSerializer
-
- def get_queryset(self):
- return self.filter_queryset(self.model.objects.filter(is_staff=True))
-
-
-class GroupViewSet(viewsets.ModelViewSet):
- model = Group
diff --git a/oscar_support/api/views/__init__.py b/oscar_support/api/views/__init__.py
new file mode 100644
index 0000000..c873610
--- /dev/null
+++ b/oscar_support/api/views/__init__.py
@@ -0,0 +1,2 @@
+from .root import *
+from .ticket import *
diff --git a/oscar_support/api/views/root.py b/oscar_support/api/views/root.py
new file mode 100644
index 0000000..2ef7f63
--- /dev/null
+++ b/oscar_support/api/views/root.py
@@ -0,0 +1,38 @@
+import collections
+
+from oscarapi.views.root import PUBLIC_APIS
+from oscarapi.views.root import PROTECTED_APIS
+from rest_framework.decorators import api_view
+from rest_framework.response import Response
+from rest_framework.reverse import reverse
+
+__all__ = ('api_root',)
+
+
+def PUBLIC_SUPPORT_APIS(r, f):
+ return [
+ ('tickets', reverse('ticket-list', request=r, format=f)),
+ ('add-ticket', reverse('ticket-add-ticket', request=r, format=f)),
+ # ('update-ticket', reverse('ticket-update-ticket', request=r, format=f)),
+ ]
+
+
+def PROTECTED_SUPPORT_APIS(r, f):
+ return []
+
+
+@api_view(('GET',))
+def api_root(request, format=None):
+ """
+ GET:
+ Display all available urls.
+ Since some urls have specific permissions, you might not be able to access
+ them all.
+ """
+ apis = PUBLIC_APIS(request, format)
+ apis += PUBLIC_SUPPORT_APIS(request, format)
+ if request.user.is_staff:
+ apis += PROTECTED_APIS(request, format)
+ apis += PROTECTED_SUPPORT_APIS(request, format)
+
+ return Response(collections.OrderedDict(apis))
diff --git a/oscar_support/api/views/ticket.py b/oscar_support/api/views/ticket.py
new file mode 100644
index 0000000..54ac2a6
--- /dev/null
+++ b/oscar_support/api/views/ticket.py
@@ -0,0 +1,59 @@
+from rest_framework import generics
+
+from oscar.core.loading import get_model
+from oscar_support.api import serializers # permissions
+
+__all__ = (
+ 'TicketList',
+ 'TicketDetail',
+ 'AddTicketView',
+)
+
+Ticket = get_model('oscar_support', 'Ticket')
+
+
+class TicketList(generics.ListAPIView):
+ queryset = Ticket.objects.all()
+ serializer_class = serializers.TicketLinkSerializer
+
+
+class TicketDetail(generics.RetrieveAPIView):
+ queryset = Ticket.objects.all()
+ serializer_class = serializers.TicketSerializer
+
+
+class AddTicketView(generics.ListCreateAPIView):
+ """
+ Create a new ticket.
+ POST(ticket, attachment,
+ [total, shipping_method_code, shipping_charge, billing_address]):
+ {
+ "type": "Products",
+ "subject": "Title for ticket",
+ "requester": "@username",
+ "body": "Text for ticket",
+ "attachments": [
+ {
+ "uuid": "znup8iQM2rWmg7r8RiNCGd",
+ "user": "http://localhost:8000/api/users/#/",
+ "date_created": "2017-10-05T21:44:59.361697Z",
+ "date_updated": "2017-10-05T21:44:59.383862Z",
+ "file": "http://localhost:8000/media/oscar_support/2017/10/PSI_Docker_Certification_Exam_lX6nNfE.pdf",
+ "ticket": "rVszTeuXWcZ9fspMkYh7wd"
+ },
+ {
+ "uuid": "Q8DNTzTXqtMXEDyfyeZFuY",
+ "user": "http://localhost:8000/api/users/#/",
+ "date_created": "2017-10-05T20:21:08.748900Z",
+ "date_updated": "2017-10-05T21:44:59.339411Z",
+ "file": "http://localhost:8000/media/oscar_support/2017/10/Invoice_Docker_Certification_lvnH4mk.pdf",
+ "ticket": "rVszTeuXWcZ9fspMkYh7wd"
+ }
+ ]
+ }
+ returns the order object.
+ """
+ queryset = Ticket.objects.all()
+ serializer_class = serializers.AddTicketSerializer
+
+# class UpdateTicketView(APIView):
diff --git a/oscar_support/app.py b/oscar_support/app.py
index cc14d43..d0bb2f9 100644
--- a/oscar_support/app.py
+++ b/oscar_support/app.py
@@ -1,4 +1,4 @@
-from django.conf.urls import patterns, url
+from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from shortuuid import get_alphabet
@@ -16,32 +16,26 @@ class SupportApplication(Application):
ticket_update_view = views.TicketUpdateView
def get_urls(self):
- urlpatterns = super(SupportApplication, self).get_urls()
-
- urlpatterns += patterns(
- '',
+ urls = [
url(
r'accounts/support/$',
- self.ticket_list_view.as_view(),
+ login_required(self.ticket_list_view.as_view()),
name='customer-ticket-list'
),
url(
r'accounts/support/ticket/create/$',
- self.ticket_create_view.as_view(),
+ login_required(self.ticket_create_view.as_view()),
name='customer-ticket-create'
),
url(
r'accounts/support/ticket/(?P[{0}]+)/update/$'.format(
get_alphabet()
),
- self.ticket_update_view.as_view(),
+ login_required(self.ticket_update_view.as_view()),
name='customer-ticket-update'
),
- )
- return self.post_process_urls(urlpatterns)
-
- def get_url_decorator(self, url_name):
- return login_required
+ ]
+ return self.post_process_urls(urls)
application = SupportApplication()
diff --git a/oscar_support/config.py b/oscar_support/config.py
new file mode 100644
index 0000000..2041268
--- /dev/null
+++ b/oscar_support/config.py
@@ -0,0 +1,8 @@
+from django.apps import AppConfig
+from django.utils.translation import ugettext_lazy as _
+
+
+class OscarSupportConfig(AppConfig):
+ # label = 'support'
+ name = 'oscar_support'
+ verbose_name = _('Support')
diff --git a/oscar_support/dashboard/app.py b/oscar_support/dashboard/app.py
index 5c72e8d..7c2dee2 100644
--- a/oscar_support/dashboard/app.py
+++ b/oscar_support/dashboard/app.py
@@ -1,24 +1,27 @@
-from django.conf.urls import patterns, url
+from django.conf.urls import url
+from django.contrib.admin.views.decorators import staff_member_required
from shortuuid import get_alphabet
-from oscar.core.application import Application
-from oscar.views.decorators import staff_member_required
+from oscar.core.application import DashboardApplication
from . import views
-class SupportDashboardApplication(Application):
+class SupportDashboardApplication(DashboardApplication):
name = 'support-dashboard'
+ default_permissions = ['is_staff', ]
ticket_list_view = views.TicketListView
ticket_create_view = views.TicketCreateView
ticket_update_view = views.TicketUpdateView
+ types_edit_view = views.TypesEditView
+ statuses_edit_view = views.StatusesEditView
+ priorities_edit_view = views.PrioritiesEditView
def get_urls(self):
- urlpatterns = patterns(
- '',
- url(r'^$', self.ticket_list_view.as_view(), name='ticket-list'),
+ urls = [
+ url(r'^ticket/$', self.ticket_list_view.as_view(), name='ticket-list'),
url(r'^ticket/create/$', self.ticket_create_view.as_view(),
name='ticket-create'),
url(
@@ -26,11 +29,20 @@ def get_urls(self):
self.ticket_update_view.as_view(),
name='ticket-update'
),
- )
- return self.post_process_urls(urlpatterns)
-
- def get_url_decorator(self, url_name):
- return staff_member_required
+ url(
+ r'tags/types/$', self.types_edit_view.as_view(),
+ name='tag-type-list'
+ ),
+ url(
+ r'tags/statuses/$', self.statuses_edit_view.as_view(),
+ name='tag-status-list'
+ ),
+ url(
+ r'tags/priorities/$', self.priorities_edit_view.as_view(),
+ name='tag-priority-list'
+ ),
+ ]
+ return self.post_process_urls(urls)
application = SupportDashboardApplication()
diff --git a/oscar_support/dashboard/config.py b/oscar_support/dashboard/config.py
new file mode 100644
index 0000000..981e162
--- /dev/null
+++ b/oscar_support/dashboard/config.py
@@ -0,0 +1,8 @@
+from django.apps import AppConfig
+from django.utils.translation import ugettext_lazy as _
+
+
+class OscarSupportDashboardConfig(AppConfig):
+ # label = 'support_dashboard'
+ name = 'oscar_support.dashboard'
+ verbose_name = _('Support dashboard')
diff --git a/oscar_support/dashboard/forms.py b/oscar_support/dashboard/forms.py
index c4c9275..74bb7b4 100644
--- a/oscar_support/dashboard/forms.py
+++ b/oscar_support/dashboard/forms.py
@@ -1,35 +1,26 @@
from django import forms
-from django.db.models import get_model
from django.core.urlresolvers import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from oscar.core.compat import get_user_model
+from oscar.core.loading import get_model
-from ..forms.widgets import AutoCompleteWidget, CustomRadioFieldRenderer
+from ..forms.widgets import AutoCompleteWidget
+from ..forms.widgets import CustomRadioInput
User = get_user_model()
-Ticket = get_model('oscar_support', 'Ticket')
-Message = get_model('oscar_support', 'Message')
CommunicationEventType = get_model('customer', 'CommunicationEventType')
-
+Message = get_model('oscar_support', 'Message')
+Priority = get_model("oscar_support", "Priority")
+Ticket = get_model('oscar_support', 'Ticket')
+TicketStatus = get_model("oscar_support", "TicketStatus")
+TicketType = get_model("oscar_support", "TicketType")
REQUESTER_FIELDS = ['requester', 'is_internal']
MESSAGE_FIELDS = ['subject', 'body']
class TicketCreateForm(forms.ModelForm):
- requester = forms.IntegerField(
- widget=AutoCompleteWidget(
- url=reverse_lazy('support-api:customer-list')
- )
- )
- assignee = forms.IntegerField(
- widget=AutoCompleteWidget(
- url=reverse_lazy('support-api:agent-list'),
- ),
- required=False,
- )
-
def get_message_fields(self):
for field in self:
if field.name in MESSAGE_FIELDS:
@@ -41,25 +32,6 @@ def get_property_fields(self):
if field.name not in ignore_fields:
yield field
- def clean_requester(self):
- requester_id = self.cleaned_data.get('requester')
- try:
- requester = User.objects.get(id=requester_id)
- except User.DoesNotExist:
- raise forms.ValidationError("Invalid user specified")
- return requester
-
- def clean_assignee(self):
- assignee_id = self.cleaned_data.get('assignee')
- # The assignee is not mandatory so if it is empty, we just ignore it
- if not assignee_id:
- return assignee_id
- try:
- assignee = User.objects.get(id=assignee_id, is_staff=True)
- except User.DoesNotExist:
- raise forms.ValidationError("Invalid user specified")
- return assignee
-
class Meta:
model = Ticket
fields = REQUESTER_FIELDS + [
@@ -77,7 +49,7 @@ class Meta:
class TicketUpdateForm(forms.ModelForm):
message_type = forms.ChoiceField(
- widget=forms.RadioSelect(renderer=CustomRadioFieldRenderer),
+ widget=CustomRadioInput(attrs={'class': 'radio-inline'}),
choices=Message.MESSAGE_TYPES,
label=_("Message type"),
initial=Message.PUBLIC,
@@ -100,7 +72,14 @@ def get_message_fields(self):
class Meta:
model = Ticket
- fields = ['status', 'message_type', 'message_text']
+ fields = [
+ 'status',
+ 'priority',
+ 'assignee',
+ 'assigned_group',
+ 'message_type',
+ 'message_text'
+ ]
widgets = {
'status': forms.HiddenInput(),
}
@@ -114,3 +93,21 @@ class RequesterCreateForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'last_name', 'email']
+
+
+class PriorityForm(forms.ModelForm):
+ class Meta:
+ model = Priority
+ fields = ['name', 'comment', ]
+
+
+class TicketStatusForm(forms.ModelForm):
+ class Meta:
+ model = TicketStatus
+ fields = ['name', ]
+
+
+class TicketTypeForm(forms.ModelForm):
+ class Meta:
+ model = TicketType
+ fields = ['name', ]
diff --git a/oscar_support/dashboard/views.py b/oscar_support/dashboard/views.py
index a46a60c..ee35b6d 100644
--- a/oscar_support/dashboard/views.py
+++ b/oscar_support/dashboard/views.py
@@ -1,15 +1,33 @@
-from django.views import generic
-from django.db.models import get_model, Q
-from django.http import HttpResponseRedirect
+from django.contrib import messages
from django.core.urlresolvers import reverse
+from django.db.models import Q
+from django.http import HttpResponseRedirect
+from django.utils.translation import ugettext_lazy as _
+from django.views import generic
+
+from extra_views import ModelFormSetView
+
+from oscar.core.loading import get_model
+from oscar_support.dashboard.forms import (
+ PriorityForm,
+ TicketStatusForm,
+ TicketTypeForm
+)
+from oscar_support.forms.formsets import (
+ AttachmentFormSet,
+ RelatedOrderFormSet,
+ RelatedOrderLineFormSet,
+ RelatedProductFormSet,
+)
from . import forms
from .. import utils
-Note = get_model('oscar_support', 'Note')
-Ticket = get_model('oscar_support', 'Ticket')
Message = get_model('oscar_support', 'Message')
+Priority = get_model("oscar_support", "Priority")
+Ticket = get_model('oscar_support', 'Ticket')
TicketStatus = get_model('oscar_support', 'TicketStatus')
+TicketType = get_model("oscar_support", "TicketType")
class TicketListMixin(object):
@@ -44,7 +62,6 @@ def get_queryset(self, queryset=None):
class UserFormInlineMixin(object):
-
def get_extra_form_kwargs(self):
kwargs = super(UserFormInlineMixin, self).get_extra_form_kwargs()
kwargs['user'] = self.request.user
@@ -73,6 +90,7 @@ def get_context_data(self, **kwargs):
ctx['default_status'] = status
ctx['status_list'] = TicketStatus.objects.exclude(name=status.name)
ctx['requester_create_form'] = forms.RequesterCreateForm()
+ ctx['title'] = _('New ticket')
return ctx
def get_success_url(self, **kwargs):
@@ -84,14 +102,65 @@ class TicketUpdateView(TicketListMixin, generic.UpdateView):
default_message_model = Message
context_object_name = 'selected_ticket'
form_class = forms.TicketUpdateForm
+ attachment_formset = AttachmentFormSet
+ related_order_formset = RelatedOrderFormSet
+ related_line_formset = RelatedOrderLineFormSet
+ related_product_formset = RelatedProductFormSet
template_name = 'oscar_support/dashboard/ticket_detail.html'
+ def __init__(self, *args, **kwargs):
+ super(TicketUpdateView, self).__init__(*args, **kwargs)
+ self.formsets = {
+ 'attachment_formset': self.attachment_formset,
+ 'related_order_formset': self.related_order_formset,
+ 'related_line_formset': self.related_line_formset,
+ 'related_product_formset': self.related_product_formset,
+ }
+
def get_context_data(self, **kwargs):
ctx = super(TicketUpdateView, self).get_context_data(**kwargs)
+ ticket_name = self.object
ctx['ticket_list'] = self.get_ticket_list()
+ ctx['title'] = _('Update {name}').format(name=ticket_name)
+ for ctx_name, formset_class in self.formsets.items():
+ if ctx_name not in ctx:
+ ctx[ctx_name] = formset_class(
+ self.object.requester,
+ instance=self.object
+ )
return ctx
- def form_valid(self, form):
+ def process_all_forms(self, form):
+
+ if form.is_valid():
+ self.object = form.save()
+
+ formsets = {}
+ for ctx_name, formset_class in self.formsets.items():
+ formsets[ctx_name] = formset_class(
+ self.object.requester,
+ self.request.POST,
+ self.request.FILES,
+ instance=self.object
+ )
+
+ is_valid = form.is_valid() and all(
+ [formset.is_valid() for formset in formsets.values()]
+ )
+
+ cross_form_validation_result = self.clean(form, formsets)
+ if is_valid and cross_form_validation_result:
+ return self.forms_valid(form, formsets)
+ else:
+ return self.forms_invalid(form, formsets)
+
+ form_valid = form_invalid = process_all_forms
+
+ def clean(self, form, formsets):
+
+ return True
+
+ def forms_valid(self, form, formsets):
ticket = form.save()
message_type = form.cleaned_data.get('message_type', Message.PUBLIC)
message_text = form.cleaned_data.get('message_text')
@@ -101,7 +170,111 @@ def form_valid(self, form):
text=message_text,
ticket=ticket
)
+
+ # Save formsets
+ for formset in formsets.values():
+ formset.save()
+
return HttpResponseRedirect(self.get_success_url())
+ def forms_invalid(self, form, formsets):
+
+ messages.error(
+ self.request,
+ _("Your submitted data was not valid - please "
+ "correct the errors below")
+ )
+ ctx = self.get_context_data(form=form, **formsets)
+ return self.render_to_response(ctx)
+
def get_success_url(self):
+
+ messages.success(
+ self.request,
+ _("Successfully updated {0}.").format(self.object), extra_tags="safe noicon"
+ )
return reverse("support-dashboard:ticket-list")
+
+
+class TypesEditView(TicketListMixin, ModelFormSetView):
+ template_name = 'oscar_support/dashboard/tags/types.html'
+ page_title = _('Types')
+ active_tab = 'types'
+ model = TicketType
+ form_class = TicketTypeForm
+ extra = 5
+ max_num = None
+ can_delete = True
+
+ def get_context_data(self, **kwargs):
+ ctx = super(TypesEditView, self).get_context_data(**kwargs)
+ ctx.setdefault('page_title', self.page_title)
+ ctx.setdefault('active_tab', self.active_tab)
+ ctx.setdefault('url', reverse("support-dashboard:tag-type-list"))
+ ctx['type_count'] = self.model.objects.all().count()
+ return ctx
+
+ def get_success_url(self):
+ messages.success(
+ self.request,
+ # TODO: Render the model updated value
+ # _("Successfully updated type {0}!.").format(self.get_formset), extra_tags="safe noicon"
+ _("Successfully updated type!."), extra_tags="safe noicon"
+ )
+ return reverse("support-dashboard:tag-type-list")
+
+
+class StatusesEditView(TicketListMixin, ModelFormSetView):
+ template_name = 'oscar_support/dashboard/tags/statuses.html'
+ page_title = _('Statuses')
+ active_tab = 'statuses'
+ model = TicketStatus
+ form_class = TicketStatusForm
+ extra = 5
+ max_num = None
+ can_delete = True
+
+ def get_context_data(self, **kwargs):
+ ctx = super(StatusesEditView, self).get_context_data(**kwargs)
+ ctx.setdefault('page_title', self.page_title)
+ ctx.setdefault('active_tab', self.active_tab)
+ ctx.setdefault('url', reverse("support-dashboard:tag-status-list"))
+ ctx['status_count'] = self.model.objects.all().count()
+ return ctx
+
+ def get_success_url(self):
+ messages.success(
+ self.request,
+ # TODO: Render the model updated value
+ # _("Successfully updated status {0}!.").format(self.get_formset), extra_tags="safe noicon"
+ _("Successfully updated status!."), extra_tags="safe noicon"
+ )
+ return reverse("support-dashboard:tag-status-list")
+
+
+class PrioritiesEditView(TicketListMixin, ModelFormSetView):
+ template_name = 'oscar_support/dashboard/tags/priorities.html'
+ page_title = _('Priorities')
+ active_tab = 'priorities'
+ model = Priority
+ form_class = PriorityForm
+ extra = 5
+ max_num = None
+ can_delete = True
+
+ def get_context_data(self, **kwargs):
+ ctx = super(PrioritiesEditView, self).get_context_data(**kwargs)
+ ctx.setdefault('page_title', self.page_title)
+ ctx.setdefault('active_tab', self.active_tab)
+ ctx.setdefault('url', reverse("support-dashboard:tag-priority-list"))
+ ctx['priority_count'] = self.model.objects.all().count()
+ return ctx
+
+ def get_success_url(self):
+ messages.success(
+ self.request,
+ # TODO: Render the model updated value
+ # _("Successfully updated priority {0}!.").format(self.get_formset), extra_tags="safe noicon"
+ _("Successfully updated priority!."), extra_tags="safe noicon"
+ )
+ return reverse("support-dashboard:tag-priority-list")
diff --git a/oscar_support/defaults.py b/oscar_support/defaults.py
index 6f47bda..af9e4e3 100644
--- a/oscar_support/defaults.py
+++ b/oscar_support/defaults.py
@@ -5,19 +5,3 @@
SUPPORT_RESOLVED_STATUS = _("Resolved")
SUPPORT_RESOLVED_STATUS_SLUG = "resolved"
-
-# Setting defaults for the REST API provided by django-rest-framework
-# for security reasons we only enable session-based authentication and
-# JSON formatting. This can be overwritten in you own settings file. For more
-# details on the DRF settings checkout http://django-rest-framework.org
-REST_FRAMEWORK = {
- 'DEFAULT_PERMISSION_CLASSES': (
- 'rest_framework.permissions.IsAuthenticated',
- ),
- 'DEFAULT_AUTHENTICATION_CLASSES': (
- 'rest_framework.authentication.SessionAuthentication',
- ),
- 'DEFAULT_RENDERER_CLASSES': (
- 'rest_framework.renderers.JSONRenderer',
- )
-}
diff --git a/oscar_support/fixtures/ticket_statuses.json b/oscar_support/fixtures/ticket_statuses.json
deleted file mode 100644
index c1f4838..0000000
--- a/oscar_support/fixtures/ticket_statuses.json
+++ /dev/null
@@ -1,37 +0,0 @@
-[
- {
- "pk": 1,
- "model": "oscar_support.ticketstatus",
- "fields": {
- "name": "New"
- }
- },
- {
- "pk": 3,
- "model": "oscar_support.ticketstatus",
- "fields": {
- "name": "Open"
- }
- },
- {
- "pk": 4,
- "model": "oscar_support.ticketstatus",
- "fields": {
- "name": "Solved"
- }
- },
- {
- "pk": 5,
- "model": "oscar_support.ticketstatus",
- "fields": {
- "name": "Pending"
- }
- },
- {
- "pk": 6,
- "model": "oscar_support.ticketstatus",
- "fields": {
- "name": "Resolved"
- }
- }
-]
diff --git a/oscar_support/fixtures/ticket_types.json b/oscar_support/fixtures/ticket_types.json
deleted file mode 100644
index 615fe12..0000000
--- a/oscar_support/fixtures/ticket_types.json
+++ /dev/null
@@ -1,16 +0,0 @@
-[
- {
- "pk": 1,
- "model": "oscar_support.tickettype",
- "fields": {
- "name": "Question about a product"
- }
- },
- {
- "pk": 2,
- "model": "oscar_support.tickettype",
- "fields": {
- "name": "Where is my order?"
- }
- }
-]
diff --git a/oscar_support/forms/__init__.py b/oscar_support/forms/__init__.py
index 36c7acd..25e9d5f 100644
--- a/oscar_support/forms/__init__.py
+++ b/oscar_support/forms/__init__.py
@@ -1,37 +1,109 @@
from django import forms
-from django.db.models import get_model
from django.utils.translation import ugettext_lazy as _
+from oscar.core.loading import get_model
+
from .. import utils
+Attachment = get_model('oscar_support', 'Attachment')
Order = get_model('order', 'Order')
RelatedOrder = get_model("oscar_support", "RelatedOrder")
-TicketStatus = get_model("oscar_support", "TicketStatus")
+RelatedOrderLine = get_model("oscar_support", "RelatedOrderLine")
+RelatedProduct = get_model("oscar_support", "RelatedProduct")
+
+
+class AttachmentForm(forms.ModelForm):
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(AttachmentForm, self).__init__(*args, **kwargs)
+
+ class Meta:
+ model = Attachment
+ fields = ['ticket', 'file', ]
+
+ def save(self, *args, **kwargs):
+ kwargs['commit'] = False
+ obj = super(AttachmentForm, self).save(*args, **kwargs)
+ obj.user = self.user
+ obj.save()
+ return obj
+
+
+class RelatedOrderForm(forms.ModelForm):
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(RelatedOrderForm, self).__init__(*args, **kwargs)
+
+ class Meta:
+ model = RelatedOrder
+ fields = ['order']
+
+ def save(self, *args, **kwargs):
+ kwargs['commit'] = False
+ obj = super(RelatedOrderForm, self).save(*args, **kwargs)
+ obj.user = self.user
+ obj.save()
+ return obj
+
+
+class RelatedOrderLineForm(forms.ModelForm):
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(RelatedOrderLineForm, self).__init__(*args, **kwargs)
+
+ class Meta:
+ model = RelatedOrderLine
+ fields = ['line']
+
+ def save(self, *args, **kwargs):
+ kwargs['commit'] = False
+ obj = super(RelatedOrderLineForm, self).save(*args, **kwargs)
+ obj.user = self.user
+ obj.save()
+ return obj
+
+
+class RelatedProductForm(forms.ModelForm):
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(RelatedProductForm, self).__init__(*args, **kwargs)
+
+ class Meta:
+ model = RelatedProduct
+ fields = ['product']
+
+ def save(self, *args, **kwargs):
+ kwargs['commit'] = False
+ obj = super(RelatedProductForm, self).save(*args, **kwargs)
+ obj.user = self.user
+ obj.save()
+ return obj
class TicketUpdateForm(forms.ModelForm):
message_text = forms.CharField(label=_("Message"), widget=forms.Textarea())
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(TicketUpdateForm, self).__init__(*args, **kwargs)
+
class Meta:
model = get_model("oscar_support", "Ticket")
fields = ['message_text']
class TicketCreateForm(forms.ModelForm):
-
def __init__(self, user, *args, **kwargs):
self.user = user
super(TicketCreateForm, self).__init__(*args, **kwargs)
- def save(self, commit=True):
- instance = super(TicketCreateForm, self).save(commit=False)
-
- instance.status = utils.TicketStatusGenerator.get_initial_status()
- instance.requester = self.user
-
- if commit:
- instance.save()
- return instance
+ def save(self, *args, **kwargs):
+ kwargs['commit'] = False
+ obj = super(TicketCreateForm, self).save(*args, **kwargs)
+ obj.status = utils.TicketStatusGenerator.get_initial_status()
+ obj.requester = self.user
+ obj.save()
+ return obj
class Meta:
model = get_model("oscar_support", "Ticket")
diff --git a/oscar_support/forms/formsets.py b/oscar_support/forms/formsets.py
new file mode 100644
index 0000000..902fa68
--- /dev/null
+++ b/oscar_support/forms/formsets.py
@@ -0,0 +1,98 @@
+from django.forms import formset_factory, modelformset_factory
+from django.forms import inlineformset_factory
+from oscar.core.loading import get_model
+from oscar_support.dashboard.forms import (
+ PriorityForm,
+ TicketStatusForm,
+ TicketTypeForm
+)
+
+from oscar_support.forms import (
+ AttachmentForm,
+ RelatedOrderForm,
+ RelatedOrderLineForm,
+ RelatedProductForm,
+)
+
+Attachment = get_model('oscar_support', 'Attachment')
+Order = get_model('order', 'Order')
+RelatedOrder = get_model("oscar_support", "RelatedOrder")
+Priority = get_model("oscar_support", "Priority")
+RelatedOrderLine = get_model("oscar_support", "RelatedOrderLine")
+RelatedProduct = get_model("oscar_support", "RelatedProduct")
+Ticket = get_model("oscar_support", "Ticket")
+TicketStatus = get_model("oscar_support", "TicketStatus")
+TicketType = get_model("oscar_support", "TicketType")
+
+BaseAttachmentFormSet = inlineformset_factory(
+ Ticket, Attachment, form=AttachmentForm, extra=2,
+ can_delete=True)
+
+
+class AttachmentFormSet(BaseAttachmentFormSet):
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(AttachmentFormSet, self).__init__(*args, **kwargs)
+
+ def _construct_form(self, i, **kwargs):
+ kwargs['user'] = self.user
+ return super(AttachmentFormSet, self)._construct_form(
+ i, **kwargs)
+
+
+BaseRelatedOrderFormSet = inlineformset_factory(
+ Ticket, RelatedOrder, form=RelatedOrderForm, extra=1,
+ can_delete=True)
+
+
+class RelatedOrderFormSet(BaseRelatedOrderFormSet):
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(RelatedOrderFormSet, self).__init__(*args, **kwargs)
+
+ def _construct_form(self, i, **kwargs):
+ kwargs['user'] = self.user
+ return super(RelatedOrderFormSet, self)._construct_form(
+ i, **kwargs)
+
+ def get_num_orders(self):
+ num_orders = 0
+ for i in range(0, self.total_form_count()):
+ form = self.forms[i]
+ if (hasattr(form, 'cleaned_data')
+ and form.cleaned_data.get('order', None)
+ and not form.cleaned_data.get('DELETE', False)):
+ num_orders += 1
+ return num_orders
+
+
+BaseRelatedOrderLineFormSet = inlineformset_factory(
+ Ticket, RelatedOrderLine, form=RelatedOrderLineForm, extra=1,
+ can_delete=True)
+
+
+class RelatedOrderLineFormSet(BaseRelatedOrderLineFormSet):
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(RelatedOrderLineFormSet, self).__init__(*args, **kwargs)
+
+ def _construct_form(self, i, **kwargs):
+ kwargs['user'] = self.user
+ return super(RelatedOrderLineFormSet, self)._construct_form(
+ i, **kwargs)
+
+
+BaseRelatedProductFormSet = inlineformset_factory(
+ Ticket, RelatedProduct, form=RelatedProductForm, extra=5,
+ can_delete=True)
+
+
+class RelatedProductFormSet(BaseRelatedProductFormSet):
+ def __init__(self, user, *args, **kwargs):
+ self.user = user
+ super(RelatedProductFormSet, self).__init__(*args, **kwargs)
+
+ def _construct_form(self, i, **kwargs):
+ kwargs['user'] = self.user
+ return super(RelatedProductFormSet, self)._construct_form(
+ i, **kwargs)
diff --git a/oscar_support/forms/widgets.py b/oscar_support/forms/widgets.py
index 7e43701..52df383 100644
--- a/oscar_support/forms/widgets.py
+++ b/oscar_support/forms/widgets.py
@@ -1,9 +1,11 @@
-from django.forms.util import flatatt
-from django.template import loader, Context
-from django.utils.encoding import force_unicode
-from django.utils.html import conditional_escape
+from django.forms.widgets import Widget
+from django.forms.widgets import RadioSelect
from django.template.loader import render_to_string
-from django.forms.widgets import Widget, RadioInput, RadioFieldRenderer
+
+try:
+ from django.utils.encoding import force_unicode as force_text
+except ImportError:
+ from django.utils.encoding import force_text
class AutoCompleteWiget(Widget):
@@ -16,54 +18,17 @@ def __init__(self, url, user_field=None, *args, **kwargs):
def render(self, name, value, attrs=None):
if value is None:
value = u''
- tmpl = loader.get_template(
- 'oscar_support/widgets/autocomplete_widget.html'
- )
- return tmpl.render(Context({
+ ctx = {
'name': name,
'url': self.url,
'user_field': self.user_field,
'value': value,
- }))
+ }
+ return render_to_string('oscar_support/widgets/autocomplete_widget.html', context=ctx)
AutoCompleteWidget = AutoCompleteWiget
-class CustomRadioInput(RadioInput):
+class CustomRadioInput(RadioSelect):
template_name = 'oscar_support/partials/custom_radio_select.html'
-
- def render(self, name=None, value=None, attrs=None, choices=()):
- name = name or self.name
- value = value or self.value
- attrs = attrs or self.attrs
-
- if 'id' in self.attrs:
- self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index)
-
- if 'id' in self.attrs:
- label_for = ' for="%s"' % self.attrs['id']
- else:
- label_for = ''
-
- choice_label = conditional_escape(force_unicode(self.choice_label))
- return render_to_string(self.template_name, Context({
- 'attrs': flatatt(self.attrs),
- 'checked': self.is_checked(),
- 'name': self.name,
- 'value': self.choice_value,
- 'label_for': label_for,
- 'choice_label': choice_label,
- }))
-
-
-class CustomRadioFieldRenderer(RadioFieldRenderer):
-
- def __iter__(self):
- for i, choice in enumerate(self.choices):
- yield CustomRadioInput(self.name, self.value, self.attrs.copy(),
- choice, i)
-
- def __getitem__(self, idx):
- choice = self.choices[idx] # Let the IndexError propogate
- return CustomRadioInput(self.name, self.value, self.attrs.copy(),
- choice, idx)
+ option_template_name = 'oscar_support/partials/custom_radio_option.html'
diff --git a/oscar_support/migrations/0001_initial.py b/oscar_support/migrations/0001_initial.py
index 546a12c..8515805 100644
--- a/oscar_support/migrations/0001_initial.py
+++ b/oscar_support/migrations/0001_initial.py
@@ -1,499 +1,288 @@
# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
+# Generated by Django 1.11.4 on 2017-09-02 23:12
+from __future__ import unicode_literals
-from oscar.core.compat import AUTH_USER_MODEL, AUTH_USER_MODEL_NAME
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import django_extensions.db.fields
+import shortuuidfield.fields
-class Migration(SchemaMigration):
+def create_default_ticket_status(apps, schema_editor):
+ statuses = [
+ 'Closed'
+ 'In progress',
+ 'In review',
+ 'New',
+ 'Open',
+ 'Pending',
+ 'Solved',
+ ]
- def forwards(self, orm):
- # Adding model 'TicketType'
- db.create_table(u'oscar_support_tickettype', (
- ('uuid', self.gf('shortuuidfield.fields.ShortUUIDField')(max_length=22, primary_key=True)),
- ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=64)),
- ))
- db.send_create_signal(u'oscar_support', ['TicketType'])
+ Status = apps.get_model('oscar_support.ticketstatus')
- # Adding model 'TicketStatus'
- db.create_table(u'oscar_support_ticketstatus', (
- ('uuid', self.gf('shortuuidfield.fields.ShortUUIDField')(max_length=22, primary_key=True)),
- ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=64)),
- ))
- db.send_create_signal(u'oscar_support', ['TicketStatus'])
+ for status in statuses:
+ Status.objects.create(name=status)
- # Adding model 'Ticket'
- db.create_table(u'oscar_support_ticket', (
- ('date_created', self.gf('django.db.models.fields.DateTimeField')()),
- ('date_updated', self.gf('django.db.models.fields.DateTimeField')()),
- ('uuid', self.gf('shortuuidfield.fields.ShortUUIDField')(max_length=22, primary_key=True)),
- ('number', self.gf('django.db.models.fields.CharField')(max_length=64, db_index=True)),
- ('subticket_id', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
- ('parent', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='subtickets', null=True, to=orm['oscar_support.Ticket'])),
- ('requester', self.gf('django.db.models.fields.related.ForeignKey')(related_name='submitted_tickets', to=orm[AUTH_USER_MODEL])),
- ('status', self.gf('django.db.models.fields.related.ForeignKey')(related_name='tickets', to=orm['oscar_support.TicketStatus'])),
- ('type', self.gf('django.db.models.fields.related.ForeignKey')(related_name='tickets', to=orm['oscar_support.TicketType'])),
- ('assigned_group', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='tickets', null=True, to=orm['auth.Group'])),
- ('assignee', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='assigned_tickets', null=True, to=orm[AUTH_USER_MODEL])),
- ('subject', self.gf('django.db.models.fields.CharField')(max_length=255)),
- ('body', self.gf('django.db.models.fields.TextField')()),
- ('priority', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='tickets', null=True, to=orm['oscar_support.Priority'])),
- ('is_internal', self.gf('django.db.models.fields.BooleanField')(default=False)),
- ))
- db.send_create_signal(u'oscar_support', ['Ticket'])
- # Adding unique constraint on 'Ticket', fields ['number', 'subticket_id']
- db.create_unique(u'oscar_support_ticket', ['number', 'subticket_id'])
+def create_default_ticket_type(apps, schema_editor):
+ types = [
+ 'Customer',
+ 'Error',
+ 'Initiative',
+ 'Order',
+ 'Product',
+ 'Work'
+ ]
- # Adding model 'Priority'
- db.create_table(u'oscar_support_priority', (
- ('uuid', self.gf('shortuuidfield.fields.ShortUUIDField')(max_length=22, primary_key=True)),
- ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
- ('slug', self.gf('django_extensions.db.fields.AutoSlugField')(allow_duplicates=False, max_length=50, separator=u'-', blank=True, populate_from='name', overwrite=False)),
- ('comment', self.gf('django.db.models.fields.TextField')(blank=True)),
- ))
- db.send_create_signal(u'oscar_support', ['Priority'])
+ Type = apps.get_model('oscar_support.tickettype')
- # Adding model 'Message'
- db.create_table(u'oscar_support_message', (
- ('date_created', self.gf('django.db.models.fields.DateTimeField')()),
- ('date_updated', self.gf('django.db.models.fields.DateTimeField')()),
- ('uuid', self.gf('shortuuidfield.fields.ShortUUIDField')(max_length=22, primary_key=True)),
- ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='messages', to=orm[AUTH_USER_MODEL])),
- ('type', self.gf('django.db.models.fields.CharField')(default=u'public', max_length=3)),
- ('ticket', self.gf('django.db.models.fields.related.ForeignKey')(related_name='messages', to=orm['oscar_support.Ticket'])),
- ('text', self.gf('django.db.models.fields.TextField')()),
- ))
- db.send_create_signal(u'oscar_support', ['Message'])
+ for type in types:
+ Type.objects.create(name=type)
- # Adding model 'RelatedOrderLine'
- db.create_table(u'oscar_support_relatedorderline', (
- ('date_created', self.gf('django.db.models.fields.DateTimeField')()),
- ('date_updated', self.gf('django.db.models.fields.DateTimeField')()),
- ('uuid', self.gf('shortuuidfield.fields.ShortUUIDField')(max_length=22, primary_key=True)),
- ('ticket', self.gf('django.db.models.fields.related.ForeignKey')(related_name='relatedorderlines', to=orm['oscar_support.Ticket'])),
- ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='relatedorderlines', to=orm[AUTH_USER_MODEL])),
- ('line', self.gf('django.db.models.fields.related.ForeignKey')(related_name='ticket_related_order_lines', to=orm['order.Line'])),
- ))
- db.send_create_signal(u'oscar_support', ['RelatedOrderLine'])
- # Adding model 'RelatedOrder'
- db.create_table(u'oscar_support_relatedorder', (
- ('date_created', self.gf('django.db.models.fields.DateTimeField')()),
- ('date_updated', self.gf('django.db.models.fields.DateTimeField')()),
- ('uuid', self.gf('shortuuidfield.fields.ShortUUIDField')(max_length=22, primary_key=True)),
- ('ticket', self.gf('django.db.models.fields.related.ForeignKey')(related_name='relatedorders', to=orm['oscar_support.Ticket'])),
- ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='relatedorders', to=orm[AUTH_USER_MODEL])),
- ('order', self.gf('django.db.models.fields.related.ForeignKey')(related_name='ticket_related_orders', to=orm['order.Order'])),
- ))
- db.send_create_signal(u'oscar_support', ['RelatedOrder'])
+def create_default_priority(apps, schema_editor):
+ priorities = [
+ 'Extremely',
+ 'High',
+ 'Infrequent',
+ 'Low',
+ 'N/A',
+ 'Normal',
+ 'Unsure',
+ ]
+ comments = [
+ "Extremely disruptive, can't be working until resolved.",
+ 'Very high priority. Needs to be resolved in short time range.',
+ 'Infrequent, serious problems. Should fix in near term.',
+ 'A low impact, low urgency issue.',
+ 'This issue did not require any action, so this field does not apply.',
+ 'Normal, common problem.',
+ "Unsure when we're going to fix this.",
+ ]
- # Adding model 'RelatedProduct'
- db.create_table(u'oscar_support_relatedproduct', (
- ('date_created', self.gf('django.db.models.fields.DateTimeField')()),
- ('date_updated', self.gf('django.db.models.fields.DateTimeField')()),
- ('uuid', self.gf('shortuuidfield.fields.ShortUUIDField')(max_length=22, primary_key=True)),
- ('ticket', self.gf('django.db.models.fields.related.ForeignKey')(related_name='relatedproducts', to=orm['oscar_support.Ticket'])),
- ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='relatedproducts', to=orm[AUTH_USER_MODEL])),
- ('product', self.gf('django.db.models.fields.related.ForeignKey')(related_name='ticket_related_products', to=orm['catalogue.Product'])),
- ))
- db.send_create_signal(u'oscar_support', ['RelatedProduct'])
+ Priority = apps.get_model('oscar_support.priority')
- # Adding model 'Attachment'
- db.create_table(u'oscar_support_attachment', (
- ('date_created', self.gf('django.db.models.fields.DateTimeField')()),
- ('date_updated', self.gf('django.db.models.fields.DateTimeField')()),
- ('uuid', self.gf('shortuuidfield.fields.ShortUUIDField')(max_length=22, primary_key=True)),
- ('ticket', self.gf('django.db.models.fields.related.ForeignKey')(related_name='attachments', to=orm['oscar_support.Ticket'])),
- ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='attachments', to=orm[AUTH_USER_MODEL])),
- ('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
- ))
- db.send_create_signal(u'oscar_support', ['Attachment'])
+ for priority, comment in zip(priorities, comments):
+ Priority.objects.create(name=priority, comment=comment)
- def backwards(self, orm):
- # Removing unique constraint on 'Ticket', fields ['number', 'subticket_id']
- db.delete_unique(u'oscar_support_ticket', ['number', 'subticket_id'])
+class Migration(migrations.Migration):
- # Deleting model 'TicketType'
- db.delete_table(u'oscar_support_tickettype')
+ initial = True
- # Deleting model 'TicketStatus'
- db.delete_table(u'oscar_support_ticketstatus')
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('catalogue', '0012_auto_20170609_1902'),
+ ('order', '0005_update_email_length'),
+ ('auth', '0008_alter_user_username_max_length'),
+ ]
- # Deleting model 'Ticket'
- db.delete_table(u'oscar_support_ticket')
-
- # Deleting model 'Priority'
- db.delete_table(u'oscar_support_priority')
-
- # Deleting model 'Message'
- db.delete_table(u'oscar_support_message')
-
- # Deleting model 'RelatedOrderLine'
- db.delete_table(u'oscar_support_relatedorderline')
-
- # Deleting model 'RelatedOrder'
- db.delete_table(u'oscar_support_relatedorder')
-
- # Deleting model 'RelatedProduct'
- db.delete_table(u'oscar_support_relatedproduct')
-
- # Deleting model 'Attachment'
- db.delete_table(u'oscar_support_attachment')
-
-
- models = {
- u'address.country': {
- 'Meta': {'ordering': "('-display_order', 'name')", 'object_name': 'Country'},
- 'display_order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0', 'db_index': 'True'}),
- 'is_shipping_country': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'iso_3166_1_a2': ('django.db.models.fields.CharField', [], {'max_length': '2', 'primary_key': 'True'}),
- 'iso_3166_1_a3': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'db_index': 'True'}),
- 'iso_3166_1_numeric': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'db_index': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'printable_name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'auth.group': {
- 'Meta': {'object_name': 'Group'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
- 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
- },
- u'auth.permission': {
- 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
- 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- },
- AUTH_USER_MODEL: {
- 'Meta': {'object_name': AUTH_USER_MODEL_NAME},
- 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
- 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
- },
- u'catalogue.attributeentity': {
- 'Meta': {'object_name': 'AttributeEntity'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'entities'", 'to': u"orm['catalogue.AttributeEntityType']"})
- },
- u'catalogue.attributeentitytype': {
- 'Meta': {'object_name': 'AttributeEntityType'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'})
- },
- u'catalogue.attributeoption': {
- 'Meta': {'object_name': 'AttributeOption'},
- 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'options'", 'to': u"orm['catalogue.AttributeOptionGroup']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'option': ('django.db.models.fields.CharField', [], {'max_length': '255'})
- },
- u'catalogue.attributeoptiongroup': {
- 'Meta': {'object_name': 'AttributeOptionGroup'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'catalogue.category': {
- 'Meta': {'ordering': "['full_name']", 'object_name': 'Category'},
- 'depth': ('django.db.models.fields.PositiveIntegerField', [], {}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'full_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- 'numchild': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'})
- },
- u'catalogue.option': {
- 'Meta': {'object_name': 'Option'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'Required'", 'max_length': '128'})
- },
- u'catalogue.product': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Product'},
- 'attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.ProductAttribute']", 'through': u"orm['catalogue.ProductAttributeValue']", 'symmetrical': 'False'}),
- 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Category']", 'through': u"orm['catalogue.ProductCategory']", 'symmetrical': 'False'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_discountable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'variants'", 'null': 'True', 'to': u"orm['catalogue.Product']"}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'products'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'product_options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'rating': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
- 'recommended_products': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Product']", 'symmetrical': 'False', 'through': u"orm['catalogue.ProductRecommendation']", 'blank': 'True'}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'relations'", 'blank': 'True', 'to': u"orm['catalogue.Product']"}),
- 'score': ('django.db.models.fields.FloatField', [], {'default': '0.0', 'db_index': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
- 'status': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productattribute': {
- 'Meta': {'ordering': "['code']", 'object_name': 'ProductAttribute'},
- 'code': ('django.db.models.fields.SlugField', [], {'max_length': '128'}),
- 'entity_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntityType']", 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'option_group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOptionGroup']", 'null': 'True', 'blank': 'True'}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attributes'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'text'", 'max_length': '20'})
- },
- u'catalogue.productattributevalue': {
- 'Meta': {'object_name': 'ProductAttributeValue'},
- 'attribute': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.ProductAttribute']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_values'", 'to': u"orm['catalogue.Product']"}),
- 'value_boolean': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- 'value_entity': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntity']", 'null': 'True', 'blank': 'True'}),
- 'value_float': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
- 'value_integer': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'value_option': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOption']", 'null': 'True', 'blank': 'True'}),
- 'value_richtext': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'value_text': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productcategory': {
- 'Meta': {'ordering': "['-is_canonical']", 'object_name': 'ProductCategory'},
- 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Category']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_canonical': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'catalogue.productclass': {
- 'Meta': {'ordering': "['name']", 'object_name': 'ProductClass'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'requires_shipping': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- 'track_stock': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
- },
- u'catalogue.productrecommendation': {
- 'Meta': {'object_name': 'ProductRecommendation'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'primary': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'primary_recommendations'", 'to': u"orm['catalogue.Product']"}),
- 'ranking': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}),
- 'recommendation': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'contenttypes.contenttype': {
- 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
- 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
- },
- u'order.billingaddress': {
- 'Meta': {'object_name': 'BillingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'order.line': {
- 'Meta': {'object_name': 'Line'},
- 'est_dispatch_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'line_price_before_discounts_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_before_discounts_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'lines'", 'to': u"orm['order.Order']"}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'order_lines'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['partner.Partner']"}),
- 'partner_line_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'partner_line_reference': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'partner_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'quantity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'stockrecord': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['partner.StockRecord']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'unit_cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_retail_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'})
- },
- u'order.order': {
- 'Meta': {'ordering': "['-date_placed']", 'object_name': 'Order'},
- 'basket_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'billing_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.BillingAddress']", 'null': 'True', 'blank': 'True'}),
- 'currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'date_placed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'guest_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
- 'shipping_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.ShippingAddress']", 'null': 'True', 'blank': 'True'}),
- 'shipping_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
- 'shipping_excl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_incl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_method': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['sites.Site']"}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
- 'total_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'total_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'orders'", 'null': 'True', 'to': u"orm['{}']".format(AUTH_USER_MODEL)})
- },
- u'order.shippingaddress': {
- 'Meta': {'object_name': 'ShippingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'oscar_support.attachment': {
- 'Meta': {'object_name': 'Attachment'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.message': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Message'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'text': ('django.db.models.fields.TextField', [], {}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['oscar_support.Ticket']"}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "u'public'", 'max_length': '3'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.priority': {
- 'Meta': {'object_name': 'Priority'},
- 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorder': {
- 'Meta': {'object_name': 'RelatedOrder'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_orders'", 'to': u"orm['order.Order']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorderline': {
- 'Meta': {'object_name': 'RelatedOrderLine'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'line': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_order_lines'", 'to': u"orm['order.Line']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedproduct': {
- 'Meta': {'object_name': 'RelatedProduct'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_products'", 'to': u"orm['catalogue.Product']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticket': {
- 'Meta': {'ordering': "['-date_updated']", 'unique_together': "(('number', 'subticket_id'),)", 'object_name': 'Ticket'},
- 'assigned_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['auth.Group']"}),
- 'assignee': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'assigned_tickets'", 'null': 'True', 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'body': ('django.db.models.fields.TextField', [], {}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'is_internal': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '64', 'db_index': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subtickets'", 'null': 'True', 'to': u"orm['oscar_support.Ticket']"}),
- 'priority': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['oscar_support.Priority']"}),
- 'related_lines': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrderLine']", 'to': u"orm['order.Line']"}),
- 'related_orders': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrder']", 'to': u"orm['order.Order']"}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedProduct']", 'to': u"orm['catalogue.Product']"}),
- 'requester': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'submitted_tickets'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketStatus']"}),
- 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'subticket_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketType']"}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticketstatus': {
- 'Meta': {'object_name': 'TicketStatus'},
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.tickettype': {
- 'Meta': {'object_name': 'TicketType'},
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'partner.partner': {
- 'Meta': {'object_name': 'Partner'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'users': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'partners'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['{}']".format(AUTH_USER_MODEL)})
- },
- u'partner.stockrecord': {
- 'Meta': {'unique_together': "(('partner', 'partner_sku'),)", 'object_name': 'StockRecord'},
- 'cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'low_stock_threshold': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_allocated': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_in_stock': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['partner.Partner']"}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'price_currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'price_retail': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['catalogue.Product']"})
- },
- u'sites.site': {
- 'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
- 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- }
- }
-
- complete_apps = ['oscar_support']
+ operations = [
+ migrations.CreateModel(
+ name='Attachment',
+ fields=[
+ ('date_created', models.DateTimeField(verbose_name='Created')),
+ ('date_updated', models.DateTimeField(verbose_name='Last modified')),
+ ('uuid', shortuuidfield.fields.ShortUUIDField(blank=True, editable=False, max_length=22, primary_key=True, serialize=False)),
+ ('file', models.FileField(upload_to='oscar_support/%Y/%m', verbose_name='File')),
+ ],
+ options={
+ 'verbose_name': 'Attachment',
+ 'verbose_name_plural': 'Attachments',
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='Message',
+ fields=[
+ ('date_created', models.DateTimeField(verbose_name='Created')),
+ ('date_updated', models.DateTimeField(verbose_name='Last modified')),
+ ('uuid', shortuuidfield.fields.ShortUUIDField(blank=True, editable=False, max_length=22, primary_key=True, serialize=False)),
+ ('type', models.CharField(choices=[('public', 'Public message'), ('internal', 'Internal note')], default='public', max_length=30, verbose_name='Message type')),
+ ('text', models.TextField(verbose_name='Text')),
+ ],
+ options={
+ 'verbose_name': 'Message',
+ 'verbose_name_plural': 'Messages',
+ 'ordering': ['-date_created'],
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='Priority',
+ fields=[
+ ('uuid', shortuuidfield.fields.ShortUUIDField(blank=True, editable=False, max_length=22, primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=255, verbose_name='Name')),
+ ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='name', verbose_name='Slug')),
+ ('comment', models.TextField(blank=True, verbose_name='Comment')),
+ ],
+ options={
+ 'verbose_name': 'Priority',
+ 'verbose_name_plural': 'Priorities',
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='RelatedOrder',
+ fields=[
+ ('date_created', models.DateTimeField(verbose_name='Created')),
+ ('date_updated', models.DateTimeField(verbose_name='Last modified')),
+ ('uuid', shortuuidfield.fields.ShortUUIDField(blank=True, editable=False, max_length=22, primary_key=True, serialize=False)),
+ ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_related_orders', to='order.Order', verbose_name='Order')),
+ ],
+ options={
+ 'verbose_name': 'Related order',
+ 'verbose_name_plural': 'Related orders',
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='RelatedOrderLine',
+ fields=[
+ ('date_created', models.DateTimeField(verbose_name='Created')),
+ ('date_updated', models.DateTimeField(verbose_name='Last modified')),
+ ('uuid', shortuuidfield.fields.ShortUUIDField(blank=True, editable=False, max_length=22, primary_key=True, serialize=False)),
+ ('line', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_related_order_lines', to='order.Line', verbose_name='Order line')),
+ ],
+ options={
+ 'verbose_name': 'Related order line',
+ 'verbose_name_plural': 'Related order lines',
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='RelatedProduct',
+ fields=[
+ ('date_created', models.DateTimeField(verbose_name='Created')),
+ ('date_updated', models.DateTimeField(verbose_name='Last modified')),
+ ('uuid', shortuuidfield.fields.ShortUUIDField(blank=True, editable=False, max_length=22, primary_key=True, serialize=False)),
+ ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_related_products', to='catalogue.Product', verbose_name='Product')),
+ ],
+ options={
+ 'verbose_name': 'Related product',
+ 'verbose_name_plural': 'Related products',
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='Ticket',
+ fields=[
+ ('date_created', models.DateTimeField(verbose_name='Created')),
+ ('date_updated', models.DateTimeField(verbose_name='Last modified')),
+ ('uuid', shortuuidfield.fields.ShortUUIDField(blank=True, editable=False, max_length=22, primary_key=True, serialize=False)),
+ ('number', models.CharField(db_index=True, max_length=64, verbose_name='Number')),
+ ('subticket_id', models.PositiveIntegerField(default=0, verbose_name='Subticket number')),
+ ('subject', models.CharField(max_length=255, verbose_name='Subject')),
+ ('body', models.TextField(verbose_name='Body')),
+ ('is_internal', models.BooleanField(default=False, help_text="use this ticket only internally and don't display to the customer", verbose_name='Internal ticket')),
+ ('assigned_group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tickets', to='auth.Group', verbose_name='Assigned group')),
+ ('assignee', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='assigned_tickets', to=settings.AUTH_USER_MODEL, verbose_name='Assignee')),
+ ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='subtickets', to='oscar_support.Ticket', verbose_name='Parent ticket')),
+ ('priority', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tickets', to='oscar_support.Priority', verbose_name='Priority')),
+ ('related_lines', models.ManyToManyField(blank=True, related_name='tickets', through='oscar_support.RelatedOrderLine', to='order.Line', verbose_name='Related order lines')),
+ ('related_orders', models.ManyToManyField(blank=True, related_name='tickets', through='oscar_support.RelatedOrder', to='order.Order', verbose_name='Related Orders')),
+ ('related_products', models.ManyToManyField(blank=True, related_name='tickets', through='oscar_support.RelatedProduct', to='catalogue.Product', verbose_name='Related products')),
+ ('requester', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='submitted_tickets', to=settings.AUTH_USER_MODEL, verbose_name='Requester')),
+ ],
+ options={
+ 'verbose_name': 'Ticket',
+ 'verbose_name_plural': 'Tickets',
+ 'ordering': ['-date_updated'],
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='TicketStatus',
+ fields=[
+ ('uuid', shortuuidfield.fields.ShortUUIDField(blank=True, editable=False, max_length=22, primary_key=True, serialize=False)),
+ ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='name', unique=True, verbose_name='Slug')),
+ ('name', models.CharField(max_length=64, verbose_name='Name')),
+ ],
+ options={
+ 'verbose_name': 'Ticket status',
+ 'verbose_name_plural': 'Ticket statuses',
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='TicketType',
+ fields=[
+ ('uuid', shortuuidfield.fields.ShortUUIDField(blank=True, editable=False, max_length=22, primary_key=True, serialize=False)),
+ ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='name', unique=True, verbose_name='Slug')),
+ ('name', models.CharField(max_length=64, verbose_name='Name')),
+ ],
+ options={
+ 'verbose_name': 'Ticket type',
+ 'verbose_name_plural': 'Ticket types',
+ 'abstract': False,
+ },
+ ),
+ migrations.AddField(
+ model_name='ticket',
+ name='status',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tickets', to='oscar_support.TicketStatus', verbose_name='Status'),
+ ),
+ migrations.AddField(
+ model_name='ticket',
+ name='type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tickets', to='oscar_support.TicketType', verbose_name='Type'),
+ ),
+ migrations.AddField(
+ model_name='relatedproduct',
+ name='ticket',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='relatedproducts', to='oscar_support.Ticket', verbose_name='Ticket'),
+ ),
+ migrations.AddField(
+ model_name='relatedproduct',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='relatedproducts', to=settings.AUTH_USER_MODEL, verbose_name='Added by'),
+ ),
+ migrations.AddField(
+ model_name='relatedorderline',
+ name='ticket',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='relatedorderlines', to='oscar_support.Ticket', verbose_name='Ticket'),
+ ),
+ migrations.AddField(
+ model_name='relatedorderline',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='relatedorderlines', to=settings.AUTH_USER_MODEL, verbose_name='Added by'),
+ ),
+ migrations.AddField(
+ model_name='relatedorder',
+ name='ticket',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='relatedorders', to='oscar_support.Ticket', verbose_name='Ticket'),
+ ),
+ migrations.AddField(
+ model_name='relatedorder',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='relatedorders', to=settings.AUTH_USER_MODEL, verbose_name='Added by'),
+ ),
+ migrations.AddField(
+ model_name='message',
+ name='ticket',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='messages', to='oscar_support.Ticket', verbose_name='Ticket'),
+ ),
+ migrations.AddField(
+ model_name='message',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='messages', to=settings.AUTH_USER_MODEL, verbose_name='Sender'),
+ ),
+ migrations.AddField(
+ model_name='attachment',
+ name='ticket',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='oscar_support.Ticket', verbose_name='Ticket'),
+ ),
+ migrations.AddField(
+ model_name='attachment',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to=settings.AUTH_USER_MODEL, verbose_name='User'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='ticket',
+ unique_together=set([('number', 'subticket_id')]),
+ ),
+ migrations.RunPython(create_default_ticket_status),
+ migrations.RunPython(create_default_ticket_type),
+ ]
diff --git a/oscar_support/migrations/0002_auto__chg_field_message_type.py b/oscar_support/migrations/0002_auto__chg_field_message_type.py
deleted file mode 100644
index ab61592..0000000
--- a/oscar_support/migrations/0002_auto__chg_field_message_type.py
+++ /dev/null
@@ -1,375 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-from oscar.core.compat import AUTH_USER_MODEL, AUTH_USER_MODEL_NAME
-
-
-class Migration(SchemaMigration):
-
- def forwards(self, orm):
-
- # Changing field 'Message.type'
- db.alter_column(u'oscar_support_message', 'type', self.gf('django.db.models.fields.CharField')(max_length=30))
-
- def backwards(self, orm):
-
- # Changing field 'Message.type'
- db.alter_column(u'oscar_support_message', 'type', self.gf('django.db.models.fields.CharField')(max_length=3))
-
- models = {
- u'address.country': {
- 'Meta': {'ordering': "('-display_order', 'name')", 'object_name': 'Country'},
- 'display_order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0', 'db_index': 'True'}),
- 'is_shipping_country': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'iso_3166_1_a2': ('django.db.models.fields.CharField', [], {'max_length': '2', 'primary_key': 'True'}),
- 'iso_3166_1_a3': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'db_index': 'True'}),
- 'iso_3166_1_numeric': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'db_index': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'printable_name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'auth.group': {
- 'Meta': {'object_name': 'Group'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
- 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
- },
- u'auth.permission': {
- 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
- 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- },
- AUTH_USER_MODEL: {
- 'Meta': {'object_name': AUTH_USER_MODEL_NAME},
- 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
- 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
- },
- u'catalogue.attributeentity': {
- 'Meta': {'object_name': 'AttributeEntity'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'entities'", 'to': u"orm['catalogue.AttributeEntityType']"})
- },
- u'catalogue.attributeentitytype': {
- 'Meta': {'object_name': 'AttributeEntityType'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'})
- },
- u'catalogue.attributeoption': {
- 'Meta': {'object_name': 'AttributeOption'},
- 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'options'", 'to': u"orm['catalogue.AttributeOptionGroup']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'option': ('django.db.models.fields.CharField', [], {'max_length': '255'})
- },
- u'catalogue.attributeoptiongroup': {
- 'Meta': {'object_name': 'AttributeOptionGroup'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'catalogue.category': {
- 'Meta': {'ordering': "['full_name']", 'object_name': 'Category'},
- 'depth': ('django.db.models.fields.PositiveIntegerField', [], {}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'full_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- 'numchild': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'})
- },
- u'catalogue.option': {
- 'Meta': {'object_name': 'Option'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'Required'", 'max_length': '128'})
- },
- u'catalogue.product': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Product'},
- 'attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.ProductAttribute']", 'through': u"orm['catalogue.ProductAttributeValue']", 'symmetrical': 'False'}),
- 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Category']", 'through': u"orm['catalogue.ProductCategory']", 'symmetrical': 'False'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_discountable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'variants'", 'null': 'True', 'to': u"orm['catalogue.Product']"}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'products'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'product_options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'rating': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
- 'recommended_products': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Product']", 'symmetrical': 'False', 'through': u"orm['catalogue.ProductRecommendation']", 'blank': 'True'}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'relations'", 'blank': 'True', 'to': u"orm['catalogue.Product']"}),
- 'score': ('django.db.models.fields.FloatField', [], {'default': '0.0', 'db_index': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
- 'status': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productattribute': {
- 'Meta': {'ordering': "['code']", 'object_name': 'ProductAttribute'},
- 'code': ('django.db.models.fields.SlugField', [], {'max_length': '128'}),
- 'entity_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntityType']", 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'option_group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOptionGroup']", 'null': 'True', 'blank': 'True'}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attributes'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'text'", 'max_length': '20'})
- },
- u'catalogue.productattributevalue': {
- 'Meta': {'object_name': 'ProductAttributeValue'},
- 'attribute': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.ProductAttribute']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_values'", 'to': u"orm['catalogue.Product']"}),
- 'value_boolean': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
- 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- 'value_entity': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntity']", 'null': 'True', 'blank': 'True'}),
- 'value_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'value_float': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
- 'value_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'value_integer': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'value_option': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOption']", 'null': 'True', 'blank': 'True'}),
- 'value_richtext': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'value_text': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productcategory': {
- 'Meta': {'ordering': "['-is_canonical']", 'object_name': 'ProductCategory'},
- 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Category']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_canonical': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'catalogue.productclass': {
- 'Meta': {'ordering': "['name']", 'object_name': 'ProductClass'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'requires_shipping': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- 'track_stock': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
- },
- u'catalogue.productrecommendation': {
- 'Meta': {'object_name': 'ProductRecommendation'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'primary': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'primary_recommendations'", 'to': u"orm['catalogue.Product']"}),
- 'ranking': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}),
- 'recommendation': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'contenttypes.contenttype': {
- 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
- 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
- },
- u'order.billingaddress': {
- 'Meta': {'object_name': 'BillingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'order.line': {
- 'Meta': {'object_name': 'Line'},
- 'est_dispatch_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'line_price_before_discounts_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_before_discounts_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'lines'", 'to': u"orm['order.Order']"}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'order_lines'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['partner.Partner']"}),
- 'partner_line_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'partner_line_reference': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'partner_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'quantity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'stockrecord': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['partner.StockRecord']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'unit_cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_retail_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'})
- },
- u'order.order': {
- 'Meta': {'ordering': "['-date_placed']", 'object_name': 'Order'},
- 'basket_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'billing_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.BillingAddress']", 'null': 'True', 'blank': 'True'}),
- 'currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'date_placed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'guest_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
- 'shipping_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.ShippingAddress']", 'null': 'True', 'blank': 'True'}),
- 'shipping_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
- 'shipping_excl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_incl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_method': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['sites.Site']"}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
- 'total_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'total_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'orders'", 'null': 'True', 'to': u"orm['{}']".format(AUTH_USER_MODEL)})
- },
- u'order.shippingaddress': {
- 'Meta': {'object_name': 'ShippingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'phone_number': ('oscar.models.fields.PhoneNumberField', [], {'max_length': '128', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'oscar_support.attachment': {
- 'Meta': {'object_name': 'Attachment'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.message': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Message'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'text': ('django.db.models.fields.TextField', [], {}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['oscar_support.Ticket']"}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "u'public'", 'max_length': '30'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.priority': {
- 'Meta': {'object_name': 'Priority'},
- 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorder': {
- 'Meta': {'object_name': 'RelatedOrder'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_orders'", 'to': u"orm['order.Order']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorderline': {
- 'Meta': {'object_name': 'RelatedOrderLine'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'line': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_order_lines'", 'to': u"orm['order.Line']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedproduct': {
- 'Meta': {'object_name': 'RelatedProduct'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_products'", 'to': u"orm['catalogue.Product']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticket': {
- 'Meta': {'ordering': "['-date_updated']", 'unique_together': "(('number', 'subticket_id'),)", 'object_name': 'Ticket'},
- 'assigned_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['auth.Group']"}),
- 'assignee': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'assigned_tickets'", 'null': 'True', 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'body': ('django.db.models.fields.TextField', [], {}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'is_internal': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '64', 'db_index': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subtickets'", 'null': 'True', 'to': u"orm['oscar_support.Ticket']"}),
- 'priority': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['oscar_support.Priority']"}),
- 'related_lines': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrderLine']", 'to': u"orm['order.Line']"}),
- 'related_orders': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrder']", 'to': u"orm['order.Order']"}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedProduct']", 'to': u"orm['catalogue.Product']"}),
- 'requester': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'submitted_tickets'", 'to': u"orm['{}']".format(AUTH_USER_MODEL)}),
- 'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketStatus']"}),
- 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'subticket_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketType']"}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticketstatus': {
- 'Meta': {'object_name': 'TicketStatus'},
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.tickettype': {
- 'Meta': {'object_name': 'TicketType'},
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'partner.partner': {
- 'Meta': {'object_name': 'Partner'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'users': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'partners'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['{}']".format(AUTH_USER_MODEL)})
- },
- u'partner.stockrecord': {
- 'Meta': {'unique_together': "(('partner', 'partner_sku'),)", 'object_name': 'StockRecord'},
- 'cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'low_stock_threshold': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_allocated': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_in_stock': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['partner.Partner']"}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'price_currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'price_retail': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['catalogue.Product']"})
- },
- u'sites.site': {
- 'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
- 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- }
- }
-
- complete_apps = ['oscar_support']
\ No newline at end of file
diff --git a/oscar_support/migrations/0003_auto__add_field_tickettype_slug__add_field_ticketstatus_slug.py b/oscar_support/migrations/0003_auto__add_field_tickettype_slug__add_field_ticketstatus_slug.py
deleted file mode 100644
index 655e318..0000000
--- a/oscar_support/migrations/0003_auto__add_field_tickettype_slug__add_field_ticketstatus_slug.py
+++ /dev/null
@@ -1,387 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-from oscar.core.compat import AUTH_USER_MODEL, AUTH_USER_MODEL_NAME
-
-
-class Migration(SchemaMigration):
-
- def forwards(self, orm):
- # Adding field 'TicketType.slug'
- db.add_column(u'oscar_support_tickettype', 'slug',
- self.gf('django_extensions.db.fields.AutoSlugField')(allow_duplicates=False, max_length=50, separator=u'-', blank=True, default='', populate_from='name', overwrite=False),
- keep_default=False)
-
- # Adding field 'TicketStatus.slug'
- db.add_column(u'oscar_support_ticketstatus', 'slug',
- self.gf('django_extensions.db.fields.AutoSlugField')(allow_duplicates=False, max_length=50, separator=u'-', blank=True, default='', populate_from='name', overwrite=False),
- keep_default=False)
-
-
- def backwards(self, orm):
- # Deleting field 'TicketType.slug'
- db.delete_column(u'oscar_support_tickettype', 'slug')
-
- # Deleting field 'TicketStatus.slug'
- db.delete_column(u'oscar_support_ticketstatus', 'slug')
-
-
- models = {
- u'address.country': {
- 'Meta': {'ordering': "('-display_order', 'name')", 'object_name': 'Country'},
- 'display_order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0', 'db_index': 'True'}),
- 'is_shipping_country': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'iso_3166_1_a2': ('django.db.models.fields.CharField', [], {'max_length': '2', 'primary_key': 'True'}),
- 'iso_3166_1_a3': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'db_index': 'True'}),
- 'iso_3166_1_numeric': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'db_index': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'printable_name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'auth.group': {
- 'Meta': {'object_name': 'Group'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
- 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
- },
- u'auth.permission': {
- 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
- 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- },
- AUTH_USER_MODEL: {
- 'Meta': {'object_name': AUTH_USER_MODEL_NAME},
- 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
- 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
- },
- u'catalogue.attributeentity': {
- 'Meta': {'object_name': 'AttributeEntity'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'entities'", 'to': u"orm['catalogue.AttributeEntityType']"})
- },
- u'catalogue.attributeentitytype': {
- 'Meta': {'object_name': 'AttributeEntityType'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'})
- },
- u'catalogue.attributeoption': {
- 'Meta': {'object_name': 'AttributeOption'},
- 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'options'", 'to': u"orm['catalogue.AttributeOptionGroup']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'option': ('django.db.models.fields.CharField', [], {'max_length': '255'})
- },
- u'catalogue.attributeoptiongroup': {
- 'Meta': {'object_name': 'AttributeOptionGroup'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'catalogue.category': {
- 'Meta': {'ordering': "['full_name']", 'object_name': 'Category'},
- 'depth': ('django.db.models.fields.PositiveIntegerField', [], {}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'full_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- 'numchild': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'})
- },
- u'catalogue.option': {
- 'Meta': {'object_name': 'Option'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'Required'", 'max_length': '128'})
- },
- u'catalogue.product': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Product'},
- 'attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.ProductAttribute']", 'through': u"orm['catalogue.ProductAttributeValue']", 'symmetrical': 'False'}),
- 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Category']", 'through': u"orm['catalogue.ProductCategory']", 'symmetrical': 'False'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_discountable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'variants'", 'null': 'True', 'to': u"orm['catalogue.Product']"}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'products'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'product_options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'rating': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
- 'recommended_products': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Product']", 'symmetrical': 'False', 'through': u"orm['catalogue.ProductRecommendation']", 'blank': 'True'}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'relations'", 'blank': 'True', 'to': u"orm['catalogue.Product']"}),
- 'score': ('django.db.models.fields.FloatField', [], {'default': '0.0', 'db_index': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
- 'status': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productattribute': {
- 'Meta': {'ordering': "['code']", 'object_name': 'ProductAttribute'},
- 'code': ('django.db.models.fields.SlugField', [], {'max_length': '128'}),
- 'entity_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntityType']", 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'option_group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOptionGroup']", 'null': 'True', 'blank': 'True'}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attributes'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'text'", 'max_length': '20'})
- },
- u'catalogue.productattributevalue': {
- 'Meta': {'object_name': 'ProductAttributeValue'},
- 'attribute': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.ProductAttribute']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_values'", 'to': u"orm['catalogue.Product']"}),
- 'value_boolean': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
- 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- 'value_entity': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntity']", 'null': 'True', 'blank': 'True'}),
- 'value_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'value_float': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
- 'value_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'value_integer': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'value_option': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOption']", 'null': 'True', 'blank': 'True'}),
- 'value_richtext': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'value_text': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productcategory': {
- 'Meta': {'ordering': "['-is_canonical']", 'object_name': 'ProductCategory'},
- 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Category']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_canonical': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'catalogue.productclass': {
- 'Meta': {'ordering': "['name']", 'object_name': 'ProductClass'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'requires_shipping': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- 'track_stock': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
- },
- u'catalogue.productrecommendation': {
- 'Meta': {'object_name': 'ProductRecommendation'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'primary': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'primary_recommendations'", 'to': u"orm['catalogue.Product']"}),
- 'ranking': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}),
- 'recommendation': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'contenttypes.contenttype': {
- 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
- 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
- },
- u'order.billingaddress': {
- 'Meta': {'object_name': 'BillingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'order.line': {
- 'Meta': {'object_name': 'Line'},
- 'est_dispatch_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'line_price_before_discounts_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_before_discounts_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'lines'", 'to': u"orm['order.Order']"}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'order_lines'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['partner.Partner']"}),
- 'partner_line_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'partner_line_reference': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'partner_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'quantity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'stockrecord': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['partner.StockRecord']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'unit_cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_retail_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'})
- },
- u'order.order': {
- 'Meta': {'ordering': "['-date_placed']", 'object_name': 'Order'},
- 'basket_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'billing_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.BillingAddress']", 'null': 'True', 'blank': 'True'}),
- 'currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'date_placed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'guest_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
- 'shipping_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.ShippingAddress']", 'null': 'True', 'blank': 'True'}),
- 'shipping_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
- 'shipping_excl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_incl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_method': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['sites.Site']"}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
- 'total_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'total_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'orders'", 'null': 'True', 'to': u"orm['{0}']".format(AUTH_USER_MODEL)})
- },
- u'order.shippingaddress': {
- 'Meta': {'object_name': 'ShippingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'phone_number': ('oscar.models.fields.PhoneNumberField', [], {'max_length': '128', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'oscar_support.attachment': {
- 'Meta': {'object_name': 'Attachment'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.message': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Message'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'text': ('django.db.models.fields.TextField', [], {}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['oscar_support.Ticket']"}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "u'public'", 'max_length': '30'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.priority': {
- 'Meta': {'object_name': 'Priority'},
- 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorder': {
- 'Meta': {'object_name': 'RelatedOrder'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_orders'", 'to': u"orm['order.Order']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorderline': {
- 'Meta': {'object_name': 'RelatedOrderLine'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'line': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_order_lines'", 'to': u"orm['order.Line']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedproduct': {
- 'Meta': {'object_name': 'RelatedProduct'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_products'", 'to': u"orm['catalogue.Product']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticket': {
- 'Meta': {'ordering': "['-date_updated']", 'unique_together': "(('number', 'subticket_id'),)", 'object_name': 'Ticket'},
- 'assigned_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['auth.Group']"}),
- 'assignee': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'assigned_tickets'", 'null': 'True', 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'body': ('django.db.models.fields.TextField', [], {}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'is_internal': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '64', 'db_index': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subtickets'", 'null': 'True', 'to': u"orm['oscar_support.Ticket']"}),
- 'priority': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['oscar_support.Priority']"}),
- 'related_lines': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrderLine']", 'to': u"orm['order.Line']"}),
- 'related_orders': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrder']", 'to': u"orm['order.Order']"}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedProduct']", 'to': u"orm['catalogue.Product']"}),
- 'requester': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'submitted_tickets'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketStatus']"}),
- 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'subticket_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketType']"}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticketstatus': {
- 'Meta': {'object_name': 'TicketStatus'},
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.tickettype': {
- 'Meta': {'object_name': 'TicketType'},
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'partner.partner': {
- 'Meta': {'object_name': 'Partner'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'users': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'partners'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['{0}']".format(AUTH_USER_MODEL)})
- },
- u'partner.stockrecord': {
- 'Meta': {'unique_together': "(('partner', 'partner_sku'),)", 'object_name': 'StockRecord'},
- 'cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'low_stock_threshold': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_allocated': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_in_stock': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['partner.Partner']"}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'price_currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'price_retail': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['catalogue.Product']"})
- },
- u'sites.site': {
- 'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
- 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- }
- }
-
- complete_apps = ['oscar_support']
\ No newline at end of file
diff --git a/oscar_support/migrations/0004_populate_slug_fields.py b/oscar_support/migrations/0004_populate_slug_fields.py
deleted file mode 100644
index cd5ea4f..0000000
--- a/oscar_support/migrations/0004_populate_slug_fields.py
+++ /dev/null
@@ -1,382 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import DataMigration
-from django.db import models
-
-from oscar.core.compat import AUTH_USER_MODEL, AUTH_USER_MODEL_NAME
-
-
-class Migration(DataMigration):
-
- def forwards(self, orm):
- "Write your forwards methods here."
- for ticket_type in orm['oscar_support.TicketType'].objects.filter(slug=''):
- # AutoSlugField will create a slug based on the name
- ticket_type.save()
-
- for ticket_status in orm['oscar_support.TicketStatus'].objects.filter(slug=''):
- # AutoSlugField will create a slug based on the name
- ticket_status.save()
-
- def backwards(self, orm):
- "Write your backwards methods here."
- pass
-
- models = {
- u'address.country': {
- 'Meta': {'ordering': "('-display_order', 'name')", 'object_name': 'Country'},
- 'display_order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0', 'db_index': 'True'}),
- 'is_shipping_country': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'iso_3166_1_a2': ('django.db.models.fields.CharField', [], {'max_length': '2', 'primary_key': 'True'}),
- 'iso_3166_1_a3': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'db_index': 'True'}),
- 'iso_3166_1_numeric': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'db_index': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'printable_name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'auth.group': {
- 'Meta': {'object_name': 'Group'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
- 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
- },
- u'auth.permission': {
- 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
- 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- },
- AUTH_USER_MODEL: {
- 'Meta': {'object_name': AUTH_USER_MODEL_NAME},
- 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
- 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
- },
- u'catalogue.attributeentity': {
- 'Meta': {'object_name': 'AttributeEntity'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'entities'", 'to': u"orm['catalogue.AttributeEntityType']"})
- },
- u'catalogue.attributeentitytype': {
- 'Meta': {'object_name': 'AttributeEntityType'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'})
- },
- u'catalogue.attributeoption': {
- 'Meta': {'object_name': 'AttributeOption'},
- 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'options'", 'to': u"orm['catalogue.AttributeOptionGroup']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'option': ('django.db.models.fields.CharField', [], {'max_length': '255'})
- },
- u'catalogue.attributeoptiongroup': {
- 'Meta': {'object_name': 'AttributeOptionGroup'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'catalogue.category': {
- 'Meta': {'ordering': "['full_name']", 'object_name': 'Category'},
- 'depth': ('django.db.models.fields.PositiveIntegerField', [], {}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'full_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- 'numchild': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'})
- },
- u'catalogue.option': {
- 'Meta': {'object_name': 'Option'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'Required'", 'max_length': '128'})
- },
- u'catalogue.product': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Product'},
- 'attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.ProductAttribute']", 'through': u"orm['catalogue.ProductAttributeValue']", 'symmetrical': 'False'}),
- 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Category']", 'through': u"orm['catalogue.ProductCategory']", 'symmetrical': 'False'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_discountable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'variants'", 'null': 'True', 'to': u"orm['catalogue.Product']"}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'products'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'product_options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'rating': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
- 'recommended_products': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Product']", 'symmetrical': 'False', 'through': u"orm['catalogue.ProductRecommendation']", 'blank': 'True'}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'relations'", 'blank': 'True', 'to': u"orm['catalogue.Product']"}),
- 'score': ('django.db.models.fields.FloatField', [], {'default': '0.0', 'db_index': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
- 'status': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productattribute': {
- 'Meta': {'ordering': "['code']", 'object_name': 'ProductAttribute'},
- 'code': ('django.db.models.fields.SlugField', [], {'max_length': '128'}),
- 'entity_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntityType']", 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'option_group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOptionGroup']", 'null': 'True', 'blank': 'True'}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attributes'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'text'", 'max_length': '20'})
- },
- u'catalogue.productattributevalue': {
- 'Meta': {'object_name': 'ProductAttributeValue'},
- 'attribute': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.ProductAttribute']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_values'", 'to': u"orm['catalogue.Product']"}),
- 'value_boolean': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
- 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- 'value_entity': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntity']", 'null': 'True', 'blank': 'True'}),
- 'value_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'value_float': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
- 'value_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'value_integer': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'value_option': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOption']", 'null': 'True', 'blank': 'True'}),
- 'value_richtext': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'value_text': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productcategory': {
- 'Meta': {'ordering': "['-is_canonical']", 'object_name': 'ProductCategory'},
- 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Category']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_canonical': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'catalogue.productclass': {
- 'Meta': {'ordering': "['name']", 'object_name': 'ProductClass'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'requires_shipping': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- 'track_stock': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
- },
- u'catalogue.productrecommendation': {
- 'Meta': {'object_name': 'ProductRecommendation'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'primary': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'primary_recommendations'", 'to': u"orm['catalogue.Product']"}),
- 'ranking': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}),
- 'recommendation': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'contenttypes.contenttype': {
- 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
- 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
- },
- u'order.billingaddress': {
- 'Meta': {'object_name': 'BillingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'order.line': {
- 'Meta': {'object_name': 'Line'},
- 'est_dispatch_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'line_price_before_discounts_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_before_discounts_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'lines'", 'to': u"orm['order.Order']"}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'order_lines'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['partner.Partner']"}),
- 'partner_line_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'partner_line_reference': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'partner_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'quantity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'stockrecord': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['partner.StockRecord']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'unit_cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_retail_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'})
- },
- u'order.order': {
- 'Meta': {'ordering': "['-date_placed']", 'object_name': 'Order'},
- 'basket_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'billing_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.BillingAddress']", 'null': 'True', 'blank': 'True'}),
- 'currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'date_placed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'guest_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
- 'shipping_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.ShippingAddress']", 'null': 'True', 'blank': 'True'}),
- 'shipping_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
- 'shipping_excl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_incl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_method': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['sites.Site']"}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
- 'total_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'total_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'orders'", 'null': 'True', 'to': u"orm['{0}']".format(AUTH_USER_MODEL)})
- },
- u'order.shippingaddress': {
- 'Meta': {'object_name': 'ShippingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'phone_number': ('oscar.models.fields.PhoneNumberField', [], {'max_length': '128', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'oscar_support.attachment': {
- 'Meta': {'object_name': 'Attachment'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.message': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Message'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'text': ('django.db.models.fields.TextField', [], {}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['oscar_support.Ticket']"}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "u'public'", 'max_length': '30'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.priority': {
- 'Meta': {'object_name': 'Priority'},
- 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorder': {
- 'Meta': {'object_name': 'RelatedOrder'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_orders'", 'to': u"orm['order.Order']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorderline': {
- 'Meta': {'object_name': 'RelatedOrderLine'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'line': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_order_lines'", 'to': u"orm['order.Line']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedproduct': {
- 'Meta': {'object_name': 'RelatedProduct'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_products'", 'to': u"orm['catalogue.Product']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticket': {
- 'Meta': {'ordering': "['-date_updated']", 'unique_together': "(('number', 'subticket_id'),)", 'object_name': 'Ticket'},
- 'assigned_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['auth.Group']"}),
- 'assignee': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'assigned_tickets'", 'null': 'True', 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'body': ('django.db.models.fields.TextField', [], {}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'is_internal': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '64', 'db_index': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subtickets'", 'null': 'True', 'to': u"orm['oscar_support.Ticket']"}),
- 'priority': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['oscar_support.Priority']"}),
- 'related_lines': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrderLine']", 'to': u"orm['order.Line']"}),
- 'related_orders': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrder']", 'to': u"orm['order.Order']"}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedProduct']", 'to': u"orm['catalogue.Product']"}),
- 'requester': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'submitted_tickets'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketStatus']"}),
- 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'subticket_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketType']"}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticketstatus': {
- 'Meta': {'object_name': 'TicketStatus'},
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.tickettype': {
- 'Meta': {'object_name': 'TicketType'},
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'partner.partner': {
- 'Meta': {'object_name': 'Partner'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'users': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'partners'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['{0}']".format(AUTH_USER_MODEL)})
- },
- u'partner.stockrecord': {
- 'Meta': {'unique_together': "(('partner', 'partner_sku'),)", 'object_name': 'StockRecord'},
- 'cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'low_stock_threshold': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_allocated': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_in_stock': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['partner.Partner']"}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'price_currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'price_retail': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['catalogue.Product']"})
- },
- u'sites.site': {
- 'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
- 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- }
- }
-
- complete_apps = ['oscar_support']
- symmetrical = True
diff --git a/oscar_support/migrations/0005_auto__add_unique_tickettype_slug__del_unique_tickettype_name__add_uniq.py b/oscar_support/migrations/0005_auto__add_unique_tickettype_slug__del_unique_tickettype_name__add_uniq.py
deleted file mode 100644
index bf8ae0f..0000000
--- a/oscar_support/migrations/0005_auto__add_unique_tickettype_slug__del_unique_tickettype_name__add_uniq.py
+++ /dev/null
@@ -1,394 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-from oscar.core.compat import AUTH_USER_MODEL, AUTH_USER_MODEL_NAME
-
-
-class Migration(SchemaMigration):
-
- def forwards(self, orm):
- # Removing unique constraint on 'TicketStatus', fields ['name']
- db.delete_unique(u'oscar_support_ticketstatus', ['name'])
-
- # Removing unique constraint on 'TicketType', fields ['name']
- db.delete_unique(u'oscar_support_tickettype', ['name'])
-
- # Adding unique constraint on 'TicketType', fields ['slug']
- db.create_unique(u'oscar_support_tickettype', ['slug'])
-
- # Adding unique constraint on 'TicketStatus', fields ['slug']
- db.create_unique(u'oscar_support_ticketstatus', ['slug'])
-
- def backwards(self, orm):
- # Removing unique constraint on 'TicketStatus', fields ['slug']
- db.delete_unique(u'oscar_support_ticketstatus', ['slug'])
-
- # Removing unique constraint on 'TicketType', fields ['slug']
- db.delete_unique(u'oscar_support_tickettype', ['slug'])
-
- # Adding unique constraint on 'TicketType', fields ['name']
- db.create_unique(u'oscar_support_tickettype', ['name'])
-
- # Adding unique constraint on 'TicketStatus', fields ['name']
- db.create_unique(u'oscar_support_ticketstatus', ['name'])
-
-
- models = {
- u'address.country': {
- 'Meta': {'ordering': "('-display_order', 'name')", 'object_name': 'Country'},
- 'display_order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0', 'db_index': 'True'}),
- 'is_shipping_country': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'iso_3166_1_a2': ('django.db.models.fields.CharField', [], {'max_length': '2', 'primary_key': 'True'}),
- 'iso_3166_1_a3': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'db_index': 'True'}),
- 'iso_3166_1_numeric': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'db_index': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'printable_name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'auth.group': {
- 'Meta': {'object_name': 'Group'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
- 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
- },
- u'auth.permission': {
- 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
- 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- },
- AUTH_USER_MODEL: {
- 'Meta': {'object_name': AUTH_USER_MODEL_NAME},
- 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
- 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
- },
- u'catalogue.attributeentity': {
- 'Meta': {'object_name': 'AttributeEntity'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'entities'", 'to': u"orm['catalogue.AttributeEntityType']"})
- },
- u'catalogue.attributeentitytype': {
- 'Meta': {'object_name': 'AttributeEntityType'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'})
- },
- u'catalogue.attributeoption': {
- 'Meta': {'object_name': 'AttributeOption'},
- 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'options'", 'to': u"orm['catalogue.AttributeOptionGroup']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'option': ('django.db.models.fields.CharField', [], {'max_length': '255'})
- },
- u'catalogue.attributeoptiongroup': {
- 'Meta': {'object_name': 'AttributeOptionGroup'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
- },
- u'catalogue.category': {
- 'Meta': {'ordering': "['full_name']", 'object_name': 'Category'},
- 'depth': ('django.db.models.fields.PositiveIntegerField', [], {}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'full_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
- 'numchild': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'})
- },
- u'catalogue.option': {
- 'Meta': {'object_name': 'Option'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'Required'", 'max_length': '128'})
- },
- u'catalogue.product': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Product'},
- 'attributes': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.ProductAttribute']", 'through': u"orm['catalogue.ProductAttributeValue']", 'symmetrical': 'False'}),
- 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Category']", 'through': u"orm['catalogue.ProductCategory']", 'symmetrical': 'False'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_discountable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'variants'", 'null': 'True', 'to': u"orm['catalogue.Product']"}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'products'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'product_options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'rating': ('django.db.models.fields.FloatField', [], {'null': 'True'}),
- 'recommended_products': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Product']", 'symmetrical': 'False', 'through': u"orm['catalogue.ProductRecommendation']", 'blank': 'True'}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'relations'", 'blank': 'True', 'to': u"orm['catalogue.Product']"}),
- 'score': ('django.db.models.fields.FloatField', [], {'default': '0.0', 'db_index': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
- 'status': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productattribute': {
- 'Meta': {'ordering': "['code']", 'object_name': 'ProductAttribute'},
- 'code': ('django.db.models.fields.SlugField', [], {'max_length': '128'}),
- 'entity_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntityType']", 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'option_group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOptionGroup']", 'null': 'True', 'blank': 'True'}),
- 'product_class': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attributes'", 'null': 'True', 'to': u"orm['catalogue.ProductClass']"}),
- 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "'text'", 'max_length': '20'})
- },
- u'catalogue.productattributevalue': {
- 'Meta': {'object_name': 'ProductAttributeValue'},
- 'attribute': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.ProductAttribute']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_values'", 'to': u"orm['catalogue.Product']"}),
- 'value_boolean': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
- 'value_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- 'value_entity': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeEntity']", 'null': 'True', 'blank': 'True'}),
- 'value_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'value_float': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
- 'value_image': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'value_integer': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'value_option': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.AttributeOption']", 'null': 'True', 'blank': 'True'}),
- 'value_richtext': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'value_text': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
- },
- u'catalogue.productcategory': {
- 'Meta': {'ordering': "['-is_canonical']", 'object_name': 'ProductCategory'},
- 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Category']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_canonical': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'catalogue.productclass': {
- 'Meta': {'ordering': "['name']", 'object_name': 'ProductClass'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'options': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['catalogue.Option']", 'symmetrical': 'False', 'blank': 'True'}),
- 'requires_shipping': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- 'track_stock': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
- },
- u'catalogue.productrecommendation': {
- 'Meta': {'object_name': 'ProductRecommendation'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'primary': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'primary_recommendations'", 'to': u"orm['catalogue.Product']"}),
- 'ranking': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}),
- 'recommendation': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']"})
- },
- u'contenttypes.contenttype': {
- 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
- 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
- },
- u'order.billingaddress': {
- 'Meta': {'object_name': 'BillingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'order.line': {
- 'Meta': {'object_name': 'Line'},
- 'est_dispatch_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'line_price_before_discounts_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_before_discounts_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'line_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'lines'", 'to': u"orm['order.Order']"}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'order_lines'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['partner.Partner']"}),
- 'partner_line_notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'partner_line_reference': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'partner_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Product']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'quantity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'stockrecord': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['partner.StockRecord']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'unit_cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_price_incl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'unit_retail_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'upc': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'})
- },
- u'order.order': {
- 'Meta': {'ordering': "['-date_placed']", 'object_name': 'Order'},
- 'basket_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'billing_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.BillingAddress']", 'null': 'True', 'blank': 'True'}),
- 'currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'date_placed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
- 'guest_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
- 'shipping_address': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['order.ShippingAddress']", 'null': 'True', 'blank': 'True'}),
- 'shipping_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
- 'shipping_excl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_incl_tax': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '12', 'decimal_places': '2'}),
- 'shipping_method': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['sites.Site']"}),
- 'status': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
- 'total_excl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'total_incl_tax': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'orders'", 'null': 'True', 'to': u"orm['{0}']".format(AUTH_USER_MODEL)})
- },
- u'order.shippingaddress': {
- 'Meta': {'object_name': 'ShippingAddress'},
- 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['address.Country']"}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
- 'line1': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'line2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line3': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'line4': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'phone_number': ('oscar.models.fields.PhoneNumberField', [], {'max_length': '128', 'blank': 'True'}),
- 'postcode': ('oscar.models.fields.UppercaseCharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
- 'search_text': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
- 'state': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'})
- },
- u'oscar_support.attachment': {
- 'Meta': {'object_name': 'Attachment'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.message': {
- 'Meta': {'ordering': "['-date_created']", 'object_name': 'Message'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'text': ('django.db.models.fields.TextField', [], {}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['oscar_support.Ticket']"}),
- 'type': ('django.db.models.fields.CharField', [], {'default': "u'public'", 'max_length': '30'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.priority': {
- 'Meta': {'object_name': 'Priority'},
- 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorder': {
- 'Meta': {'object_name': 'RelatedOrder'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_orders'", 'to': u"orm['order.Order']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorders'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedorderline': {
- 'Meta': {'object_name': 'RelatedOrderLine'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'line': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_order_lines'", 'to': u"orm['order.Line']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedorderlines'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.relatedproduct': {
- 'Meta': {'object_name': 'RelatedProduct'},
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ticket_related_products'", 'to': u"orm['catalogue.Product']"}),
- 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['oscar_support.Ticket']"}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'relatedproducts'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticket': {
- 'Meta': {'ordering': "['-date_updated']", 'unique_together': "(('number', 'subticket_id'),)", 'object_name': 'Ticket'},
- 'assigned_group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['auth.Group']"}),
- 'assignee': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'assigned_tickets'", 'null': 'True', 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'body': ('django.db.models.fields.TextField', [], {}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {}),
- 'is_internal': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'number': ('django.db.models.fields.CharField', [], {'max_length': '64', 'db_index': 'True'}),
- 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subtickets'", 'null': 'True', 'to': u"orm['oscar_support.Ticket']"}),
- 'priority': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'tickets'", 'null': 'True', 'to': u"orm['oscar_support.Priority']"}),
- 'related_lines': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrderLine']", 'to': u"orm['order.Line']"}),
- 'related_orders': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedOrder']", 'to': u"orm['order.Order']"}),
- 'related_products': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'tickets'", 'blank': 'True', 'through': u"orm['oscar_support.RelatedProduct']", 'to': u"orm['catalogue.Product']"}),
- 'requester': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'submitted_tickets'", 'to': u"orm['{0}']".format(AUTH_USER_MODEL)}),
- 'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketStatus']"}),
- 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- 'subticket_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
- 'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': u"orm['oscar_support.TicketType']"}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.ticketstatus': {
- 'Meta': {'object_name': 'TicketStatus'},
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'unique': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'oscar_support.tickettype': {
- 'Meta': {'object_name': 'TicketType'},
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
- 'slug': ('django_extensions.db.fields.AutoSlugField', [], {'allow_duplicates': 'False', 'max_length': '50', 'separator': "u'-'", 'blank': 'True', 'unique': 'True', 'populate_from': "'name'", 'overwrite': 'False'}),
- 'uuid': ('shortuuidfield.fields.ShortUUIDField', [], {'max_length': '22', 'primary_key': 'True'})
- },
- u'partner.partner': {
- 'Meta': {'object_name': 'Partner'},
- 'code': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '128'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
- 'users': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'partners'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['{0}']".format(AUTH_USER_MODEL)})
- },
- u'partner.stockrecord': {
- 'Meta': {'unique_together': "(('partner', 'partner_sku'),)", 'object_name': 'StockRecord'},
- 'cost_price': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'date_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'low_stock_threshold': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_allocated': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'num_in_stock': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'partner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['partner.Partner']"}),
- 'partner_sku': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'price_currency': ('django.db.models.fields.CharField', [], {'default': "'GBP'", 'max_length': '12'}),
- 'price_excl_tax': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'price_retail': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '12', 'decimal_places': '2', 'blank': 'True'}),
- 'product': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stockrecords'", 'to': u"orm['catalogue.Product']"})
- },
- u'sites.site': {
- 'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
- 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- }
- }
-
- complete_apps = ['oscar_support']
\ No newline at end of file
diff --git a/oscar_support/mixins.py b/oscar_support/mixins.py
index d44e2b8..972154e 100644
--- a/oscar_support/mixins.py
+++ b/oscar_support/mixins.py
@@ -4,8 +4,8 @@
class ModificationTrackingMixin(models.Model):
- date_created = models.DateTimeField(_("Created"))
- date_updated = models.DateTimeField(_("Last modified"))
+ date_created = models.DateTimeField(_("Created"), blank=True)
+ date_updated = models.DateTimeField(_("Last modified"), blank=True)
def save(self, *args, **kwargs):
if not self.date_created:
diff --git a/oscar_support/static/oscar_support/js/dashboard.js b/oscar_support/static/oscar_support/js/dashboard.js
deleted file mode 100644
index 9110086..0000000
--- a/oscar_support/static/oscar_support/js/dashboard.js
+++ /dev/null
@@ -1,50 +0,0 @@
-var support = support || {};
-support.dashboard = {
- init: function () {},
- initAutoComplete: function () {
- $('.autocomplete-ajax-field').select2({
- minimumInputLength: 3,
- query: function (options) {
- var apiUrl = $(this)[0].element.data('source-url');
- var results = [];
-
- $.ajax({
- url: apiUrl,
- dataType: 'json',
- data: {
- filter: options.term,
- },
- success: function (data) {
- $.each(data, function (key, obj) {
- results.push({
- id: obj.id,
- text: obj.display_text,
- });
- });
- options.callback({more: false, results: results});
- }
- });
- },
- /**
- * Initialise the select2 element with the ID in the value. This
- * requests the corresponding entity (given bey the source URL with
- * the specified ID and passes the returned object to select2.
- * If no value is present, the lookup is ignored.
- *
- */
- initSelection: function (element, callback) {
- var elemValue = $(element).val();
- if (elemValue === null) {
- return;
- }
- $.ajax({
- url: $(element).data('source-url') + elemValue + '/',
- dataType: 'json',
- success: function (data) {
- callback({id: data.id, text: data.display_text});
- }
- });
- }
- });
- }
-};
diff --git a/oscar_support/static/oscar_support/less/support.less b/oscar_support/static/oscar_support/less/support.less
deleted file mode 100644
index df902a8..0000000
--- a/oscar_support/static/oscar_support/less/support.less
+++ /dev/null
@@ -1,154 +0,0 @@
-.ticket-list {
- .well {
- margin-bottom:0;
- border-top-width:0;
- border-color:#e2e2e2;
- position: relative;
- &:first-child {
- border-top-width:1px;
- }
- &:nth-child(odd) {
- background:#fff;
- }
- &:hover {
- background:#f1faff;
- }
- }
- .well.active {
- background:#f1faff;
- &:after {
- border-bottom: 10px solid transparent;
- border-left: 10px solid #f1faff;
- border-top: 10px solid transparent;
- content: "";
- display: inline-block;
- position: absolute;
- right: -10px;
- top: 40px;
- }
- &:before {
- border-bottom: 11px solid transparent;
- border-left: 11px solid #bbb;
- border-top: 11px solid transparent;
- content: "";
- display: inline-block;
- position: absolute;
- right: -11px;
- top: 39px;
- }
- }
-}
-.ticket-messages {
- .well {
- border-left-width:0;
- border-right-width:0;
- background-color:#fff;
- border-color:#e2e2e2;
- font-size: 1.2em;
-
- &:hover {
- background-color:#fff;
- }
- ul, ul>li {
- margin-left: 0;
- }
- ul>li {
- list-style-type: none;
- }
- }
- .internal-message {
- background:#f1faff;
- &:nth-child(odd) {
- background:#f1faff;
- }
- }
-}
-.form-assigned {
- .control-label {
- text-align:right;
- }
-}
-.ticket-message {
- ul {
- margin:0;
- }
- li {
- display:inline-block;
- }
-}
-:root .ticket-message {
- input[type=radio] {
- position: absolute;
- clip: rect(0,0,0,0);
- }
- input[type=radio] ~ label {
- font-size: 12px;
- font-weight: bold;
- display: inline-block;
- padding: 4px 14px;
- margin-bottom: 0;
- line-height: 20px;
- text-align: center;
- vertical-align: middle;
- cursor: pointer;
- color: #fff;
- border: 1px solid #BBB;
- border-bottom-color: #A2A2A2;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- background-color: #006FB5;
- background-image: -moz-linear-gradient(top, #0083C9, #005096);
- background-image: -ms-linear-gradient(top, #0083C9, #005096);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0083C9), to(#005096));
- background-image: -webkit-linear-gradient(top, #0083C9, #005096);
- background-image: -o-linear-gradient(top, #0083C9, #005096);
- background-image: linear-gradient(top, #0083C9, #005096);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0083c9', endColorstr='#005096', GradientType=0);
- border-color: #005096 #005096 #00274A;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- filter: progid:dximagetransform.microsoft.gradient(enabled=false);
- }
- input[type=radio]:checked ~ label {
- background-color: #005096;
- background-image: none;
- outline: 0;
- -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- }
- textarea {
- width: 99%;
- height: 150px;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- }
-}
-
-.status-dropdown-button {
- width: 100%;
- border: none;
-}
-
-.ticket-message-fields {
- padding-right: 30px;
- input {
- width: 100%;
- }
- textarea {
- width: 100%;
- height: 200px;
- }
-}
-
-.ticket-property-fields {
- input, select {
- width: 100%;
- }
-}
-
diff --git a/oscar_support/static/oscar_support/lib/less/less-1.4.1.min.js b/oscar_support/static/oscar_support/lib/less/less-1.4.1.min.js
deleted file mode 100644
index 5aaea85..0000000
--- a/oscar_support/static/oscar_support/lib/less/less-1.4.1.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * LESS - Leaner CSS v1.4.1
- * http://lesscss.org
- *
- * Copyright (c) 2009-2013, Alexis Sellier
- * Licensed under the Apache 2.0 License.
- *
- * @licence
- */(function(e,t){function n(t){return e.less[t.split("/")[1]]}function f(){r.env==="development"?(r.optimization=0,r.watchTimer=setInterval(function(){r.watchMode&&g(function(e,t,n,i,s){e?k(e,i.href):t&&S(t.toCSS(r),i,s.lastModified)})},r.poll)):r.optimization=3}function m(){var e=document.getElementsByTagName("style");for(var t=0;t0&&(s.splice(o-1,2),o-=2)}return i.hostPart=r[1],i.directories=s,i.path=r[1]+s.join("/"),i.fileUrl=i.path+(r[4]||""),i.url=i.fileUrl+(r[5]||""),i}function w(t,n,i,s){var o=b(t.href,e.location.href),u=o.url,a=l&&l.getItem(u),f=l&&l.getItem(u+":timestamp"),c={css:a,timestamp:f},h,p={relativeUrls:r.relativeUrls,currentDirectory:o.path,filename:u};t instanceof r.tree.parseEnv?(h=new r.tree.parseEnv(t),p.entryPath=h.currentFileInfo.entryPath,p.rootpath=h.currentFileInfo.rootpath,p.rootFilename=h.currentFileInfo.rootFilename):(h=new r.tree.parseEnv(r),h.mime=t.type,p.entryPath=o.path,p.rootpath=r.rootpath||o.path,p.rootFilename=u),h.relativeUrls&&(r.rootpath?p.rootpath=b(r.rootpath+y(o.path,p.entryPath)).path:p.rootpath=o.path),x(u,t.type,function(e,a){v+=e.replace(/@import .+?;/ig,"");if(!i&&c&&a&&(new Date(a)).valueOf()===(new Date(c.timestamp)).valueOf())S(c.css,t),n(null,null,e,t,{local:!0,remaining:s},u);else try{h.contents[u]=e,h.paths=[o.path],h.currentFileInfo=p,(new r.Parser(h)).parse(e,function(r,i){if(r)return n(r,null,null,t);try{n(r,i,e,t,{local:!1,lastModified:a,remaining:s},u),h.currentFileInfo.rootFilename===u&&N(document.getElementById("less-error-message:"+E(u)))}catch(r){n(r,null,null,t)}})}catch(f){n(f,null,null,t)}},function(e,r){n({type:"File",message:"'"+r+"' wasn't found ("+e+")"},null,null,t)})}function E(e){return e.replace(/^[a-z-]+:\/+?[^\/]+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function S(e,t,n){var r=t.href||"",i="less:"+(t.title||E(r)),s=document.getElementById(i),o=!1,u=document.createElement("style");u.setAttribute("type","text/css"),t.media&&u.setAttribute("media",t.media),u.id=i;if(u.styleSheet)try{u.styleSheet.cssText=e}catch(a){throw new Error("Couldn't reassign styleSheet.cssText.")}else u.appendChild(document.createTextNode(e)),o=s!==null&&s.childNodes.length>0&&u.childNodes.length>0&&s.firstChild.nodeValue===u.firstChild.nodeValue;var f=document.getElementsByTagName("head")[0];if(s==null||o===!1){var c=t&&t.nextSibling||null;(c||document.getElementsByTagName("head")[0]).parentNode.insertBefore(u,c)}s&&o===!1&&f.removeChild(s);if(n&&l){C("saving "+r+" to cache.");try{l.setItem(r,e),l.setItem(r+":timestamp",n)}catch(a){C("failed to save")}}}function x(e,t,n,i){function a(t,n,r){t.status>=200&&t.status<300?n(t.responseText,t.getResponseHeader("Last-Modified")):typeof r=="function"&&r(t.status,e)}var s=T(),u=o?r.fileAsync:r.async;typeof s.overrideMimeType=="function"&&s.overrideMimeType("text/css"),s.open("GET",e,u),s.setRequestHeader("Accept",t||"text/x-less, text/css; q=0.9, */*; q=0.5"),s.send(null),o&&!r.fileAsync?s.status===0||s.status>=200&&s.status<300?n(s.responseText):i(s.status,e):u?s.onreadystatechange=function(){s.readyState==4&&a(s,n,i)}:a(s,n,i)}function T(){if(e.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(t){return C("browser doesn't support AJAX."),null}}function N(e){return e&&e.parentNode.removeChild(e)}function C(e){r.env=="development"&&typeof console!="undefined"&&console.log("less: "+e)}function k(e,n){var i="less-error-message:"+E(n||""),s='{line} {content} ',o=document.createElement("div"),u,a,f=[],l=e.filename||n,c=l.match(/([^\/]+(\?.*)?)$/)[1];o.id=i,o.className="less-error-message",a=""+(e.type||"Syntax")+"Error: "+(e.message||"There is an error in your .less file")+" "+'in '+c+" ";var h=function(e,n,r){e.extract[n]!=t&&f.push(s.replace(/\{line\}/,(parseInt(e.line)||0)+(n-1)).replace(/\{class\}/,r).replace(/\{content\}/,e.extract[n]))};e.extract?(h(e,0,""),h(e,1,"line"),h(e,2,""),a+="on line "+e.line+", column "+(e.column+1)+":
"+""):e.stack&&(a+=" "+e.stack.split("\n").slice(1).join(" ")),o.innerHTML=a,S([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),o.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),r.env=="development"&&(u=setInterval(function(){document.body&&(document.getElementById(i)?document.body.replaceChild(o,document.getElementById(i)):document.body.insertBefore(o,document.body.firstChild),clearInterval(u))},10))}var r,i,s;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(typeof e=="undefined"?r={}:r=e.less={},i=r.tree={},r.mode="rhino"):typeof e=="undefined"?(r=exports,i=n("./tree"),r.mode="node"):(typeof e.less=="undefined"&&(e.less={}),r=e.less,i=e.less.tree={},r.mode="browser"),r.Parser=function(t){function m(){a=c[u],f=o,h=o}function g(){c[u]=a,o=f,h=o}function y(){o>h&&(c[u]=c[u].slice(o-h),h=o)}function b(e){var t=e.charCodeAt(0);return t===32||t===10||t===9}function w(e){var t,n,r,i,a;if(e instanceof Function)return e.call(p.parsers);if(typeof e=="string")t=s.charAt(o)===e?e:null,r=1,y();else{y();if(!(t=e.exec(c[u])))return null;r=t[0].length}if(t)return E(r),typeof t=="string"?t:t.length===1?t[0]:t}function E(e){var t=o,n=u,r=o+c[u].length,i=o+=e;while(o=0&&t.charAt(n)!=="\n";n--)r++;return{line:typeof e=="number"?(t.slice(0,e).match(/\n/g)||"").length:null,column:r}}function k(e,t,i){var s=i.currentFileInfo.filename;return r.mode!=="browser"&&r.mode!=="rhino"&&(s=n("path").resolve(s)),{lineNumber:C(e,t).line+1,fileName:s}}function L(e,t){var n=N(e,t),r=C(e.index,n),i=r.line,s=r.column,o=n.split("\n");this.type=e.type||"Syntax",this.message=e.message,this.filename=e.filename||t.currentFileInfo.filename,this.index=e.index,this.line=typeof i=="number"?i+1:null,this.callLine=e.call&&C(e.call,n).line+1,this.callExtract=o[C(e.call,n).line],this.stack=e.stack,this.column=s,this.extract=[o[i-1],o[i],o[i+1]]}var s,o,u,a,f,l,c,h,p,d=this;t instanceof i.parseEnv||(t=new i.parseEnv(t));var v=this.imports={paths:t.paths||[],queue:[],files:t.files,contents:t.contents,mime:t.mime,error:null,push:function(e,n,i){var s=this;this.queue.push(e),r.Parser.importer(e,n,function(t,n,r){s.queue.splice(s.queue.indexOf(e),1);var o=r in s.files;s.files[r]=n,t&&!s.error&&(s.error=t),i(t,n,o)},t)}};return L.prototype=new Error,L.prototype.constructor=L,this.env=t=t||{},this.optimization="optimization"in this.env?this.env.optimization:1,p={imports:v,parse:function(e,a){var f,d,v,m,g,y,b=[],E,S=null;o=u=h=l=0,s=e.replace(/\r\n/g,"\n"),s=s.replace(/^\uFEFF/,""),c=function(e){var n=0,r=/(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,i=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,o=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,u=0,a,f=e[0],l;for(var c=0,h,p;c0?"missing closing `}`":"missing opening `{`",filename:t.currentFileInfo.filename},t)),e.map(function(e){return e.join("")})}([[]]);if(S)return a(new L(S,t));try{f=new i.Ruleset([],w(this.parsers.primary)),f.root=!0,f.firstRoot=!0}catch(x){return a(new L(x,t))}f.toCSS=function(e){var s,o,u;return function(s,o){s=s||{};var u,a=new i.evalEnv(s);typeof o=="object"&&!Array.isArray(o)&&(o=Object.keys(o).map(function(e){var t=o[e];return t instanceof i.Value||(t instanceof i.Expression||(t=new i.Expression([t])),t=new i.Value([t])),new i.Rule("@"+e,t,!1,0)}),a.frames=[new i.Ruleset(null,o)]);try{var f=e.call(this,a);(new i.joinSelectorVisitor).run(f),(new i.processExtendsVisitor).run(f);var l=f.toCSS({compress:Boolean(s.compress),dumpLineNumbers:t.dumpLineNumbers,strictUnits:Boolean(s.strictUnits)})}catch(c){throw new L(c,t)}return s.yuicompress&&r.mode==="node"?n("ycssmin").cssmin(l,s.maxLineLen):s.compress?l.replace(/(\s)+/g,"$1"):l}}(f.eval);if(o=0&&s.charAt(T)!=="\n";T--)N++;S={type:"Parse",message:"Unrecognised input",index:o,filename:t.currentFileInfo.filename,line:g,column:N,extract:[y[g-2],y[g-1],y[g]]}}var C=function(e){e=S||e||p.imports.error,e?(e instanceof L||(e=new L(e,t)),a(e)):a(null,f)};t.processImports!==!1?(new i.importVisitor(this.imports,C)).run(f):C()},parsers:{primary:function(){var e,t=[];while((e=w(this.extendRule)||w(this.mixin.definition)||w(this.rule)||w(this.ruleset)||w(this.mixin.call)||w(this.comment)||w(this.directive))||w(/^[\s\n]+/)||w(/^;+/))e&&t.push(e);return t},comment:function(){var e;if(s.charAt(o)!=="/")return;if(s.charAt(o+1)==="/")return new i.Comment(w(/^\/\/.*/),!0);if(e=w(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new i.Comment(e)},entities:{quoted:function(){var e,n=o,r,u=o;s.charAt(n)==="~"&&(n++,r=!0);if(s.charAt(n)!=='"'&&s.charAt(n)!=="'")return;r&&w("~");if(e=w(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new i.Quoted(e[0],e[1]||e[2],r,u,t.currentFileInfo)},keyword:function(){var e;if(e=w(/^[_A-Za-z-][_A-Za-z0-9-]*/))return i.colors.hasOwnProperty(e)?new i.Color(i.colors[e].slice(1)):new i.Keyword(e)},call:function(){var e,n,r,s,a=o;if(!(e=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(c[u])))return;e=e[1],n=e.toLowerCase();if(n==="url")return null;o+=e.length;if(n==="alpha"){s=w(this.alpha);if(typeof s!="undefined")return s}w("("),r=w(this.entities.arguments);if(!w(")"))return;if(e)return new i.Call(e,r,a,t.currentFileInfo)},arguments:function(){var e=[],t;while(t=w(this.entities.assignment)||w(this.expression)){e.push(t);if(!w(","))break}return e},literal:function(){return w(this.entities.dimension)||w(this.entities.color)||w(this.entities.quoted)||w(this.entities.unicodeDescriptor)},assignment:function(){var e,t;if((e=w(/^\w+(?=\s?=)/i))&&w("=")&&(t=w(this.entity)))return new i.Assignment(e,t)},url:function(){var e;if(s.charAt(o)!=="u"||!w(/^url\(/))return;return e=w(this.entities.quoted)||w(this.entities.variable)||w(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/)||"",S(")"),new i.URL(e.value!=null||e instanceof i.Variable?e:new i.Anonymous(e),t.currentFileInfo)},variable:function(){var e,n=o;if(s.charAt(o)==="@"&&(e=w(/^@@?[\w-]+/)))return new i.Variable(e,n,t.currentFileInfo)},variableCurly:function(){var e,n,r=o;if(s.charAt(o)==="@"&&(n=w(/^@\{([\w-]+)\}/)))return new i.Variable("@"+n[1],r,t.currentFileInfo)},color:function(){var e;if(s.charAt(o)==="#"&&(e=w(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/)))return new i.Color(e[1])},dimension:function(){var e,t=s.charCodeAt(o);if(t>57||t<43||t===47||t==44)return;if(e=w(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/))return new i.Dimension(e[1],e[2])},unicodeDescriptor:function(){var e;if(e=w(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/))return new i.UnicodeDescriptor(e[0])},javascript:function(){var e,t=o,n;s.charAt(t)==="~"&&(t++,n=!0);if(s.charAt(t)!=="`")return;n&&w("~");if(e=w(/^`([^`]*)`/))return new i.JavaScript(e[1],o,n)}},variable:function(){var e;if(s.charAt(o)==="@"&&(e=w(/^(@[\w-]+)\s*:/)))return e[1]},extend:function(e){var t,n,r=o,s,u=[];if(!w(e?/^&:extend\(/:/^:extend\(/))return;do{s=null,t=[];for(;;){s=w(/^(all)(?=\s*(\)|,))/);if(s)break;n=w(this.element);if(!n)break;t.push(n)}s=s&&s[1],u.push(new i.Extend(new i.Selector(t),s,r))}while(w(","));return S(/^\)/),e&&S(/^;/),u},extendRule:function(){return this.extend(!0)},mixin:{call:function(){var e=[],n,r,u,a,f,l=o,c=s.charAt(o),h=!1;if(c!=="."&&c!=="#")return;m();while(n=w(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/))e.push(new i.Element(r,n,o)),r=w(">");w("(")&&(u=this.mixin.args.call(this,!0).args,S(")")),u=u||[],w(this.important)&&(h=!0);if(e.length>0&&(w(";")||T("}")))return new i.mixin.Call(e,u,l,t.currentFileInfo,h);g()},args:function(e){var t=[],n=[],r,u=[],a,f,l,c,h,p={args:null,variadic:!1};for(;;){if(e)h=w(this.expression);else{w(this.comment);if(s.charAt(o)==="."&&w(/^\.{3}/)){p.variadic=!0,w(";")&&!r&&(r=!0),(r?n:u).push({variadic:!0});break}h=w(this.entities.variable)||w(this.entities.literal)||w(this.entities.keyword)}if(!h)break;l=null,h.throwAwayComments&&h.throwAwayComments(),c=h;var d=null;if(e){if(h.value.length==1)var d=h.value[0]}else d=h;if(d&&d instanceof i.Variable)if(w(":"))t.length>0&&(r&&x("Cannot mix ; and , as delimiter types"),a=!0),c=S(this.expression),l=f=d.name;else{if(!e&&w(/^\.{3}/)){p.variadic=!0,w(";")&&!r&&(r=!0),(r?n:u).push({name:h.name,variadic:!0});break}e||(f=l=d.name,c=null)}c&&t.push(c),u.push({name:l,value:c});if(w(","))continue;if(w(";")||r)a&&x("Cannot mix ; and , as delimiter types"),r=!0,t.length>1&&(c=new i.Value(t)),n.push({name:f,value:c}),f=null,t=[],a=!1}return p.args=r?n:u,p},definition:function(){var e,t=[],n,r,u,a,f,c=!1;if(s.charAt(o)!=="."&&s.charAt(o)!=="#"||T(/^[^{]*\}/))return;m();if(n=w(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){e=n[1];var h=this.mixin.args.call(this,!1);t=h.args,c=h.variadic,w(")")||(l=o,g()),w(this.comment),w(/^when/)&&(f=S(this.conditions,"expected condition")),r=w(this.block);if(r)return new i.mixin.Definition(e,t,r,f,c);g()}}},entity:function(){return w(this.entities.literal)||w(this.entities.variable)||w(this.entities.url)||w(this.entities.call)||w(this.entities.keyword)||w(this.entities.javascript)||w(this.comment)},end:function(){return w(";")||T("}")},alpha:function(){var e;if(!w(/^\(opacity=/i))return;if(e=w(/^\d+/)||w(this.entities.variable))return S(")"),new i.Alpha(e)},element:function(){var e,t,n,r;n=w(this.combinator),e=w(/^(?:\d+\.\d+|\d+)%/)||w(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||w("*")||w("&")||w(this.attribute)||w(/^\([^()@]+\)/)||w(/^[\.#](?=@)/)||w(this.entities.variableCurly),e||w("(")&&(r=w(this.selector))&&w(")")&&(e=new i.Paren(r));if(e)return new i.Element(n,e,o)},combinator:function(){var e=s.charAt(o);if(e===">"||e==="+"||e==="~"||e==="|"){o++;while(s.charAt(o).match(/\s/))o++;return new i.Combinator(e)}return s.charAt(o-1).match(/\s/)?new i.Combinator(" "):new i.Combinator(null)},selector:function(){var e,t,n=[],r,u,a=[];while((u=w(this.extend))||(t=w(this.element))){u?a.push.apply(a,u):(a.length&&x("Extend can only be used at the end of selector"),r=s.charAt(o),n.push(t),t=null);if(r==="{"||r==="}"||r===";"||r===","||r===")")break}if(n.length>0)return new i.Selector(n,a);a.length&&x("Extend must be used to extend a selector, it cannot be used on its own")},attribute:function(){var e="",t,n,r;if(!w("["))return;(t=w(this.entities.variableCurly))||(t=S(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/));if(r=w(/^[|~*$^]?=/))n=w(this.entities.quoted)||w(/^[\w-]+/)||w(this.entities.variableCurly);return S("]"),new i.Attribute(t,r,n)},block:function(){var e;if(w("{")&&(e=w(this.primary))&&w("}"))return e},ruleset:function(){var e=[],n,r,u;m(),t.dumpLineNumbers&&(u=k(o,s,t));while(n=w(this.selector)){e.push(n),w(this.comment);if(!w(","))break;w(this.comment)}if(e.length>0&&(r=w(this.block))){var a=new i.Ruleset(e,r,t.strictImports);return t.dumpLineNumbers&&(a.debugInfo=u),a}l=o,g()},rule:function(e){var n,r,u=s.charAt(o),a;m();if(u==="."||u==="#"||u==="&")return;if(n=w(this.variable)||w(this.property)){r=!e&&(t.compress||n.charAt(0)==="@")?w(this.value)||w(this.anonymousValue):w(this.anonymousValue)||w(this.value),a=w(this.important);if(r&&w(this.end))return new i.Rule(n,r,a,f,t.currentFileInfo);l=o,g();if(r&&!e)return this.rule(!0)}},anonymousValue:function(){var e;if(e=/^([^@+\/'"*`(;{}-]*);/.exec(c[u]))return o+=e[0].length-1,new i.Anonymous(e[1])},"import":function(){var e,n,r=o;m();var s=w(/^@import?\s+/),u=(s?w(this.importOptions):null)||{};if(s&&(e=w(this.entities.quoted)||w(this.entities.url))){n=w(this.mediaFeatures);if(w(";"))return n=n&&new i.Value(n),new i.Import(e,n,u,r,t.currentFileInfo)}g()},importOptions:function(){var e,t={},n,r;if(!w("("))return null;do if(e=w(this.importOption)){n=e,r=!0;switch(n){case"css":n="less",r=!1;break;case"once":n="multiple",r=!1}t[n]=r;if(!w(","))break}while(e);return S(")"),t},importOption:function(){var e=w(/^(less|css|multiple|once)/);if(e)return e[1]},mediaFeature:function(){var e,n,r=[];do if(e=w(this.entities.keyword))r.push(e);else if(w("(")){n=w(this.property),e=w(this.value);if(!w(")"))return null;if(n&&e)r.push(new i.Paren(new i.Rule(n,e,null,o,t.currentFileInfo,!0)));else{if(!e)return null;r.push(new i.Paren(e))}}while(e);if(r.length>0)return new i.Expression(r)},mediaFeatures:function(){var e,t=[];do if(e=w(this.mediaFeature)){t.push(e);if(!w(","))break}else if(e=w(this.entities.variable)){t.push(e);if(!w(","))break}while(e);return t.length>0?t:null},media:function(){var e,n,r,u;t.dumpLineNumbers&&(u=k(o,s,t));if(w(/^@media/)){e=w(this.mediaFeatures);if(n=w(this.block))return r=new i.Media(n,e),t.dumpLineNumbers&&(r.debugInfo=u),r}},directive:function(){var e,n,r,u,a,f,l,c,h,p;if(s.charAt(o)!=="@")return;if(n=w(this["import"])||w(this.media))return n;m(),e=w(/^@[a-z-]+/);if(!e)return;l=e,e.charAt(1)=="-"&&e.indexOf("-",2)>0&&(l="@"+e.slice(e.indexOf("-",2)+1));switch(l){case"@font-face":c=!0;break;case"@viewport":case"@top-left":case"@top-left-corner":case"@top-center":case"@top-right":case"@top-right-corner":case"@bottom-left":case"@bottom-left-corner":case"@bottom-center":case"@bottom-right":case"@bottom-right-corner":case"@left-top":case"@left-middle":case"@left-bottom":case"@right-top":case"@right-middle":case"@right-bottom":c=!0;break;case"@page":case"@document":case"@supports":case"@keyframes":c=!0,h=!0;break;case"@namespace":p=!0}h&&(e+=" "+(w(/^[^{]+/)||"").trim());if(c){if(r=w(this.block))return new i.Directive(e,r)}else if((n=p?w(this.expression):w(this.entity))&&w(";")){var d=new i.Directive(e,n);return t.dumpLineNumbers&&(d.debugInfo=k(o,s,t)),d}g()},value:function(){var e,t=[],n;while(e=w(this.expression)){t.push(e);if(!w(","))break}if(t.length>0)return new i.Value(t)},important:function(){if(s.charAt(o)==="!")return w(/^! *important/)},sub:function(){var e,t;if(w("("))if(e=w(this.addition))return t=new i.Expression([e]),S(")"),t.parens=!0,t},multiplication:function(){var e,t,n,r,u,a=[];if(e=w(this.operand)){u=b(s.charAt(o-1));while(!T(/^\/[*\/]/)&&(n=w("/")||w("*"))){if(!(t=w(this.operand)))break;e.parensInOp=!0,t.parensInOp=!0,r=new i.Operation(n,[r||e,t],u),u=b(s.charAt(o-1))}return r||e}},addition:function(){var e,t,n,r,u;if(e=w(this.multiplication)){u=b(s.charAt(o-1));while((n=w(/^[-+]\s+/)||!u&&(w("+")||w("-")))&&(t=w(this.multiplication)))e.parensInOp=!0,t.parensInOp=!0,r=new i.Operation(n,[r||e,t],u),u=b(s.charAt(o-1));return r||e}},conditions:function(){var e,t,n=o,r;if(e=w(this.condition)){while(w(",")&&(t=w(this.condition)))r=new i.Condition("or",r||e,t,n);return r||e}},condition:function(){var e,t,n,r,s=o,u=!1;w(/^not/)&&(u=!0),S("(");if(e=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))return(r=w(/^(?:>=|=<|[<=>])/))?(t=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))?n=new i.Condition(r,e,t,s,u):x("expected expression"):n=new i.Condition("=",e,new i.Keyword("true"),s,u),S(")"),w(/^and/)?new i.Condition("and",n,w(this.condition)):n},operand:function(){var e,t=s.charAt(o+1);s.charAt(o)==="-"&&(t==="@"||t==="(")&&(e=w("-"));var n=w(this.sub)||w(this.entities.dimension)||w(this.entities.color)||w(this.entities.variable)||w(this.entities.call);return e&&(n.parensInOp=!0,n=new i.Negative(n)),n},expression:function(){var e,t,n=[],r;while(e=w(this.addition)||w(this.entity))n.push(e),!T(/^\/[\/*]/)&&(t=w("/"))&&n.push(new i.Anonymous(t));if(n.length>0)return new i.Expression(n)},property:function(){var e;if(e=w(/^(\*?-?[_a-z0-9-]+)\s*:/))return e[1]}}}};if(r.mode==="browser"||r.mode==="rhino")r.Parser.importer=function(e,t,n,r){!/^([a-z-]+:)?\//.test(e)&&t.currentDirectory&&(e=t.currentDirectory+e);var i=r.toSheet(e);i.processImports=!1,i.currentFileInfo=t,w(i,function(e,t,r,i,s,o){n.call(null,e,t,o)},!0)};(function(r){function u(e){return r.functions.hsla(e.h,e.s,e.l,e.a)}function a(e,t){return e instanceof r.Dimension&&e.unit.is("%")?parseFloat(e.value*t/100):f(e)}function f(e){if(e instanceof r.Dimension)return parseFloat(e.unit.is("%")?e.value/100:e.value);if(typeof e=="number")return e;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function l(e){return Math.min(1,Math.max(0,e))}r.functions={rgb:function(e,t,n){return this.rgba(e,t,n,1)},rgba:function(e,t,n,i){var s=[e,t,n].map(function(e){return a(e,256)});return i=f(i),new r.Color(s,i)},hsl:function(e,t,n){return this.hsla(e,t,n,1)},hsla:function(e,t,n,r){function o(e){return e=e<0?e+1:e>1?e-1:e,e*6<1?s+(i-s)*e*6:e*2<1?i:e*3<2?s+(i-s)*(2/3-e)*6:s}e=f(e)%360/360,t=l(f(t)),n=l(f(n)),r=l(f(r));var i=n<=.5?n*(t+1):n+t-n*t,s=n*2-i;return this.rgba(o(e+1/3)*255,o(e)*255,o(e-1/3)*255,r)},hsv:function(e,t,n){return this.hsva(e,t,n,1)},hsva:function(e,t,n,r){e=f(e)%360/360*360,t=f(t),n=f(n),r=f(r);var i,s;i=Math.floor(e/60%6),s=e/60-i;var o=[n,n*(1-t),n*(1-s*t),n*(1-(1-s)*t)],u=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return this.rgba(o[u[i][0]]*255,o[u[i][1]]*255,o[u[i][2]]*255,r)},hue:function(e){return new r.Dimension(Math.round(e.toHSL().h))},saturation:function(e){return new r.Dimension(Math.round(e.toHSL().s*100),"%")},lightness:function(e){return new r.Dimension(Math.round(e.toHSL().l*100),"%")},hsvhue:function(e){return new r.Dimension(Math.round(e.toHSV().h))},hsvsaturation:function(e){return new r.Dimension(Math.round(e.toHSV().s*100),"%")},hsvvalue:function(e){return new r.Dimension(Math.round(e.toHSV().v*100),"%")},red:function(e){return new r.Dimension(e.rgb[0])},green:function(e){return new r.Dimension(e.rgb[1])},blue:function(e){return new r.Dimension(e.rgb[2])},alpha:function(e){return new r.Dimension(e.toHSL().a)},luma:function(e){return new r.Dimension(Math.round(e.luma()*e.alpha*100),"%")},saturate:function(e,t){var n=e.toHSL();return n.s+=t.value/100,n.s=l(n.s),u(n)},desaturate:function(e,t){var n=e.toHSL();return n.s-=t.value/100,n.s=l(n.s),u(n)},lighten:function(e,t){var n=e.toHSL();return n.l+=t.value/100,n.l=l(n.l),u(n)},darken:function(e,t){var n=e.toHSL();return n.l-=t.value/100,n.l=l(n.l),u(n)},fadein:function(e,t){var n=e.toHSL();return n.a+=t.value/100,n.a=l(n.a),u(n)},fadeout:function(e,t){var n=e.toHSL();return n.a-=t.value/100,n.a=l(n.a),u(n)},fade:function(e,t){var n=e.toHSL();return n.a=t.value/100,n.a=l(n.a),u(n)},spin:function(e,t){var n=e.toHSL(),r=(n.h+t.value)%360;return n.h=r<0?360+r:r,u(n)},mix:function(e,t,n){n||(n=new r.Dimension(50));var i=n.value/100,s=i*2-1,o=e.toHSL().a-t.toHSL().a,u=((s*o==-1?s:(s+o)/(1+s*o))+1)/2,a=1-u,f=[e.rgb[0]*u+t.rgb[0]*a,e.rgb[1]*u+t.rgb[1]*a,e.rgb[2]*u+t.rgb[2]*a],l=e.alpha*i+t.alpha*(1-i);return new r.Color(f,l)},greyscale:function(e){return this.desaturate(e,new r.Dimension(100))},contrast:function(e,t,n,r){if(!e.rgb)return null;typeof n=="undefined"&&(n=this.rgba(255,255,255,1)),typeof t=="undefined"&&(t=this.rgba(0,0,0,1));if(t.luma()>n.luma()){var i=n;n=t,t=i}return typeof r=="undefined"?r=.43:r=f(r),e.luma()*e.alpha=d){if(this.env.ieCompat!==!1)return this.env.silent||console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!",o,v,d),(new r.URL(i||t,this.currentFileInfo)).eval(this.env);this.env.silent||console.warn("WARNING: Embedding %s (%dKB) exceeds IE8's data-uri size limit of %dKB!",o,v,d)}p=f?p.toString("base64"):encodeURIComponent(p);var m="'data:"+s+","+p+"'";return new r.URL(new r.Anonymous(m))}},r._mime={_types:{".htm":"text/html",".html":"text/html",".gif":"image/gif",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png"},lookup:function(e){var i=n("path").extname(e),s=r._mime._types[i];if(s===t)throw new Error('Optional dependency "mime" is required for '+i);return s},charsets:{lookup:function(e){return e&&/^text\//.test(e)?"UTF-8":""}}};var i=[{name:"ceil"},{name:"floor"},{name:"sqrt"},{name:"abs"},{name:"tan",unit:""},{name:"sin",unit:""},{name:"cos",unit:""},{name:"atan",unit:"rad"},{name:"asin",unit:"rad"},{name:"acos",unit:"rad"}],s=function(e,t){return function(n){return t!=null&&(n=n.unify()),this._math(Math[e],t,n)}};for(var o=0;o255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("");return n&&(r=r.split(""),r[0]==r[1]&&r[2]==r[3]&&r[4]==r[5]?r=r[0]+r[2]+r[4]:r=r.join("")),"#"+r},operate:function(t,n,r){var i=[];r instanceof e.Color||(r=r.toColor());for(var s=0;s<3;s++)i[s]=e.operate(t,n,this.rgb[s],r.rgb[s]);return new e.Color(i,this.alpha+r.alpha)},toHSL:function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255,r=this.alpha,i=Math.max(e,t,n),s=Math.min(e,t,n),o,u,a=(i+s)/2,f=i-s;if(i===s)o=u=0;else{u=a>.5?f/(2-i-s):f/(i+s);switch(i){case e:o=(t-n)/f+(t255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("")},compare:function(e){return e.rgb?e.rgb[0]===this.rgb[0]&&e.rgb[1]===this.rgb[1]&&e.rgb[2]===this.rgb[2]&&e.alpha===this.alpha?0:-1:-1}}}(n("../tree")),function(e){e.Comment=function(e,t){this.value=e,this.silent=!!t},e.Comment.prototype={type:"Comment",toCSS:function(e){return e.compress?"":this.value},eval:function(){return this}}}(n("../tree")),function(e){e.Condition=function(e,t,n,r,i){this.op=e.trim(),this.lvalue=t,this.rvalue=n,this.index=r,this.negate=i},e.Condition.prototype={type:"Condition",accept:function(e){this.lvalue=e.visit(this.lvalue),this.rvalue=e.visit(this.rvalue)},eval:function(e){var t=this.lvalue.eval(e),n=this.rvalue.eval(e),r=this.index,i,i=function(e){switch(e){case"and":return t&&n;case"or":return t||n;default:if(t.compare)i=t.compare(n);else{if(!n.compare)throw{type:"Type",message:"Unable to perform comparison",index:r};i=n.compare(t)}switch(i){case-1:return e==="<"||e==="=<";case 0:return e==="="||e===">="||e==="=<";case 1:return e===">"||e===">="}}}(this.op);return this.negate?!i:i}}}(n("../tree")),function(e){e.Dimension=function(n,r){this.value=parseFloat(n),this.unit=r&&r instanceof e.Unit?r:new e.Unit(r?[r]:t)},e.Dimension.prototype={type:"Dimension",accept:function(e){this.unit=e.visit(this.unit)},eval:function(e){return this},toColor:function(){return new e.Color([this.value,this.value,this.value])},toCSS:function(e){if(e&&e.strictUnits&&!this.unit.isSingular())throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString());var t=this.value,n=String(t);t!==0&&t<1e-6&&t>-0.000001&&(n=t.toFixed(20).replace(/0+$/,""));if(e&&e.compress){if(t===0&&!this.unit.isAngle())return n;t>0&&t<1&&(n=n.substr(1))}return n+this.unit.toCSS(e)},operate:function(t,n,r){var i=e.operate(t,n,this.value,r.value),s=this.unit.clone();if(n==="+"||n==="-"){if(s.numerator.length===0&&s.denominator.length===0)s.numerator=r.unit.numerator.slice(0),s.denominator=r.unit.denominator.slice(0);else if(r.unit.numerator.length!=0||s.denominator.length!=0){r=r.convertTo(this.unit.usedUnits());if(t.strictUnits&&r.unit.toString()!==s.toString())throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '"+s.toString()+"' and '"+r.unit.toString()+"'.");i=e.operate(t,n,this.value,r.value)}}else n==="*"?(s.numerator=s.numerator.concat(r.unit.numerator).sort(),s.denominator=s.denominator.concat(r.unit.denominator).sort(),s.cancel()):n==="/"&&(s.numerator=s.numerator.concat(r.unit.denominator).sort(),s.denominator=s.denominator.concat(r.unit.numerator).sort(),s.cancel());return new e.Dimension(i,s)},compare:function(t){if(t instanceof e.Dimension){var n=this.unify(),r=t.unify(),i=n.value,s=r.value;return s>i?-1:s=1?this.numerator[0]:this.denominator.length>=1?this.denominator[0]:(!e||!e.strictUnits)&&this.backupUnit?this.backupUnit:""},toString:function(){var e,t=this.numerator.join("*");for(e=0;e0)for(n=0;n":e.compress?">":" > ","|":e.compress?"|":" | "}[this.value]}}}(n("../tree")),function(e){e.Expression=function(e){this.value=e},e.Expression.prototype={type:"Expression",accept:function(e){this.value=e.visit(this.value)},eval:function(t){var n,r=this.parens&&!this.parensInOp,i=!1;return r&&t.inParenthesis(),this.value.length>1?n=new e.Expression(this.value.map(function(e){return e.eval(t)})):this.value.length===1?(this.value[0].parens&&!this.value[0].parensInOp&&(i=!0),n=this.value[0].eval(t)):n=this,r&&t.outOfParenthesis(),this.parens&&this.parensInOp&&!t.isMathOn()&&!i&&(n=new e.Paren(n)),n},toCSS:function(e){return this.value.map(function(t){return t.toCSS?t.toCSS(e):""}).join(" ")},throwAwayComments:function(){this.value=this.value.filter(function(t){return!(t instanceof e.Comment)})}}}(n("../tree")),function(e){e.Extend=function(t,n,r){this.selector=t,this.option=n,this.index=r;switch(n){case"all":this.allowBefore=!0,this.allowAfter=!0;break;default:this.allowBefore=!1,this.allowAfter=!1}},e.Extend.prototype={type:"Extend",accept:function(e){this.selector=e.visit(this.selector)},eval:function(t){return new e.Extend(this.selector.eval(t),this.option,this.index)},clone:function(t){return new e.Extend(this.selector,this.option,this.index)},findSelfSelectors:function(e){var t=[],n;for(n=0;n1){var r=this.emptySelectors();n=new e.Ruleset(r,t.mediaBlocks),n.multiMedia=!0}return delete t.mediaBlocks,delete t.mediaPath,n},evalNested:function(t){var n,r,i=t.mediaPath.concat([this]);for(n=0;n0;n--)t.splice(n,0,new e.Anonymous("and"));return new e.Expression(t)})),new e.Ruleset([],[])},permute:function(e){if(e.length===0)return[];if(e.length===1)return e[0];var t=[],n=this.permute(e.slice(1));for(var r=0;r0){c=!0;for(a=0;athis.params.length)return!1;if(this.required>0&&n>this.params.length)return!1}r=Math.min(n,this.arity);for(var s=0;si.selectors[o].elements.length?Array.prototype.push.apply(r,i.find(new e.Selector(t.elements.slice(1)),n)):r.push(i);break}}),this._lookups[o]=r)},toCSS:function(t){var n=[],r=[],i=[],s=[],o,u,a;for(var f=0;f0){u=e.debugInfo(t,this),o=this.paths.map(function(e){return e.map(function(e){return e.toCSS(t)}).join("").trim()}).join(t.compress?",":",\n");for(var f=r.length-1;f>=0;f--)(r[f].slice(0,2)==="/*"||i.indexOf(r[f])===-1)&&i.unshift(r[f]);r=i,n.push(u+o+(t.compress?"{":" {\n ")+r.join(t.compress?"":"\n ")+(t.compress?"}":"\n}\n"))}return n.push(s),n.join("")+(t.compress?"\n":"")},joinSelectors:function(e,t,n){for(var r=0;r0)for(i=0;i0&&this.mergeElementsOnToSelectors(g,a);for(s=0;s0&&(l[0].elements=l[0].elements.slice(0),l[0].elements.push(new e.Element(f.combinator,"",0))),y.push(l);else for(o=0;o0?(h=l.slice(0),m=h.pop(),d=new e.Selector(m.elements.slice(0),r.extendList),v=!1):d=new e.Selector([],r.extendList),c.length>1&&(p=p.concat(c.slice(1))),c.length>0&&(v=!1,d.elements.push(new e.Element(f.combinator,c[0].elements[0].value,0)),d.elements=d.elements.concat(c[0].elements.slice(1))),v||h.push(d),h=h.concat(p),y.push(h)}a=y,g=[]}}g.length>0&&this.mergeElementsOnToSelectors(g,a);for(i=0;i0&&t.push(a[i])},mergeElementsOnToSelectors:function(t,n){var r,i,s;if(n.length==0){n.push([new e.Selector(t)]);return}for(r=0;r0?i[i.length-1]=new e.Selector(i[i.length-1].elements.concat(t),i[i.length-1].extendList):i.push(new e.Selector(t))}}}(n("../tree")),function(e){e.Selector=function(e,t){this.elements=e,this.extendList=t||[]},e.Selector.prototype={type:"Selector",accept:function(e){this.elements=e.visit(this.elements),this.extendList=e.visit(this.extendList)},match:function(e){var t=this.elements,n=t.length,r,i,s,o;r=e.elements.slice(e.elements.length&&e.elements[0].value==="&"?1:0),i=r.length,s=Math.min(n,i);if(i===0||n1?"["+e.value.map(function(e){return e.toCSS(!1)}).join(", ")+"]":e.toCSS(!1)}}(n("./tree")),function(e){var t=["paths","optimization","files","contents","relativeUrls","strictImports","dumpLineNumbers","compress","processImports","syncImport","mime","currentFileInfo"];e.parseEnv=function(e){r(e,this,t),this.contents||(this.contents={}),this.files||(this.files={});if(!this.currentFileInfo){var n=e&&e.filename||"input",i=n.replace(/[^\/\\]*$/,"");e&&(e.filename=null),this.currentFileInfo={filename:n,relativeUrls:this.relativeUrls,rootpath:e&&e.rootpath||"",currentDirectory:i,entryPath:i,rootFilename:n}}},e.parseEnv.prototype.toSheet=function(t){var n=new e.parseEnv(this);return n.href=t,n.type=this.mime,n};var n=["silent","verbose","compress","yuicompress","ieCompat","strictMath","strictUnits"];e.evalEnv=function(e,t){r(e,this,n),this.frames=t||[]},e.evalEnv.prototype.inParenthesis=function(){this.parensStack||(this.parensStack=[]),this.parensStack.push(!0)},e.evalEnv.prototype.outOfParenthesis=function(){this.parensStack.pop()},e.evalEnv.prototype.isMathOn=function(){return this.strictMath?this.parensStack&&this.parensStack.length:!0},e.evalEnv.prototype.isPathRelative=function(e){return!/^(?:[a-z-]+:|\/)/.test(e)};var r=function(e,t,n){if(!e)return;for(var r=0;r100){var d="{unable to calculate}",v="{unable to calculate}";try{d=u[0].selfSelectors[0].toCSS(),v=u[0].selector.toCSS()}catch(m){}throw{message:"extend circular reference detected. One of the circular extends is currently:"+d+":extend("+v+")"}}return u.concat(f.doExtendChaining(u,n,r+1))}return u},inInheritanceChain:function(e,t){if(e===t)return!0;if(t.parents){if(this.inInheritanceChain(e,t.parents[0]))return!0;if(this.inInheritanceChain(e,t.parents[1]))return!0}return!1},visitRule:function(e,t){t.visitDeeper=!1},visitMixinDefinition:function(e,t){t.visitDeeper=!1},visitSelector:function(e,t){t.visitDeeper=!1},visitRuleset:function(e,t){if(e.root)return;var n,r,i,s=this.allExtendsStack[this.allExtendsStack.length-1],o=[],u=this,a;for(i=0;i0&&f[c.matched].combinator.value!==o?c=null:c.matched++,c&&(c.finished=c.matched===f.length,c.finished&&!e.allowAfter&&(i+1i&&s>0&&(o[o.length-1].elements=o[o.length-1].elements.concat(n[i].elements.slice(s)),s=0,i++),o=o.concat(n.slice(i,l.pathIndex)),o.push(new e.Selector(a.elements.slice(s,l.index).concat([f]).concat(r.elements.slice(1)))),i=l.endPathIndex,s=l.endPathElementIndex,s>=a.elements.length&&(s=0,i++);return i0&&(o[o.length-1].elements=o[o.length-1].elements.concat(n[i].elements.slice(s)),s=0,i++),o=o.concat(n.slice(i,n.length)),o},visitRulesetOut:function(e){},visitMedia:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},visitMediaOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1},visitDirective:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},visitDirectiveOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1}}}(n("./tree"));var o=/^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);r.env=r.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||o?"development":"production"),r.async=r.async||!1,r.fileAsync=r.fileAsync||!1,r.poll=r.poll||(o?1e3:1500);if(r.functions)for(var u in r.functions)r.tree.functions[u]=r.functions[u];var a=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);a&&(r.dumpLineNumbers=a[1]),r.watch=function(){return r.watchMode||(r.env="development",f()),this.watchMode=!0},r.unwatch=function(){return clearInterval(r.watchTimer),this.watchMode=!1},/!watch/.test(location.hash)&&r.watch();var l=null;if(r.env!="development")try{l=typeof e.localStorage=="undefined"?null:e.localStorage}catch(c){}var h=document.getElementsByTagName("link"),p=/^text\/(x-)?less$/;r.sheets=[];for(var d=0;d .select2-chosen {
- margin-right: 26px;
- display: block;
- overflow: hidden;
-
- white-space: nowrap;
-
- text-overflow: ellipsis;
-}
-
-.select2-container .select2-choice abbr {
- display: none;
- width: 12px;
- height: 12px;
- position: absolute;
- right: 24px;
- top: 8px;
-
- font-size: 1px;
- text-decoration: none;
-
- border: 0;
- background: url('select2.png') right top no-repeat;
- cursor: pointer;
- outline: 0;
-}
-
-.select2-container.select2-allowclear .select2-choice abbr {
- display: inline-block;
-}
-
-.select2-container .select2-choice abbr:hover {
- background-position: right -11px;
- cursor: pointer;
-}
-
-.select2-drop-mask {
- border: 0;
- margin: 0;
- padding: 0;
- position: fixed;
- left: 0;
- top: 0;
- min-height: 100%;
- min-width: 100%;
- height: auto;
- width: auto;
- opacity: 0;
- z-index: 9998;
- /* styles required for IE to work */
- background-color: #fff;
- filter: alpha(opacity=0);
-}
-
-.select2-drop {
- width: 100%;
- margin-top: -1px;
- position: absolute;
- z-index: 9999;
- top: 100%;
-
- background: #fff;
- color: #000;
- border: 1px solid #aaa;
- border-top: 0;
-
- border-radius: 0 0 4px 4px;
-
- -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
- box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
-}
-
-.select2-drop-auto-width {
- border-top: 1px solid #aaa;
- width: auto;
-}
-
-.select2-drop-auto-width .select2-search {
- padding-top: 4px;
-}
-
-.select2-drop.select2-drop-above {
- margin-top: 1px;
- border-top: 1px solid #aaa;
- border-bottom: 0;
-
- border-radius: 4px 4px 0 0;
-
- -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
- box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
-}
-
-.select2-drop-active {
- border: 1px solid #5897fb;
- border-top: none;
-}
-
-.select2-drop.select2-drop-above.select2-drop-active {
- border-top: 1px solid #5897fb;
-}
-
-.select2-container .select2-choice .select2-arrow {
- display: inline-block;
- width: 18px;
- height: 100%;
- position: absolute;
- right: 0;
- top: 0;
-
- border-left: 1px solid #aaa;
- border-radius: 0 4px 4px 0;
-
- background-clip: padding-box;
-
- background: #ccc;
- background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
- background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
- background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);
- background-image: linear-gradient(top, #ccc 0%, #eee 60%);
-}
-
-.select2-container .select2-choice .select2-arrow b {
- display: block;
- width: 100%;
- height: 100%;
- background: url('select2.png') no-repeat 0 1px;
-}
-
-.select2-search {
- display: inline-block;
- width: 100%;
- min-height: 26px;
- margin: 0;
- padding-left: 4px;
- padding-right: 4px;
-
- position: relative;
- z-index: 10000;
-
- white-space: nowrap;
-}
-
-.select2-search input {
- width: 100%;
- height: auto !important;
- min-height: 26px;
- padding: 4px 20px 4px 5px;
- margin: 0;
-
- outline: 0;
- font-family: sans-serif;
- font-size: 1em;
-
- border: 1px solid #aaa;
- border-radius: 0;
-
- -webkit-box-shadow: none;
- box-shadow: none;
-
- background: #fff url('select2.png') no-repeat 100% -22px;
- background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
- background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
- background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
- background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #fff 85%, #eee 99%);
-}
-
-.select2-drop.select2-drop-above .select2-search input {
- margin-top: 4px;
-}
-
-.select2-search input.select2-active {
- background: #fff url('select2-spinner.gif') no-repeat 100%;
- background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
- background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
- background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
- background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(top, #fff 85%, #eee 99%);
-}
-
-.select2-container-active .select2-choice,
-.select2-container-active .select2-choices {
- border: 1px solid #5897fb;
- outline: none;
-
- -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
- box-shadow: 0 0 5px rgba(0, 0, 0, .3);
-}
-
-.select2-dropdown-open .select2-choice {
- border-bottom-color: transparent;
- -webkit-box-shadow: 0 1px 0 #fff inset;
- box-shadow: 0 1px 0 #fff inset;
-
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
-
- background-color: #eee;
- background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));
- background-image: -webkit-linear-gradient(center bottom, #fff 0%, #eee 50%);
- background-image: -moz-linear-gradient(center bottom, #fff 0%, #eee 50%);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
- background-image: linear-gradient(top, #fff 0%, #eee 50%);
-}
-
-.select2-dropdown-open.select2-drop-above .select2-choice,
-.select2-dropdown-open.select2-drop-above .select2-choices {
- border: 1px solid #5897fb;
- border-top-color: transparent;
-
- background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee));
- background-image: -webkit-linear-gradient(center top, #fff 0%, #eee 50%);
- background-image: -moz-linear-gradient(center top, #fff 0%, #eee 50%);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
- background-image: linear-gradient(bottom, #fff 0%, #eee 50%);
-}
-
-.select2-dropdown-open .select2-choice .select2-arrow {
- background: transparent;
- border-left: none;
- filter: none;
-}
-.select2-dropdown-open .select2-choice .select2-arrow b {
- background-position: -18px 1px;
-}
-
-/* results */
-.select2-results {
- max-height: 200px;
- padding: 0 0 0 4px;
- margin: 4px 4px 4px 0;
- position: relative;
- overflow-x: hidden;
- overflow-y: auto;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-}
-
-.select2-results ul.select2-result-sub {
- margin: 0;
- padding-left: 0;
-}
-
-.select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px }
-.select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px }
-.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px }
-.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px }
-.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px }
-.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px }
-.select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px }
-
-.select2-results li {
- list-style: none;
- display: list-item;
- background-image: none;
-}
-
-.select2-results li.select2-result-with-children > .select2-result-label {
- font-weight: bold;
-}
-
-.select2-results .select2-result-label {
- padding: 3px 7px 4px;
- margin: 0;
- cursor: pointer;
-
- min-height: 1em;
-
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-
-.select2-results .select2-highlighted {
- background: #3875d7;
- color: #fff;
-}
-
-.select2-results li em {
- background: #feffde;
- font-style: normal;
-}
-
-.select2-results .select2-highlighted em {
- background: transparent;
-}
-
-.select2-results .select2-highlighted ul {
- background: #fff;
- color: #000;
-}
-
-
-.select2-results .select2-no-results,
-.select2-results .select2-searching,
-.select2-results .select2-selection-limit {
- background: #f4f4f4;
- display: list-item;
-}
-
-/*
-disabled look for disabled choices in the results dropdown
-*/
-.select2-results .select2-disabled.select2-highlighted {
- color: #666;
- background: #f4f4f4;
- display: list-item;
- cursor: default;
-}
-.select2-results .select2-disabled {
- background: #f4f4f4;
- display: list-item;
- cursor: default;
-}
-
-.select2-results .select2-selected {
- display: none;
-}
-
-.select2-more-results.select2-active {
- background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
-}
-
-.select2-more-results {
- background: #f4f4f4;
- display: list-item;
-}
-
-/* disabled styles */
-
-.select2-container.select2-container-disabled .select2-choice {
- background-color: #f4f4f4;
- background-image: none;
- border: 1px solid #ddd;
- cursor: default;
-}
-
-.select2-container.select2-container-disabled .select2-choice .select2-arrow {
- background-color: #f4f4f4;
- background-image: none;
- border-left: 0;
-}
-
-.select2-container.select2-container-disabled .select2-choice abbr {
- display: none;
-}
-
-
-/* multiselect */
-
-.select2-container-multi .select2-choices {
- height: auto !important;
- height: 1%;
- margin: 0;
- padding: 0;
- position: relative;
-
- border: 1px solid #aaa;
- cursor: text;
- overflow: hidden;
-
- background-color: #fff;
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
- background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%);
- background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%);
- background-image: linear-gradient(top, #eee 1%, #fff 15%);
-}
-
-.select2-locked {
- padding: 3px 5px 3px 5px !important;
-}
-
-.select2-container-multi .select2-choices {
- min-height: 26px;
-}
-
-.select2-container-multi.select2-container-active .select2-choices {
- border: 1px solid #5897fb;
- outline: none;
-
- -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
- box-shadow: 0 0 5px rgba(0, 0, 0, .3);
-}
-.select2-container-multi .select2-choices li {
- float: left;
- list-style: none;
-}
-.select2-container-multi .select2-choices .select2-search-field {
- margin: 0;
- padding: 0;
- white-space: nowrap;
-}
-
-.select2-container-multi .select2-choices .select2-search-field input {
- padding: 5px;
- margin: 1px 0;
-
- font-family: sans-serif;
- font-size: 100%;
- color: #666;
- outline: 0;
- border: 0;
- -webkit-box-shadow: none;
- box-shadow: none;
- background: transparent !important;
-}
-
-.select2-container-multi .select2-choices .select2-search-field input.select2-active {
- background: #fff url('select2-spinner.gif') no-repeat 100% !important;
-}
-
-.select2-default {
- color: #999 !important;
-}
-
-.select2-container-multi .select2-choices .select2-search-choice {
- padding: 3px 5px 3px 18px;
- margin: 3px 0 3px 5px;
- position: relative;
-
- line-height: 13px;
- color: #333;
- cursor: default;
- border: 1px solid #aaaaaa;
-
- border-radius: 3px;
-
- -webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
- box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
-
- background-clip: padding-box;
-
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-
- background-color: #e4e4e4;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
- background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
- background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
- background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
-}
-.select2-container-multi .select2-choices .select2-search-choice .select2-chosen {
- cursor: default;
-}
-.select2-container-multi .select2-choices .select2-search-choice-focus {
- background: #d4d4d4;
-}
-
-.select2-search-choice-close {
- display: block;
- width: 12px;
- height: 13px;
- position: absolute;
- right: 3px;
- top: 4px;
-
- font-size: 1px;
- outline: none;
- background: url('select2.png') right top no-repeat;
-}
-
-.select2-container-multi .select2-search-choice-close {
- left: 3px;
-}
-
-.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
- background-position: right -11px;
-}
-.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
- background-position: right -11px;
-}
-
-/* disabled styles */
-.select2-container-multi.select2-container-disabled .select2-choices {
- background-color: #f4f4f4;
- background-image: none;
- border: 1px solid #ddd;
- cursor: default;
-}
-
-.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
- padding: 3px 5px 3px 5px;
- border: 1px solid #ddd;
- background-image: none;
- background-color: #f4f4f4;
-}
-
-.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { display: none;
- background: none;
-}
-/* end multiselect */
-
-
-.select2-result-selectable .select2-match,
-.select2-result-unselectable .select2-match {
- text-decoration: underline;
-}
-
-.select2-offscreen, .select2-offscreen:focus {
- clip: rect(0 0 0 0) !important;
- width: 1px !important;
- height: 1px !important;
- border: 0 !important;
- margin: 0 !important;
- padding: 0 !important;
- overflow: hidden !important;
- position: absolute !important;
- outline: 0 !important;
- left: 0px !important;
- top: 0px !important;
-}
-
-.select2-display-none {
- display: none;
-}
-
-.select2-measure-scrollbar {
- position: absolute;
- top: -10000px;
- left: -10000px;
- width: 100px;
- height: 100px;
- overflow: scroll;
-}
-/* Retina-ize icons */
-
-@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) {
- .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice .select2-arrow b {
- background-image: url('select2x2.png') !important;
- background-repeat: no-repeat !important;
- background-size: 60px 40px !important;
- }
- .select2-search input {
- background-position: 100% -21px !important;
- }
-}
diff --git a/oscar_support/static/oscar_support/lib/select2/select2.min.js b/oscar_support/static/oscar_support/lib/select2/select2.min.js
deleted file mode 100644
index 0910fdf..0000000
--- a/oscar_support/static/oscar_support/lib/select2/select2.min.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-Copyright 2012 Igor Vaynberg
-
-Version: 3.4.3 Timestamp: Tue Sep 17 06:47:14 PDT 2013
-
-This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
-General Public License version 2 (the "GPL License"). You may choose either license to govern your
-use of this software only upon the condition that you accept all of the terms of either the Apache
-License or the GPL License.
-
-You may obtain a copy of the Apache License and the GPL License at:
-
-http://www.apache.org/licenses/LICENSE-2.0
-http://www.gnu.org/licenses/gpl-2.0.html
-
-Unless required by applicable law or agreed to in writing, software distributed under the Apache License
-or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
-either express or implied. See the Apache License and the GPL License for the specific language governing
-permissions and limitations under the Apache License and the GPL License.
-*/
-!function(a){"undefined"==typeof a.fn.each2&&a.extend(a.fn,{each2:function(b){for(var c=a([0]),d=-1,e=this.length;++dc;c++)e=a.charAt(c),b+=m[e]||e;return b}function o(a,b){for(var c=0,d=b.length;d>c;c+=1)if(q(a,b[c]))return c;return-1}function p(){var b=a(l);b.appendTo("body");var c={width:b.width()-b[0].clientWidth,height:b.height()-b[0].clientHeight};return b.remove(),c}function q(a,c){return a===c?!0:a===b||c===b?!1:null===a||null===c?!1:a.constructor===String?a+""==c+"":c.constructor===String?c+""==a+"":!1}function r(b,c){var d,e,f;if(null===b||b.length<1)return[];for(d=b.split(c),e=0,f=d.length;f>e;e+=1)d[e]=a.trim(d[e]);return d}function s(a){return a.outerWidth(!1)-a.width()}function t(c){var d="keyup-change-value";c.on("keydown",function(){a.data(c,d)===b&&a.data(c,d,c.val())}),c.on("keyup",function(){var e=a.data(c,d);e!==b&&c.val()!==e&&(a.removeData(c,d),c.trigger("keyup-change"))})}function u(c){c.on("mousemove",function(c){var d=i;(d===b||d.x!==c.pageX||d.y!==c.pageY)&&a(c.target).trigger("mousemove-filtered",c)})}function v(a,c,d){d=d||b;var e;return function(){var b=arguments;window.clearTimeout(e),e=window.setTimeout(function(){c.apply(d,b)},a)}}function w(a){var c,b=!1;return function(){return b===!1&&(c=a(),b=!0),c}}function x(a,b){var c=v(a,function(a){b.trigger("scroll-debounced",a)});b.on("scroll",function(a){o(a.target,b.get())>=0&&c(a)})}function y(a){a[0]!==document.activeElement&&window.setTimeout(function(){var d,b=a[0],c=a.val().length;a.focus(),a.is(":visible")&&b===document.activeElement&&(b.setSelectionRange?b.setSelectionRange(c,c):b.createTextRange&&(d=b.createTextRange(),d.collapse(!1),d.select()))},0)}function z(b){b=a(b)[0];var c=0,d=0;if("selectionStart"in b)c=b.selectionStart,d=b.selectionEnd-c;else if("selection"in document){b.focus();var e=document.selection.createRange();d=document.selection.createRange().text.length,e.moveStart("character",-b.value.length),c=e.text.length-d}return{offset:c,length:d}}function A(a){a.preventDefault(),a.stopPropagation()}function B(a){a.preventDefault(),a.stopImmediatePropagation()}function C(b){if(!h){var c=b[0].currentStyle||window.getComputedStyle(b[0],null);h=a(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:c.fontSize,fontFamily:c.fontFamily,fontStyle:c.fontStyle,fontWeight:c.fontWeight,letterSpacing:c.letterSpacing,textTransform:c.textTransform,whiteSpace:"nowrap"}),h.attr("class","select2-sizer"),a("body").append(h)}return h.text(b.val()),h.width()}function D(b,c,d){var e,g,f=[];e=b.attr("class"),e&&(e=""+e,a(e.split(" ")).each2(function(){0===this.indexOf("select2-")&&f.push(this)})),e=c.attr("class"),e&&(e=""+e,a(e.split(" ")).each2(function(){0!==this.indexOf("select2-")&&(g=d(this),g&&f.push(this))})),b.attr("class",f.join(" "))}function E(a,b,c,d){var e=n(a.toUpperCase()).indexOf(n(b.toUpperCase())),f=b.length;return 0>e?(c.push(d(a)),void 0):(c.push(d(a.substring(0,e))),c.push(""),c.push(d(a.substring(e,e+f))),c.push(" "),c.push(d(a.substring(e+f,a.length))),void 0)}function F(a){var b={"\\":"\","&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})}function G(c){var d,e=null,f=c.quietMillis||100,g=c.url,h=this;return function(i){window.clearTimeout(d),d=window.setTimeout(function(){var d=c.data,f=g,j=c.transport||a.fn.select2.ajaxDefaults.transport,k={type:c.type||"GET",cache:c.cache||!1,jsonpCallback:c.jsonpCallback||b,dataType:c.dataType||"json"},l=a.extend({},a.fn.select2.ajaxDefaults.params,k);d=d?d.call(h,i.term,i.page,i.context):null,f="function"==typeof f?f.call(h,i.term,i.page,i.context):f,e&&e.abort(),c.params&&(a.isFunction(c.params)?a.extend(l,c.params.call(h)):a.extend(l,c.params)),a.extend(l,{url:f,dataType:c.dataType,data:d,success:function(a){var b=c.results(a,i.page);i.callback(b)}}),e=j.call(h,l)},f)}}function H(b){var d,e,c=b,f=function(a){return""+a.text};a.isArray(c)&&(e=c,c={results:e}),a.isFunction(c)===!1&&(e=c,c=function(){return e});var g=c();return g.text&&(f=g.text,a.isFunction(f)||(d=g.text,f=function(a){return a[d]})),function(b){var g,d=b.term,e={results:[]};return""===d?(b.callback(c()),void 0):(g=function(c,e){var h,i;if(c=c[0],c.children){h={};for(i in c)c.hasOwnProperty(i)&&(h[i]=c[i]);h.children=[],a(c.children).each2(function(a,b){g(b,h.children)}),(h.children.length||b.matcher(d,f(h),c))&&e.push(h)}else b.matcher(d,f(c),c)&&e.push(c)},a(c().results).each2(function(a,b){g(b,e.results)}),b.callback(e),void 0)}}function I(c){var d=a.isFunction(c);return function(e){var f=e.term,g={results:[]};a(d?c():c).each(function(){var a=this.text!==b,c=a?this.text:this;(""===f||e.matcher(f,c))&&g.results.push(a?this:{id:this,text:this})}),e.callback(g)}}function J(b,c){if(a.isFunction(b))return!0;if(!b)return!1;throw new Error(c+" must be a function or a falsy value")}function K(b){return a.isFunction(b)?b():b}function L(b){var c=0;return a.each(b,function(a,b){b.children?c+=L(b.children):c++}),c}function M(a,c,d,e){var h,i,j,k,l,f=a,g=!1;if(!e.createSearchChoice||!e.tokenSeparators||e.tokenSeparators.length<1)return b;for(;;){for(i=-1,j=0,k=e.tokenSeparators.length;k>j&&(l=e.tokenSeparators[j],i=a.indexOf(l),!(i>=0));j++);if(0>i)break;if(h=a.substring(0,i),a=a.substring(i+l.length),h.length>0&&(h=e.createSearchChoice.call(this,h,c),h!==b&&null!==h&&e.id(h)!==b&&null!==e.id(h))){for(g=!1,j=0,k=c.length;k>j;j++)if(q(e.id(h),e.id(c[j]))){g=!0;break}g||d(h)}}return f!==a?a:void 0}function N(b,c){var d=function(){};return d.prototype=new b,d.prototype.constructor=d,d.prototype.parent=b.prototype,d.prototype=a.extend(d.prototype,c),d}if(window.Select2===b){var c,d,e,f,g,h,j,k,i={x:0,y:0},c={TAB:9,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,SHIFT:16,CTRL:17,ALT:18,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,BACKSPACE:8,DELETE:46,isArrow:function(a){switch(a=a.which?a.which:a){case c.LEFT:case c.RIGHT:case c.UP:case c.DOWN:return!0}return!1},isControl:function(a){var b=a.which;switch(b){case c.SHIFT:case c.CTRL:case c.ALT:return!0}return a.metaKey?!0:!1},isFunctionKey:function(a){return a=a.which?a.which:a,a>=112&&123>=a}},l="
",m={"\u24b6":"A","\uff21":"A","\xc0":"A","\xc1":"A","\xc2":"A","\u1ea6":"A","\u1ea4":"A","\u1eaa":"A","\u1ea8":"A","\xc3":"A","\u0100":"A","\u0102":"A","\u1eb0":"A","\u1eae":"A","\u1eb4":"A","\u1eb2":"A","\u0226":"A","\u01e0":"A","\xc4":"A","\u01de":"A","\u1ea2":"A","\xc5":"A","\u01fa":"A","\u01cd":"A","\u0200":"A","\u0202":"A","\u1ea0":"A","\u1eac":"A","\u1eb6":"A","\u1e00":"A","\u0104":"A","\u023a":"A","\u2c6f":"A","\ua732":"AA","\xc6":"AE","\u01fc":"AE","\u01e2":"AE","\ua734":"AO","\ua736":"AU","\ua738":"AV","\ua73a":"AV","\ua73c":"AY","\u24b7":"B","\uff22":"B","\u1e02":"B","\u1e04":"B","\u1e06":"B","\u0243":"B","\u0182":"B","\u0181":"B","\u24b8":"C","\uff23":"C","\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\xc7":"C","\u1e08":"C","\u0187":"C","\u023b":"C","\ua73e":"C","\u24b9":"D","\uff24":"D","\u1e0a":"D","\u010e":"D","\u1e0c":"D","\u1e10":"D","\u1e12":"D","\u1e0e":"D","\u0110":"D","\u018b":"D","\u018a":"D","\u0189":"D","\ua779":"D","\u01f1":"DZ","\u01c4":"DZ","\u01f2":"Dz","\u01c5":"Dz","\u24ba":"E","\uff25":"E","\xc8":"E","\xc9":"E","\xca":"E","\u1ec0":"E","\u1ebe":"E","\u1ec4":"E","\u1ec2":"E","\u1ebc":"E","\u0112":"E","\u1e14":"E","\u1e16":"E","\u0114":"E","\u0116":"E","\xcb":"E","\u1eba":"E","\u011a":"E","\u0204":"E","\u0206":"E","\u1eb8":"E","\u1ec6":"E","\u0228":"E","\u1e1c":"E","\u0118":"E","\u1e18":"E","\u1e1a":"E","\u0190":"E","\u018e":"E","\u24bb":"F","\uff26":"F","\u1e1e":"F","\u0191":"F","\ua77b":"F","\u24bc":"G","\uff27":"G","\u01f4":"G","\u011c":"G","\u1e20":"G","\u011e":"G","\u0120":"G","\u01e6":"G","\u0122":"G","\u01e4":"G","\u0193":"G","\ua7a0":"G","\ua77d":"G","\ua77e":"G","\u24bd":"H","\uff28":"H","\u0124":"H","\u1e22":"H","\u1e26":"H","\u021e":"H","\u1e24":"H","\u1e28":"H","\u1e2a":"H","\u0126":"H","\u2c67":"H","\u2c75":"H","\ua78d":"H","\u24be":"I","\uff29":"I","\xcc":"I","\xcd":"I","\xce":"I","\u0128":"I","\u012a":"I","\u012c":"I","\u0130":"I","\xcf":"I","\u1e2e":"I","\u1ec8":"I","\u01cf":"I","\u0208":"I","\u020a":"I","\u1eca":"I","\u012e":"I","\u1e2c":"I","\u0197":"I","\u24bf":"J","\uff2a":"J","\u0134":"J","\u0248":"J","\u24c0":"K","\uff2b":"K","\u1e30":"K","\u01e8":"K","\u1e32":"K","\u0136":"K","\u1e34":"K","\u0198":"K","\u2c69":"K","\ua740":"K","\ua742":"K","\ua744":"K","\ua7a2":"K","\u24c1":"L","\uff2c":"L","\u013f":"L","\u0139":"L","\u013d":"L","\u1e36":"L","\u1e38":"L","\u013b":"L","\u1e3c":"L","\u1e3a":"L","\u0141":"L","\u023d":"L","\u2c62":"L","\u2c60":"L","\ua748":"L","\ua746":"L","\ua780":"L","\u01c7":"LJ","\u01c8":"Lj","\u24c2":"M","\uff2d":"M","\u1e3e":"M","\u1e40":"M","\u1e42":"M","\u2c6e":"M","\u019c":"M","\u24c3":"N","\uff2e":"N","\u01f8":"N","\u0143":"N","\xd1":"N","\u1e44":"N","\u0147":"N","\u1e46":"N","\u0145":"N","\u1e4a":"N","\u1e48":"N","\u0220":"N","\u019d":"N","\ua790":"N","\ua7a4":"N","\u01ca":"NJ","\u01cb":"Nj","\u24c4":"O","\uff2f":"O","\xd2":"O","\xd3":"O","\xd4":"O","\u1ed2":"O","\u1ed0":"O","\u1ed6":"O","\u1ed4":"O","\xd5":"O","\u1e4c":"O","\u022c":"O","\u1e4e":"O","\u014c":"O","\u1e50":"O","\u1e52":"O","\u014e":"O","\u022e":"O","\u0230":"O","\xd6":"O","\u022a":"O","\u1ece":"O","\u0150":"O","\u01d1":"O","\u020c":"O","\u020e":"O","\u01a0":"O","\u1edc":"O","\u1eda":"O","\u1ee0":"O","\u1ede":"O","\u1ee2":"O","\u1ecc":"O","\u1ed8":"O","\u01ea":"O","\u01ec":"O","\xd8":"O","\u01fe":"O","\u0186":"O","\u019f":"O","\ua74a":"O","\ua74c":"O","\u01a2":"OI","\ua74e":"OO","\u0222":"OU","\u24c5":"P","\uff30":"P","\u1e54":"P","\u1e56":"P","\u01a4":"P","\u2c63":"P","\ua750":"P","\ua752":"P","\ua754":"P","\u24c6":"Q","\uff31":"Q","\ua756":"Q","\ua758":"Q","\u024a":"Q","\u24c7":"R","\uff32":"R","\u0154":"R","\u1e58":"R","\u0158":"R","\u0210":"R","\u0212":"R","\u1e5a":"R","\u1e5c":"R","\u0156":"R","\u1e5e":"R","\u024c":"R","\u2c64":"R","\ua75a":"R","\ua7a6":"R","\ua782":"R","\u24c8":"S","\uff33":"S","\u1e9e":"S","\u015a":"S","\u1e64":"S","\u015c":"S","\u1e60":"S","\u0160":"S","\u1e66":"S","\u1e62":"S","\u1e68":"S","\u0218":"S","\u015e":"S","\u2c7e":"S","\ua7a8":"S","\ua784":"S","\u24c9":"T","\uff34":"T","\u1e6a":"T","\u0164":"T","\u1e6c":"T","\u021a":"T","\u0162":"T","\u1e70":"T","\u1e6e":"T","\u0166":"T","\u01ac":"T","\u01ae":"T","\u023e":"T","\ua786":"T","\ua728":"TZ","\u24ca":"U","\uff35":"U","\xd9":"U","\xda":"U","\xdb":"U","\u0168":"U","\u1e78":"U","\u016a":"U","\u1e7a":"U","\u016c":"U","\xdc":"U","\u01db":"U","\u01d7":"U","\u01d5":"U","\u01d9":"U","\u1ee6":"U","\u016e":"U","\u0170":"U","\u01d3":"U","\u0214":"U","\u0216":"U","\u01af":"U","\u1eea":"U","\u1ee8":"U","\u1eee":"U","\u1eec":"U","\u1ef0":"U","\u1ee4":"U","\u1e72":"U","\u0172":"U","\u1e76":"U","\u1e74":"U","\u0244":"U","\u24cb":"V","\uff36":"V","\u1e7c":"V","\u1e7e":"V","\u01b2":"V","\ua75e":"V","\u0245":"V","\ua760":"VY","\u24cc":"W","\uff37":"W","\u1e80":"W","\u1e82":"W","\u0174":"W","\u1e86":"W","\u1e84":"W","\u1e88":"W","\u2c72":"W","\u24cd":"X","\uff38":"X","\u1e8a":"X","\u1e8c":"X","\u24ce":"Y","\uff39":"Y","\u1ef2":"Y","\xdd":"Y","\u0176":"Y","\u1ef8":"Y","\u0232":"Y","\u1e8e":"Y","\u0178":"Y","\u1ef6":"Y","\u1ef4":"Y","\u01b3":"Y","\u024e":"Y","\u1efe":"Y","\u24cf":"Z","\uff3a":"Z","\u0179":"Z","\u1e90":"Z","\u017b":"Z","\u017d":"Z","\u1e92":"Z","\u1e94":"Z","\u01b5":"Z","\u0224":"Z","\u2c7f":"Z","\u2c6b":"Z","\ua762":"Z","\u24d0":"a","\uff41":"a","\u1e9a":"a","\xe0":"a","\xe1":"a","\xe2":"a","\u1ea7":"a","\u1ea5":"a","\u1eab":"a","\u1ea9":"a","\xe3":"a","\u0101":"a","\u0103":"a","\u1eb1":"a","\u1eaf":"a","\u1eb5":"a","\u1eb3":"a","\u0227":"a","\u01e1":"a","\xe4":"a","\u01df":"a","\u1ea3":"a","\xe5":"a","\u01fb":"a","\u01ce":"a","\u0201":"a","\u0203":"a","\u1ea1":"a","\u1ead":"a","\u1eb7":"a","\u1e01":"a","\u0105":"a","\u2c65":"a","\u0250":"a","\ua733":"aa","\xe6":"ae","\u01fd":"ae","\u01e3":"ae","\ua735":"ao","\ua737":"au","\ua739":"av","\ua73b":"av","\ua73d":"ay","\u24d1":"b","\uff42":"b","\u1e03":"b","\u1e05":"b","\u1e07":"b","\u0180":"b","\u0183":"b","\u0253":"b","\u24d2":"c","\uff43":"c","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\xe7":"c","\u1e09":"c","\u0188":"c","\u023c":"c","\ua73f":"c","\u2184":"c","\u24d3":"d","\uff44":"d","\u1e0b":"d","\u010f":"d","\u1e0d":"d","\u1e11":"d","\u1e13":"d","\u1e0f":"d","\u0111":"d","\u018c":"d","\u0256":"d","\u0257":"d","\ua77a":"d","\u01f3":"dz","\u01c6":"dz","\u24d4":"e","\uff45":"e","\xe8":"e","\xe9":"e","\xea":"e","\u1ec1":"e","\u1ebf":"e","\u1ec5":"e","\u1ec3":"e","\u1ebd":"e","\u0113":"e","\u1e15":"e","\u1e17":"e","\u0115":"e","\u0117":"e","\xeb":"e","\u1ebb":"e","\u011b":"e","\u0205":"e","\u0207":"e","\u1eb9":"e","\u1ec7":"e","\u0229":"e","\u1e1d":"e","\u0119":"e","\u1e19":"e","\u1e1b":"e","\u0247":"e","\u025b":"e","\u01dd":"e","\u24d5":"f","\uff46":"f","\u1e1f":"f","\u0192":"f","\ua77c":"f","\u24d6":"g","\uff47":"g","\u01f5":"g","\u011d":"g","\u1e21":"g","\u011f":"g","\u0121":"g","\u01e7":"g","\u0123":"g","\u01e5":"g","\u0260":"g","\ua7a1":"g","\u1d79":"g","\ua77f":"g","\u24d7":"h","\uff48":"h","\u0125":"h","\u1e23":"h","\u1e27":"h","\u021f":"h","\u1e25":"h","\u1e29":"h","\u1e2b":"h","\u1e96":"h","\u0127":"h","\u2c68":"h","\u2c76":"h","\u0265":"h","\u0195":"hv","\u24d8":"i","\uff49":"i","\xec":"i","\xed":"i","\xee":"i","\u0129":"i","\u012b":"i","\u012d":"i","\xef":"i","\u1e2f":"i","\u1ec9":"i","\u01d0":"i","\u0209":"i","\u020b":"i","\u1ecb":"i","\u012f":"i","\u1e2d":"i","\u0268":"i","\u0131":"i","\u24d9":"j","\uff4a":"j","\u0135":"j","\u01f0":"j","\u0249":"j","\u24da":"k","\uff4b":"k","\u1e31":"k","\u01e9":"k","\u1e33":"k","\u0137":"k","\u1e35":"k","\u0199":"k","\u2c6a":"k","\ua741":"k","\ua743":"k","\ua745":"k","\ua7a3":"k","\u24db":"l","\uff4c":"l","\u0140":"l","\u013a":"l","\u013e":"l","\u1e37":"l","\u1e39":"l","\u013c":"l","\u1e3d":"l","\u1e3b":"l","\u017f":"l","\u0142":"l","\u019a":"l","\u026b":"l","\u2c61":"l","\ua749":"l","\ua781":"l","\ua747":"l","\u01c9":"lj","\u24dc":"m","\uff4d":"m","\u1e3f":"m","\u1e41":"m","\u1e43":"m","\u0271":"m","\u026f":"m","\u24dd":"n","\uff4e":"n","\u01f9":"n","\u0144":"n","\xf1":"n","\u1e45":"n","\u0148":"n","\u1e47":"n","\u0146":"n","\u1e4b":"n","\u1e49":"n","\u019e":"n","\u0272":"n","\u0149":"n","\ua791":"n","\ua7a5":"n","\u01cc":"nj","\u24de":"o","\uff4f":"o","\xf2":"o","\xf3":"o","\xf4":"o","\u1ed3":"o","\u1ed1":"o","\u1ed7":"o","\u1ed5":"o","\xf5":"o","\u1e4d":"o","\u022d":"o","\u1e4f":"o","\u014d":"o","\u1e51":"o","\u1e53":"o","\u014f":"o","\u022f":"o","\u0231":"o","\xf6":"o","\u022b":"o","\u1ecf":"o","\u0151":"o","\u01d2":"o","\u020d":"o","\u020f":"o","\u01a1":"o","\u1edd":"o","\u1edb":"o","\u1ee1":"o","\u1edf":"o","\u1ee3":"o","\u1ecd":"o","\u1ed9":"o","\u01eb":"o","\u01ed":"o","\xf8":"o","\u01ff":"o","\u0254":"o","\ua74b":"o","\ua74d":"o","\u0275":"o","\u01a3":"oi","\u0223":"ou","\ua74f":"oo","\u24df":"p","\uff50":"p","\u1e55":"p","\u1e57":"p","\u01a5":"p","\u1d7d":"p","\ua751":"p","\ua753":"p","\ua755":"p","\u24e0":"q","\uff51":"q","\u024b":"q","\ua757":"q","\ua759":"q","\u24e1":"r","\uff52":"r","\u0155":"r","\u1e59":"r","\u0159":"r","\u0211":"r","\u0213":"r","\u1e5b":"r","\u1e5d":"r","\u0157":"r","\u1e5f":"r","\u024d":"r","\u027d":"r","\ua75b":"r","\ua7a7":"r","\ua783":"r","\u24e2":"s","\uff53":"s","\xdf":"s","\u015b":"s","\u1e65":"s","\u015d":"s","\u1e61":"s","\u0161":"s","\u1e67":"s","\u1e63":"s","\u1e69":"s","\u0219":"s","\u015f":"s","\u023f":"s","\ua7a9":"s","\ua785":"s","\u1e9b":"s","\u24e3":"t","\uff54":"t","\u1e6b":"t","\u1e97":"t","\u0165":"t","\u1e6d":"t","\u021b":"t","\u0163":"t","\u1e71":"t","\u1e6f":"t","\u0167":"t","\u01ad":"t","\u0288":"t","\u2c66":"t","\ua787":"t","\ua729":"tz","\u24e4":"u","\uff55":"u","\xf9":"u","\xfa":"u","\xfb":"u","\u0169":"u","\u1e79":"u","\u016b":"u","\u1e7b":"u","\u016d":"u","\xfc":"u","\u01dc":"u","\u01d8":"u","\u01d6":"u","\u01da":"u","\u1ee7":"u","\u016f":"u","\u0171":"u","\u01d4":"u","\u0215":"u","\u0217":"u","\u01b0":"u","\u1eeb":"u","\u1ee9":"u","\u1eef":"u","\u1eed":"u","\u1ef1":"u","\u1ee5":"u","\u1e73":"u","\u0173":"u","\u1e77":"u","\u1e75":"u","\u0289":"u","\u24e5":"v","\uff56":"v","\u1e7d":"v","\u1e7f":"v","\u028b":"v","\ua75f":"v","\u028c":"v","\ua761":"vy","\u24e6":"w","\uff57":"w","\u1e81":"w","\u1e83":"w","\u0175":"w","\u1e87":"w","\u1e85":"w","\u1e98":"w","\u1e89":"w","\u2c73":"w","\u24e7":"x","\uff58":"x","\u1e8b":"x","\u1e8d":"x","\u24e8":"y","\uff59":"y","\u1ef3":"y","\xfd":"y","\u0177":"y","\u1ef9":"y","\u0233":"y","\u1e8f":"y","\xff":"y","\u1ef7":"y","\u1e99":"y","\u1ef5":"y","\u01b4":"y","\u024f":"y","\u1eff":"y","\u24e9":"z","\uff5a":"z","\u017a":"z","\u1e91":"z","\u017c":"z","\u017e":"z","\u1e93":"z","\u1e95":"z","\u01b6":"z","\u0225":"z","\u0240":"z","\u2c6c":"z","\ua763":"z"};j=a(document),g=function(){var a=1;return function(){return a++}}(),j.on("mousemove",function(a){i.x=a.pageX,i.y=a.pageY}),d=N(Object,{bind:function(a){var b=this;return function(){a.apply(b,arguments)}},init:function(c){var d,e,h,i,f=".select2-results";this.opts=c=this.prepareOpts(c),this.id=c.id,c.element.data("select2")!==b&&null!==c.element.data("select2")&&c.element.data("select2").destroy(),this.container=this.createContainer(),this.containerId="s2id_"+(c.element.attr("id")||"autogen"+g()),this.containerSelector="#"+this.containerId.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,"\\$1"),this.container.attr("id",this.containerId),this.body=w(function(){return c.element.closest("body")}),D(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.attr("style",c.element.attr("style")),this.container.css(K(c.containerCss)),this.container.addClass(K(c.containerCssClass)),this.elementTabIndex=this.opts.element.attr("tabindex"),this.opts.element.data("select2",this).attr("tabindex","-1").before(this.container).on("click.select2",A),this.container.data("select2",this),this.dropdown=this.container.find(".select2-drop"),D(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(K(c.dropdownCssClass)),this.dropdown.data("select2",this),this.dropdown.on("click",A),this.results=d=this.container.find(f),this.search=e=this.container.find("input.select2-input"),this.queryCount=0,this.resultsPage=0,this.context=null,this.initContainer(),this.container.on("click",A),u(this.results),this.dropdown.on("mousemove-filtered touchstart touchmove touchend",f,this.bind(this.highlightUnderEvent)),x(80,this.results),this.dropdown.on("scroll-debounced",f,this.bind(this.loadMoreIfNeeded)),a(this.container).on("change",".select2-input",function(a){a.stopPropagation()}),a(this.dropdown).on("change",".select2-input",function(a){a.stopPropagation()}),a.fn.mousewheel&&d.mousewheel(function(a,b,c,e){var f=d.scrollTop();e>0&&0>=f-e?(d.scrollTop(0),A(a)):0>e&&d.get(0).scrollHeight-d.scrollTop()+e<=d.height()&&(d.scrollTop(d.get(0).scrollHeight-d.height()),A(a))}),t(e),e.on("keyup-change input paste",this.bind(this.updateResults)),e.on("focus",function(){e.addClass("select2-focused")}),e.on("blur",function(){e.removeClass("select2-focused")}),this.dropdown.on("mouseup",f,this.bind(function(b){a(b.target).closest(".select2-result-selectable").length>0&&(this.highlightUnderEvent(b),this.selectHighlighted(b))})),this.dropdown.on("click mouseup mousedown",function(a){a.stopPropagation()}),a.isFunction(this.opts.initSelection)&&(this.initSelection(),this.monitorSource()),null!==c.maximumInputLength&&this.search.attr("maxlength",c.maximumInputLength);var h=c.element.prop("disabled");h===b&&(h=!1),this.enable(!h);var i=c.element.prop("readonly");i===b&&(i=!1),this.readonly(i),k=k||p(),this.autofocus=c.element.prop("autofocus"),c.element.prop("autofocus",!1),this.autofocus&&this.focus(),this.nextSearchTerm=b},destroy:function(){var a=this.opts.element,c=a.data("select2");this.close(),this.propertyObserver&&(delete this.propertyObserver,this.propertyObserver=null),c!==b&&(c.container.remove(),c.dropdown.remove(),a.removeClass("select2-offscreen").removeData("select2").off(".select2").prop("autofocus",this.autofocus||!1),this.elementTabIndex?a.attr({tabindex:this.elementTabIndex}):a.removeAttr("tabindex"),a.show())},optionToData:function(a){return a.is("option")?{id:a.prop("value"),text:a.text(),element:a.get(),css:a.attr("class"),disabled:a.prop("disabled"),locked:q(a.attr("locked"),"locked")||q(a.data("locked"),!0)}:a.is("optgroup")?{text:a.attr("label"),children:[],element:a.get(),css:a.attr("class")}:void 0},prepareOpts:function(c){var d,e,f,g,h=this;if(d=c.element,"select"===d.get(0).tagName.toLowerCase()&&(this.select=e=c.element),e&&a.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in c)throw new Error("Option '"+this+"' is not allowed for Select2 when attached to a element.")}),c=a.extend({},{populateResults:function(d,e,f){var g,l=this.opts.id;g=function(d,e,i){var j,k,m,n,o,p,q,r,s,t;for(d=c.sortResults(d,e,f),j=0,k=d.length;k>j;j+=1)m=d[j],o=m.disabled===!0,n=!o&&l(m)!==b,p=m.children&&m.children.length>0,q=a(" "),q.addClass("select2-results-dept-"+i),q.addClass("select2-result"),q.addClass(n?"select2-result-selectable":"select2-result-unselectable"),o&&q.addClass("select2-disabled"),p&&q.addClass("select2-result-with-children"),q.addClass(h.opts.formatResultCssClass(m)),r=a(document.createElement("div")),r.addClass("select2-result-label"),t=c.formatResult(m,r,f,h.opts.escapeMarkup),t!==b&&r.html(t),q.append(r),p&&(s=a(""),s.addClass("select2-result-sub"),g(m.children,s,i+1),q.append(s)),q.data("select2-data",m),e.append(q)},g(e,d,0)}},a.fn.select2.defaults,c),"function"!=typeof c.id&&(f=c.id,c.id=function(a){return a[f]}),a.isArray(c.element.data("select2Tags"))){if("tags"in c)throw"tags specified as both an attribute 'data-select2-tags' and in options of Select2 "+c.element.attr("id");c.tags=c.element.data("select2Tags")}if(e?(c.query=this.bind(function(a){var f,g,i,c={results:[],more:!1},e=a.term;i=function(b,c){var d;b.is("option")?a.matcher(e,b.text(),b)&&c.push(h.optionToData(b)):b.is("optgroup")&&(d=h.optionToData(b),b.children().each2(function(a,b){i(b,d.children)}),d.children.length>0&&c.push(d))},f=d.children(),this.getPlaceholder()!==b&&f.length>0&&(g=this.getPlaceholderOption(),g&&(f=f.not(g))),f.each2(function(a,b){i(b,c.results)}),a.callback(c)}),c.id=function(a){return a.id},c.formatResultCssClass=function(a){return a.css}):"query"in c||("ajax"in c?(g=c.element.data("ajax-url"),g&&g.length>0&&(c.ajax.url=g),c.query=G.call(c.element,c.ajax)):"data"in c?c.query=H(c.data):"tags"in c&&(c.query=I(c.tags),c.createSearchChoice===b&&(c.createSearchChoice=function(b){return{id:a.trim(b),text:a.trim(b)}}),c.initSelection===b&&(c.initSelection=function(b,d){var e=[];a(r(b.val(),c.separator)).each(function(){var b={id:this,text:this},d=c.tags;a.isFunction(d)&&(d=d()),a(d).each(function(){return q(this.id,b.id)?(b=this,!1):void 0}),e.push(b)}),d(e)}))),"function"!=typeof c.query)throw"query function not defined for Select2 "+c.element.attr("id");return c},monitorSource:function(){var c,a=this.opts.element;a.on("change.select2",this.bind(function(){this.opts.element.data("select2-change-triggered")!==!0&&this.initSelection()})),c=this.bind(function(){var d,f=a.prop("disabled");f===b&&(f=!1),this.enable(!f);var d=a.prop("readonly");d===b&&(d=!1),this.readonly(d),D(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.addClass(K(this.opts.containerCssClass)),D(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(K(this.opts.dropdownCssClass))}),a.on("propertychange.select2 DOMAttrModified.select2",c),this.mutationCallback===b&&(this.mutationCallback=function(a){a.forEach(c)}),"undefined"!=typeof WebKitMutationObserver&&(this.propertyObserver&&(delete this.propertyObserver,this.propertyObserver=null),this.propertyObserver=new WebKitMutationObserver(this.mutationCallback),this.propertyObserver.observe(a.get(0),{attributes:!0,subtree:!1}))},triggerSelect:function(b){var c=a.Event("select2-selecting",{val:this.id(b),object:b});return this.opts.element.trigger(c),!c.isDefaultPrevented()},triggerChange:function(b){b=b||{},b=a.extend({},b,{type:"change",val:this.val()}),this.opts.element.data("select2-change-triggered",!0),this.opts.element.trigger(b),this.opts.element.data("select2-change-triggered",!1),this.opts.element.click(),this.opts.blurOnChange&&this.opts.element.blur()},isInterfaceEnabled:function(){return this.enabledInterface===!0},enableInterface:function(){var a=this._enabled&&!this._readonly,b=!a;return a===this.enabledInterface?!1:(this.container.toggleClass("select2-container-disabled",b),this.close(),this.enabledInterface=a,!0)},enable:function(a){a===b&&(a=!0),this._enabled!==a&&(this._enabled=a,this.opts.element.prop("disabled",!a),this.enableInterface())},disable:function(){this.enable(!1)},readonly:function(a){return a===b&&(a=!1),this._readonly===a?!1:(this._readonly=a,this.opts.element.prop("readonly",a),this.enableInterface(),!0)},opened:function(){return this.container.hasClass("select2-dropdown-open")},positionDropdown:function(){var q,r,s,t,b=this.dropdown,c=this.container.offset(),d=this.container.outerHeight(!1),e=this.container.outerWidth(!1),f=b.outerHeight(!1),g=a(window).scrollLeft()+a(window).width(),h=a(window).scrollTop()+a(window).height(),i=c.top+d,j=c.left,l=h>=i+f,m=c.top-f>=this.body().scrollTop(),n=b.outerWidth(!1),o=g>=j+n,p=b.hasClass("select2-drop-above");this.opts.dropdownAutoWidth?(t=a(".select2-results",b)[0],b.addClass("select2-drop-auto-width"),b.css("width",""),n=b.outerWidth(!1)+(t.scrollHeight===t.clientHeight?0:k.width),n>e?e=n:n=e,o=g>=j+n):this.container.removeClass("select2-drop-auto-width"),"static"!==this.body().css("position")&&(q=this.body().offset(),i-=q.top,j-=q.left),p?(r=!0,!m&&l&&(r=!1)):(r=!1,!l&&m&&(r=!0)),o||(j=c.left+e-n),r?(i=c.top-f,this.container.addClass("select2-drop-above"),b.addClass("select2-drop-above")):(this.container.removeClass("select2-drop-above"),b.removeClass("select2-drop-above")),s=a.extend({top:i,left:j,width:e},K(this.opts.dropdownCss)),b.css(s)},shouldOpen:function(){var b;return this.opened()?!1:this._enabled===!1||this._readonly===!0?!1:(b=a.Event("select2-opening"),this.opts.element.trigger(b),!b.isDefaultPrevented())},clearDropdownAlignmentPreference:function(){this.container.removeClass("select2-drop-above"),this.dropdown.removeClass("select2-drop-above")},open:function(){return this.shouldOpen()?(this.opening(),!0):!1},opening:function(){var f,b=this.containerId,c="scroll."+b,d="resize."+b,e="orientationchange."+b;this.container.addClass("select2-dropdown-open").addClass("select2-container-active"),this.clearDropdownAlignmentPreference(),this.dropdown[0]!==this.body().children().last()[0]&&this.dropdown.detach().appendTo(this.body()),f=a("#select2-drop-mask"),0==f.length&&(f=a(document.createElement("div")),f.attr("id","select2-drop-mask").attr("class","select2-drop-mask"),f.hide(),f.appendTo(this.body()),f.on("mousedown touchstart click",function(b){var d,c=a("#select2-drop");c.length>0&&(d=c.data("select2"),d.opts.selectOnBlur&&d.selectHighlighted({noFocus:!0}),d.close({focus:!1}),b.preventDefault(),b.stopPropagation())})),this.dropdown.prev()[0]!==f[0]&&this.dropdown.before(f),a("#select2-drop").removeAttr("id"),this.dropdown.attr("id","select2-drop"),f.show(),this.positionDropdown(),this.dropdown.show(),this.positionDropdown(),this.dropdown.addClass("select2-drop-active");var h=this;this.container.parents().add(window).each(function(){a(this).on(d+" "+c+" "+e,function(){h.positionDropdown()})})},close:function(){if(this.opened()){var b=this.containerId,c="scroll."+b,d="resize."+b,e="orientationchange."+b;this.container.parents().add(window).each(function(){a(this).off(c).off(d).off(e)}),this.clearDropdownAlignmentPreference(),a("#select2-drop-mask").hide(),this.dropdown.removeAttr("id"),this.dropdown.hide(),this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active"),this.results.empty(),this.clearSearch(),this.search.removeClass("select2-active"),this.opts.element.trigger(a.Event("select2-close"))}},externalSearch:function(a){this.open(),this.search.val(a),this.updateResults(!1)},clearSearch:function(){},getMaximumSelectionSize:function(){return K(this.opts.maximumSelectionSize)},ensureHighlightVisible:function(){var c,d,e,f,g,h,i,b=this.results;if(d=this.highlight(),!(0>d)){if(0==d)return b.scrollTop(0),void 0;c=this.findHighlightableChoices().find(".select2-result-label"),e=a(c[d]),f=e.offset().top+e.outerHeight(!0),d===c.length-1&&(i=b.find("li.select2-more-results"),i.length>0&&(f=i.offset().top+i.outerHeight(!0))),g=b.offset().top+b.outerHeight(!0),f>g&&b.scrollTop(b.scrollTop()+(f-g)),h=e.offset().top-b.offset().top,0>h&&"none"!=e.css("display")&&b.scrollTop(b.scrollTop()+h)}},findHighlightableChoices:function(){return this.results.find(".select2-result-selectable:not(.select2-disabled)")},moveHighlight:function(b){for(var c=this.findHighlightableChoices(),d=this.highlight();d>-1&&d=c.length&&(b=c.length-1),0>b&&(b=0),this.removeHighlight(),d=a(c[b]),d.addClass("select2-highlighted"),this.ensureHighlightVisible(),e=d.data("select2-data"),e&&this.opts.element.trigger({type:"select2-highlight",val:this.id(e),choice:e}),void 0)},removeHighlight:function(){this.results.find(".select2-highlighted").removeClass("select2-highlighted")},countSelectableResults:function(){return this.findHighlightableChoices().length},highlightUnderEvent:function(b){var c=a(b.target).closest(".select2-result-selectable");if(c.length>0&&!c.is(".select2-highlighted")){var d=this.findHighlightableChoices();this.highlight(d.index(c))}else 0==c.length&&this.removeHighlight()},loadMoreIfNeeded:function(){var c,a=this.results,b=a.find("li.select2-more-results"),e=this.resultsPage+1,f=this,g=this.search.val(),h=this.context;0!==b.length&&(c=b.offset().top-a.offset().top-a.height(),c<=this.opts.loadMorePadding&&(b.addClass("select2-active"),this.opts.query({element:this.opts.element,term:g,page:e,context:h,matcher:this.opts.matcher,callback:this.bind(function(c){f.opened()&&(f.opts.populateResults.call(this,a,c.results,{term:g,page:e,context:h}),f.postprocessResults(c,!1,!1),c.more===!0?(b.detach().appendTo(a).text(f.opts.formatLoadMore(e+1)),window.setTimeout(function(){f.loadMoreIfNeeded()},10)):b.remove(),f.positionDropdown(),f.resultsPage=e,f.context=c.context,this.opts.element.trigger({type:"select2-loaded",items:c}))})})))},tokenize:function(){},updateResults:function(c){function m(){d.removeClass("select2-active"),h.positionDropdown()}function n(a){e.html(a),m()}var g,i,l,d=this.search,e=this.results,f=this.opts,h=this,j=d.val(),k=a.data(this.container,"select2-last-term");if((c===!0||!k||!q(j,k))&&(a.data(this.container,"select2-last-term",j),c===!0||this.showSearchInput!==!1&&this.opened())){l=++this.queryCount;var o=this.getMaximumSelectionSize();if(o>=1&&(g=this.data(),a.isArray(g)&&g.length>=o&&J(f.formatSelectionTooBig,"formatSelectionTooBig")))return n(""+f.formatSelectionTooBig(o)+" "),void 0;if(d.val().length"+f.formatInputTooShort(d.val(),f.minimumInputLength)+""):n(""),c&&this.showSearch&&this.showSearch(!0),void 0;if(f.maximumInputLength&&d.val().length>f.maximumInputLength)return J(f.formatInputTooLong,"formatInputTooLong")?n(""+f.formatInputTooLong(d.val(),f.maximumInputLength)+" "):n(""),void 0;
-f.formatSearching&&0===this.findHighlightableChoices().length&&n(""+f.formatSearching()+" "),d.addClass("select2-active"),this.removeHighlight(),i=this.tokenize(),i!=b&&null!=i&&d.val(i),this.resultsPage=1,f.query({element:f.element,term:d.val(),page:this.resultsPage,context:null,matcher:f.matcher,callback:this.bind(function(g){var i;if(l==this.queryCount){if(!this.opened())return this.search.removeClass("select2-active"),void 0;if(this.context=g.context===b?null:g.context,this.opts.createSearchChoice&&""!==d.val()&&(i=this.opts.createSearchChoice.call(h,d.val(),g.results),i!==b&&null!==i&&h.id(i)!==b&&null!==h.id(i)&&0===a(g.results).filter(function(){return q(h.id(this),h.id(i))}).length&&g.results.unshift(i)),0===g.results.length&&J(f.formatNoMatches,"formatNoMatches"))return n(""+f.formatNoMatches(d.val())+" "),void 0;e.empty(),h.opts.populateResults.call(this,e,g.results,{term:d.val(),page:this.resultsPage,context:null}),g.more===!0&&J(f.formatLoadMore,"formatLoadMore")&&(e.append(""+h.opts.escapeMarkup(f.formatLoadMore(this.resultsPage))+" "),window.setTimeout(function(){h.loadMoreIfNeeded()},10)),this.postprocessResults(g,c),m(),this.opts.element.trigger({type:"select2-loaded",items:g})}})})}},cancel:function(){this.close()},blur:function(){this.opts.selectOnBlur&&this.selectHighlighted({noFocus:!0}),this.close(),this.container.removeClass("select2-container-active"),this.search[0]===document.activeElement&&this.search.blur(),this.clearSearch(),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")},focusSearch:function(){y(this.search)},selectHighlighted:function(a){var b=this.highlight(),c=this.results.find(".select2-highlighted"),d=c.closest(".select2-result").data("select2-data");d?(this.highlight(b),this.onSelect(d,a)):a&&a.noFocus&&this.close()},getPlaceholder:function(){var a;return this.opts.element.attr("placeholder")||this.opts.element.attr("data-placeholder")||this.opts.element.data("placeholder")||this.opts.placeholder||((a=this.getPlaceholderOption())!==b?a.text():b)},getPlaceholderOption:function(){if(this.select){var a=this.select.children().first();if(this.opts.placeholderOption!==b)return"first"===this.opts.placeholderOption&&a||"function"==typeof this.opts.placeholderOption&&this.opts.placeholderOption(this.select);if(""===a.text()&&""===a.val())return a}},initContainerWidth:function(){function c(){var c,d,e,f,g;if("off"===this.opts.width)return null;if("element"===this.opts.width)return 0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px";if("copy"===this.opts.width||"resolve"===this.opts.width){if(c=this.opts.element.attr("style"),c!==b)for(d=c.split(";"),f=0,g=d.length;g>f;f+=1)if(e=d[f].replace(/\s/g,"").match(/[^-]width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i),null!==e&&e.length>=1)return e[1];return"resolve"===this.opts.width?(c=this.opts.element.css("width"),c.indexOf("%")>0?c:0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px"):null}return a.isFunction(this.opts.width)?this.opts.width():this.opts.width}var d=c.call(this);null!==d&&this.container.css("width",d)}}),e=N(d,{createContainer:function(){var b=a(document.createElement("div")).attr({"class":"select2-container"}).html([""," "," "," "," ",""].join(""));return b},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.focusser.prop("disabled",!this.isInterfaceEnabled())},opening:function(){var c,d,e;this.opts.minimumResultsForSearch>=0&&this.showSearch(!0),this.parent.opening.apply(this,arguments),this.showSearchInput!==!1&&this.search.val(this.focusser.val()),this.search.focus(),c=this.search.get(0),c.createTextRange?(d=c.createTextRange(),d.collapse(!1),d.select()):c.setSelectionRange&&(e=this.search.val().length,c.setSelectionRange(e,e)),""===this.search.val()&&this.nextSearchTerm!=b&&(this.search.val(this.nextSearchTerm),this.search.select()),this.focusser.prop("disabled",!0).val(""),this.updateResults(!0),this.opts.element.trigger(a.Event("select2-open"))},close:function(a){this.opened()&&(this.parent.close.apply(this,arguments),a=a||{focus:!0},this.focusser.removeAttr("disabled"),a.focus&&this.focusser.focus())},focus:function(){this.opened()?this.close():(this.focusser.removeAttr("disabled"),this.focusser.focus())},isFocused:function(){return this.container.hasClass("select2-container-active")},cancel:function(){this.parent.cancel.apply(this,arguments),this.focusser.removeAttr("disabled"),this.focusser.focus()},destroy:function(){a("label[for='"+this.focusser.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments)},initContainer:function(){var b,d=this.container,e=this.dropdown;this.opts.minimumResultsForSearch<0?this.showSearch(!1):this.showSearch(!0),this.selection=b=d.find(".select2-choice"),this.focusser=d.find(".select2-focusser"),this.focusser.attr("id","s2id_autogen"+g()),a("label[for='"+this.opts.element.attr("id")+"']").attr("for",this.focusser.attr("id")),this.focusser.attr("tabindex",this.elementTabIndex),this.search.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()){if(a.which===c.PAGE_UP||a.which===c.PAGE_DOWN)return A(a),void 0;switch(a.which){case c.UP:case c.DOWN:return this.moveHighlight(a.which===c.UP?-1:1),A(a),void 0;case c.ENTER:return this.selectHighlighted(),A(a),void 0;case c.TAB:return this.selectHighlighted({noFocus:!0}),void 0;case c.ESC:return this.cancel(a),A(a),void 0}}})),this.search.on("blur",this.bind(function(){document.activeElement===this.body().get(0)&&window.setTimeout(this.bind(function(){this.search.focus()}),0)})),this.focusser.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()&&a.which!==c.TAB&&!c.isControl(a)&&!c.isFunctionKey(a)&&a.which!==c.ESC){if(this.opts.openOnEnter===!1&&a.which===c.ENTER)return A(a),void 0;if(a.which==c.DOWN||a.which==c.UP||a.which==c.ENTER&&this.opts.openOnEnter){if(a.altKey||a.ctrlKey||a.shiftKey||a.metaKey)return;return this.open(),A(a),void 0}return a.which==c.DELETE||a.which==c.BACKSPACE?(this.opts.allowClear&&this.clear(),A(a),void 0):void 0}})),t(this.focusser),this.focusser.on("keyup-change input",this.bind(function(a){if(this.opts.minimumResultsForSearch>=0){if(a.stopPropagation(),this.opened())return;this.open()}})),b.on("mousedown","abbr",this.bind(function(a){this.isInterfaceEnabled()&&(this.clear(),B(a),this.close(),this.selection.focus())})),b.on("mousedown",this.bind(function(b){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),A(b)})),e.on("mousedown",this.bind(function(){this.search.focus()})),b.on("focus",this.bind(function(a){A(a)})),this.focusser.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})).on("blur",this.bind(function(){this.opened()||(this.container.removeClass("select2-container-active"),this.opts.element.trigger(a.Event("select2-blur")))})),this.search.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})),this.initContainerWidth(),this.opts.element.addClass("select2-offscreen"),this.setPlaceholder()},clear:function(b){var c=this.selection.data("select2-data");if(c){var d=a.Event("select2-clearing");if(this.opts.element.trigger(d),d.isDefaultPrevented())return;var e=this.getPlaceholderOption();this.opts.element.val(e?e.val():""),this.selection.find(".select2-chosen").empty(),this.selection.removeData("select2-data"),this.setPlaceholder(),b!==!1&&(this.opts.element.trigger({type:"select2-removed",val:this.id(c),choice:c}),this.triggerChange({removed:c}))}},initSelection:function(){if(this.isPlaceholderOptionSelected())this.updateSelection(null),this.close(),this.setPlaceholder();else{var c=this;this.opts.initSelection.call(null,this.opts.element,function(a){a!==b&&null!==a&&(c.updateSelection(a),c.close(),c.setPlaceholder())})}},isPlaceholderOptionSelected:function(){var a;return this.getPlaceholder()?(a=this.getPlaceholderOption())!==b&&a.is(":selected")||""===this.opts.element.val()||this.opts.element.val()===b||null===this.opts.element.val():!1},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=a.find(":selected");b(c.optionToData(d))}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=c.val(),f=null;b.query({matcher:function(a,c,d){var g=q(e,b.id(d));return g&&(f=d),g},callback:a.isFunction(d)?function(){d(f)}:a.noop})}),b},getPlaceholder:function(){return this.select&&this.getPlaceholderOption()===b?b:this.parent.getPlaceholder.apply(this,arguments)},setPlaceholder:function(){var a=this.getPlaceholder();if(this.isPlaceholderOptionSelected()&&a!==b){if(this.select&&this.getPlaceholderOption()===b)return;this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(a)),this.selection.addClass("select2-default"),this.container.removeClass("select2-allowclear")}},postprocessResults:function(a,b,c){var d=0,e=this;if(this.findHighlightableChoices().each2(function(a,b){return q(e.id(b.data("select2-data")),e.opts.element.val())?(d=a,!1):void 0}),c!==!1&&(b===!0&&d>=0?this.highlight(d):this.highlight(0)),b===!0){var g=this.opts.minimumResultsForSearch;g>=0&&this.showSearch(L(a.results)>=g)}},showSearch:function(b){this.showSearchInput!==b&&(this.showSearchInput=b,this.dropdown.find(".select2-search").toggleClass("select2-search-hidden",!b),this.dropdown.find(".select2-search").toggleClass("select2-offscreen",!b),a(this.dropdown,this.container).toggleClass("select2-with-searchbox",b))},onSelect:function(a,b){if(this.triggerSelect(a)){var c=this.opts.element.val(),d=this.data();this.opts.element.val(this.id(a)),this.updateSelection(a),this.opts.element.trigger({type:"select2-selected",val:this.id(a),choice:a}),this.nextSearchTerm=this.opts.nextSearchTerm(a,this.search.val()),this.close(),b&&b.noFocus||this.focusser.focus(),q(c,this.id(a))||this.triggerChange({added:a,removed:d})}},updateSelection:function(a){var d,e,c=this.selection.find(".select2-chosen");this.selection.data("select2-data",a),c.empty(),null!==a&&(d=this.opts.formatSelection(a,c,this.opts.escapeMarkup)),d!==b&&c.append(d),e=this.opts.formatSelectionCssClass(a,c),e!==b&&c.addClass(e),this.selection.removeClass("select2-default"),this.opts.allowClear&&this.getPlaceholder()!==b&&this.container.addClass("select2-allowclear")},val:function(){var a,c=!1,d=null,e=this,f=this.data();if(0===arguments.length)return this.opts.element.val();if(a=arguments[0],arguments.length>1&&(c=arguments[1]),this.select)this.select.val(a).find(":selected").each2(function(a,b){return d=e.optionToData(b),!1}),this.updateSelection(d),this.setPlaceholder(),c&&this.triggerChange({added:d,removed:f});else{if(!a&&0!==a)return this.clear(c),void 0;if(this.opts.initSelection===b)throw new Error("cannot call val() if initSelection() is not defined");this.opts.element.val(a),this.opts.initSelection(this.opts.element,function(a){e.opts.element.val(a?e.id(a):""),e.updateSelection(a),e.setPlaceholder(),c&&e.triggerChange({added:a,removed:f})})}},clearSearch:function(){this.search.val(""),this.focusser.val("")},data:function(a){var c,d=!1;return 0===arguments.length?(c=this.selection.data("select2-data"),c==b&&(c=null),c):(arguments.length>1&&(d=arguments[1]),a?(c=this.data(),this.opts.element.val(a?this.id(a):""),this.updateSelection(a),d&&this.triggerChange({added:a,removed:c})):this.clear(d),void 0)}}),f=N(d,{createContainer:function(){var b=a(document.createElement("div")).attr({"class":"select2-container select2-container-multi"}).html(["",""].join(""));return b},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=[];a.find(":selected").each2(function(a,b){d.push(c.optionToData(b))}),b(d)}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=r(c.val(),b.separator),f=[];b.query({matcher:function(c,d,g){var h=a.grep(e,function(a){return q(a,b.id(g))}).length;return h&&f.push(g),h},callback:a.isFunction(d)?function(){for(var a=[],c=0;c0||(this.selectChoice(null),this.clearPlaceholder(),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.open(),this.focusSearch(),b.preventDefault()))})),this.container.on("focus",b,this.bind(function(){this.isInterfaceEnabled()&&(this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"),this.clearPlaceholder())})),this.initContainerWidth(),this.opts.element.addClass("select2-offscreen"),this.clearSearch()},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.search.prop("disabled",!this.isInterfaceEnabled())},initSelection:function(){if(""===this.opts.element.val()&&""===this.opts.element.text()&&(this.updateSelection([]),this.close(),this.clearSearch()),this.select||""!==this.opts.element.val()){var c=this;this.opts.initSelection.call(null,this.opts.element,function(a){a!==b&&null!==a&&(c.updateSelection(a),c.close(),c.clearSearch())})}},clearSearch:function(){var a=this.getPlaceholder(),c=this.getMaxSearchWidth();a!==b&&0===this.getVal().length&&this.search.hasClass("select2-focused")===!1?(this.search.val(a).addClass("select2-default"),this.search.width(c>0?c:this.container.css("width"))):this.search.val("").width(10)},clearPlaceholder:function(){this.search.hasClass("select2-default")&&this.search.val("").removeClass("select2-default")},opening:function(){this.clearPlaceholder(),this.resizeSearch(),this.parent.opening.apply(this,arguments),this.focusSearch(),this.updateResults(!0),this.search.focus(),this.opts.element.trigger(a.Event("select2-open"))},close:function(){this.opened()&&this.parent.close.apply(this,arguments)},focus:function(){this.close(),this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(b){var c=[],d=[],e=this;a(b).each(function(){o(e.id(this),c)<0&&(c.push(e.id(this)),d.push(this))}),b=d,this.selection.find(".select2-search-choice").remove(),a(b).each(function(){e.addSelectedChoice(this)}),e.postprocessResults()},tokenize:function(){var a=this.search.val();a=this.opts.tokenizer.call(this,a,this.data(),this.bind(this.onSelect),this.opts),null!=a&&a!=b&&(this.search.val(a),a.length>0&&this.open())},onSelect:function(a,b){this.triggerSelect(a)&&(this.addSelectedChoice(a),this.opts.element.trigger({type:"selected",val:this.id(a),choice:a}),(this.select||!this.opts.closeOnSelect)&&this.postprocessResults(a,!1,this.opts.closeOnSelect===!0),this.opts.closeOnSelect?(this.close(),this.search.width(10)):this.countSelectableResults()>0?(this.search.width(10),this.resizeSearch(),this.getMaximumSelectionSize()>0&&this.val().length>=this.getMaximumSelectionSize()&&this.updateResults(!0),this.positionDropdown()):(this.close(),this.search.width(10)),this.triggerChange({added:a}),b&&b.noFocus||this.focusSearch())},cancel:function(){this.close(),this.focusSearch()},addSelectedChoice:function(c){var j,k,d=!c.locked,e=a("
"),f=a("
"),g=d?e:f,h=this.id(c),i=this.getVal();j=this.opts.formatSelection(c,g.find("div"),this.opts.escapeMarkup),j!=b&&g.find("div").replaceWith(""+j+"
"),k=this.opts.formatSelectionCssClass(c,g.find("div")),k!=b&&g.addClass(k),d&&g.find(".select2-search-choice-close").on("mousedown",A).on("click dblclick",this.bind(function(b){this.isInterfaceEnabled()&&(a(b.target).closest(".select2-search-choice").fadeOut("fast",this.bind(function(){this.unselect(a(b.target)),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"),this.close(),this.focusSearch()})).dequeue(),A(b))})).on("focus",this.bind(function(){this.isInterfaceEnabled()&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"))})),g.data("select2-data",c),g.insertBefore(this.searchContainer),i.push(h),this.setVal(i)},unselect:function(a){var c,d,b=this.getVal();if(a=a.closest(".select2-search-choice"),0===a.length)throw"Invalid argument: "+a+". Must be .select2-search-choice";if(c=a.data("select2-data")){for(;(d=o(this.id(c),b))>=0;)b.splice(d,1),this.setVal(b),this.select&&this.postprocessResults();a.remove(),this.opts.element.trigger({type:"removed",val:this.id(c),choice:c}),this.triggerChange({removed:c})}},postprocessResults:function(a,b,c){var d=this.getVal(),e=this.results.find(".select2-result"),f=this.results.find(".select2-result-with-children"),g=this;e.each2(function(a,b){var c=g.id(b.data("select2-data"));o(c,d)>=0&&(b.addClass("select2-selected"),b.find(".select2-result-selectable").addClass("select2-selected"))}),f.each2(function(a,b){b.is(".select2-result-selectable")||0!==b.find(".select2-result-selectable:not(.select2-selected)").length||b.addClass("select2-selected")}),-1==this.highlight()&&c!==!1&&g.highlight(0),!this.opts.createSearchChoice&&!e.filter(".select2-result:not(.select2-selected)").length>0&&(!a||a&&!a.more&&0===this.results.find(".select2-no-results").length)&&J(g.opts.formatNoMatches,"formatNoMatches")&&this.results.append(""+g.opts.formatNoMatches(g.search.val())+" ")},getMaxSearchWidth:function(){return this.selection.width()-s(this.search)},resizeSearch:function(){var a,b,c,d,e,f=s(this.search);a=C(this.search)+10,b=this.search.offset().left,c=this.selection.width(),d=this.selection.offset().left,e=c-(b-d)-f,a>e&&(e=c-f),40>e&&(e=c-f),0>=e&&(e=a),this.search.width(Math.floor(e))},getVal:function(){var a;return this.select?(a=this.select.val(),null===a?[]:a):(a=this.opts.element.val(),r(a,this.opts.separator))},setVal:function(b){var c;this.select?this.select.val(b):(c=[],a(b).each(function(){o(this,c)<0&&c.push(this)}),this.opts.element.val(0===c.length?"":c.join(this.opts.separator)))},buildChangeDetails:function(a,b){for(var b=b.slice(0),a=a.slice(0),c=0;c. Attach to instead.");this.search.width(0),this.searchContainer.hide()},onSortEnd:function(){var b=[],c=this;this.searchContainer.show(),this.searchContainer.appendTo(this.searchContainer.parent()),this.resizeSearch(),this.selection.find(".select2-search-choice").each(function(){b.push(c.opts.id(a(this).data("select2-data")))}),this.setVal(b),this.triggerChange()},data:function(b,c){var e,f,d=this;return 0===arguments.length?this.selection.find(".select2-search-choice").map(function(){return a(this).data("select2-data")}).get():(f=this.data(),b||(b=[]),e=a.map(b,function(a){return d.opts.id(a)}),this.setVal(e),this.updateSelection(b),this.clearSearch(),c&&this.triggerChange(this.buildChangeDetails(f,this.data())),void 0)}}),a.fn.select2=function(){var d,g,h,i,j,c=Array.prototype.slice.call(arguments,0),k=["val","destroy","opened","open","close","focus","isFocused","container","dropdown","onSortStart","onSortEnd","enable","disable","readonly","positionDropdown","data","search"],l=["opened","isFocused","container","dropdown"],m=["val","data"],n={search:"externalSearch"};return this.each(function(){if(0===c.length||"object"==typeof c[0])d=0===c.length?{}:a.extend({},c[0]),d.element=a(this),"select"===d.element.get(0).tagName.toLowerCase()?j=d.element.prop("multiple"):(j=d.multiple||!1,"tags"in d&&(d.multiple=j=!0)),g=j?new f:new e,g.init(d);else{if("string"!=typeof c[0])throw"Invalid arguments to select2 plugin: "+c;if(o(c[0],k)<0)throw"Unknown method: "+c[0];if(i=b,g=a(this).data("select2"),g===b)return;if(h=c[0],"container"===h?i=g.container:"dropdown"===h?i=g.dropdown:(n[h]&&(h=n[h]),i=g[h].apply(g,c.slice(1))),o(c[0],l)>=0||o(c[0],m)&&1==c.length)return!1}}),i===b?this:i},a.fn.select2.defaults={width:"copy",loadMorePadding:0,closeOnSelect:!0,openOnEnter:!0,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(a,b,c,d){var e=[];return E(a.text,c.term,e,d),e.join("")},formatSelection:function(a,c,d){return a?d(a.text):b},sortResults:function(a){return a},formatResultCssClass:function(){return b},formatSelectionCssClass:function(){return b},formatNoMatches:function(){return"No matches found"},formatInputTooShort:function(a,b){var c=b-a.length;return"Please enter "+c+" more character"+(1==c?"":"s")},formatInputTooLong:function(a,b){var c=a.length-b;return"Please delete "+c+" character"+(1==c?"":"s")},formatSelectionTooBig:function(a){return"You can only select "+a+" item"+(1==a?"":"s")},formatLoadMore:function(){return"Loading more results..."},formatSearching:function(){return"Searching..."},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(a){return a.id},matcher:function(a,b){return n(""+b).toUpperCase().indexOf(n(""+a).toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:M,escapeMarkup:F,blurOnChange:!1,selectOnBlur:!1,adaptContainerCssClass:function(a){return a},adaptDropdownCssClass:function(){return null},nextSearchTerm:function(){return b}},a.fn.select2.ajaxDefaults={transport:a.ajax,params:{type:"GET",cache:!1,dataType:"json"}},window.Select2={query:{ajax:G,local:H,tags:I},util:{debounce:v,markMatch:E,escapeMarkup:F,stripDiacritics:n},"class":{"abstract":d,single:e,multi:f}}}}(jQuery);
\ No newline at end of file
diff --git a/oscar_support/static/oscar_support/lib/select2/select2.png b/oscar_support/static/oscar_support/lib/select2/select2.png
deleted file mode 100644
index 1d804ff..0000000
Binary files a/oscar_support/static/oscar_support/lib/select2/select2.png and /dev/null differ
diff --git a/oscar_support/static/oscar_support/lib/select2/select2x2.png b/oscar_support/static/oscar_support/lib/select2/select2x2.png
deleted file mode 100644
index 4bdd5c9..0000000
Binary files a/oscar_support/static/oscar_support/lib/select2/select2x2.png and /dev/null differ
diff --git a/oscar_support/templates/oscar_support/customer/partials/ticket_table.html b/oscar_support/templates/oscar_support/customer/partials/ticket_table.html
index cb8a204..f10bd15 100644
--- a/oscar_support/templates/oscar_support/customer/partials/ticket_table.html
+++ b/oscar_support/templates/oscar_support/customer/partials/ticket_table.html
@@ -1,5 +1,4 @@
{% load i18n %}
-{% load url from future %}
{% if ticket_list|length %}
@@ -19,7 +18,7 @@
{{ ticket.date_updated|date:"jS M Y H:i" }}
{{ ticket.assignee.get_full_name|default:"-" }}
- {% trans "Update" %}
+ {% trans "Update" %}
{% endfor %}
diff --git a/oscar_support/templates/oscar_support/customer/ticket_create.html b/oscar_support/templates/oscar_support/customer/ticket_create.html
index c63548b..c0706bb 100644
--- a/oscar_support/templates/oscar_support/customer/ticket_create.html
+++ b/oscar_support/templates/oscar_support/customer/ticket_create.html
@@ -1,46 +1,40 @@
-{% extends "oscar/customer/profile/profile.html" %}
-
+{% extends "customer/baseaccountpage.html" %}
{% load i18n %}
-{% load url from future %}
-
-{% block title %}
-{% trans 'Create new ticket' %} | {{ block.super }}
-{% endblock %}
-{% block body_class %}account-pages{% endblock %}
-
-{% block breadcrumbs %}
-
{% endblock %}
-{% block headertext %}{% trans 'Create new ticket' %}{% endblock headertext %}
-
-{% block content %}
-
-{% endblock content %}
+{% block tabcontent %}
+
+{% endblock tabcontent %}
diff --git a/oscar_support/templates/oscar_support/customer/ticket_list.html b/oscar_support/templates/oscar_support/customer/ticket_list.html
index 658ec81..b280a38 100644
--- a/oscar_support/templates/oscar_support/customer/ticket_list.html
+++ b/oscar_support/templates/oscar_support/customer/ticket_list.html
@@ -1,61 +1,34 @@
-{% extends "oscar/customer/profile/profile.html" %}
+{% extends "customer/baseaccountpage.html" %}
{% load i18n %}
-{% load url from future %}
-{% block title %}
-{% trans 'Your tickets' %} | {{ block.super }}
-{% endblock %}
-
-{% block body_class %}account-pages{% endblock %}
-
-{% block breadcrumbs %}
-
-{% endblock %}
-
-{% block headertext %}{% trans 'Your tickets' %}{% endblock headertext %}
-
-{% block content %}
-
-
-
-
-
+{% block tabcontent %}
+
-
-
- {% include "oscar_support/customer/partials/ticket_table.html" with ticket_list=open_ticket_list %}
+
+
-
- {% include "oscar_support/customer/partials/ticket_table.html" with ticket_list=resolved_ticket_list %}
+
+
+ {% include "oscar_support/customer/partials/ticket_table.html" with ticket_list=open_ticket_list %}
+
+
+
+ {% include "oscar_support/customer/partials/ticket_table.html" with ticket_list=resolved_ticket_list %}
+
-
-{% endblock content %}
+{% endblock tabcontent %}
diff --git a/oscar_support/templates/oscar_support/customer/ticket_update.html b/oscar_support/templates/oscar_support/customer/ticket_update.html
index 6a7a43a..78da7b4 100644
--- a/oscar_support/templates/oscar_support/customer/ticket_update.html
+++ b/oscar_support/templates/oscar_support/customer/ticket_update.html
@@ -1,118 +1,136 @@
-{% extends "oscar/customer/profile/profile.html" %}
+{% extends "customer/baseaccountpage.html" %}
{% load i18n %}
-{% load url from future %}
{% load thumbnail %}
-{% block body_class %}account-pages{% endblock %}
-
-{% block title %}
-{% blocktrans with ticket_number=ticket.number %}Update ticket #{{ ticket_number }}{% endblocktrans %} | {{ block.super }}
-{% endblock %}
-
-{% block breadcrumbs %}
-
{% endblock %}
-{% block headertext %}
- {% blocktrans with ticket_number=ticket.number %}Update ticket #{{ ticket_number }}{% endblocktrans %}
-{% endblock headertext %}
+{% block tabcontent %}
+
+
+
+
+ {% trans "Type" %}
+ {% trans "Status" %}
+ {% trans "Priority" %}
+ {% trans "Date created" %}
+ {% trans "Last updated" %}
+ {% trans "Assigned to" %}
+
+
+ {{ ticket.type.name }}
+ {{ ticket.status.name }}
+ {{ ticket.priority.name }}
+ {{ ticket.date_created|date:"jS M Y H:i" }}
+ {{ ticket.date_updated|date:"jS M Y H:i" }}
+ {{ ticket.assignee.get_full_name|default:"-" }}
+
-{% block content %}
-
+
+
- {% with related_products=ticket.relatedproducts.all %}
- {% if related_products|length %}
-
-
- {% trans "Related product(s):" %}
- {% for related_product in related_products %}
+
+ {% endblock ticket_attachment_content %}
+
+ {% endblock ticket_attachment %}
-
+
+ {% trans "Send message" %}
+
+
-
+
-{% for message in message_list %}
-
-
From: {{ message.user.get_full_name|default:message.user.email }}, {{ message.date_created|date:"jS M Y H:i" }}
- {{ message.text|safe }}
-
-{% endfor %}
+ {% for message in message_list %}
+ {% if not message.is_internal %}
+
+
+ From: {{ message.user.get_full_name|default:message.user.email }}, {{ message.date_created|date:"jS M Y H:i" }}
+
+ {{ message.text|safe }}
+
+ {% endif %}
+ {% endfor %}
-
-
From: {{ ticket.requester.get_full_name|default:ticket.requester.email }}, {{ ticket.date_created|date:"jS M Y H:i" }}
- {{ ticket.body|safe }}
-
-{% endblock content %}
+
+
+ From: {{ ticket.requester.get_full_name|default:ticket.requester.email }}, {{ ticket.date_created|date:"jS M Y H:i" }}
+
+ {{ ticket.body|safe }}
+
+{% endblock tabcontent %}
diff --git a/oscar_support/templates/oscar_support/dashboard/layout.html b/oscar_support/templates/oscar_support/dashboard/layout.html
index c1cf48d..5481527 100644
--- a/oscar_support/templates/oscar_support/dashboard/layout.html
+++ b/oscar_support/templates/oscar_support/dashboard/layout.html
@@ -3,7 +3,6 @@
{% block extrahead %}
{{ block.super }}
-
@@ -11,6 +10,5 @@
{% block extrascripts %}
{{ block.super }}
-
{% endblock %}
diff --git a/oscar_support/templates/oscar_support/dashboard/partials/attachments.html b/oscar_support/templates/oscar_support/dashboard/partials/attachments.html
new file mode 100644
index 0000000..88715c9
--- /dev/null
+++ b/oscar_support/templates/oscar_support/dashboard/partials/attachments.html
@@ -0,0 +1,50 @@
+{% load i18n %}
+{% load currency_filters %}
+
+
+{% block ticket_attachment %}
+
+ {% block ticket_attachment_content %}
+ {{ attachment_formset.management_form }}
+ {{ attachment_formset.non_form_errors }}
+
+
+
+ {% trans "File" %}
+ {% trans "Delete?" %}
+
+
+
+ {% for attachment_form in attachment_formset %}
+ {% if attachment_form.non_field_errors %}
+
+
+ {% for error in attachment_form.non_field_errors %}
+ {{ error }}
+ {% endfor %}
+
+
+ {% endif %}
+
+
+ {% include "dashboard/partials/form_field.html" with field=attachment_form.file nolabel=True %}
+
+
+ {% include "dashboard/partials/form_field.html" with field=attachment_form.uuid nolabel=True %}
+ {% include "dashboard/partials/form_field.html" with field=attachment_form.DELETE nolabel=True %}
+
+
+ {% endfor %}
+
+
+ {% endblock ticket_attachment_content %}
+
+{% endblock ticket_attachment %}
diff --git a/oscar_support/templates/oscar_support/dashboard/partials/inline_form.html b/oscar_support/templates/oscar_support/dashboard/partials/inline_form.html
index aa7751c..2266da4 100644
--- a/oscar_support/templates/oscar_support/dashboard/partials/inline_form.html
+++ b/oscar_support/templates/oscar_support/dashboard/partials/inline_form.html
@@ -1,4 +1,4 @@
-
+
{{ formset.management_form }}
{% for form in formset %}
diff --git a/oscar_support/templates/oscar_support/dashboard/partials/inline_tag.html b/oscar_support/templates/oscar_support/dashboard/partials/inline_tag.html
new file mode 100644
index 0000000..5fdb662
--- /dev/null
+++ b/oscar_support/templates/oscar_support/dashboard/partials/inline_tag.html
@@ -0,0 +1,53 @@
+{% load i18n %}
+{% load currency_filters %}
+
+
+{% block tag %}
+
+
+{% endblock tag %}
diff --git a/oscar_support/templates/oscar_support/dashboard/partials/related_lines.html b/oscar_support/templates/oscar_support/dashboard/partials/related_lines.html
index 7aaae06..3adc1af 100644
--- a/oscar_support/templates/oscar_support/dashboard/partials/related_lines.html
+++ b/oscar_support/templates/oscar_support/dashboard/partials/related_lines.html
@@ -2,34 +2,63 @@
{% load currency_filters %}
-{% for rel_line in ticket.relatedlines.all %}
- {% with line=rel_line.line %}
-
+{% endblock ticket_line %}
diff --git a/oscar_support/templates/oscar_support/dashboard/partials/related_orders.html b/oscar_support/templates/oscar_support/dashboard/partials/related_orders.html
index 3cb6a18..51db02a 100644
--- a/oscar_support/templates/oscar_support/dashboard/partials/related_orders.html
+++ b/oscar_support/templates/oscar_support/dashboard/partials/related_orders.html
@@ -1,29 +1,58 @@
{% load i18n %}
{% load currency_filters %}
+
-{% for rel_order in ticket.relatedorders.all %}
- {% with order=rel_order.order %}
-
+{% endblock ticket_order %}
diff --git a/oscar_support/templates/oscar_support/dashboard/partials/related_products.html b/oscar_support/templates/oscar_support/dashboard/partials/related_products.html
index 21b2dd8..26ccb5b 100644
--- a/oscar_support/templates/oscar_support/dashboard/partials/related_products.html
+++ b/oscar_support/templates/oscar_support/dashboard/partials/related_products.html
@@ -5,16 +5,20 @@
-{% for rel_product in ticket.relatedproducts.all %}
- {% with product=rel_product.product %}
-
+{% endblock ticket_product %}
diff --git a/oscar_support/templates/oscar_support/dashboard/partials/save_with_status.html b/oscar_support/templates/oscar_support/dashboard/partials/save_with_status.html
index a0d3cdc..5d1187a 100644
--- a/oscar_support/templates/oscar_support/dashboard/partials/save_with_status.html
+++ b/oscar_support/templates/oscar_support/dashboard/partials/save_with_status.html
@@ -11,15 +11,17 @@
Submit as {{ status_name }}
{% endblocktrans %}
-
+
-