def test_sends_email_on_out_of_stock_error(self, messagebus: MessageBus): fakebus = FakeMessageBus(messagebus, fake_messages={events.OutOfStock}) fakebus.handle(commands.CreateBatch("b1", "POPULAR-CURTAINS", 9, None)) fakebus.handle(commands.Allocate("o1", "POPULAR-CURTAINS", 10)) [event] = fakebus.message_published assert events.OutOfStock == type(event) assert "POPULAR-CURTAINS" == cast(events.OutOfStock, event).sku
def post_allocate_batch(req: BatchAllocateSchema): """``POST /allocate`` 엔트포인트 요청을 처리합니다.""" try: event = commands.Allocate(req.orderid, req.sku, req.qty) results = messagebus.handle(event) return {"batchref": results.pop(0)} except InvalidSku as e: return {"batchref": None, "error": "InvalidSku"}
def reallocate( event: events.Deallocated, uow: SqlAlchemyUnitOfWork, ): with uow: product = uow[Product].get(event.sku) product.messages.append(commands.Allocate(**asdict(event))) uow.commit()
def test_reallocates_if_necessary(self, messagebus: MessageBus): message_history = [ commands.CreateBatch("batch1", "INDIFFERENT-TABLE", 50, None), commands.CreateBatch("batch2", "INDIFFERENT-TABLE", 50, datetime.today()), commands.Allocate("order1", "INDIFFERENT-TABLE", 20), commands.Allocate("order2", "INDIFFERENT-TABLE", 20), ] for e in message_history: messagebus.handle(e) [batch1, batch2] = messagebus.uow[Product].get("INDIFFERENT-TABLE").items assert batch1.available_quantity == 10 assert batch2.available_quantity == 50 messagebus.handle(commands.ChangeBatchQuantity("batch1", 25)) # order1 or order2 will be deallocated and, so we'll have 25 - 20 assert batch1.available_quantity == 5 # and 20 will be reallocated to the next batch assert batch2.available_quantity == 30
def test_deallocation(sqlite_uow: SqlAlchemyUnitOfWork, messagebus: MessageBus): uow = sqlite_uow fakebus = FakeMessageBus(messagebus) fakebus.handle(commands.CreateBatch("b1", "sku1", 50, None), uow) fakebus.handle(commands.CreateBatch("b2", "sku1", 50, today), uow) fakebus.handle(commands.Allocate("o1", "sku1", 40), uow) fakebus.handle(commands.ChangeBatchQuantity("b1", 10), uow) assert get_allocations_by("o1", uow) == [ { "sku": "sku1", "batchref": "b2" }, ]
def test_allocations_view(sqlite_uow: SqlAlchemyUnitOfWork, messagebus: MessageBus): uow = sqlite_uow fakebus = FakeMessageBus(messagebus) fakebus.handle(commands.CreateBatch("sku1batch", "sku1", 50, None), uow) fakebus.handle(commands.CreateBatch("sku2batch", "sku2", 50, today), uow) fakebus.handle(commands.Allocate("order1", "sku1", 20), uow) fakebus.handle(commands.Allocate("order1", "sku2", 20), uow) # add a spurious batch and order to make sure we're getting the right ones fakebus.handle(commands.CreateBatch("sku1batch-later", "sku1", 50, today), uow) fakebus.handle(commands.Allocate("otherorder", "sku1", 30), uow) fakebus.handle(commands.Allocate("otherorder", "sku2", 10), uow) assert get_allocations_by("order1", uow) == [ { "sku": "sku1", "batchref": "sku1batch" }, { "sku": "sku2", "batchref": "sku2batch" }, ]
def change_batch_quantity(self, ref: str, new_qty: int) -> None: """배치에 할당된 주문선을 수량만큼 해제합니다.""" batch = next(b for b in self.items if b.reference == ref) batch._purchased_quantity = new_qty logger.info( "change_batch_quantity: ref=%r, new_qty=%r, avail_qty=%r", ref, new_qty, batch.available_quantity, ) while batch.available_quantity < 0: line = batch.deallocate_one() if line: self.messages.append( commands.Allocate(line.orderid, line.sku, line.qty) ) self.messages.append( events.Deallocated(line.orderid, line.sku, line.qty) )
def test_commits(self, messagebus: MessageBus): messagebus.handle( commands.CreateBatch("b1", "OMINOUS-MIRROR", 100, None)) messagebus.handle(commands.Allocate("o1", "OMINOUS-MIRROR", 10)) assert messagebus.uow.committed
def test_errors_for_invalid_sku(self, messagebus: MessageBus): messagebus.handle(commands.CreateBatch("b1", "AREALSKU", 100, None)) with pytest.raises(allocation.InvalidSku, match="Invalid sku NONEXISTENTSKU"): messagebus.handle(commands.Allocate("o1", "NONEXISTENTSKU", 10))
def test_returns_allocation(self, messagebus: MessageBus): messagebus.handle( commands.CreateBatch("batch1", "COMPLICATED-LAMP", 100, None)) result = messagebus.handle( commands.Allocate("o1", "COMPLICATED-LAMP", 10)) assert ["batch1"] == result