def articles(self):
        """Returns list of dictionary of articles in shop

        :rtype: list
        """
        res = []
        for item in IShoppingSite(self.context).get_content_listing(IArticle, sort_on="sku"):
            obj = item.getObject()
            article = IArticleAdapter(obj)
            sbehavior = IStockBehavior(obj)
            stock = sbehavior.stock()
            stocks = sbehavior.stocks()
            if stocks:
                price = stocks[-1].price
                subtotal = price * stock
                price = getUtility(IPriceUtility, name="string")(price)
                subtotal = getUtility(IPriceUtility, name="string")(subtotal)
            else:
                price = subtotal = "N/A"
            res.append(
                {
                    "price": price,
                    "sku": item.sku,
                    "stock": stock,
                    "subtotal": subtotal,
                    "title": article.title(),
                    "url": item.getURL(),
                }
            )
        return res
    def articles(self):
        """Returns list of dictionary of articles

        :rtype: list
        """
        res = []

        context = aq_inner(self.context)
        if not getattr(context, 'related_articles', None):
            context = aq_parent(context)
            if not getattr(context, 'related_articles', None):
                context = aq_parent(context)

        if getattr(context, 'related_articles', None):
            shopping_site = IShoppingSite(self.context)
            path = shopping_site.shop_path()
            for uuid in context.related_articles:
                obj = shopping_site.get_object(IArticle, UID=uuid, path=path, review_state='published')
                if obj is not None:
                    art = IArticleAdapter(obj)
                    res.append({
                        'gross': art.gross(),
                        'image_url': art.image_url(size='preview'),
                        'title': art.title(),
                        'url': obj.absolute_url(),
                    })
        return res[:4]
class ArticleContentListingObject(RealContentListingObject):
    adapts(IArticle)

    def __init__(self, obj):
        super(ArticleContentListingObject, self).__init__(obj)
        self.adapter = IArticleAdapter(self._realobject)
        self.shopping_site = IShoppingSite(self._realobject)

    def __repr__(self):
        return "<collective.cart.shopping.adapter.content_listing_object.ArticleContentListingObject instance at {}>".format(self.getPath())

    def discount_available(self):
        """Return True if discount is available else False

        :rtype boolean
        """
        return self.adapter.discount_available()

    def klass(self):
        """Return discount if discount is available esle normal

        :rtype: str
        """
        if self.discount_available():
            return 'discount'
        else:
            return 'normal'

    def gross(self):
        """Reterun localized gross

        :rtype: unicode
        """
        return self.shopping_site.format_money(self.adapter.gross())

    def money(self):
        """Return localize money

        :rtype: unicode
        """
        return self.shopping_site.format_money(self._realobject.money)

# IContentListingObject

    def CroppedDescription(self):
        """A cropped description"""
        raise NotImplementedError

    def getSize(self):
        """size in bytes"""
        raise NotImplementedError
    def test_discount_end(self):
        context = self.create_content('collective.cart.core.Article')
        instance = IArticleAdapter(context)
        self.assertIsNone(instance.discount_end())

        context.discount_enabled = True
        from datetime import date
        context.discount_end = date.today()
        self.assertIsNotNone(instance.discount_end())

        context.discount_enabled = False
        context.registered_member_discount_enabled = True
        context.registered_member_discount_price = 'PRICE'
        self.assertIsNone(instance.discount_end())
示例#5
0
    def test_discount_end(self):
        context = self.create_content('collective.cart.core.Article')
        instance = IArticleAdapter(context)
        self.assertIsNone(instance.discount_end())

        context.discount_enabled = True
        from datetime import date
        context.discount_end = date.today()
        self.assertIsNotNone(instance.discount_end())

        context.discount_enabled = False
        context.registered_member_discount_enabled = True
        context.registered_member_discount_price = 'PRICE'
        self.assertIsNone(instance.discount_end())
