def create_booking(self, order, cart_data, uid, count, comment): brain = get_catalog_brain(self.context, uid) # brain could be None if uid for item in cookie which no longer exists. if not brain: return buyable = brain.getObject() item_state = get_item_state(buyable, self.request) if not item_state.validate_count(count): msg = u'Item no longer available {0}'.format(buyable.id) logger.warning(msg) raise CheckoutError(msg) item_stock = get_item_stock(buyable) # stock not applied, state new if item_stock is None: available = None state = ifaces.STATE_NEW # calculate state from stock else: if item_stock.available is not None: item_stock.available -= float(count) available = item_stock.available state = ifaces.STATE_NEW if available is None or available >= 0.0\ else ifaces.STATE_RESERVED item_data = get_item_data_provider(buyable) vendor = acquire_vendor_or_shop_root(buyable) booking = OOBTNode() booking.attrs['email'] = order.attrs['personal_data.email'] booking.attrs['uid'] = uuid.uuid4() booking.attrs['buyable_uid'] = uid booking.attrs['buyable_count'] = count booking.attrs['buyable_comment'] = comment booking.attrs['order_uid'] = order.attrs['uid'] booking.attrs['vendor_uid'] = uuid.UUID(IUUID(vendor)) booking.attrs['creator'] = order.attrs['creator'] booking.attrs['created'] = order.attrs['created'] booking.attrs['exported'] = False booking.attrs['title'] = brain and brain.Title or 'unknown' booking.attrs['net'] = item_data.net booking.attrs['vat'] = item_data.vat booking.attrs['discount_net'] = item_data.discount_net(count) booking.attrs['currency'] = cart_data.currency booking.attrs['quantity_unit'] = item_data.quantity_unit booking.attrs['remaining_stock_available'] = available booking.attrs['state'] = state booking.attrs['salaried'] = ifaces.SALARIED_NO booking.attrs['tid'] = 'none' shipping_info = queryAdapter(buyable, IShippingItem) if shipping_info: booking.attrs['shippable'] = shipping_info.shippable else: booking.attrs['shippable'] = False trading_info = queryAdapter(buyable, ifaces.ITrading) if trading_info: booking.attrs['item_number'] = trading_info.item_number booking.attrs['gtin'] = trading_info.gtin else: booking.attrs['item_number'] = None booking.attrs['gtin'] = None return booking
def overbook_available_message(self): state = get_item_state(self.context, self.request) overbook = self.stock.overbook if overbook is None: reservable = '' else: reservable = int(overbook - state.reserved) message = _(u'ticket_overbook_available_message', default=u'Tickets are sold out. You can add ${reservable} ' u'tickets on a reservations list. If some tickets ' u'gets refused, you\'ll get informed.', mapping={'reservable': reservable}) return message
def validate_count(self, uid, count): """Validate setting cart item count for uid. uid - Is the cart item UID. count - If count is 0, it means that a cart item is going to be deleted, which is always allowed. If count is > 0, it's the aggregated item count in cart. """ count = float(count) # count is 0, return if not count: return {'success': True, 'error': ''} cart_item = get_object_by_uid(self.context, uid) item_data = get_item_data_provider(cart_item) buyable_event = self.acquire_event(cart_item) buyable_event_data = IBuyableEventData(buyable_event) # cart count limit is set for all event tickets if buyable_event_data.cart_count_limit: related_uids = IEventTickets(cart_item).related_uids aggregated_count = count items = extractitems(readcookie(self.request)) for ticket_uid in related_uids: # we already have count for item to validate if uid == ticket_uid: continue aggregated_count += float( aggregate_cart_item_count(ticket_uid, items)) if aggregated_count > buyable_event_data.cart_count_limit: message = translate( _('event_tickets_limit_reached', default="Limit of tickets for this event reached"), context=self.request) return {'success': False, 'error': message} # cart count limit is set for ticket elif item_data.cart_count_limit: if count > item_data.cart_count_limit: message = translate( _('ticket_limit_reached', default="Limit for this ticket reached"), context=self.request) return {'success': False, 'error': message} # stock check item_state = get_item_state(cart_item, self.request) if item_state.validate_count(count): return {'success': True, 'error': ''} # out of stock message = translate(_('trying_to_add_more_tickets_than_available', default="Not enough tickets available, abort."), context=self.request) return {'success': False, 'error': message}
def validate_count(self, uid, count): """Validate setting cart item count for uid. uid - Is the cart item UID. count - If count is 0, it means that a cart item is going to be deleted, which is always allowed. If count is > 0, it's the aggregated item count in cart. """ count = float(count) # count is 0, return if not count: return {'success': True, 'error': ''} cart_item = get_object_by_uid(self.context, uid) item_data = get_item_data_provider(cart_item) buyable_event = self.acquire_event(cart_item) buyable_event_data = IBuyableEventData(buyable_event) # cart count limit is set for all event tickets if buyable_event_data.cart_count_limit: related_uids = IEventTickets(cart_item).related_uids aggregated_count = count items = extractitems(readcookie(self.request)) for ticket_uid in related_uids: # we already have count for item to validate if uid == ticket_uid: continue aggregated_count += float( aggregate_cart_item_count(ticket_uid, items)) if aggregated_count > buyable_event_data.cart_count_limit: message = translate(_( 'event_tickets_limit_reached', default="Limit of tickets for this event reached"), context=self.request) return {'success': False, 'error': message} # cart count limit is set for ticket elif item_data.cart_count_limit: if count > item_data.cart_count_limit: message = translate(_('ticket_limit_reached', default="Limit for this ticket reached"), context=self.request) return {'success': False, 'error': message} # stock check item_state = get_item_state(cart_item, self.request) if item_state.validate_count(count): return {'success': True, 'error': ''} # out of stock message = translate(_('trying_to_add_more_tickets_than_available', default="Not enough tickets available, abort."), context=self.request) return {'success': False, 'error': message}
def overbook_available_message(self): state = get_item_state(self.context, self.request) overbook = self.stock.overbook if overbook is None: reservable = '' else: reservable = overbook - state.reserved if not get_item_data_provider(self.context).quantity_unit_float: reservable = int(reservable) message = _(u'overbook_available_message', default=u'Item is sold out. You can pre-order ' u'${reservable} items. As soon as item is ' u'available again, it gets delivered.', mapping={'reservable': reservable}) return message
def cart_items(self, items): ret = list() sm = getSecurityManager() for uid, count, comment in items: try: obj = api.content.get(UID=uid) except ValueError: remove_item_from_cart(self.request, uid) continue if obj is None: remove_item_from_cart(self.request, uid) continue if not sm.checkPermission(permissions.BuyItems, obj): remove_item_from_cart(self.request, uid) continue buyable_period = queryAdapter(obj, IBuyablePeriod) if buyable_period: now = datetime.now() effective = buyable_period.effective if effective and now < effective: remove_item_from_cart(self.request, uid) continue expires = buyable_period.expires if expires and now > expires: remove_item_from_cart(self.request, uid) continue data = get_item_data_provider(obj) title = data.title discount_net = data.discount_net(count) price = (Decimal(str(data.net)) - discount_net) * count if data.display_gross: price = price + price / Decimal(100) * Decimal(str(data.vat)) url = obj.absolute_url() description = obj.Description() comment_required = data.comment_required quantity_unit_float = data.quantity_unit_float quantity_unit = translate(data.quantity_unit, context=self.request) preview_image_url = get_item_preview(obj).url item_state = get_item_state(obj, self.request) no_longer_available = not item_state.validate_count(count) alert = item_state.alert(count) item = self.item( uid, title, count, price, url, comment, description, comment_required, quantity_unit_float, quantity_unit, preview_image_url, no_longer_available, alert) ret.append(item) return ret
def cart_items(self, items): ret = list() sm = getSecurityManager() for uid, count, comment in items: try: obj = api.content.get(UID=uid) except ValueError: remove_item_from_cart(self.request, uid) continue if obj is None: remove_item_from_cart(self.request, uid) continue if not sm.checkPermission(permissions.BuyItems, obj): remove_item_from_cart(self.request, uid) continue buyable_period = queryAdapter(obj, IBuyablePeriod) if buyable_period: now = datetime.now() effective = buyable_period.effective if effective and now < effective: remove_item_from_cart(self.request, uid) continue expires = buyable_period.expires if expires and now > expires: remove_item_from_cart(self.request, uid) continue data = get_item_data_provider(obj) title = data.title discount_net = data.discount_net(count) price = (Decimal(str(data.net)) - discount_net) * count if data.display_gross: price = price + price / Decimal(100) * Decimal(str(data.vat)) url = obj.absolute_url() description = obj.Description() comment_required = data.comment_required quantity_unit_float = data.quantity_unit_float quantity_unit = translate(data.quantity_unit, context=self.request) preview_image_url = get_item_preview(obj).url item_state = get_item_state(obj, self.request) no_longer_available = not item_state.validate_count(count) alert = item_state.alert(count) item = self.item(uid, title, count, price, url, comment, description, comment_required, quantity_unit_float, quantity_unit, preview_image_url, no_longer_available, alert) ret.append(item) return ret
def create_booking(self, order, cart_data, uid, count, comment): brain = get_catalog_brain(self.context, uid) # brain could be None if uid for item in cookie which no longer exists. if not brain: return buyable = brain.getObject() item_state = get_item_state(buyable, self.request) if not item_state.validate_count(item_state.aggregated_count): raise CheckoutError(u'Item no longer available') item_stock = get_item_stock(buyable) if item_stock.available is not None: item_stock.available -= float(count) available = item_stock.available state = (available is None or available >= 0) and ifaces.STATE_NEW\ or ifaces.STATE_RESERVED item_data = get_item_data_provider(buyable) vendor = acquire_vendor_or_shop_root(buyable) booking = OOBTNode() booking.attrs['uid'] = uuid.uuid4() booking.attrs['buyable_uid'] = uid booking.attrs['buyable_count'] = count booking.attrs['buyable_comment'] = comment booking.attrs['order_uid'] = order.attrs['uid'] booking.attrs['vendor_uid'] = uuid.UUID(IUUID(vendor)) booking.attrs['creator'] = order.attrs['creator'] booking.attrs['created'] = order.attrs['created'] booking.attrs['exported'] = False booking.attrs['title'] = brain and brain.Title or 'unknown' booking.attrs['net'] = item_data.net booking.attrs['vat'] = item_data.vat booking.attrs['discount_net'] = item_data.discount_net(count) booking.attrs['currency'] = cart_data.currency booking.attrs['quantity_unit'] = item_data.quantity_unit booking.attrs['remaining_stock_available'] = available booking.attrs['state'] = state booking.attrs['salaried'] = ifaces.SALARIED_NO booking.attrs['tid'] = 'none' return booking