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

Uxprod 5001 #125

Closed
wants to merge 15 commits into from
Closed
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
36 changes: 33 additions & 3 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,30 @@
"dcb.transactions.collection.get"
],
"modulePermissions": []
},
{
"methods": [
"PUT"
],
"pathPattern": "/transactions/{dcbTransactionId}",
"permissionsRequired": [
"dcb.transactions.item.put"
],
"modulePermissions": [
"inventory-storage.items.item.get",
"inventory-storage.items.collection.get",
"inventory-storage.holdings.item.get",
"circulation.requests.item.post",
"circulation.requests.item.put",
"circulation-item.item.post",
"circulation-item.collection.get",
"circulation-item.item.get",
"inventory-storage.material-types.collection.get",
"inventory-storage.loan-types.collection.get",
"circulation-storage.requests.item.get",
"circulation-storage.cancellation-reasons.item.get",
"circulation-storage.cancellation-reasons.item.post"
]
}
]
},
Expand Down Expand Up @@ -232,7 +256,8 @@
"dcb.transactions.put",
"dcb.transactions.get",
"dcb.transactions.collection.get",
"dcb.ecs-request.transactions.post"
"dcb.ecs-request.transactions.post",
"dcb.transactions.item.put"
]
},
{
Expand All @@ -247,8 +272,8 @@
},
{
"permissionName": "dcb.transactions.put",
"displayName": "update transaction details",
"description": "update transaction details"
"displayName": "update transaction status",
"description": "update transaction status"
},
{
"permissionName": "dcb.transactions.collection.get",
Expand All @@ -259,6 +284,11 @@
"permissionName": "dcb.ecs-request.transactions.post",
"displayName": "creates new ECS request transaction",
"description": "creates new ECS request transaction"
},
{
"permissionName": "dcb.transactions.item.put",
"displayName": "update transaction details",
"description": "update transaction details"
}
],
"metadata": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ public interface CirculationItemClient {
CirculationItem retrieveCirculationItemById(@PathVariable("circulationItemId") String circulationItemId);

@GetMapping
CirculationItemCollection fetchItemByIdAndBarcode(@RequestParam("query") String query);}
CirculationItemCollection fetchItemByCqlQuery(@RequestParam("query") String query);}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.dcb.domain.dto.DcbTransaction;
import org.folio.dcb.domain.dto.DcbUpdateTransaction;
import org.folio.dcb.domain.dto.TransactionStatus;
import org.folio.dcb.domain.dto.TransactionStatusResponseCollection;
import org.folio.dcb.rest.resource.TransactionsApi;
Expand Down Expand Up @@ -74,4 +75,11 @@ public ResponseEntity<TransactionStatusResponseCollection> getTransactionStatusL
.body(transactionsService.getTransactionStatusList(fromDate, toDate, pageNumber, pageSize));
}

@Override
public ResponseEntity<Void> updateTransactionDetails(String dcbTransactionId, DcbUpdateTransaction dcbUpdateTransaction) {
transactionsService.updateTransactionDetails(dcbTransactionId, dcbUpdateTransaction);
return ResponseEntity.status(HttpStatus.NO_CONTENT)
.build();
}

}
11 changes: 11 additions & 0 deletions src/main/java/org/folio/dcb/domain/mapper/TransactionMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.folio.dcb.domain.dto.DcbItem;
import org.folio.dcb.domain.dto.DcbPatron;
import org.folio.dcb.domain.dto.DcbPickup;
import org.folio.dcb.domain.dto.DcbUpdateItem;
import org.folio.dcb.domain.dto.TransactionStatusResponseList;
import org.folio.dcb.domain.entity.TransactionAuditEntity;
import org.folio.dcb.domain.entity.TransactionEntity;
Expand Down Expand Up @@ -91,4 +92,14 @@ public DcbPickup mapTransactionEntityToDcbPickup(TransactionEntity transactionEn
.build();
}