示例#6
0
    def test__registered_member_discount_available(self, member):
        context = self.create_content('collective.cart.core.Article')
        instance = IArticleAdapter(context)
        member().getProperty.return_value = ''
        self.assertFalse(instance._registered_member_discount_available())

        member().getProperty.return_value = 'RN'
        self.assertFalse(instance._registered_member_discount_available())

        context.registered_member_discount_enabled = True
        self.assertFalse(instance._registered_member_discount_available())

        context.registered_member_discount_price = 'PRICE'
        self.assertTrue(instance._registered_member_discount_available())
    def __call__(self):

        authenticator = self.context.restrictedTraverse('@@authenticator')
        if not authenticator.verify():
            raise Forbidden()

        form = self.request.form
        uuid = form.get('uuid')
        if uuid:
            adapter = IArticleAdapter(self.context)
            obj = adapter.get_object(UID=uuid)
            if obj:
                maximum = IArticleAdapter(obj).quantity_max()
                data = {'uuid': uuid, 'size': len(str(maximum)), 'maximum': maximum}

                self.request.response.setHeader('Content-Type', 'application/json')
                return json.dumps(data)
def make_subarticles_private(context, logger=None):
    """Make subarticles private if article with use_subarticle is private"""
    if logger is None:
        logger = logging.getLogger(__name__)
    from Products.CMFCore.WorkflowCore import WorkflowException
    from collective.base.interfaces import IAdapter
    from collective.cart.shopping.interfaces import IArticle
    from collective.cart.shopping.interfaces import IArticleAdapter
    from zope.lifecycleevent import modified

    wftool = getToolByName(context, 'portal_workflow')
    portal = IAdapter(context).portal()
    adapter = IAdapter(portal)
    particles = adapter.get_objects(IArticle, use_subarticle=True, review_state="published")
    action = 'hide'

    if particles:
        obj = particles[0]
        for trans in wftool.getTransitionsFor(obj):
            tid = trans['id']
            if tid == 'retract' or tid == 'reject':
                action = tid

    articles = adapter.get_objects(IArticle, use_subarticle=True, review_state="private")
    count = 0

    for article in articles:
        aadapter = IArticleAdapter(article)
        subarticles = aadapter.get_objects(IArticle, review_state="published")
        for subarticle in subarticles:
            subarticle_path = '/'.join(subarticle.getPhysicalPath())
            try:
                wftool.doActionFor(subarticle, action)
                modified(subarticle)
                message = 'Successfully hid subarticle: {}'.format(subarticle_path)
                logger.info(message)
                count += 1
            except WorkflowException:
                message = 'Already hidden subarticle? {}'.format(subarticle_path)
                logger.info(message)

    if count:
        message = 'There are total of {} subarticles hidden.'.format(count)
        logger.info(message)
    def test_discount_available(self):
        context = self.create_content('collective.cart.core.Article')
        instance = IArticleAdapter(context)
        self.assertFalse(instance.discount_available())

        context.discount_enabled = True
        self.assertFalse(instance.discount_available())

        from datetime import date
        context.discount_end = date.today()
        self.assertTrue(instance.discount_available())

        context.discount_enabled = False
        self.assertFalse(instance.discount_available())

        instance._registered_member_discount_available = mock.Mock(
            return_value=True)
        self.assertTrue(instance.discount_available())

        instance._registered_member_discount_available = mock.Mock(
            return_value=False)
        self.assertFalse(instance.discount_available())
    def test_discount_available(self):
        article1 = self.create_content(
            "collective.cart.core.Article", title="Ärticle1", sku="SKÖ1", money=self.money("12.40"), vat_rate=24.0
        )
        adapter = IArticleAdapter(article1)
        self.assertFalse(adapter.discount_available())

        from collective.behavior.discount.interfaces import IDiscount

        discount = IDiscount(article1)
        discount.discount_enabled = True
        self.assertFalse(adapter.discount_available())

        from datetime import date

        today = date.today()
        from datetime import timedelta

        discount.discount_end = today - timedelta(1)
        self.assertFalse(adapter.discount_available())

        discount.discount_end = today + timedelta(1)
        self.assertTrue(adapter.discount_available())

        article1.discount_end = None
        discount.discount_start = today + timedelta(1)
        self.assertFalse(adapter.discount_available())

        discount.discount_start = today - timedelta(1)
        self.assertTrue(adapter.discount_available())

        discount.discount_end = today - timedelta(1)
        self.assertFalse(adapter.discount_available())

        discount.discount_end = today + timedelta(1)
        self.assertTrue(adapter.discount_available())

        discount.discount_start = today + timedelta(1)
        self.assertFalse(adapter.discount_available())
