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())
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())
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_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 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")
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)
def test_verifyObject(self): from zope.interface.verify import verifyObject context = self.create_content('collective.cart.core.Article') self.assertTrue(verifyObject(IArticleAdapter, IArticleAdapter(context)))