# Path: catalog/models.py
# class Attribute(TranslatableModel):
#     """
#     Used to define different types of attributes to be assigned on a
#     Product variant. Eg. For a t-shirt attributes could be size, color,
#     pattern etc.
#     """
#     KIND_OPTION = 'option'
#     KIND_FILE = 'file'
#     KIND_IMAGE = 'image'
#     KIND_INTEGER = 'integer'
#     KIND_BOOLEAN = 'boolean'
#     KIND_FLOAT = 'float'
#     KIND_DATE = 'date'
#     KIND_CHOICES = (
#         (KIND_INTEGER, _('Integer')),
#         (KIND_BOOLEAN, _('True / False')),
#         (KIND_FLOAT, _('Float')),
#         (KIND_DATE, _('Date')),
#         (KIND_OPTION, _('Option')),
#         (KIND_FILE, _('File')),
#         (KIND_IMAGE, _('Image')),
#     )
# 
#     code = models.SlugField(
#         _('Code'), max_length=128, unique=True,
#         help_text=scs.SLUG_FIELD_HELP_TEXT)
# 
#     kind = models.CharField(
#         max_length=20, choices=KIND_CHOICES, default=KIND_CHOICES[0][0],
#         verbose_name=_('Type'),
#         help_text=_('Select data type. If you choose "Option" data type, '
#                     'specify the options below.'))
# 
#     template = models.CharField(
#         _('Template'), max_length=255, blank=True, null=True,
#         choices=scs.ATTRIBUTE_TEMPLATE_CHOICES,
#         help_text=_('You can select a template for rendering this attribute '
#                     'or leave it empty for the default (dropdown) look.'))
# 
#     translations = TranslatedFields(
#         name=models.CharField(_('Name'), max_length=128),
#     )
# 
#     class Meta:
#         db_table = 'catalog_attributes'
#         ordering = ('code', )
#         verbose_name = _('Attribute')
#         verbose_name_plural = _('Attributes')
# 
#     def __str__(self):
#         return '{} ({})'.format(
#             self.get_slug(), dict(self.KIND_CHOICES)[self.kind])
# 
#     def get_name(self):
#         return self.safe_translation_getter('name')
# 
#     def get_slug(self):
#         return self.code
# 
#     @property
#     def type(self):
#         return self.kind
# 
#     @property
#     def is_option(self):
#         return self.kind == self.KIND_OPTION
# 
#     @property
#     def is_file(self):
#         return self.kind in (self.KIND_FILE, self.KIND_IMAGE)
# 
#     @property
#     def as_dict(self):
#         template = force_str(self.template) if self.template else None
#         return dict(
#             code=force_str(self.get_slug()),
#             name=force_str(self.get_name()),
#             type=force_str(self.kind),
#             template=template,
#         )
# 
#     def get_values(self):
#         return list(set([x.value for x in self.values.select_related().all()]))
# 
#     @classmethod
#     def is_nullable(cls, attr_code, obj):
#         """
#         If any of 'obj.variants' miss the given attribute means that
#         this attribute can be null and returns True.
# 
#         If all 'obj.variants' have defined this attribute, then it's
#         required and returns False.
#         """
#         if obj.is_group:
#             for variant in obj.variants.select_related().all():
#                 if attr_code not in [x['code'] for x in variant.get_attrs()]:
#                     return True
#             return False
# 
#     @classmethod
#     def template_for(cls, attr_code):
#         """
#         Returns an attribute template for attribute with a given code.
#         """
#         try:
#             return cls.objects.get(code=attr_code).template
#         except cls.DoesNotExist:
#             return None
# 
#     @classmethod
#     def filter_dict(cls, dictionary):
#         """
#         Filters the given dictionary, removes items where key is not
#         an attribute code.
#         """
#         codes = [x.code for x in cls.objects.all()]
#         return dict((k, v) for k, v in dictionary.items() if k in codes and v)
# 
# class AttributeOption(TranslatableModel):
#     """
#     Option values for Attribute used when kind is Attribute.KIND_OPTION.
#     """
#     attribute = models.ForeignKey(
#         Attribute, related_name='options', verbose_name=_('Attribute'))
# 
#     translations = TranslatedFields(
#         value=models.CharField(_('Value'), max_length=128),
#     )
# 
#     class Meta:
#         db_table = 'catalog_attribute_options'
#         verbose_name = _('Option')
#         verbose_name_plural = _('Options')
# 
#     def __str__(self):
#         return self.get_value()
# 
#     def get_value(self):
#         return self.safe_translation_getter('value')


from django import forms
from django.utils.safestring import mark_safe
from django.utils.html import format_html
from django.utils.encoding import force_text
from catalog.models import Attribute, AttributeOption
# -*- coding: utf-8 -*-
from __future__ import unicode_literals




class AttributeValueKindsMapSelect(forms.Select):
    """
    A custom Select widget for generating 'data-choices' attribute when
    selected attributes kind is Attribute.KIND_OPTION.
    """
    def render_option(self, selected_choices, option_value, option_label):
        option_value = force_text(option_value)
        if option_value in selected_choices:
            selected_html = mark_safe(' selected="selected"')
            if not self.allow_multiple_selected:
                selected_choices.remove(option_value)
        else:
            selected_html = ''


