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

MCBFF-38: Update hardcoded effective location during checkin #47

Merged
merged 7 commits into from
Jan 27, 2025
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
10 changes: 9 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,15 @@
"circulation-bff.loans.check-in-by-barcode.execute"
],
"modulePermissions": [
"circulation.check-in-by-barcode.post"
"circulation.check-in-by-barcode.post",
"user-tenants.collection.get",
Copy link
Contributor

Choose a reason for hiding this comment

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

please add the same for item

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why we need user-tenants.item.get?

Copy link
Contributor

Choose a reason for hiding this comment

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

There's a rule that if we add a permission for an item, we need to add a similar one for the collection, and vice versa

Copy link
Contributor Author

@imerabishvili imerabishvili Jan 24, 2025

Choose a reason for hiding this comment

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

Could not find user-tenants.item.get anywhere in folio-org. Does it exists?

Copy link
Contributor

Choose a reason for hiding this comment

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

you are right, it exists only for consortia.user-tenants.item.get, so ignore it then

"search.instances.collection.get",
"inventory-storage.items.item.get",
"inventory-storage.items.collection.get",
"inventory-storage.locations.item.get",
"inventory-storage.locations.collection.get",
"inventory-storage.service-points.item.get",
"inventory-storage.service-points.collection.get"
]
}
]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.folio.circulationbff.service;

import org.folio.circulationbff.domain.dto.Item;
import org.folio.circulationbff.domain.dto.Location;
import org.folio.circulationbff.domain.dto.ServicePoint;

