Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat (INVT-CPC 885 ) : Ability to get product by id and details page #541

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api-gateway/src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@
<script src="scripts/inventory-product-list/inventory-product-list.controller.js"></script>
<script src="scripts/inventory-product-list/inventory-product-list.component.js"></script>

<script src="scripts/product-details-info/product-details-info.js"></script>
<script src="scripts/product-details-info/product-details-info.controller.js"></script>
<script src="scripts/product-details-info/product-details-info.component.js"></script>



<script src="scripts/product-form/product-form.js"></script>
<script src="scripts/product-form/product-form.controller.js"></script>
<script src="scripts/product-form/product-form.component.js"></script>
Expand Down
6 changes: 3 additions & 3 deletions api-gateway/src/main/resources/static/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ const whiteList = new Set([
/* App Module */
const petClinicApp = angular.module('petClinicApp', [
'ui.router', 'layoutNav', 'layoutFooter', 'layoutWelcome', 'ownerList', 'ownerDetails', 'ownerForm', 'ownerRegister', 'petRegister', 'petForm'
, 'visits', 'vetList','vetForm','vetDetails', 'visitList', 'billForm', 'billUpdateForm', 'loginForm', 'rolesDetails', 'signupForm',
'billDetails', 'billsByOwnerId', 'billHistory','billsByVetId','inventoryList', 'inventoryForm', 'productForm','inventoryProductList', 'inventoryUpdateForm', 'productUpdateForm'
, 'verification' , 'adminPanel','resetPwdForm','forgotPwdForm','petTypeList']);
, 'visits', 'vetList','vetForm','vetDetails', 'visitList', 'billForm', 'billUpdateForm', 'loginForm', 'rolesDetails', 'signupForm', 'productDetailsInfo',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you think it was necessary to add "productDetailsInfo" in the app.js?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i didn't add the product detail info, in the app.js, then my page would never render when called.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's very smart thank you for your input Mr Siddiqui.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad that you found out, that the order matters when setting the module on the app.js when it comes to loading new files.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, took me a while to figure it out but after doing some debugging found my issue.

'billDetails', 'billsByOwnerId', 'billHistory','billsByVetId','inventoryList', 'inventoryForm', 'productForm','inventoryProductList', 'inventoryUpdateForm', 'productUpdateForm',
'verification' , 'adminPanel','resetPwdForm','forgotPwdForm','petTypeList']);



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ <h2>Inventory</h2>
<td>Name</td>
<td>Type</td>
<td>Description</td>
<td>Update</td>

