| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- from django.db.models.loading import get_model
-
- from oscar.apps.order.exceptions import InvalidShippingEvent
-
- ShippingEventQuantity = get_model('order', 'ShippingEventQuantity')
- PaymentEventQuantity = get_model('order', 'PaymentEventQuantity')
-
-
- class EventHandler(object):
-
- def handle_order_status_change(self, order, new_status):
- """
- Handle a requested order status change
- """
- order.set_status(new_status)
-
- def handle_shipping_event(self, order, event_type, lines, line_quantities, **kwargs):
- """
- Handle a shipping event for a given order.
-
- This might involve taking payment, sending messages and
- creating the event models themeselves. You will generally want to
- override this method to implement the specifics of you order processing
- pipeline.
- """
- self.create_shipping_event(order, event_type, lines, line_quantities, **kwargs)
-
- def has_any_line_passed_shipping_event(self, order, lines, line_quantities, event_name):
- """
- Test whether any one of the lines passed has been through the event
- specified.
- """
- events = order.shipping_events.filter(event_type__name=event_name)
- remaining_qtys = [line.quantity - qty for line, qty in zip(lines, line_quantities)]
- spare_line_qtys = dict(zip([line.id for line in lines], remaining_qtys))
- for event in events:
- for line_qty in event.line_quantities.all():
- line_id = line_qty.line.id
- if line_id in spare_line_qtys:
- spare_line_qtys[line_id] -= line_qty.quantity
- return any(map(lambda x: x<0, spare_line_qtys.values()))
-
- def have_lines_passed_shipping_event(self, order, lines, line_quantities, event_name):
- """
- Test whether the passed lines and quantities have been through the
- specified shipping event.
-
- This is useful for validating if certain shipping events are allowed (ie
- you can't return something before it has shipped).
- """
- events = order.shipping_events.filter(event_type__name=event_name)
- required_line_qtys = dict(zip([line.id for line in lines], line_quantities))
- for event in events:
- for line_qty in event.line_quantities.all():
- line_id = line_qty.line.id
- if line_id in required_line_qtys:
- required_line_qtys[line_id] -= line_qty.quantity
- return not any(map(lambda x: x>0, required_line_qtys.values()))
-
- def handle_payment_event(self, order, event_type, amount, lines=None,
- line_quantities=None, **kwargs):
- """
- Handle a payment event for a given order.
- """
- self.create_payment_event(order, event_type, amount, lines, line_quantities, **kwargs)
-
- def are_stock_allocations_available(self, lines, line_quantities):
- """
- Check whether stock records still have enough stock to honour the
- requested allocations.
- """
- for line, qty in zip(lines, line_quantities):
- record = line.product.stockrecord
- if not record.is_allocation_consumption_possible(qty):
- return False
- return True
-
- def consume_stock_allocations(self, order, lines, line_quantities):
- """
- Consume the stock allocations for the passed lines
- """
- for line, qty in zip(lines, line_quantities):
- if line.product:
- line.product.stockrecord.consume_allocation(qty)
-
- def cancel_stock_allocations(self, order, lines, line_quantities):
- """
- Cancel the stock allocations for the passed lines
- """
- for line, qty in zip(lines, line_quantities):
- line.product.stockrecord.cancel_allocation(qty)
-
- def create_shipping_event(self, order, event_type, lines, line_quantities,
- **kwargs):
- reference = kwargs.get('reference', None)
- event = order.shipping_events.create(event_type=event_type,
- notes=reference)
- try:
- for line, quantity in zip(lines, line_quantities):
- ShippingEventQuantity.objects.create(event=event,
- line=line,
- quantity=quantity)
- except InvalidShippingEvent:
- event.delete()
- raise
-
- def create_payment_event(self, order, event_type, amount, lines=None,
- line_quantities=None, **kwargs):
- event = order.payment_events.create(event_type=event_type, amount=amount)
- if lines and line_quantities:
- for line, quantity in zip(lines, line_quantities):
- PaymentEventQuantity.objects.create(event=event,
- line=line,
- quantity=quantity)
-
- def create_communication_event(self, order, event_type):
- order.communication_events.create(event_type=event_type)
-
- def create_note(self, order, message, note_type='System'):
- order.notes.create(message=message, note_type=note_type)
|