public interface InventoryService {
Item fetchItem(String id);
Location fetchLocation(String id);
ServicePoint fetchServicePoint(String id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import java.util.Collection;

import org.folio.circulationbff.domain.dto.BffSearchInstance;
import org.folio.circulationbff.domain.dto.SearchInstance;

public interface SearchService {
SearchInstance findInstanceByItemId(String itemId);
Collection<BffSearchInstance> findInstances(String query);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.folio.circulationbff.service;

public interface UserTenantsService {
String getCurrentTenant();
String getCentralTenant();
boolean isCentralTenant();
boolean isCentralTenant(String tenantId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,91 @@
package org.folio.circulationbff.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.circulationbff.client.feign.CheckInClient;
import org.folio.circulationbff.domain.dto.CheckInRequest;
import org.folio.circulationbff.domain.dto.CheckInResponse;
import org.folio.circulationbff.domain.dto.SearchItem;
import org.folio.circulationbff.service.CheckInService;
import org.folio.circulationbff.service.InventoryService;
import org.folio.circulationbff.service.SearchService;
import org.folio.circulationbff.service.UserTenantsService;
import org.folio.spring.service.SystemUserScopedExecutionService;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import java.util.Objects;

@Service
@RequiredArgsConstructor
@Log4j2
public class CheckInServiceImpl implements CheckInService {

private final CheckInClient checkInClient;
private final SearchService searchService;
private final UserTenantsService userTenantsService;
private final InventoryService inventoryService;
private final SystemUserScopedExecutionService executionService;

@Override
public CheckInResponse checkIn(CheckInRequest request) {
log.info("checkIn: checking in item with barcode {} on service point {}",
request::getItemBarcode, request::getServicePointId);
return checkInClient.checkIn(request);
request.getItemBarcode(), request.getServicePointId());
var response = checkInClient.checkIn(request);
var item = response.getItem();
var servicePointName = getEffectiveLocationServicePoint(item.getId());
if (servicePointName != null) {
var slipContextItem = response.getStaffSlipContext().getItem();
slipContextItem.setEffectiveLocationPrimaryServicePointName(servicePointName);
slipContextItem.toServicePoint(servicePointName);
}
return response;
}

private String getEffectiveLocationServicePoint(String itemId) {
log.info("getEffectiveLocationServicePoint: itemId {}", itemId);
var instance = searchService.findInstanceByItemId(itemId);
if (instance == null) {
log.warn("getEffectiveLocationServicePoint: instance not found");
return null;
}
var tenantId = instance.getItems()
.stream()
.filter(item -> item.getId().equals(itemId))
.findFirst()
.map(SearchItem::getTenantId)
.orElse(null);

if (Objects.equals(tenantId, userTenantsService.getCurrentTenant())) {
log.info("getEffectiveLocationServicePoint: same tenant case {}", tenantId);
return fetchServicePointName(itemId);
} else {
log.info("getEffectiveLocationServicePoint: cross tenant case {}", tenantId);
return executionService.executeSystemUserScoped(tenantId, () -> fetchServicePointName(itemId));
}
}

private String fetchServicePointName(String itemId) {
var item = inventoryService.fetchItem(itemId);
if (item == null) {
log.warn("fetchServicePointName:: item not found, itemId: {}", itemId);
return null;
}
var location = inventoryService.fetchLocation(item.getEffectiveLocationId());
if (location == null) {
log.warn("fetchServicePointName:: location not found, locationId: {}",
item.getEffectiveLocationId());
return null;
}
var servicePoint = inventoryService.fetchServicePoint(location.getPrimaryServicePoint().toString());
if (servicePoint == null) {
log.warn("fetchServicePointName:: servicePoint not found, servicePointId: {}",
location.getPrimaryServicePoint());
return null;
}
String servicePointName = servicePoint.getName();
log.info("fetchServicePointName:: result: {}", servicePointName);

return servicePointName;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.folio.circulationbff.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.circulationbff.client.feign.ItemStorageClient;
import org.folio.circulationbff.client.feign.LocationClient;
import org.folio.circulationbff.client.feign.ServicePointClient;
import org.folio.circulationbff.domain.dto.Item;
import org.folio.circulationbff.domain.dto.Location;
import org.folio.circulationbff.domain.dto.ServicePoint;
import org.folio.circulationbff.service.InventoryService;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@Log4j2
public class InventoryServiceImpl implements InventoryService {
private final ItemStorageClient itemClient;
private final LocationClient locationClient;
private final ServicePointClient servicePointClient;

@Override
public Item fetchItem(String id) {
log.info("fetchItem:: fetching item {}", id);
return itemClient.findItem(id);
}

@Override
public Location fetchLocation(String id) {
log.info("fetchLocation:: fetching location {}", id);
return locationClient.findLocation(id);
}

@Override
public ServicePoint fetchServicePoint(String id) {
log.info("fetchServicePoint:: fetching service point {}", id);
return servicePointClient.findServicePoint(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.folio.circulationbff.client.feign.HoldingsStorageClient;
import org.folio.circulationbff.client.feign.InstanceStorageClient;
Expand Down Expand Up @@ -71,6 +72,17 @@ public class SearchServiceImpl implements SearchService {
private final BulkFetchingService fetchingService;
private final SearchInstanceMapper searchInstanceMapper;

@Override
public SearchInstance findInstanceByItemId(String itemId) {
log.info("findInstanceByItemId:: itemId {}", itemId);
String query = "items.id==" + itemId;
SearchInstances searchResult = searchClient.findInstances(query, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
SearchInstances searchResult = searchClient.findInstances(query, true);
SearchInstances searchInstances = searchClient.findInstances(query, true);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

if (CollectionUtils.isEmpty(searchResult.getInstances())) {
return null;
}
return searchResult.getInstances().get(0);
}

@Override
public Collection<BffSearchInstance> findInstances(String query) {
log.info("findInstances:: searching instances by query: {}", query);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.folio.circulationbff.service.impl;

import java.util.List;

import org.apache.commons.collections4.CollectionUtils;
import org.folio.circulationbff.client.feign.UserTenantsClient;
import org.folio.circulationbff.domain.dto.UserTenant;
import org.folio.circulationbff.domain.dto.UserTenantCollection;
Expand All @@ -18,11 +17,21 @@ public class UserTenantsServiceImpl implements UserTenantsService {

private final UserTenantsClient userTenantsClient;

@Override
public String getCurrentTenant() {
UserTenant firstUserTenant = getFirstUserTenant();
if (firstUserTenant == null) {
return null;
}
String currentTenantId = firstUserTenant.getTenantId();
log.info("getCurrentTenant:: currentTenantId={}", currentTenantId);
return currentTenantId;
}

@Override
public String getCentralTenant() {
UserTenant firstUserTenant = getFirstUserTenant();
if (firstUserTenant == null) {
log.info("getCentralTenant:: failed to fetch user tenants");
return null;
}
String centralTenantId = firstUserTenant.getCentralTenantId();
Expand All @@ -34,7 +43,6 @@ public String getCentralTenant() {
public boolean isCentralTenant() {
UserTenant firstUserTenant = getFirstUserTenant();
if (firstUserTenant == null) {
log.info("isCentralTenant:: failed to fetch user tenants");
return false;
}
String centralTenantId = firstUserTenant.getCentralTenantId();
Expand All @@ -45,14 +53,6 @@ public boolean isCentralTenant() {
return centralTenantId.equals(tenantId);
}

private UserTenant getFirstUserTenant() {
UserTenant firstUserTenant = findFirstUserTenant();
if (firstUserTenant == null) {
log.info("processUserGroupEvent: Failed to get user-tenants info");
}
return firstUserTenant;
}

@Override
public boolean isCentralTenant(String tenantId) {
UserTenant firstUserTenant = getFirstUserTenant();
Expand All @@ -67,21 +67,16 @@ public boolean isCentralTenant(String tenantId) {
return false;
}

private UserTenant findFirstUserTenant() {
log.info("findFirstUserTenant:: finding first userTenant");
UserTenant firstUserTenant = null;
UserTenantCollection userTenantCollection = userTenantsClient.getUserTenants(1);
log.info("findFirstUserTenant:: userTenantCollection: {}", () -> userTenantCollection);
if (userTenantCollection != null) {
log.info("findFirstUserTenant:: userTenantCollection: {}", () -> userTenantCollection);
List<UserTenant> userTenants = userTenantCollection.getUserTenants();
if (!userTenants.isEmpty()) {
firstUserTenant = userTenants.get(0);
log.info("findFirstUserTenant:: found userTenant: {}", firstUserTenant);
}
private UserTenant getFirstUserTenant() {
log.info("getFirstUserTenant:: finding first userTenant");
UserTenantCollection userTenants = userTenantsClient.getUserTenants(1);
log.info("getFirstUserTenant:: userTenants: {}", () -> userTenants);
if (userTenants == null || CollectionUtils.isEmpty(userTenants.getUserTenants())) {
log.warn("getFirstUserTenant: failed to fetch user tenants");
return null;
}
log.info("findFirstUserTenant:: result: {}", firstUserTenant);
var firstUserTenant = userTenants.getUserTenants().get(0);
log.info("getFirstUserTenant:: result: {}", firstUserTenant);
return firstUserTenant;
}
}

Loading
Loading