Esempio n. 1
0
def test_allocating_to_a_batch_reduces_the_available_quantity() -> None:
    batch = Batch("batch-001", "SMALL-TABLE", qty=20, eta=today)
    line = OrderLine("order-ref", "SMALL-TABLE", 2)

    batch.allocate(line)

    assert batch.available_quantity == 18
Esempio n. 2
0
def test_prefers_current_stock_batches_to_shipments() -> None:
    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
Esempio n. 3
0
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",
                      items=[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
Esempio n. 4
0
def test_prefers_earlier_batches() -> None:
    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)

    allocate(line, [medium, earliest, latest])

    assert earliest.available_quantity == 90
    assert medium.available_quantity == 100
    assert latest.available_quantity == 100
Esempio n. 5
0
def test_returns_allocated_batch_ref() -> None:
    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)
    allocation = allocate(line, [in_stock_batch, shipment_batch])
    assert allocation == in_stock_batch.reference
Esempio n. 6
0
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",
                      items=[in_stock_batch, shipment_batch])
    allocation = product.allocate(line)
    assert allocation == in_stock_batch.reference
Esempio n. 7
0
def test_increments_version_number():
    line = OrderLine("oref", "SCANDI-PEN", 10)
    product = Product(sku="SCANDI-PEN",
                      items=[Batch("b1", "SCANDI-PEN", 100, eta=None)])
    product.version_number = 7
    product.allocate(line)
    assert product.version_number == 8
Esempio n. 8
0
def test_error_for_invalid_sku() -> None:
    batch = Batch("b1", "AREALSKU", 100, eta=None)
    product = Product(batch.sku, [batch])
    uow = FakeUnitOfWork({Product: "sku"}, [product])
    with pytest.raises(services.allocation.InvalidSku,
                       match="Invalid sku NONEXISTENTSKU"):
        services.allocation.allocate("o1", "NONEXISTENTSKU", 10, uow)
Esempio n. 9
0
def test_records_out_of_stock_event_if_cannot_allocate():
    batch = Batch("batch1", "SMALL-FORK", 10, eta=today)
    product = Product(sku="SMALL-FORK", items=[batch])
    product.allocate(OrderLine("order1", "SMALL-FORK", 10))

    allocation = product.allocate(OrderLine("order2", "SMALL-FORK", 1))
    assert product.messages[-1] == events.OutOfStock(sku="SMALL-FORK")
    assert allocation is None
Esempio n. 10
0
def add_batch(e: commands.CreateBatch, uow: AbstractUnitOfWork):
    """UOW를 이용해 배치를 추가합니다."""
    with uow:
        product = uow[Product].get(e.sku)

        if not product:
            product = Product(e.sku, items=[])
            uow[Product].add(product)
        product.items.append(Batch(e.ref, e.sku, e.qty, e.eta))
        uow.commit()
Esempio n. 11
0
def add_batch(
    ref: str, sku: str, qty: int, eta: Optional[datetime], uow: AbstractUnitOfWork
) -> None:
    """UOW를 이용해 배치를 추가합니다."""
    with uow:
        product = uow[Product].get(sku)

        if not product:
            product = Product(sku, items=[])
            uow[Product].add(product)
        product.items.append(Batch(ref, sku, qty, eta))
        uow.commit()
Esempio n. 12
0
def test_repository_can_save_a_batch(session: Session) -> None:
    batch = Batch("batch1", "RUSTY-SOAPDISH", 100, eta=None)
    product = Product(batch.sku, [batch])

    repo = SqlAlchemyRepository(Product, session)
    repo.add(product)
    session.commit()

    rows = list(
        session.execute(
            "SELECT reference, sku, _purchased_quantity, eta FROM batch"))
    assert rows == [("batch1", "RUSTY-SOAPDISH", 100, None)]
Esempio n. 13
0
def test_repository_can_retrieve_a_batch_with_allocations(
        session: Session) -> None:
    orderline_id = insert_order_line(session)
    batch1_id = insert_batch(session, "batch1", "GENERIC-SOFA")
    insert_product(session, "GENERIC-SOFA")
    insert_batch(session, "batch2", "GENERIC-TABLE")
    insert_product(session, "GENERIC-TABLE")
    insert_allocation(session, orderline_id, batch1_id)

    repo = SqlAlchemyRepository(Product, session)
    product = repo.get("GENERIC-SOFA")
    retrieved = product.items[0] if product else None

    expected = Batch("batch1", "GENERIC-SOFA", 100, eta=None)
    assert retrieved == expected  # Batch.__eq__ only compares reference
    assert retrieved.sku == expected.sku
    assert retrieved._purchased_quantity == expected._purchased_quantity
    assert retrieved._allocations == {
        OrderLine("order1", "GENERIC-SOFA", 12),
    }
Esempio n. 14
0
def test_cannot_allocate_if_skus_do_not_match() -> None:
    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
Esempio n. 15
0
def make_batch_and_line(sku: str, batch_qty: int,
                        line_qty: int) -> tuple[Batch, OrderLine]:
    return (
        Batch("batch-001", sku, batch_qty, eta=today),
        OrderLine("order-123", sku, line_qty),
    )
Esempio n. 16
0
def test_commits() -> None:
    batch = Batch("b1", "OMINOUS-MIRROR", 100, eta=None)
    product = Product(batch.sku, [batch])
    uow = FakeUnitOfWork({Product: "sku"}, [product])
    services.allocation.allocate("o1", "OMINOUS-MIRROR", 10, uow)
    assert uow.committed is True
Esempio n. 17
0
def test_returns_allocation() -> None:
    batch = Batch("b1", "COMPLICATED-LAMP", 100, eta=None)
    product = Product(batch.sku, [batch])
    uow = FakeUnitOfWork({Product: "sku"}, [product])
    result = services.allocation.allocate("o1", "COMPLICATED-LAMP", 10, uow)
    assert result == "b1"
Esempio n. 18
0
def test_batch_equality() -> None:
    batch1 = Batch("batch-001", "SIMPLE-TABLE", 10, eta=today)
    batch2 = Batch("batch-001", "SIMPLE-CHAIR", 5, eta=today)

    assert batch1 == batch2