setUpDB(); $this->drinkTypeRepository = $this->container->get(DrinkTypeRepository::class); $this->inventoryRecordRepository = $this->container->get(InventoryRecordRepository::class); $this->configService = $this->container->get(ConfigurationService::class); $this->service = $this->container->get(InventoryService::class); // Create a drink type for testing $this->drinkType = new DrinkType('Cola', 'Refreshing cola drink', 10); $this->drinkTypeRepository->save($this->drinkType); } public function testGetAllInventoryRecords(): void { // Initially the repository should be empty $this->assertCount(0, $this->service->getAllInventoryRecords()); // Create some inventory records $record1 = new InventoryRecord($this->drinkType, 5, new DateTimeImmutable('2023-01-01')); $record2 = new InventoryRecord($this->drinkType, 10, new DateTimeImmutable('2023-01-02')); $this->inventoryRecordRepository->save($record1); $this->inventoryRecordRepository->save($record2); // Now getAllInventoryRecords should return both records $records = $this->service->getAllInventoryRecords(); $this->assertCount(2, $records); $this->assertContainsOnlyInstancesOf(InventoryRecord::class, $records); } public function testGetInventoryRecordsByDrinkType(): void { // Create another drink type $anotherDrinkType = new DrinkType('Fanta', 'Orange soda', 5); $this->drinkTypeRepository->save($anotherDrinkType); // Create inventory records for both drink types $record1 = new InventoryRecord($this->drinkType, 5, new DateTimeImmutable('2023-01-01')); $record2 = new InventoryRecord($this->drinkType, 10, new DateTimeImmutable('2023-01-02')); $record3 = new InventoryRecord($anotherDrinkType, 15, new DateTimeImmutable('2023-01-03')); $this->inventoryRecordRepository->save($record1); $this->inventoryRecordRepository->save($record2); $this->inventoryRecordRepository->save($record3); // Get records for the first drink type $records = $this->service->getInventoryRecordsByDrinkType($this->drinkType); $this->assertCount(2, $records); $this->assertContainsOnlyInstancesOf(InventoryRecord::class, $records); // Check that the records are for the correct drink type foreach ($records as $record) { $this->assertEquals($this->drinkType->getId(), $record->getDrinkType()->getId()); } // Get records for the second drink type $records = $this->service->getInventoryRecordsByDrinkType($anotherDrinkType); $this->assertCount(1, $records); $this->assertEquals($anotherDrinkType->getId(), $records[0]->getDrinkType()->getId()); } public function testGetLatestInventoryRecord(): void { // Create inventory records with different timestamps $record1 = new InventoryRecord($this->drinkType, 5, new DateTimeImmutable('2023-01-01')); $record2 = new InventoryRecord($this->drinkType, 10, new DateTimeImmutable('2023-01-02')); $record3 = new InventoryRecord($this->drinkType, 15, new DateTimeImmutable('2023-01-03')); $this->inventoryRecordRepository->save($record1); $this->inventoryRecordRepository->save($record2); $this->inventoryRecordRepository->save($record3); // Get the latest record $latestRecord = $this->service->getLatestInventoryRecord($this->drinkType); $this->assertInstanceOf(InventoryRecord::class, $latestRecord); $this->assertEquals(15, $latestRecord->getQuantity()); $this->assertEquals('2023-01-03', $latestRecord->getTimestamp()->format('Y-m-d')); } public function testGetInventoryRecordsByTimeRange(): void { // Create inventory records with different timestamps $record1 = new InventoryRecord($this->drinkType, 5, new DateTimeImmutable('2023-01-01')); $record2 = new InventoryRecord($this->drinkType, 10, new DateTimeImmutable('2023-01-02')); $record3 = new InventoryRecord($this->drinkType, 15, new DateTimeImmutable('2023-01-03')); $record4 = new InventoryRecord($this->drinkType, 20, new DateTimeImmutable('2023-01-04')); $record5 = new InventoryRecord($this->drinkType, 25, new DateTimeImmutable('2023-01-05')); $this->inventoryRecordRepository->save($record1); $this->inventoryRecordRepository->save($record2); $this->inventoryRecordRepository->save($record3); $this->inventoryRecordRepository->save($record4); $this->inventoryRecordRepository->save($record5); // Get records in a specific range $start = new DateTimeImmutable('2023-01-02'); $end = new DateTimeImmutable('2023-01-04'); $records = $this->service->getInventoryRecordsByTimeRange($start, $end); $this->assertCount(3, $records); // Check that the records are within the range foreach ($records as $record) { $timestamp = $record->getTimestamp(); $this->assertTrue($timestamp >= $start && $timestamp <= $end); } } public function testGetCurrentStockLevel(): void { // Initially there should be no stock $this->assertEquals(0, $this->service->getCurrentStockLevel($this->drinkType)); // Create inventory records with different timestamps $record1 = new InventoryRecord($this->drinkType, 5, new DateTimeImmutable('2023-01-01')); $record2 = new InventoryRecord($this->drinkType, 10, new DateTimeImmutable('2023-01-02')); $record3 = new InventoryRecord($this->drinkType, 15, new DateTimeImmutable('2023-01-03')); $this->inventoryRecordRepository->save($record1); $this->inventoryRecordRepository->save($record2); $this->inventoryRecordRepository->save($record3); // The current stock level should be from the latest record $this->assertEquals(15, $this->service->getCurrentStockLevel($this->drinkType)); } public function testGetStockDifference(): void { // Create inventory records $record = new InventoryRecord($this->drinkType, 15, new DateTimeImmutable('2023-01-01')); $this->inventoryRecordRepository->save($record); // The drink type has a desired stock of 10, and a current stock of 15 // So the difference should be 5 (excess) $this->assertEquals(5, $this->service->getStockDifference($this->drinkType)); // Create a new record with less stock $record = new InventoryRecord($this->drinkType, 5, new DateTimeImmutable('2023-01-02')); $this->inventoryRecordRepository->save($record); // Now the current stock is 5, and the desired stock is 10 // So the difference should be -5 (shortage) $this->assertEquals(-5, $this->service->getStockDifference($this->drinkType)); } public function testUpdateStockLevel(): void { // Update the stock level with a specific timestamp $timestamp1 = new DateTimeImmutable('2023-01-01 10:00:00'); $record = $this->service->updateStockLevel($this->drinkType, 15, $timestamp1); // Check that the record was created correctly $this->assertInstanceOf(InventoryRecord::class, $record); $this->assertEquals($this->drinkType->getId(), $record->getDrinkType()->getId()); $this->assertEquals(15, $record->getQuantity()); $this->assertEquals($timestamp1, $record->getTimestamp()); // Check that the current stock level is updated $this->assertEquals(15, $this->service->getCurrentStockLevel($this->drinkType)); // Update the stock level again with a later timestamp $timestamp2 = new DateTimeImmutable('2023-01-02 10:00:00'); $record = $this->service->updateStockLevel($this->drinkType, 20, $timestamp2); // Check that the record was created correctly $this->assertEquals(20, $record->getQuantity()); $this->assertEquals($timestamp2, $record->getTimestamp()); // Check that the current stock level is updated to the latest record's quantity $this->assertEquals(20, $this->service->getCurrentStockLevel($this->drinkType)); } public function testGetAllDrinkTypesWithStockLevels(): void { // Create another drink type $anotherDrinkType = new DrinkType('Fanta', 'Orange soda', 5); $this->drinkTypeRepository->save($anotherDrinkType); // Create inventory records $record1 = new InventoryRecord($this->drinkType, 15, new DateTimeImmutable('2023-01-01')); $record2 = new InventoryRecord($anotherDrinkType, 3, new DateTimeImmutable('2023-01-01')); $this->inventoryRecordRepository->save($record1); $this->inventoryRecordRepository->save($record2); // Get all drink types with stock levels $result = $this->service->getAllDrinkTypesWithStockLevels(); $this->assertCount(2, $result); // Check the first drink type $this->assertEquals($this->drinkType->getId(), $result[0]['drinkType']->getId()); $this->assertEquals(15, $result[0]['currentStock']); $this->assertEquals(10, $result[0]['desiredStock']); $this->assertEquals(5, $result[0]['difference']); // Check the second drink type $this->assertEquals($anotherDrinkType->getId(), $result[1]['drinkType']->getId()); $this->assertEquals(3, $result[1]['currentStock']); $this->assertEquals(5, $result[1]['desiredStock']); $this->assertEquals(-2, $result[1]['difference']); } public function testGetLowStockDrinkTypes(): void { // Set the low stock threshold to 70% so that 3/5 (60%) is considered low stock $this->configService->setConfigValue(SystemSettingKey::LOW_STOCK_THRESHOLD->value, '70'); // Create another drink type $anotherDrinkType = new DrinkType('Fanta', 'Orange soda', 5); $this->drinkTypeRepository->save($anotherDrinkType); // Create inventory records $record1 = new InventoryRecord($this->drinkType, 15, new DateTimeImmutable('2023-01-01')); $record2 = new InventoryRecord($anotherDrinkType, 3, new DateTimeImmutable('2023-01-01')); $this->inventoryRecordRepository->save($record1); $this->inventoryRecordRepository->save($record2); // Get low stock drink types $result = $this->service->getLowStockDrinkTypes(); // Only the second drink type has low stock $this->assertCount(1, $result); $this->assertEquals($anotherDrinkType->getId(), $result[0]['drinkType']->getId()); $this->assertEquals(3, $result[0]['currentStock']); $this->assertEquals(5, $result[0]['desiredStock']); $this->assertEquals(2, $result[0]['shortage']); } }