public DcbItem convertTransactionUpdateItemToDcbItem(DcbUpdateItem dcbUpdateItem, TransactionEntity entity) {
return DcbItem
.builder()
.lendingLibraryCode(dcbUpdateItem.getLendingLibraryCode())
.barcode(dcbUpdateItem.getBarcode())
.materialType(dcbUpdateItem.getMaterialType())
.title(entity.getItemTitle())
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ public void handleRequestEvent(String data, MessageHeaders messageHeaders) {
systemUserScopedExecutionService.executeAsyncSystemUserScoped(tenantId, () ->
transactionRepository.findTransactionByRequestIdAndStatusNotInClosed(UUID.fromString(requestId))
.ifPresent(transactionEntity -> {
if (eventData.getType() == EventData.EventType.CANCEL) {
if (eventData.getType() == EventData.EventType.CANCEL && !eventData.isDcbReRequestCancellation()) {
baseLibraryService.cancelTransactionEntity(transactionEntity);
} else if (eventData.getType() == EventData.EventType.IN_TRANSIT && transactionEntity.getRole() == LENDER) {
baseLibraryService.updateTransactionEntity(transactionEntity, TransactionStatus.StatusEnum.OPEN);
} else if (eventData.getType() == EventData.EventType.AWAITING_PICKUP && (transactionEntity.getRole() == BORROWING_PICKUP || transactionEntity.getRole() == PICKUP)) {
baseLibraryService.updateTransactionEntity(transactionEntity, TransactionStatus.StatusEnum.AWAITING_PICKUP);
} else {
log.info("handleRequestEvent:: status for event {} can not be updated", eventData.getType());
log.info("handleRequestEvent:: status for event {} can not be updated", eventData);
}
})
);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/folio/dcb/listener/kafka/EventData.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public class EventData {
private String itemId;
private String requestId;
private boolean isDcb;
private String cancellationAdditionalInformation;
private boolean isDcbReRequestCancellation;

public enum EventType {
CHECK_IN, CHECK_OUT, IN_TRANSIT, AWAITING_PICKUP, CANCEL
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/org/folio/dcb/service/CirculationService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,17 @@ public interface CirculationService {
*/
void checkOutByBarcode(TransactionEntity dcbTransaction);

void cancelRequest(TransactionEntity dcbTransaction);
/**
* Cancels a transaction request based on the provided transaction details.
* <p>
* If {@code isItemUnavailableCancellation} is {@code true}, the notification for this
* cancellation will be suppressed by setting the {@code suppressNotification} flag
* to {@code true}.
* </p>
*
* @param dcbTransaction the transaction entity representing the request to be canceled
* @param isItemUnavailableCancellation a flag indicating whether the cancellation is due to item unavailability
* (true if the item is unavailable, false otherwise)
*/
void cancelRequest(TransactionEntity dcbTransaction, boolean isItemUnavailableCancellation);
}
2 changes: 2 additions & 0 deletions src/main/java/org/folio/dcb/service/TransactionsService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.folio.dcb.service;

import org.folio.dcb.domain.dto.DcbTransaction;
import org.folio.dcb.domain.dto.DcbUpdateTransaction;
import org.folio.dcb.domain.dto.TransactionStatus;
import org.folio.dcb.domain.dto.TransactionStatusResponse;
import org.folio.dcb.domain.dto.TransactionStatusResponseCollection;
Expand All @@ -17,5 +18,6 @@ public interface TransactionsService {
TransactionStatusResponse updateTransactionStatus(String dcbTransactionId, TransactionStatus transactionStatus);
TransactionStatusResponse getTransactionStatusById(String dcbTransactionId);
TransactionStatusResponseCollection getTransactionStatusList(OffsetDateTime fromDate, OffsetDateTime toDate, Integer pageNumber, Integer pageSize);
void updateTransactionDetails(String dcbTransactionId, DcbUpdateTransaction dcbUpdateTransaction);

}
30 changes: 29 additions & 1 deletion src/main/java/org/folio/dcb/service/impl/BaseLibraryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import org.apache.commons.lang3.ObjectUtils;
import org.folio.dcb.domain.dto.CirculationItem;
import org.folio.dcb.domain.dto.CirculationRequest;
import org.folio.dcb.domain.dto.DcbItem;
import org.folio.dcb.domain.dto.DcbPatron;
import org.folio.dcb.domain.dto.DcbTransaction;
import org.folio.dcb.domain.dto.DcbUpdateItem;
import org.folio.dcb.domain.dto.TransactionStatus;
import org.folio.dcb.domain.dto.TransactionStatusResponse;
import org.folio.dcb.domain.entity.TransactionEntity;
Expand Down Expand Up @@ -54,6 +57,7 @@ public TransactionStatusResponse createBorrowingLibraryTransaction(String dcbTra
}
checkItemExistsInInventoryAndThrow(itemVirtual.getBarcode());
CirculationItem item = circulationItemService.checkIfItemExistsAndCreate(itemVirtual, pickupServicePointId);
dcbTransaction.getItem().setId(item.getId());
checkOpenTransactionExistsAndThrow(item.getId());
CirculationRequest holdRequest = requestService.createHoldItemRequest(user, itemVirtual, pickupServicePointId);
saveDcbTransaction(dcbTransactionId, dcbTransaction, holdRequest.getId());
Expand Down Expand Up @@ -106,7 +110,7 @@ public void updateTransactionStatus(TransactionEntity dcbTransaction, Transactio

public void cancelTransactionRequest(TransactionEntity transactionEntity){
try {
circulationService.cancelRequest(transactionEntity);
circulationService.cancelRequest(transactionEntity, false);
} catch (CirculationRequestException e) {
updateTransactionEntity(transactionEntity, TransactionStatus.StatusEnum.ERROR);
}
Expand All @@ -133,4 +137,28 @@ public void updateTransactionEntity(TransactionEntity transactionEntity, Transac
transactionEntity.setStatus(transactionStatusEnum);
transactionRepository.save(transactionEntity);
}

public void updateTransactionDetails(TransactionEntity transactionEntity, DcbUpdateItem dcbUpdateItem) {
DcbPatron dcbPatron = transactionMapper.mapTransactionEntityToDcbPatron(transactionEntity);
DcbItem dcbItem = transactionMapper.convertTransactionUpdateItemToDcbItem(dcbUpdateItem, transactionEntity);
checkItemExistsInInventoryAndThrow(dcbItem.getBarcode());
CirculationItem item = circulationItemService.checkIfItemExistsAndCreate(dcbItem, transactionEntity.getServicePointId());
dcbItem.setId(item.getId());
checkOpenTransactionExistsAndThrow(item.getId());
circulationService.cancelRequest(transactionEntity, true);
CirculationRequest holdRequest = requestService.createHoldItemRequest(userService.fetchUser(dcbPatron), dcbItem,
transactionEntity.getServicePointId());
updateItemDetailsAndSaveEntity(transactionEntity, item, dcbItem.getMaterialType(), holdRequest.getId());
}

private void updateItemDetailsAndSaveEntity(TransactionEntity transactionEntity, CirculationItem item,
String materialType, String requestId) {
transactionEntity.setItemId(item.getId());
transactionEntity.setRequestId(UUID.fromString(requestId));
transactionEntity.setItemBarcode(item.getBarcode());
transactionEntity.setLendingLibraryCode(item.getLendingLibraryCode());
transactionEntity.setMaterialType(materialType);
transactionEntity.setStatus(CREATED);
transactionRepository.save(transactionEntity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import org.folio.dcb.domain.dto.ItemStatus;
import org.folio.dcb.service.CirculationItemService;
import org.folio.dcb.service.ItemService;
import org.folio.util.StringUtil;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.UUID;

import static org.folio.dcb.domain.dto.ItemStatus.NameEnum.IN_TRANSIT;
import static org.folio.dcb.utils.DCBConstants.HOLDING_ID;
Expand All @@ -29,18 +31,18 @@ public class CirculationItemServiceImpl implements CirculationItemService {

@Override
public CirculationItem checkIfItemExistsAndCreate(DcbItem dcbItem, String pickupServicePointId) {
var dcbItemId = dcbItem.getId();
log.debug("checkIfItemExistsAndCreate:: generate Circulation item by DcbItem with id={} if nit doesn't exist.", dcbItemId);
var circulationItem = fetchCirculationItemByIdAndBarcode(dcbItemId, dcbItem.getBarcode());
var dcbItemBarcode = dcbItem.getBarcode();
log.debug("checkIfItemExistsAndCreate:: generate Circulation item with barcode {} if it doesn't exist.", dcbItemBarcode);
var circulationItem = fetchCirculationItemByBarcode(dcbItem.getBarcode());
if(Objects.isNull(circulationItem)) {
log.warn("Circulation item not found by id={}. Creating it.", dcbItemId);
log.warn("checkIfItemExistsAndCreate:: Circulation item not found by barcode={}. Creating it.", dcbItemBarcode);
circulationItem = createCirculationItem(dcbItem, pickupServicePointId);
}
return circulationItem;
}

private CirculationItem fetchCirculationItemByIdAndBarcode(String id, String barcode) {
return circulationItemClient.fetchItemByIdAndBarcode("id==" + id + " and barcode==" + barcode)
private CirculationItem fetchCirculationItemByBarcode(String barcode) {
return circulationItemClient.fetchItemByCqlQuery("barcode==" + StringUtil.cqlEncode(barcode))
.getItems()
.stream()
.findFirst()
Expand All @@ -56,10 +58,10 @@ private CirculationItem createCirculationItem(DcbItem item, String pickupService
//SetupDefaultMaterialTypeIfNotGiven
String materialType = StringUtils.isBlank(item.getMaterialType()) ? MATERIAL_TYPE_NAME_BOOK : item.getMaterialType();
var materialTypeId = itemService.fetchItemMaterialTypeIdByMaterialTypeName(materialType);

var itemId = UUID.randomUUID().toString();
CirculationItem circulationItem =
CirculationItem.builder()
.id(item.getId())
.id(itemId)
.barcode(item.getBarcode())
.status(ItemStatus.builder()
.name(IN_TRANSIT)
Expand All @@ -72,6 +74,6 @@ private CirculationItem createCirculationItem(DcbItem item, String pickupService
.lendingLibraryCode(item.getLendingLibraryCode())
.build();

return circulationItemClient.createCirculationItem(item.getId(), circulationItem);
return circulationItemClient.createCirculationItem(itemId, circulationItem);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,14 @@ public void checkOutByBarcode(TransactionEntity dcbTransaction) {
}

@Override
public void cancelRequest(TransactionEntity dcbTransaction) {
public void cancelRequest(TransactionEntity dcbTransaction, boolean isItemUnavailableCancellation) {
log.debug("cancelRequest:: cancelling request using request id {} ", dcbTransaction.getRequestId());
CirculationRequest request = circulationStorageService.getCancellationRequestIfOpenOrNull(dcbTransaction.getRequestId().toString());
if (request != null){
try {
if (isItemUnavailableCancellation) {
request.setIsDcbReRequestCancellation(true);
}
circulationClient.updateRequest(request.getId(), request);
} catch (FeignException e) {
log.warn("cancelRequest:: error cancelling request using request id {} ", dcbTransaction.getRequestId(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public TransactionStatusResponse createCirculation(String dcbTransactionId, DcbT
baseLibraryService.checkUserTypeAndThrowIfMismatch(user.getType());
baseLibraryService.checkItemExistsInInventoryAndThrow(itemVirtual.getBarcode());
CirculationItem item = circulationItemService.checkIfItemExistsAndCreate(itemVirtual, dcbTransaction.getPickup().getServicePointId());
dcbTransaction.getItem().setId(item.getId());
baseLibraryService.checkOpenTransactionExistsAndThrow(item.getId());
CirculationRequest holdRequest = requestService.createHoldItemRequest(user, itemVirtual, dcbTransaction.getPickup().getServicePointId());
baseLibraryService.saveDcbTransaction(dcbTransactionId, dcbTransaction, holdRequest.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.dcb.domain.dto.DcbTransaction;
import org.folio.dcb.domain.dto.DcbUpdateTransaction;
import org.folio.dcb.domain.dto.TransactionStatus;
import org.folio.dcb.domain.dto.TransactionStatusResponse;
import org.folio.dcb.domain.dto.TransactionStatusResponseCollection;
Expand Down Expand Up @@ -39,6 +40,7 @@ public class TransactionsServiceImpl implements TransactionsService {
private final StatusProcessorService statusProcessorService;
private final TransactionMapper transactionMapper;
private final TransactionAuditRepository transactionAuditRepository;
private final BaseLibraryService baseLibraryService;

@Override
public TransactionStatusResponse createCirculationRequest(String dcbTransactionId, DcbTransaction dcbTransaction) {
Expand Down Expand Up @@ -109,6 +111,19 @@ public TransactionStatusResponseCollection getTransactionStatusList(OffsetDateTi
.build();
}

@Override
public void updateTransactionDetails(String dcbTransactionId, DcbUpdateTransaction dcbUpdateTransaction) {
var transactionEntity = getTransactionEntityOrThrow(dcbTransactionId);
if (!TransactionStatus.StatusEnum.CREATED.equals(transactionEntity.getStatus())) {
throw new StatusException(String.format(
"Transaction details should not be updated from %s status, it can be updated only from CREATED status", transactionEntity.getStatus()));
}
if (DcbTransaction.RoleEnum.LENDER.equals(transactionEntity.getRole())) {
throw new IllegalArgumentException("Item details cannot be updated for lender role");
}
baseLibraryService.updateTransactionDetails(transactionEntity, dcbUpdateTransaction.getItem());
}

private TransactionStatusResponse generateTransactionStatusResponseFromTransactionEntity(TransactionEntity transactionEntity) {
TransactionStatus.StatusEnum transactionStatus = transactionEntity.getStatus();
TransactionStatusResponse.StatusEnum transactionStatusResponseStatusEnum = TransactionStatusResponse.StatusEnum.fromValue(transactionStatus.getValue());
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/folio/dcb/utils/TransactionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static EventData parseRequestEvent(String eventPayload){
&& kafkaEvent.getNewNode().has(STATUS)){
EventData eventData = new EventData();
eventData.setRequestId(kafkaEvent.getNewNode().get("id").asText());
eventData.setDcbReRequestCancellation(getNodeAsBoolean(kafkaEvent, "dcbReRequestCancellation"));
RequestStatus requestStatus = RequestStatus.from(kafkaEvent.getNewNode().get(STATUS).asText());
switch (requestStatus) {
case OPEN_IN_TRANSIT -> eventData.setType(EventData.EventType.IN_TRANSIT);
Expand All @@ -69,6 +70,11 @@ public static EventData parseRequestEvent(String eventPayload){
}
return null;
}

private static boolean getNodeAsBoolean(KafkaEvent kafkaEvent, String name) {
return kafkaEvent.getNewNode().get(name).asBoolean();
}

private static boolean checkDcbRequest(KafkaEvent kafkaEvent) {
return (kafkaEvent.getNewNode().has(INSTANCE) && kafkaEvent.getNewNode().get(INSTANCE).has(TITLE)
&& kafkaEvent.getNewNode().get(INSTANCE).get(TITLE).asText().equals(DCB_INSTANCE_TITLE)) || (kafkaEvent.getNewNode().has(REQUESTER)
Expand Down
Loading
Loading