示例#11
0
    def test_discount_available(self):
        context = self.create_content('collective.cart.core.Article')
        instance = IArticleAdapter(context)
        self.assertFalse(instance.discount_available())

        context.discount_enabled = True
        self.assertFalse(instance.discount_available())

        from datetime import date
        context.discount_end = date.today()
        self.assertTrue(instance.discount_available())

        context.discount_enabled = False
        self.assertFalse(instance.discount_available())

        instance._registered_member_discount_available = mock.Mock(return_value=True)
        self.assertTrue(instance.discount_available())

        instance._registered_member_discount_available = mock.Mock(return_value=False)
        self.assertFalse(instance.discount_available())
示例#12
0
    def test_gross(self):
        context = self.create_content('collective.cart.core.Article')
        instance = IArticleAdapter(context)
        self.assertEqual(instance.gross(), self.money('10.00'))

        instance._registered_member_discount_available = mock.Mock(
            return_value=True)
        context.registered_member_discount_money = self.money('11.00')
        self.assertEqual(instance.gross(), self.money('10.00'))

        context.registered_member_discount_money = self.money('10.00')
        self.assertEqual(instance.gross(), self.money('10.00'))

        context.registered_member_discount_money = self.money('9.00')
        self.assertEqual(instance.gross(), self.money('9.00'))
示例#13
0
    def test__registered_member_discount_available(self, member):
        context = self.create_content('collective.cart.core.Article')
        instance = IArticleAdapter(context)
        member().getProperty.return_value = ''
        self.assertFalse(instance._registered_member_discount_available())

        member().getProperty.return_value = 'RN'
        self.assertFalse(instance._registered_member_discount_available())

        context.registered_member_discount_enabled = True
        self.assertFalse(instance._registered_member_discount_available())

        context.registered_member_discount_price = 'PRICE'
        self.assertTrue(instance._registered_member_discount_available())
示例#14
0
    def test_gross(self):
        context = self.create_content('collective.cart.core.Article')
        instance = IArticleAdapter(context)
        self.assertEqual(instance.gross(), self.money('10.00'))

        instance._registered_member_discount_available = mock.Mock(return_value=True)
        context.registered_member_discount_money = self.money('11.00')
        self.assertEqual(instance.gross(), self.money('10.00'))

        context.registered_member_discount_money = self.money('10.00')
        self.assertEqual(instance.gross(), self.money('10.00'))

        context.registered_member_discount_money = self.money('9.00')
        self.assertEqual(instance.gross(), self.money('9.00'))
    def articles(self):
        """Returns list of dictionary of articles

        :rtype: list
        """
        res = []
        shopping_site = IShoppingSite(self.context)
        articles = super(ArticlesInArticleViewlet, self).articles()
        if articles:
            for item in IContentListing(articles):
                obj = item.getObject()
                adapter = IArticleAdapter(obj)
                soldout = adapter.soldout()
                quantity_max = adapter.quantity_max()
                numbers = xrange(1, quantity_max + 1)
                quantity_size = len(str(quantity_max))
                subarticles = []
                if obj.use_subarticle:
                    subarticles = adapter.subarticles()
                res.append({
                    'description': item.Description(),
                    'discount_end': adapter.discount_end(),
                    'gross': shopping_site.format_money(adapter.gross()),
                    'id': item.getId(),
                    'image_url': adapter.image_url(size='mini'),
                    'klass': 'add-to-cart {}'.format(item.getId()),
                    'money': shopping_site.format_money(item.money),
                    'numbers': numbers,
                    'quantity_max': quantity_max,
                    'quantity_size': quantity_size,
                    'soldout': soldout,
                    'subarticles': subarticles,
                    'title': adapter.title(),
                    'url': item.getURL(),
                    'uuid': item.uuid(),
                    'vat_rate': IVATAdapter(self.context).percent(item.vat_rate)
                })
        return res
    def test_image_url(self):
        article1 = self.create_content(
            "collective.cart.core.Article", title="Ärticle1", sku="SKÖ1", money=self.money("12.40"), vat_rate=24.0
        )
        adapter = IArticleAdapter(article1)
        self.assertEqual(adapter.image_url(), "http://nohost/plone/fallback.png")

        article2 = self.create_content(
            "collective.cart.core.Article",
            article1,
            title="Ärticle2",
            sku="SKÖ1",
            money=self.money("12.40"),
            vat_rate=24.0,
        )
        adapter = IArticleAdapter(article2)
        self.assertEqual(adapter.image_url(), "http://nohost/plone/fallback.png")

        article1.image = mock.Mock()
        self.assertEqual(adapter.image_url(), "http://nohost/plone/article1/@@images/image")

        adapter.context.image = mock.Mock()
        self.assertEqual(adapter.image_url(), "http://nohost/plone/article1/article2/@@images/image")