</tr>
<tr>
<td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ angular.module('inventoryProductList')
// Handle if inventory is empty
console.log("The inventory is empty!");
}


}).catch(function (error) {
if (error.status === 404) {
console.clear()
Expand All @@ -24,7 +26,7 @@ angular.module('inventoryProductList')
});


$scope.deleteProduct = function (product) {
$scope.deleteProduct = function (product) {
let varIsConf = confirm('Are you sure you want to remove this product?');
if (varIsConf) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,27 @@ <h2>Inventory Products</h2>
</thead>
<tr ng-repeat="product in $ctrl.inventoryProductList | filter:$ctrl.query track by product.productId">
<td><span>{{product.productName}}</span></td>
<td><span>{{product.productId}}</span></td>
<td><span>{{product.productId}}</span></td>
<td><span>{{product.productQuantity}}</span></td>
<td><span>{{product.productPrice}}</span></td>
<td><span>{{product.productDescription}}</span></td>
<td><span>{{product.productSalePrice}}</span></td>

<td>
<a href="#!/inventory/{{$ctrl.inventory.inventoryId}}/products/{{product.productId}}">
Get Product Details
</a>

</td>


<td><a ui-sref="updateProductInventory({inventoryId: $ctrl.inventoryProductList[0].inventoryId, productId: product.productId})">
<button class="add-bundle-button btn btn-success">Edit</button>
<button class="add-bundle-button btn btn-warning">Edit</button>
Copy link
Collaborator

@DiSavio DiSavio Oct 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on why you changed the btn-success to the btn-warning?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My pleasure, so I changed the color from btn -success to btn - warning, because green means success and you haven't changed or modified any value yet, thats why i changed the btn color to yellow to show that you need to test the functionality of the button.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see thank you for informing me. It does make sense now because it will also match better with the inventory since the other update button in the inventories has it on "Warning" as well now that I look at it.

</a></td>




<td><a class="btn btn-danger" href="javascript:void(0)" ng-click="deleteProduct(product)">Delete</a></td>
<td></td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

angular.module('productDetailsInfo')
.component('productDetailsInfo', {
templateUrl: 'scripts/product-details-info/product-details-info.template.html',
controller: 'ProductDetailsInfoController'
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
angular.module('productDetailsInfo')
.controller('ProductDetailsInfoController', ["$http", '$state', '$stateParams', '$scope', 'InventoryService', function ($http, $state, $stateParams, $scope, InventoryService) {
var self = this;
self.product = {}; // Initialize self.product
var inventoryId = InventoryService.getInventoryId();
var productId = $stateParams.productId;

$http.get('/api/gateway/inventory/' + inventoryId + '/products/' + productId)
.then(function (resp) {
// Handle the response data for the specific product
var product = resp.data;
console.log("Product found:", product);
self.product = product; // Update the product data in your controller
})
.catch(function (error) {
// Handle errors if the product is not found or other issues
console.error("Error fetching product:", error);
});

}]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

angular.module('productDetailsInfo', ['ui.router'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('productDetails', {
parent: 'app',
url: '/inventory/:inventoryId/products/:productId',
template: '<product-details-info></product-details-info>'
})

.state('products', {
parent: 'app',
url: '/inventory/:inventoryId/products',
template: '<inventory-product-list></inventory-product-list>'
})
}]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">

<div class="bColor text-center"><h2 class="titleBundle form" id="title">Product Details Info</h2></div>
<div class="container mt-5">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-6 text-end">
<h3 class="inventory-id">Inventory Id: </h3>
</div>
<div class="col-md-6">
<h3>{{$ctrl.product.inventoryId}}</h3>
</div>
</div>
<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h3 class="product-id">Product Id: </h3>
</div>
<div class="col-md-6">
<h3>{{$ctrl.product.productId}}</h3>
</div>
</div>
<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h5 class="product-description-label">Product Description:</h5>
</div>
<div class="col-md-6">
<h5>{{$ctrl.product.productDescription}}</h5>
</div>
</div>
<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h5 class="product-price-label">Product Price:</h5>
</div>
<div class="col-md-6">
<h5>{{$ctrl.product.productPrice}}</h5>
</div>



</div>
<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h5 class="product-price-label">Product SalePrice:</h5>
</div>
<div class="col-md-6">
<h5>{{$ctrl.product.productSalePrice}}</h5>
</div>

</div>

<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h5 class="product-quantity-label">Product Quantity:</h5>
</div>
<div class="col-md-6">
<h5>{{$ctrl.product.productQuantity}}</h5>
</div>
</div>
<hr> <!-- Horizontal line -->
</div>
</div>
<div class="text-center mt-4">
<a class="btn btn-primary" href="#!/inventory/{{$ctrl.product.inventoryId}}/products">
Back to Products page
</a>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

angular.module('productDetails')
.component('productDetails', {
templateUrl: 'scripts/product-details/product-details.template.html',
controller: 'ProductDetailsController'
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">

<div class="bColor text-center"><h2 class="titleBundle form" id="title">Product Details</h2></div>
<div class="container mt-5">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-6 text-end">
<h3 class="inventory-id">Inventory Id: </h3>
</div>
<div class="col-md-6">
<h3>{{$ctrl.product.inventoryId}}</h3>
</div>
</div>
<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h3 class="product-id">Product Id: </h3>
</div>
<div class="col-md-6">
<h3>{{$ctrl.product.productId}}</h3>
</div>
</div>
<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h5 class="product-description-label">Product Description:</h5>
</div>
<div class="col-md-6">
<h5>{{$ctrl.product.productDescription}}</h5>
</div>
</div>
<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h5 class="product-price-label">Product Price:</h5>
</div>
<div class="col-md-6">
<h5>{{$ctrl.product.productPrice}}</h5>
</div>



</div>
<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h5 class="product-price-label">Product SalePrice:</h5>
</div>
<div class="col-md-6">
<h5>{{$ctrl.product.productSalePrice}}</h5>
</div>

</div>

<hr> <!-- Horizontal line -->
<div class="row">
<div class="col-md-6 text-end">
<h5 class="product-quantity-label">Product Quantity:</h5>
</div>
<div class="col-md-6">
<h5>{{$ctrl.product.productQuantity}}</h5>
</div>
</div>
<hr> <!-- Horizontal line -->
</div>
</div>
<div class="text-center mt-4">
<a class="btn btn-primary" href="#!/inventory/{{$ctrl.product.inventoryId}}/products">
Back to Products page
</a>
</div>
</div>





Original file line number Diff line number Diff line change
Expand Up @@ -2769,8 +2769,36 @@ void updateInventory_withValidValue_shouldSucceed() {


@Test
void getInventoryByInventoryId_ValidId_shouldSucceed() {
void GetProductByInventoryIdAndProductId_InsideInventory() {
ProductResponseDTO productResponseDTO = buildProductDTO();
when(inventoryServiceClient.getProductByProductIdInInventory(productResponseDTO.getInventoryId(), productResponseDTO.getProductId()))
.thenReturn(Mono.just(productResponseDTO));

client.get()
.uri("/api/gateway/inventory/{inventoryId}/products/{productId}", productResponseDTO.getInventoryId(), productResponseDTO.getProductId())
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody(ProductResponseDTO.class)
.value(dto -> {
assertNotNull(dto);
assertEquals(productResponseDTO.getInventoryId(), dto.getInventoryId());
assertEquals(productResponseDTO.getProductId(), dto.getProductId());
assertEquals(productResponseDTO.getProductName(), dto.getProductName());
assertEquals(productResponseDTO.getProductDescription(), dto.getProductDescription());
assertEquals(productResponseDTO.getProductPrice(), dto.getProductPrice());
assertEquals(productResponseDTO.getProductQuantity(), dto.getProductQuantity());
assertEquals(productResponseDTO.getProductSalePrice(), dto.getProductSalePrice());

});

verify(inventoryServiceClient, times(1))
.getProductByProductIdInInventory(productResponseDTO.getInventoryId(), productResponseDTO.getProductId());
}


@Test
void getInventoryByInventoryId_ValidId_shouldSucceed() {
String validInventoryId = "inventoryId_1";
InventoryResponseDTO inventoryResponseDTO = InventoryResponseDTO.builder()
.inventoryId(validInventoryId)
Expand Down Expand Up @@ -2987,6 +3015,9 @@ void testAddProductToInventory_InvalidInventoryId_ShouldReturnNotFoundException(
.addProductToInventory(eq(requestDTO), eq("invalidInventoryId"));
}




private ProductResponseDTO buildProductDTO(){
return ProductResponseDTO.builder()
.id("1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@
return inventoryRepository
.findAllByInventoryNameAndInventoryTypeAndInventoryDescription(inventoryName, inventoryType, inventoryDescription)
.map(EntityDTOUtil::toInventoryResponseDTO)
.skip(page.getPageNumber() * page.getPageSize())

Check warning on line 231 in inventory-service/src/main/java/com/petclinic/inventoryservice/businesslayer/ProductInventoryServiceImpl.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Integer multiplication or shift implicitly cast to 'long'

page.getPageNumber() \* page.getPageSize(): integer multiplication implicitly cast to long
.take(page.getPageSize())
.switchIfEmpty(Mono.error(new NotFoundException("Inventory not found with Name: " + inventoryName +
", Type: " + inventoryType + ", Description: " + inventoryDescription)));
Expand All @@ -238,7 +238,7 @@
return inventoryRepository
.findAllByInventoryTypeAndInventoryDescription(inventoryType, inventoryDescription)
.map(EntityDTOUtil::toInventoryResponseDTO)
.skip(page.getPageNumber() * page.getPageSize())

Check warning on line 241 in inventory-service/src/main/java/com/petclinic/inventoryservice/businesslayer/ProductInventoryServiceImpl.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Integer multiplication or shift implicitly cast to 'long'

page.getPageNumber() \* page.getPageSize(): integer multiplication implicitly cast to long
.take(page.getPageSize())
.switchIfEmpty(Mono.error(new NotFoundException("Inventory not found with Type: " + inventoryType +
" and Description: " + inventoryDescription)));
Expand All @@ -255,7 +255,7 @@
return inventoryRepository
.findByInventoryNameRegex(regexPattern)
.map(EntityDTOUtil::toInventoryResponseDTO)
.skip(page.getPageNumber() * page.getPageSize())

Check warning on line 258 in inventory-service/src/main/java/com/petclinic/inventoryservice/businesslayer/ProductInventoryServiceImpl.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Integer multiplication or shift implicitly cast to 'long'

page.getPageNumber() \* page.getPageSize(): integer multiplication implicitly cast to long
.take(page.getPageSize())
.switchIfEmpty(Mono.error(new NotFoundException("Inventory not found starting with: " + inventoryName)));
}
Expand All @@ -264,7 +264,7 @@
return inventoryRepository
.findByInventoryNameRegex(regexPattern)
.map(EntityDTOUtil::toInventoryResponseDTO)
.skip(page.getPageNumber() * page.getPageSize())

Check warning on line 267 in inventory-service/src/main/java/com/petclinic/inventoryservice/businesslayer/ProductInventoryServiceImpl.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Integer multiplication or shift implicitly cast to 'long'

page.getPageNumber() \* page.getPageSize(): integer multiplication implicitly cast to long
.take(page.getPageSize())
.switchIfEmpty(Mono.error(new NotFoundException("Inventory not found with Name starting with or matching: " + inventoryName)));
}
Expand All @@ -275,7 +275,7 @@
return inventoryRepository
.findAllByInventoryType(inventoryType)
.map(EntityDTOUtil::toInventoryResponseDTO)
.skip(page.getPageNumber() * page.getPageSize())

Check warning on line 278 in inventory-service/src/main/java/com/petclinic/inventoryservice/businesslayer/ProductInventoryServiceImpl.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Integer multiplication or shift implicitly cast to 'long'

page.getPageNumber() \* page.getPageSize(): integer multiplication implicitly cast to long
.take(page.getPageSize())
.switchIfEmpty(Mono.error(new NotFoundException("Inventory not found with Type: " + inventoryType)));
}
Expand All @@ -289,23 +289,23 @@
return inventoryRepository
.findByInventoryDescriptionRegex(regexPattern)
.map(EntityDTOUtil::toInventoryResponseDTO)
.skip(page.getPageNumber() * page.getPageSize())

Check warning on line 292 in inventory-service/src/main/java/com/petclinic/inventoryservice/businesslayer/ProductInventoryServiceImpl.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Integer multiplication or shift implicitly cast to 'long'

page.getPageNumber() \* page.getPageSize(): integer multiplication implicitly cast to long
.take(page.getPageSize())
.switchIfEmpty(Mono.error(new NotFoundException("Inventory not found with Description: " + inventoryDescription)));
} else {
return inventoryRepository
.findByInventoryDescriptionRegex(regexPattern)
.map(EntityDTOUtil::toInventoryResponseDTO)
.skip(page.getPageNumber() * page.getPageSize())

Check warning on line 299 in inventory-service/src/main/java/com/petclinic/inventoryservice/businesslayer/ProductInventoryServiceImpl.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Integer multiplication or shift implicitly cast to 'long'

page.getPageNumber() \* page.getPageSize(): integer multiplication implicitly cast to long
.take(page.getPageSize())
.switchIfEmpty(Mono.error(new NotFoundException("Inventory not found with Name starting with or matching: " + inventoryName)));

Check notice on line 301 in inventory-service/src/main/java/com/petclinic/inventoryservice/businesslayer/ProductInventoryServiceImpl.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Constant values

Value `inventoryName` is always 'null'
}
}

// Default - fetch all if no criteria provided.
return inventoryRepository
.findAll()
.skip(page.getPageNumber() * page.getPageSize())

Check warning on line 308 in inventory-service/src/main/java/com/petclinic/inventoryservice/businesslayer/ProductInventoryServiceImpl.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Integer multiplication or shift implicitly cast to 'long'

page.getPageNumber() \* page.getPageSize(): integer multiplication implicitly cast to long
.take(page.getPageSize())
.map(EntityDTOUtil::toInventoryResponseDTO);
}
Expand All @@ -313,21 +313,10 @@

@Override
public Mono<ProductResponseDTO> getProductByProductIdInInventory(String inventoryId, String productId) {
if(inventoryId == null ){
return Mono.error(new NotFoundException("Inventory id not found:" + inventoryId ));

}
else if (productId == null) {
return Mono.error(new NotFoundException("product id not found:" + productId ));
}


return productRepository
.findProductByInventoryIdAndProductId(inventoryId, productId)
.map(EntityDTOUtil::toProductResponseDTO)
.switchIfEmpty(Mono.error(new NotFoundException("Inventory id:" + inventoryId + "and product:" + productId + "are not found")));


}

//delete all products and delete all inventory
Expand Down
Loading
Loading