def get_by_name(self, name, category, **options):
        """
        Returns product info.

        :param category:
        :param name:
        :return:
        """

        unique_name = generate_product_unique_name(name, category)

        store = get_current_transaction_store()
        entity = store.find(
            ProductsEntity,
            ProductsEntity.product_unique_name == unique_name).one()

        if entity is None:
            raise ProductsException("Product [{0}] not found".format(name))

        product = DynamicObject(entity_to_dic(entity))

        fetch_details = options.get('fetch_details')
        if fetch_details is None:
            fetch_details = True

        if fetch_details:
            store = get_current_transaction_store()

            product.colors = []
            colors = store.find(
                ProductsColorsEntity,
                ProductsColorsEntity.product_id == product.product_id)
            product.colors.extend(
                [DynamicObject(entity_to_dic(e)) for e in colors])

            product.sizes = []
            sizes = store.find(
                ProductsSizesEntity,
                ProductsSizesEntity.product_id == product.product_id)
            product.sizes.extend(
                [DynamicObject(entity_to_dic(e)) for e in sizes])

            product.brands = []
            brands = store.find(
                ProductsBrandsEntity,
                ProductsBrandsEntity.product_id == product.product_id)
            product.brands.extend(
                [DynamicObject(entity_to_dic(e)) for e in brands])

        return product
    def get(self, product_id, **options):
        """
        Returns product info.

        :param product_id:
        :return:
        """

        entity = self._get(product_id)
        product = DynamicObject(entity_to_dic(entity))

        fetch_details = options.get('fetch_details')
        if fetch_details is None:
            fetch_details = True

        if fetch_details:
            store = get_current_transaction_store()

            product.colors = []
            colors = store.find(ProductsColorsEntity,
                                ProductsColorsEntity.product_id == product_id)
            product.colors.extend(
                [DynamicObject(entity_to_dic(e)) for e in colors])

            product.sizes = []
            sizes = store.find(ProductsSizesEntity,
                               ProductsSizesEntity.product_id == product_id)
            product.sizes.extend(
                [DynamicObject(entity_to_dic(e)) for e in sizes])

            product.brands = []
            brands = store.find(ProductsBrandsEntity,
                                ProductsBrandsEntity.product_id == product_id)
            product.brands.extend(
                [DynamicObject(entity_to_dic(e)) for e in brands])

        return product
    def update(self, id, **options):
        """
        Updates product.

        :param id:
        :param options:
        :return:
        """

        entity = self._get(id)
        store = get_current_transaction_store()

        new_name = options.get('name')
        if new_name is not None and new_name.strip() != "":
            self._validate_product_unique_name(new_name,
                                               entity.product_category)
            entity.product_name = new_name
            entity.product_unique_name = generate_product_unique_name(
                new_name, entity.product_category)

        new_price = options.get('price')
        if new_price is not None and new_price >= 0:
            entity.product_price = new_price

        new_image = options.get('image_data')
        if new_image is not None:
            entity.product_image = buffer(new_image)

        new_status = options.get('status')
        if new_status is None:
            entity.product_status = new_status

        colors = options.get('colors')
        if colors is not None and len('colors') > 0:
            already_colors = store.find(
                ProductsColorsEntity,
                ProductsColorsEntity.product_id == entity.product_id)

            to_delete = []
            for c in already_colors:
                if c.product_color_hex not in colors:
                    to_delete.append(c)

            to_insert = []
            for c in colors:
                if c not in [a.product_color_hex for a in already_colors]:
                    to_insert.append(c)

            for d in to_delete:
                store.remove(d)

            for i in to_insert:
                color_entity = ProductsColorsEntity()
                color_entity.product_color_id = unicode(
                    unique_id_services.get('uuid'))
                color_entity.product_id = entity.product_id
                color_entity.product_color_hex = unicode(i)
                store.add(color_entity)

        sizes = options.get('sizes')
        if sizes is not None and len(sizes) > 0:
            already_sizes = store.find(
                ProductsSizesEntity,
                ProductsSizesEntity.product_id == entity.product_id)

            to_delete = []
            for s in already_sizes:
                if s.product_size not in sizes:
                    to_delete.append(s)

            to_insert = []
            for s in sizes:
                if s not in [a.product_size for a in already_sizes]:
                    to_insert.append(s)

            for d in to_delete:
                store.remove(d)

            for i in to_insert:
                size_entity = ProductsSizesEntity()
                size_entity.product_size_id = unicode(
                    unique_id_services.get_id('uuid'))
                size_entity.product_id = entity.product_id
                size_entity.product_size = unicode(i)
                store.add(size_entity)

        brands = options.get('brands')
        if brands is not None and len(brands) > 0:
            already_brands = store.find(
                ProductsBrandsEntity,
                ProductsBrandsEntity.product_id == entity.product_id)

            to_delete = []
            for b in already_brands:
                if b.product_brand not in brands:
                    to_delete.append(b)

            to_insert = []
            for b in brands:
                if b not in [a.product_brand for a in already_brands]:
                    to_insert.append(b)

            for d in to_delete:
                store.remove(d)

            for i in to_insert:
                brand_entity = ProductsBrandsEntity()
                brand_entity.product_brand_id = unicode(
                    unique_id_services.get_id('uuid'))
                brand_entity.product_id = entity.product_id
                brand_entity.product_brand = unicode(i)
                store.add(brand_entity)

        product = DynamicObject(entity_to_dic(entity))
        product.sizes = []
        product.colors = []
        product.brands = []

        history_services.write_history(entity, colors, sizes, brands,
                                       **options)

        return product