示例#17
0
 def test_instance(self):
     context = self.create_content('collective.cart.core.Article')
     self.assertIsInstance(IArticleAdapter(context), ArticleAdapter)
 def __init__(self, obj):
     super(ArticleContentListingObject, self).__init__(obj)
     self.adapter = IArticleAdapter(self._realobject)
     self.shopping_site = IShoppingSite(self._realobject)
    def add_to_cart(self):
        """Add article to cart"""
        shopping_site = IShoppingSite(self.context)
        form = self.request.form
        add_to_cart = form.pop('form.buttons.AddToCart', None)
        subarticle = form.pop('subarticle', None)

        uuid = None
        quantity = '1'

        if subarticle is not None:

            uuids = subarticle
            parent_uuid = add_to_cart

            if not isinstance(uuids, list):
                uuids = [subarticle]

            for subarticle_uuid in uuids:
                parent = aq_parent(aq_inner(shopping_site.get_object(UID=subarticle_uuid)))
                if parent_uuid == IUUID(parent):
                    uuid = subarticle_uuid

                quantity = form.get(parent_uuid)

        uuid = uuid or add_to_cart

        if uuid is not None:

            quantity = form.get('quantity') or form.get(uuid) or quantity
            validate = validation.validatorFor('isInt')
            url = self.context.restrictedTraverse('@@plone_context_state').current_base_url()
            message = None

            if quantity is not None and validate(quantity) == 1:
                quantity = int(quantity)
                obj = shopping_site.get_object(UID=uuid)
                if obj:
                    item = IArticleAdapter(obj)
                    if quantity > item.quantity_max():
                        quantity = item.quantity_max()
                    if quantity > 0:
                        size = ISize(obj)
                        gross = item.gross()
                        kwargs = {
                            'depth': size.depth,
                            'gross': gross,
                            'height': size.height,
                            'net': item.get_net(gross),
                            'quantity': quantity,
                            'title': item.title(),
                            'sku': obj.sku,
                            'vat': item.get_vat(gross),
                            'vat_rate': item.context.vat_rate,
                            'weight': size.weight,
                            'width': size.width,
                        }
                        item.add_to_cart(**kwargs)
                        notify(ArticleAddedToCartEvent(item, self.request))
                    else:
                        message = _(u'Input positive integer value to add to cart.')
                else:
                    message = _(u"Not available to add to cart.")
            else:
                message = _(u"Input integer value to add to cart.")

            if message:
                IStatusMessage(self.request).addStatusMessage(message, type='warn')

            return self.request.response.redirect(url)
示例#20
0
 def test_verifyObject(self):
     from zope.interface.verify import verifyObject
     context = self.create_content('collective.cart.core.Article')
     self.assertTrue(verifyObject(IArticleAdapter,
                                  IArticleAdapter(context)))