def test_raises_out_of_stock_exception_if_cannot_allocate(): batch = Batch('batch1', 'SMALL-FORK', 10, eta=today) product = Product(sku="SMALL-FORK", batches=[batch]) product.allocate(OrderLine('order1', 'SMALL-FORK', 10)) with pytest.raises(OutOfStock, match='SMALL-FORK'): product.allocate(OrderLine('order2', 'SMALL-FORK', 1))
def test_can_only_allocate_with_same_sku() -> None: batch = BatchOrder("bref-01", "CACTO SECO-P11", qty=19, eta=None) line = OrderLine("oline-03", "CACTO GRANDE", qty=2) assert batch.can_allocate(line) is False goat_line = OrderLine("oline-03", "CACTO SECO-P11", qty=2) assert batch.can_allocate(goat_line)
def test_records_out_of_stock_event_if_cannot_allocate(): batch = Batch('batch1', 'SMALL-FORK', 10, eta=today) product = Product(sku="SMALL-FORK", batches=[batch]) product.allocate(OrderLine('order1', 'SMALL-FORK', 10)) allocation = product.allocate(OrderLine('order2', 'SMALL-FORK', 1)) assert product.events[-1] == events.OutOfStock(sku="SMALL-FORK") assert allocation is None
def test_records_out_of_stock_event_if_cannot_allocate(): sku = "KALANCHOE-EVENTO" batch = BatchOrder("b1", sku, 15, eta=TOMORROW) product = Product(sku, batches=[batch]) product.allocate(OrderLine("o1", sku, 10)) b2 = product.allocate(OrderLine("o2", sku, 20)) assert product.latest_event == events.OutOfStock(sku=sku) assert b2 is None
def test_raises_out_of_stock_exception_if_cannot_allocate(): batch = Batch("batch-001", "SMALL-TABLE", qty=5, eta=today) line1 = OrderLine("order-1", "SMALL-TABLE", 5) line2 = OrderLine("order-2", "SMALL-TABLE", 5) product = Product(sku="SMALL-TABLE", batches=[batch]) product.allocate(line1) allocation = product.allocate(line2) assert product.events[-1] == OutOfStock(sku="SMALL-TABLE") assert allocation is None
def test_returns_allocated_batch_ref(): in_stock_batch = Batch("in-stock-batch-ref", "HIGHBROW-POSTER", 100, eta=None) shipment_batch = Batch("shipment-batch-ref", "HIGHBROW-POSTER", 100, eta=tomorrow) line = OrderLine("oref", "HIGHBROW-POSTER", 10) product = Product(sku="HIGHBROW-POSTER", batches=[in_stock_batch, shipment_batch]) allocation = product.allocate(line) assert allocation == in_stock_batch.reference
def test_increments_version_number(): line = OrderLine('oref', "SCANDI-PEN", 10) product = Product(sku="SCANDI-PEN", batches=[Batch('b1', "SCANDI-PEN", 100, eta=None)]) product.version_number = 7 product.allocate(line) assert product.version_number == 8
def test_prefers_warehouse_batches_to_shipments(): batch_in_warehouse = Batch("batch-001", "DESK-LAMP", 100, None) batch_tomorrow = Batch("batch-002", "DESK-LAMP", 100, tomorrow) line = OrderLine("oref", "DESK-LAMP", 10) batches = [batch_in_warehouse, batch_tomorrow] selected_batch_ref = allocate(line, batches) assert selected_batch_ref == batch_in_warehouse.reference and batch_in_warehouse.available_quantity == 90
def test_allocating_to_a_batch_reduces_the_available_quantity(): batch = Batch("batch-001", "SMALL-TABLE", qty=20, eta=date.today()) line = OrderLine('order-ref', "SMALL-TABLE", 2) batch.allocate(line) assert batch.available_quantity == 18
def test_returns_allocated_ref(): in_stock_batch = Batch("in-stock-batch", "RETRO-CLOCK", 100, eta=None) shipment_batch = Batch("shipment-batch", "RETRO-CLOCK", 100, eta=tomrrow) line = OrderLine("oref", "RETRO-CLOCK", 10) allocations = allocate(line, [in_stock_batch, shipment_batch]) assert allocations == in_stock_batch.reference
def allocate(cmd: commands.Allocate, uow: unit_of_work.AbstractUnitOfWork): line = OrderLine(cmd.orderid, cmd.sku, cmd.qty) with uow: product = uow.products.get(sku=line.sku) if product is None: raise InvalidSku(f"Invalid sku {line.sku}") product.allocate(line) uow.commit()
def test_prefers_earlier_batches(): earliest = Batch("speedy-batch", "MINIMALIST-SPOON", 100, eta=today) medium = Batch("normal-batch", "MINIMALIST-SPOON", 100, eta=tomorrow) latest = Batch("slow-batch", "MINIMALIST-SPOON", 100, eta=later) line = OrderLine("order1", "MINIMALIST-SPOON", 10) selected_batch_ref = allocate(line, [medium, earliest, latest]) assert selected_batch_ref == earliest.reference and earliest.available_quantity == 90
def test_outputs_allocated_event(): batch = Batch("batchref", "RETRO-LAMPSHADE", 100, eta=None) line = OrderLine("oref", "RETRO-LAMPSHADE", 10) product = Product(sku="RETRO-LAMPSHADE", batches=[batch]) product.allocate(line) expected = events.Allocated( orderid="oref", sku="RETRO-LAMPSHADE", qty=10, batchref=batch.reference ) assert product.events[-1] == expected
def test_returns_allocated_batch_reference(): in_stock_batch = Batch("batch-001", "BIG-SOFA", qty=20, eta=None) shipment_batch = Batch("batch-002", "BIG-SOFA", qty=20, eta=today) product = Product(sku="BIG-SOFA", batches=[in_stock_batch, shipment_batch]) line = OrderLine("order-123", "BIG-SOFA", 5) allocation = product.allocate(line) assert allocation == in_stock_batch.reference
def test_prefers_current_stock_batches_to_shipments(): in_stock_batch = Batch("in-stock-batch", "RETRO-CLOCK", 100, eta=None) shipment_batch = Batch("shipment-batch", "RETRO-CLOCK", 100, eta=tomorrow) line = OrderLine("oref", "RETRO-CLOCK", 10) allocate(line, [in_stock_batch, shipment_batch]) assert in_stock_batch.available_quantity == 90 assert shipment_batch.available_quantity == 100
def test_prefers_warehouse_batches_to_shipments(): in_stock_batch = Batch("batch-001", "BIG-SOFA", qty=20, eta=None) shipment_batch = Batch("batch-002", "BIG-SOFA", qty=20, eta=today) product = Product(sku="BIG-SOFA", batches=[in_stock_batch, shipment_batch]) line = OrderLine("order-123", "BIG-SOFA", 5) product.allocate(line) assert in_stock_batch.available_quantity == 15 assert shipment_batch.available_quantity == 20
def test_allocation_emmits_events(): sku = "KALANCHOE-EVENTO" batch = BatchOrder("b1", sku, 100, eta=TOMORROW) product = Product(sku, batches=[batch]) line = OrderLine("o1", sku, qty=85) product.add_batch(batch) product.allocate(line) assert type(product.latest_event) == events.Allocated
def test_prefers_warehouse_batches_to_shipments(): in_stock_batch = Batch("in-stock-batch", "RETRO-CLOCK", 100, eta=None) shipment_batch = Batch("shipment-batch", "RETRO-CLOCK", 100, eta=tomorrow) product = Product(sku="RETRO-CLOCK", batches=[in_stock_batch, shipment_batch]) line = OrderLine("oref", "RETRO-CLOCK", 10) product.allocate(line) assert in_stock_batch.available_quantity == 90 assert shipment_batch.available_quantity == 100
def allocate(orderid: str, sku: str, qty: int, uow: unit_of_work.AbstractUnitOfWork) -> str: line = OrderLine(orderid, sku, qty) with uow: product = uow.products.get(sku=line.sku) if product is None: raise InvalidSku(f'Invalid sku {line.sku}') batchref = product.allocate(line) uow.commit() return batchref
def test_prefers_current_stock_batches_to_shipments() -> None: sku = "KALANCHOE-P11" batch_in_stock = BatchOrder("in-stock-ref", sku, 100, eta=None) batch_shipment = BatchOrder("shipment-ref", sku, 100, eta=TOMORROW) line = OrderLine("o-ref", sku, 10) product = Product(sku, [batch_in_stock, batch_shipment]) product.allocate(line) assert batch_in_stock.available_quantity == 90 assert batch_shipment.available_quantity == 100
def test_prefers_earlier_batches(): earliest = Batch("speedy-batch", "MINIMALIST-SPOON", 100, eta=today) medium = Batch("speedy-batch", "MINIMALIST-SPOON", 100, eta=tomrrow) latest = Batch("speedy-batch", "MINIMALIST-SPOON", 100, eta=later) line = OrderLine("oref", "MINIMALIST-SPOON", 10) allocate(line, [earliest, medium, latest]) assert earliest.available_quantity == 90 assert medium.available_quantity == 100 assert latest.available_quantity == 100
def test_version_number_increments() -> None: sku = "KALANCHOE-P11" batch_today = BatchOrder("shipment-ref02", sku, 100, eta=date.today()) line = OrderLine("o-ref", sku, 10) product = Product(sku, [batch_today]) assert product.version_number == 0 product.allocate(line) assert product.version_number == 1 product.deallocate() assert product.version_number == 2
def test_prefers_earlier_batches(): tomorrows_batch = Batch("batch-001", "MINI-SPOON", qty=20, eta=tomorrow) upcoming_batch = Batch("batch-001", "MINI-SPOON", qty=20, eta=later) product = Product(sku="MINI-SPOON", batches=[tomorrows_batch, upcoming_batch]) line = OrderLine("order-123", "MINI-SPOON", 5) allocation = product.allocate(line) assert allocation == tomorrows_batch.reference assert tomorrows_batch.available_quantity == 15 assert upcoming_batch.available_quantity == 20
def test_prefers_earlier_batches(): earliest = Batch("speedy-batch", "MINIMALIST-SPOON", 100, eta=today) medium = Batch("normal-batch", "MINIMALIST-SPOON", 100, eta=tomorrow) latest = Batch("slow-batch", "MINIMALIST-SPOON", 100, eta=later) product = Product(sku="MINIMALIST-SPOON", batches=[medium, earliest, latest]) line = OrderLine("order1", "MINIMALIST-SPOON", 10) product.allocate(line) assert earliest.available_quantity == 90 assert medium.available_quantity == 100 assert latest.available_quantity == 100
def test_returns_allocated_batch_ref(): in_stock_batch = Batch('in-stock-batch', 'HIGHBROW-POSTER', 100, eta=None) shipment_batch = Batch('shipment-batch', 'HIGHBROW-POSTER', 100, eta=tomorrow) product = Product(sku='HIGHBROW-POSTER', batches=[in_stock_batch, shipment_batch]) line = OrderLine('oref', 'HIGHBROW-POSTER', 10) allocation = product.allocate(line) assert allocation == in_stock_batch.reference
def allocate( orderid: str, sku: str, qty: int, uow: unit_of_work.AbstractUnitOfWork ) -> str: line = OrderLine(orderid, sku, qty) with uow: batches = uow.batches.list() if not is_valid_sku(line.sku, batches): raise InvalidSku(f'Invalid sku {line.sku}') batchref = model.allocate(line, batches) uow.commit() return batchref
def test_prefer_earlier_batches() -> None: sku = "KALANCHOE-P11" batch_today = BatchOrder("shipment-ref02", sku, 100, eta=date.today()) batch_yesterday = BatchOrder("shipment-ref03", sku, 100, eta=YESTERDAY) batch_tomorrow = BatchOrder("shipment-ref04", sku, 100, eta=TOMORROW) line = OrderLine("o-ref", sku, 10) product = Product(sku, [batch_today, batch_yesterday, batch_tomorrow]) product.allocate(line) assert batch_yesterday.available_quantity == 90 assert batch_today.available_quantity == 100 assert batch_tomorrow.available_quantity == 100
def make_batch_and_line(sku, batch_qty, line_qty): return (Batch("batch-001", sku, batch_qty, eta=date.today()), OrderLine("order-123", sku, line_qty))
def test_outputs_allocated_event(): batch = Batch("batchref", "RETRO-LAMPSHADE", 100, eta=None) line = OrderLine("oref", "RETRO-LAMPSHADE", 10) product = Product(sku="RETRO-LAMPSHADE", batches=[batch]) product.allocate(line) expected = events.Allocated( orderid="oref", sku="RETRO-LAMPSHADE", qty=10, batchref=batch.reference ) assert product.events[-1] == expected def test_records_out_of_stock_event_if_cannot_allocate(): <<<<<<< HEAD batch = Batch('batch1', 'SMALL-FORK', 10, eta=today) product = Product(sku="SMALL-FORK", batches=[batch]) product.allocate(OrderLine('order1', 'SMALL-FORK', 10)) allocation = product.allocate(OrderLine('order2', 'SMALL-FORK', 1)) ======= batch = Batch("batch1", "SMALL-FORK", 10, eta=today) product = Product(sku="SMALL-FORK", batches=[batch]) product.allocate(OrderLine("order1", "SMALL-FORK", 10)) allocation = product.allocate(OrderLine("order2", "SMALL-FORK", 1)) >>>>>>> upstream/master assert product.events[-1] == events.OutOfStock(sku="SMALL-FORK") assert allocation is None def test_increments_version_number(): <<<<<<< HEAD
def test_cannot_allocate_if_skus_do_not_match(): batch = Batch("batch-001", "UNCOMFORTABLE-CHAIR", 100, eta=None) different_sku_line = OrderLine("order-123", "EXPENSIVE-TOASTER", 10) assert batch.can_allocate(different_sku_line) is False