# Path: catalog/models.py
# class Attribute(TranslatableModel):
#     """
#     Used to define different types of attributes to be assigned on a
#     Product variant. Eg. For a t-shirt attributes could be size, color,
#     pattern etc.
#     """
#     KIND_OPTION = 'option'
#     KIND_FILE = 'file'
#     KIND_IMAGE = 'image'
#     KIND_INTEGER = 'integer'
#     KIND_BOOLEAN = 'boolean'
#     KIND_FLOAT = 'float'
#     KIND_DATE = 'date'
#     KIND_CHOICES = (
#         (KIND_INTEGER, _('Integer')),
#         (KIND_BOOLEAN, _('True / False')),
#         (KIND_FLOAT, _('Float')),
#         (KIND_DATE, _('Date')),
#         (KIND_OPTION, _('Option')),
#         (KIND_FILE, _('File')),
#         (KIND_IMAGE, _('Image')),
#     )
# 
#     code = models.SlugField(
#         _('Code'), max_length=128, unique=True,
#         help_text=scs.SLUG_FIELD_HELP_TEXT)
# 
#     kind = models.CharField(
#         max_length=20, choices=KIND_CHOICES, default=KIND_CHOICES[0][0],
#         verbose_name=_('Type'),
#         help_text=_('Select data type. If you choose "Option" data type, '
#                     'specify the options below.'))
# 
#     template = models.CharField(
#         _('Template'), max_length=255, blank=True, null=True,
#         choices=scs.ATTRIBUTE_TEMPLATE_CHOICES,
#         help_text=_('You can select a template for rendering this attribute '
#                     'or leave it empty for the default (dropdown) look.'))
# 
#     translations = TranslatedFields(
#         name=models.CharField(_('Name'), max_length=128),
#     )
# 
#     class Meta:
#         db_table = 'catalog_attributes'
#         ordering = ('code', )
#         verbose_name = _('Attribute')
#         verbose_name_plural = _('Attributes')
# 
#     def __str__(self):
#         return '{} ({})'.format(
#             self.get_slug(), dict(self.KIND_CHOICES)[self.kind])
# 
#     def get_name(self):
#         return self.safe_translation_getter('name')
# 
#     def get_slug(self):
#         return self.code
# 
#     @property
#     def type(self):
#         return self.kind
# 
#     @property
#     def is_option(self):
#         return self.kind == self.KIND_OPTION
# 
#     @property
#     def is_file(self):
#         return self.kind in (self.KIND_FILE, self.KIND_IMAGE)
# 
#     @property
#     def as_dict(self):
#         template = force_str(self.template) if self.template else None
#         return dict(
#             code=force_str(self.get_slug()),
#             name=force_str(self.get_name()),
#             type=force_str(self.kind),
#             template=template,
#         )
# 
#     def get_values(self):
#         return list(set([x.value for x in self.values.select_related().all()]))
# 
#     @classmethod
#     def is_nullable(cls, attr_code, obj):
#         """
#         If any of 'obj.variants' miss the given attribute means that
#         this attribute can be null and returns True.
# 
#         If all 'obj.variants' have defined this attribute, then it's
#         required and returns False.
#         """
#         if obj.is_group:
#             for variant in obj.variants.select_related().all():
#                 if attr_code not in [x['code'] for x in variant.get_attrs()]:
#                     return True
#             return False
# 
#     @classmethod
#     def template_for(cls, attr_code):
#         """
#         Returns an attribute template for attribute with a given code.
#         """
#         try:
#             return cls.objects.get(code=attr_code).template
#         except cls.DoesNotExist:
#             return None
# 
#     @classmethod
#     def filter_dict(cls, dictionary):
#         """
#         Filters the given dictionary, removes items where key is not
#         an attribute code.
#         """
#         codes = [x.code for x in cls.objects.all()]
#         return dict((k, v) for k, v in dictionary.items() if k in codes and v)
# 
# class AttributeOption(TranslatableModel):
#     """
#     Option values for Attribute used when kind is Attribute.KIND_OPTION.
#     """
#     attribute = models.ForeignKey(
#         Attribute, related_name='options', verbose_name=_('Attribute'))
# 
#     translations = TranslatedFields(
#         value=models.CharField(_('Value'), max_length=128),
#     )
# 
#     class Meta:
#         db_table = 'catalog_attribute_options'
#         verbose_name = _('Option')
#         verbose_name_plural = _('Options')
# 
#     def __str__(self):
#         return self.get_value()
# 
#     def get_value(self):
#         return self.safe_translation_getter('value')


# Path: catalog/widgets.py
from django import forms
from django.utils.safestring import mark_safe
from django.utils.html import format_html
from django.utils.encoding import force_text
from catalog.models import Attribute, AttributeOption

# -*- coding: utf-8 -*-
from __future__ import unicode_literals




class AttributeValueKindsMapSelect(forms.Select):
    """
    A custom Select widget for generating 'data-choices' attribute when
    selected attributes kind is Attribute.KIND_OPTION.
    """
    def render_option(self, selected_choices, option_value, option_label):
        option_value = force_text(option_value)
        if option_value in selected_choices:
            selected_html = mark_safe(' selected="selected"')
            if not self.allow_multiple_selected:
                selected_choices.remove(option_value)
        else:
            selected_html = ''


        if option_value == Attribute.KIND_OPTION: