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 buyable_available(context, booking): obj = get_object_by_uid(context, booking.attrs['buyable_uid']) if not obj: return None item_stock = get_item_stock(obj) if not item_stock: return None return item_stock.available
def increase_stock(self, booking): obj = get_object_by_uid(self.context, booking.attrs['buyable_uid']) # object no longer exists if not obj: return stock = get_item_stock(obj) # if stock.available is None, no stock information used if stock.available is not None: stock.available += float(booking.attrs['buyable_count'])
def update_stock(ob, event): if getattr(ob, 'use_barcodes' , None): new_stock = get_number_of_barcodes(ob, ob.barcode_list, True) item_stock = get_item_stock(ob) item_stock.available = new_stock return True
def decrease_stock(self, booking): obj = get_object_by_uid(self.context, booking.attrs['buyable_uid']) # object no longer exists if not obj: return stock = get_item_stock(obj) # if stock.available is None, no stock information used if stock.available is not None: # TODO: ATTENTION: here might get removed more than available..? stock.available -= float(booking.attrs['buyable_count'])
def decrease_stock(self, bookings): for booking in bookings: obj = get_object_by_uid(self.context, booking.attrs['buyable_uid']) # object no longer exists if not obj: continue stock = get_item_stock(obj) # if stock.available is None, no stock information used if stock.available is not None: stock.available -= float(booking.attrs['buyable_count'])
def alert(self, count): stock = get_item_stock(self.context) # stock not applied if stock is None: return '' available = stock.available # no limitation if available is None: return '' reserved = self.reserved exceed = self.exceed # no reservations and no exceed if not reserved and not exceed: # no message return '' item_data = get_item_data_provider(self.context) quantity_unit = item_data.quantity_unit quantity_unit_float = item_data.quantity_unit_float def display_format(num): if quantity_unit_float: return num return int(num) # exceed if exceed: remaining_available = self.remaining_available # partly exceeded if remaining_available > 0: return self.partly_exceeded_alert(display_format(exceed), quantity_unit) # completely exceeded return self.completely_exceeded_alert # reservations if reserved: aggregated_count = float(self.aggregated_count) count = float(count) # some reservations message if aggregated_count > count: return self.some_reservations_alert # number reservations message else: return self.number_reservations_alert(display_format(reserved), quantity_unit) return ''
def alert(self, count): stock = get_item_stock(self.context) # stock not applied if stock is None: return '' available = stock.available # no limitation if available is None: return '' reserved = self.reserved exceed = self.exceed # no reservations and no exceed if not reserved and not exceed: # no message return '' item_data = get_item_data_provider(self.context) quantity_unit = item_data.quantity_unit quantity_unit_float = item_data.quantity_unit_float def display_format(num): if quantity_unit_float: return num return int(num) # exceed if exceed: remaining_available = self.remaining_available # partly exceeded if remaining_available > 0: return self.partly_exceeded_alert( display_format(exceed), quantity_unit) # completely exceeded return self.completely_exceeded_alert # reservations if reserved: aggregated_count = float(self.aggregated_count) count = float(count) # some reservations message if aggregated_count > count: return self.some_reservations_alert # number reservations message else: return self.number_reservations_alert( display_format(reserved), quantity_unit) return ''
def alert(self, count): stock = get_item_stock(self.context) available = stock.available if available is None: return '' reserved = self.reserved exceed = self.exceed if not reserved and not exceed: return '' if exceed: remaining_available = self.remaining_available if remaining_available > 0: return self.partly_exceeded_alert(exceed) return self.completely_exceeded_alert if reserved: # XXX: cart item state needs love how to display item # warnings return self.some_reservations_alert # return self.number_reservations_alert(reserved) return ''
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
def save(self, providers, widget, data): super(OrderCheckoutAdapter, self).save(providers, widget, data) order = self.order # order UUID uid = order.attrs['uid'] = uuid.uuid4() # order creator creator = None member = plone.api.user.get_current() if member: creator = member.getId() order.attrs['creator'] = creator # order creation date created = datetime.datetime.now() order.attrs['created'] = created cart_data = get_data_provider(self.context, self.request) # payment related information if cart_data.total > Decimal(0): payment_param = 'checkout.payment_selection.payment' pid = data.fetch(payment_param).extracted payment = Payments(self.context).get(pid) order.attrs['payment_method'] = pid if payment: order.attrs['payment_label'] = payment.label else: order.attrs['payment_label'] = _('unknown', default=u'Unknown') # no payment else: order.attrs['payment_method'] = 'no_payment' order.attrs['payment_label'] = _('no_payment', default=u'No Payment') # shipping related information if cart_data.include_shipping_costs: shipping_param = 'checkout.shipping_selection.shipping' sid = data.fetch(shipping_param).extracted shipping = Shippings(self.context).get(sid) order.attrs['shipping_method'] = sid order.attrs['shipping_label'] = shipping.label order.attrs['shipping_description'] = shipping.description try: shipping_net = shipping.net(self.items) shipping_vat = shipping.vat(self.items) order.attrs['shipping_net'] = shipping_net order.attrs['shipping_vat'] = shipping_vat order.attrs['shipping'] = shipping_net + shipping_vat # B/C for bda.plone.shipping < 0.4 except NotImplementedError: shipping_net = shipping.calculate(self.items) order.attrs['shipping_net'] = shipping_net order.attrs['shipping_vat'] = Decimal(0) order.attrs['shipping'] = shipping_net # no shipping else: order.attrs['shipping_method'] = 'no_shipping' order.attrs['shipping_label'] = _('no_shipping', default=u'No Shipping') order.attrs['shipping_description'] = '' order.attrs['shipping_net'] = Decimal(0) order.attrs['shipping_vat'] = Decimal(0) order.attrs['shipping'] = Decimal(0) # create order bookings bookings = self.create_bookings(order) # set order state, needed for sorting in orders table order.attrs['state'] = calculate_order_state(bookings) # set order salaried, needed for sorting in orders table order.attrs['salaried'] = ifaces.SALARIED_NO # lookup booking uids, buyable uids and vendor uids booking_uids = list() buyable_uids = list() vendor_uids = set() for booking in bookings: booking_uids.append(booking.attrs['uid']) buyable_uids.append(booking.attrs['buyable_uid']) vendor_uids.add(booking.attrs['vendor_uid']) order.attrs['booking_uids'] = booking_uids order.attrs['buyable_uids'] = buyable_uids order.attrs['vendor_uids'] = list(vendor_uids) # cart discount related information # XXX: in order to be able to reliably modify orders, cart discount # rules for this order must be stored instead of the actual # calculated discount. cart_discount = cart_data.discount(self.items) order.attrs['cart_discount_net'] = cart_discount['net'] order.attrs['cart_discount_vat'] = cart_discount['vat'] # create ordernumber orders_soup = get_orders_soup(self.context) ordernumber = create_ordernumber() while self.ordernumber_exists(orders_soup, ordernumber): ordernumber = create_ordernumber() order.attrs['ordernumber'] = ordernumber # add order orders_soup.add(order) # add bookings bookings_soup = get_bookings_soup(self.context) # list containing items where stock threshold has been reached stock_threshold_reached_items = list() for booking in bookings: bookings_soup.add(booking) buyable = get_object_by_uid( self.context, booking.attrs['buyable_uid'] ) item_stock = get_item_stock(buyable) # no stock applied if item_stock is None: stock_warning_threshold = None else: stock_warning_threshold = item_stock.stock_warning_threshold if stock_warning_threshold: remaining = booking.attrs['remaining_stock_available'] # stock threshold has been reached if remaining <= stock_warning_threshold: stock_threshold_reached_items.append(booking.attrs) if stock_threshold_reached_items: event = events.StockThresholdReached( self.context, self.request, order.attrs['uid'], stock_threshold_reached_items, ) notify(event) # return uid of added order return uid
def buyable_overbook(context, booking): obj = get_object_by_uid(context, booking.attrs['buyable_uid']) if obj: item_stock = get_item_stock(obj) return item_stock.overbook return None
def save(self, providers, widget, data): super(OrderCheckoutAdapter, self).save(providers, widget, data) order = self.order # order UUID uid = order.attrs['uid'] = uuid.uuid4() # order creator creator = None member = plone.api.user.get_current() if member: creator = member.getId() order.attrs['creator'] = creator # order creation date created = datetime.datetime.now() order.attrs['created'] = created cart_data = get_data_provider(self.context, self.request) # payment related information if cart_data.total > Decimal(0): payment_param = 'checkout.payment_selection.payment' pid = data.fetch(payment_param).extracted payment = Payments(self.context).get(pid) order.attrs['payment_method'] = pid if payment: order.attrs['payment_label'] = payment.label else: order.attrs['payment_label'] = _('unknown', default=u'Unknown') # no payment else: order.attrs['payment_method'] = 'no_payment' order.attrs['payment_label'] = _('no_payment', default=u'No Payment') # shipping related information if cart_data.include_shipping_costs: shipping_param = 'checkout.shipping_selection.shipping' sid = data.fetch(shipping_param).extracted shipping = Shippings(self.context).get(sid) order.attrs['shipping_method'] = sid order.attrs['shipping_label'] = shipping.label order.attrs['shipping_description'] = shipping.description try: shipping_net = shipping.net(self.items) shipping_vat = shipping.vat(self.items) order.attrs['shipping_net'] = shipping_net order.attrs['shipping_vat'] = shipping_vat order.attrs['shipping'] = shipping_net + shipping_vat # B/C for bda.plone.shipping < 0.4 except NotImplementedError: shipping_net = shipping.calculate(self.items) order.attrs['shipping_net'] = shipping_net order.attrs['shipping_vat'] = Decimal(0) order.attrs['shipping'] = shipping_net # no shipping else: order.attrs['shipping_method'] = 'no_shipping' order.attrs['shipping_label'] = _('no_shipping', default=u'No Shipping') order.attrs['shipping_description'] = '' order.attrs['shipping_net'] = Decimal(0) order.attrs['shipping_vat'] = Decimal(0) order.attrs['shipping'] = Decimal(0) # create order bookings bookings = self.create_bookings(order) # set order state, needed for sorting in orders table order.attrs['state'] = calculate_order_state(bookings) # set order salaried, needed for sorting in orders table order.attrs['salaried'] = ifaces.SALARIED_NO # lookup booking uids, buyable uids and vendor uids booking_uids = list() buyable_uids = list() vendor_uids = set() for booking in bookings: booking_uids.append(booking.attrs['uid']) buyable_uids.append(booking.attrs['buyable_uid']) vendor_uids.add(booking.attrs['vendor_uid']) order.attrs['booking_uids'] = booking_uids order.attrs['buyable_uids'] = buyable_uids order.attrs['vendor_uids'] = list(vendor_uids) # cart discount related information cart_discount = cart_data.discount(self.items) order.attrs['cart_discount_net'] = cart_discount['net'] order.attrs['cart_discount_vat'] = cart_discount['vat'] # create ordernumber orders_soup = get_orders_soup(self.context) ordernumber = create_ordernumber() while self.ordernumber_exists(orders_soup, ordernumber): ordernumber = create_ordernumber() order.attrs['ordernumber'] = ordernumber # add order orders_soup.add(order) # add bookings bookings_soup = get_bookings_soup(self.context) # list containing items where stock threshold has been reached stock_threshold_reached_items = list() for booking in bookings: bookings_soup.add(booking) buyable = get_object_by_uid(self.context, booking.attrs['buyable_uid']) item_stock = get_item_stock(buyable) # no stock applied if item_stock is None: stock_warning_threshold = None else: stock_warning_threshold = item_stock.stock_warning_threshold if stock_warning_threshold: remaining = booking.attrs['remaining_stock_available'] # stock threshold has been reached if remaining <= stock_warning_threshold: stock_threshold_reached_items.append(booking.attrs) if stock_threshold_reached_items: event = events.StockThresholdReached( self.context, self.request, order.attrs['uid'], stock_threshold_reached_items, ) notify(event) # return uid of added order return uid
def _get_occs(self): date = guess_date_from(self.date) if date: start, end = start_end_from_mode('day', date, self.context) query = {} query['review_state'] = self.data.state search_base_path = self.search_base_path if search_base_path: query['path'] = {'query': search_base_path} list_events = [] events = get_events(self.context, start=start, end=end, sort='start', sort_reverse=False, ret_mode=RET_MODE_OBJECTS, expand=True, **query) today = datetime.datetime.today().date() for occ in events: if IOccurrence.providedBy(occ): occurrence_id = occ.id event = aq_parent(occ) occ_data = ITicketOccurrenceData(event) occs = occ_data.ticket_occurrences(occurrence_id) if occs: occurrence_ticket = occs[0] item_stock = get_item_stock(occurrence_ticket) if item_stock: stock = item_stock.available else: stock = 0 is_today = occ.start.date() == today new_event = { "start": occ.start, "uid": occurrence_ticket.UID(), "stock": stock, "is_today": is_today } list_events.append(new_event) elif IBuyableEvent.providedBy(occ): occ_data = ITicketOccurrenceData(occ) occs = occ_data.tickets if occs: occurrence_ticket = occs[0] item_stock = get_item_stock(occurrence_ticket) if item_stock: stock = item_stock.available else: stock = 0 is_today = occ.start.date() == today new_event = { "start": occ.start, "uid": occurrence_ticket.UID(), "stock": stock, "is_today": is_today } list_events.append(new_event) else: print 'NOT AVAILABLE' return list_events else: return []