Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
febe0f2
CROSSLINK-264 ask-retry action
adamdickmeiss May 29, 2026
ac9170a
RETRY_REQUESTED state
adamdickmeiss May 29, 2026
d2f057b
Merge branch 'main' into CROSSLINK-264-ask-retry-action
adamdickmeiss Jun 1, 2026
67708e4
Update state model for retry
adamdickmeiss Jun 1, 2026
fa8eb8c
Potential fix for pull request finding
adamdickmeiss Jun 1, 2026
920a937
Potential fix for pull request finding
adamdickmeiss Jun 1, 2026
ddb2333
update returnables.json
adamdickmeiss Jun 1, 2026
4f1c545
Implement ask-retry
adamdickmeiss Jun 2, 2026
e7bf570
Create retry-conditonal event
adamdickmeiss Jun 2, 2026
524a26a
illmock: RETRY:NOTFOUNDASCITED
adamdickmeiss Jun 2, 2026
9529072
reject-retry
adamdickmeiss Jun 2, 2026
0b7be58
illmock: sets DeliveryInfo.ItemId on RETRY:NOTFOUNDASCITED
adamdickmeiss Jun 2, 2026
d1f9912
acceptRetry begin
adamdickmeiss Jun 2, 2026
95586a0
Add {next,prev}_req_id
adamdickmeiss Jun 2, 2026
cb56c77
Merge remote-tracking branch 'origin/main' into CROSSLINK-264-ask-ret…
adamdickmeiss Jun 4, 2026
d6da9bb
Clone patronrequest WIP
adamdickmeiss Jun 8, 2026
217bfb7
lint
adamdickmeiss Jun 8, 2026
7544ce8
Potential fix for pull request finding
adamdickmeiss Jun 8, 2026
eb34de0
Potential fix for pull request finding
adamdickmeiss Jun 8, 2026
3bc091f
Potential fix for pull request finding
adamdickmeiss Jun 8, 2026
3f13e33
Potential fix for pull request finding
adamdickmeiss Jun 8, 2026
fdeb194
has_internal_note
adamdickmeiss Jun 8, 2026
317fcb3
update
adamdickmeiss Jun 8, 2026
a78c2a1
Merge remote-tracking branch 'origin/main' into CROSSLINK-264-ask-ret…
adamdickmeiss Jun 8, 2026
ff241ea
migrations update
adamdickmeiss Jun 8, 2026
846bac8
retry_item_id persisted
adamdickmeiss Jun 8, 2026
975772f
Merge branch 'main' into CROSSLINK-264-ask-retry-action
adamdickmeiss Jun 12, 2026
614664c
migrations merge
adamdickmeiss Jun 12, 2026
b281c10
retryItemId in API structure
adamdickmeiss Jun 14, 2026
780e65a
Set new patron request fields one by one
adamdickmeiss Jun 14, 2026
776c9c2
unfilled as last; fix SupplierUniqueRecordId overwrite
adamdickmeiss Jun 15, 2026
d742ac3
Revert go.work.sum
adamdickmeiss Jun 15, 2026
6cbd997
Use definition
adamdickmeiss Jun 15, 2026
a13ff15
ItemID
adamdickmeiss Jun 15, 2026
aa1678c
Remove Info log
adamdickmeiss Jun 15, 2026
48216b6
retry_bib_info
adamdickmeiss Jun 17, 2026
7db5fe9
Unused function
adamdickmeiss Jun 17, 2026
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
11 changes: 11 additions & 0 deletions broker/handler/iso18626-handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,17 @@ func handleRetryRequest(ctx common.ExtendedContext, request *iso18626.Request, r
illTrans.Timestamp = timestamp

_, err = repo.SaveIllTransaction(ctx, ill_db.SaveIllTransactionParams(illTrans))
if err != nil {
return err
}

// Keep the selected supplier's LocalID in sync with the updated SupplierUniqueRecordId.
// createRequestMessage overwrites BibliographicInfo.SupplierUniqueRecordId with LocalID, so
// without this update the stale LocalID from the original holdings lookup would be sent.
if newLocalId := request.BibliographicInfo.SupplierUniqueRecordId; newLocalId != "" {
selSup.LocalID = pgtype.Text{String: newLocalId, Valid: true}
_, err = repo.SaveLocatedSupplier(ctx, ill_db.SaveLocatedSupplierParams(selSup))
}
return err
})
return id, err
Expand Down
30 changes: 30 additions & 0 deletions broker/migrations/046_add_patron_links.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
DROP VIEW IF EXISTS patron_request_search_view;
ALTER TABLE patron_request DROP COLUMN next_req_id;
ALTER TABLE patron_request DROP COLUMN prev_req_id;
ALTER TABLE patron_request DROP COLUMN retry_bib_info;

CREATE VIEW patron_request_search_view AS
Comment thread
adamdickmeiss marked this conversation as resolved.
SELECT
pr.*,
EXISTS (
SELECT 1
FROM notification n
WHERE n.pr_id = pr.id
) AS has_notification,
EXISTS (
SELECT 1
FROM notification n
WHERE n.pr_id = pr.id and cost is not null
) AS has_cost,
(unread.unread_notifications_count > 0) AS has_unread_notification,
(pr.internal_note IS NOT NULL AND btrim(pr.internal_note) <> '') AS has_internal_note,
pr.ill_request -> 'serviceInfo' ->> 'serviceType' AS service_type,
pr.ill_request -> 'serviceInfo' -> 'serviceLevel' ->> '#text' AS service_level,
Comment thread
adamdickmeiss marked this conversation as resolved.
immutable_to_timestamp(pr.ill_request -> 'serviceInfo' ->> 'needBeforeDate') AS needed_at,
unread.unread_notifications_count AS unread_notifications_count
FROM patron_request pr
LEFT JOIN LATERAL (
SELECT COUNT(*) AS unread_notifications_count
FROM notification n
Comment thread
adamdickmeiss marked this conversation as resolved.
WHERE n.pr_id = pr.id and n.acknowledged_at is null
) unread ON true;
31 changes: 31 additions & 0 deletions broker/migrations/046_add_patron_links.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ALTER TABLE patron_request ADD COLUMN next_req_id VARCHAR;
ALTER TABLE patron_request ADD COLUMN prev_req_id VARCHAR;
ALTER TABLE patron_request ADD COLUMN retry_bib_info JSONB;

DROP VIEW IF EXISTS patron_request_search_view;

CREATE VIEW patron_request_search_view AS
SELECT
pr.*,
Comment on lines +5 to +9
EXISTS (
SELECT 1
FROM notification n
WHERE n.pr_id = pr.id
) AS has_notification,
EXISTS (
SELECT 1
FROM notification n
WHERE n.pr_id = pr.id and cost is not null
) AS has_cost,
(unread.unread_notifications_count > 0) AS has_unread_notification,
(pr.internal_note IS NOT NULL AND btrim(pr.internal_note) <> '') AS has_internal_note,
pr.ill_request -> 'serviceInfo' ->> 'serviceType' AS service_type,
pr.ill_request -> 'serviceInfo' -> 'serviceLevel' ->> '#text' AS service_level,
immutable_to_timestamp(pr.ill_request -> 'serviceInfo' ->> 'needBeforeDate') AS needed_at,
unread.unread_notifications_count AS unread_notifications_count
FROM patron_request pr
LEFT JOIN LATERAL (
SELECT COUNT(*) AS unread_notifications_count
FROM notification n
WHERE n.pr_id = pr.id and n.acknowledged_at is null
) unread ON true;
9 changes: 9 additions & 0 deletions broker/oapi/open-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,15 @@ components:
internalNote:
type: string
description: Staff-only internal note, local to this request and never shared with peers
nextReqId:
type: string
description: ID of the next patron request in the sequence
prevReqId:
type: string
description: ID of the previous patron request in the sequence
retryBibInfo:
type: object
description: Bibliographic information for the item to retry the request for when in retrying state
required:
- id
- createdAt
Expand Down
18 changes: 18 additions & 0 deletions broker/patron_request/api/api-handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,9 @@ func toApiPatronRequest(r *http.Request, request pr_db.PatronRequestSearchView)
EventsLink: eventsLink,
TerminalState: request.TerminalState,
InternalNote: toString(request.InternalNote),
NextReqId: toString(request.NextReqID),
PrevReqId: toString(request.PrevReqID),
RetryBibInfo: bibInfoToMap(request.RetryBibInfo),
}
if request.UpdatedAt.Valid {
pr.UpdatedAt = &request.UpdatedAt.Time
Expand All @@ -932,6 +935,21 @@ func toString(text pgtype.Text) *string {
return value
}

func bibInfoToMap(info *iso18626.BibliographicInfo) *map[string]interface{} {
if info == nil {
return nil
}
b, err := json.Marshal(info)
if err != nil {
return nil
}
var m map[string]interface{}
if err := json.Unmarshal(b, &m); err != nil {
return nil
}
return &m
}

func (a *PatronRequestApiHandler) parseAndValidateIllRequest(
ctx common.ExtendedContext,
request *proapi.CreatePatronRequest,
Expand Down
3 changes: 3 additions & 0 deletions broker/patron_request/db/prcql.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ func (q *Queries) ListPatronRequestsCql(ctx context.Context, db DBTX, arg ListPa
&i.PatronRequestSearchView.UpdatedAt,
&i.PatronRequestSearchView.IllResponse,
&i.PatronRequestSearchView.InternalNote,
&i.PatronRequestSearchView.NextReqID,
&i.PatronRequestSearchView.PrevReqID,
&i.PatronRequestSearchView.RetryBibInfo,
&i.PatronRequestSearchView.HasNotification,
&i.PatronRequestSearchView.HasCost,
&i.PatronRequestSearchView.HasUnreadNotification,
Expand Down
85 changes: 85 additions & 0 deletions broker/patron_request/service/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ type actionParams struct {
Cost *float64 `json:"cost,omitempty"`
Currency string `json:"currency,omitempty"`
ReasonUnfilled string `json:"reasonUnfilled,omitempty"`
ReasonRetry string `json:"reasonRetry,omitempty"`
ItemID string `json:"itemId,omitempty"`
}

func CreatePatronRequestActionService(prRepo pr_db.PrRepo, eventBus events.EventBus, iso18626Handler handler.Iso18626HandlerInterface, lmsCreator lms.LmsCreator) *PatronRequestActionService {
Expand Down Expand Up @@ -275,6 +277,10 @@ func (a *PatronRequestActionService) handleBorrowingAction(ctx common.ExtendedCo
return a.acceptConditionBorrowingRequest(ctx, pr)
case BorrowerActionRejectCondition:
return a.rejectConditionBorrowingRequest(ctx, pr)
case BorrowerActionRejectRetry:
return a.rejectRetryBorrowingRequest(pr)
case BorrowerActionAcceptRetry:
return a.acceptRetryBorrowingRequest(ctx, pr)
default:
status, result := logActionErrorAndReturnResult(ctx, "borrower action "+string(action)+" is not implemented yet", errors.New("invalid action"))
return actionExecutionResult{status: status, result: result, pr: pr}
Expand Down Expand Up @@ -329,6 +335,8 @@ func (a *PatronRequestActionService) handleLenderAction(ctx common.ExtendedConte
return a.markReceivedLenderRequest(ctx, pr, lms)
case LenderActionAcceptCancel:
return a.acceptCancelLenderRequest(ctx, pr)
case LenderActionAskRetry:
return a.askRetryLenderRequest(ctx, pr, params)
default:
status, result := logActionErrorAndReturnResult(ctx, "lender action "+string(action)+" is not implemented yet", errors.New("invalid action"))
return actionExecutionResult{status: status, result: result, pr: pr}
Expand Down Expand Up @@ -528,6 +536,57 @@ func (a *PatronRequestActionService) rejectConditionBorrowingRequest(ctx common.
return actionExecutionResult{status: events.EventStatusSuccess, result: &result, pr: pr}
}

func (a *PatronRequestActionService) rejectRetryBorrowingRequest(pr pr_db.PatronRequest) actionExecutionResult {
result := events.EventResult{}
return actionExecutionResult{status: events.EventStatusSuccess, result: &result, pr: pr}
}

func (a *PatronRequestActionService) acceptRetryBorrowingRequest(ctx common.ExtendedContext, pr pr_db.PatronRequest) actionExecutionResult {
result := events.EventResult{}

clone := pr_db.PatronRequest{}
clone.Side = pr.Side
clone.RequesterSymbol = pr.RequesterSymbol
clone.SupplierSymbol = pr.SupplierSymbol
clone.Patron = pr.Patron
clone.Tenant = pr.Tenant
var err error
clone.IllRequest, err = deepCopyISO18626Request(pr.IllRequest)
if err != nil {
status, result := logActionErrorAndReturnResult(ctx, "failed to clone IllRequest for retry", err)
return actionExecutionResult{status: status, result: result, pr: pr}
}
clone.State = BorrowerStateValidated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@adamdickmeiss this is fragile. What if there's no BorrowerStateValidate in the state model? Also, there's no trace of this operation in the event log. I think we should create the new request in the initial state and run the auto-actions on it so it behaves like a regular request.

clone.TerminalState = false
clone.ID = uuid.NewString()
clone.RequesterReqID = getDbTextPtr(&clone.ID)
clone.CreatedAt = pgtype.Timestamp{Valid: true, Time: time.Now()}
clone.PrevReqID = getDbTextPtr(&pr.ID)
clone.Language = pr.Language
clone.Items = []pr_db.PrItem{} // items will be copied when the retry request is sent
clone.RetryBibInfo = nil // clear retry bib info to avoid confusion
if pr.RetryBibInfo != nil {
// only take selected fields from retry bib info to allow for corrections without affecting other fields
if pr.RetryBibInfo.SupplierUniqueRecordId != "" {
clone.IllRequest.BibliographicInfo.SupplierUniqueRecordId = pr.RetryBibInfo.SupplierUniqueRecordId
}
if pr.RetryBibInfo.Title != "" {
clone.IllRequest.BibliographicInfo.Title = pr.RetryBibInfo.Title
}
if pr.RetryBibInfo.Author != "" {
clone.IllRequest.BibliographicInfo.Author = pr.RetryBibInfo.Author
}
}

_, err = a.prRepo.CreatePatronRequest(ctx, pr_db.CreatePatronRequestParams(clone))
if err != nil {
status, result := logActionErrorAndReturnResult(ctx, "failed to create patron request for retry", err)
return actionExecutionResult{status: status, result: result, pr: pr}
}
Comment on lines +581 to +585
pr.NextReqID = getDbTextPtr(&clone.ID)
return actionExecutionResult{status: events.EventStatusSuccess, result: &result, pr: pr}
Comment on lines +581 to +587
}

func (a *PatronRequestActionService) validateLenderRequest(ctx common.ExtendedContext, pr pr_db.PatronRequest, lms lms.LmsAdapter) actionExecutionResult {
institutionalPatron := lms.InstitutionalPatron(pr.RequesterSymbol.String)
_, err := lms.LookupUser(institutionalPatron)
Expand Down Expand Up @@ -772,6 +831,32 @@ func (a *PatronRequestActionService) acceptCancelLenderRequest(ctx common.Extend
return a.checkSupplyingResponse(status, eventResult, &result, httpStatus, pr)
}

func (a *PatronRequestActionService) askRetryLenderRequest(ctx common.ExtendedContext, pr pr_db.PatronRequest, params actionParams) actionExecutionResult {
var deliveryInfo *iso18626.DeliveryInfo
if params.ItemID != "" {
deliveryInfo = &iso18626.DeliveryInfo{
ItemId: params.ItemID,
}
}
reasonRetry := string(iso18626.ReasonRetryNotFoundAsCited)
if params.ReasonRetry != "" {
reasonRetry = params.ReasonRetry
}
result := events.EventResult{}
status, eventResult, httpStatus := a.sendSupplyingAgencyMessage(ctx, pr, &result,
iso18626.MessageInfo{
ReasonRetry: &iso18626.TypeSchemeValuePair{Text: reasonRetry},
ReasonForMessage: iso18626.TypeReasonForMessageStatusChange,
Note: params.Note,
},
iso18626.StatusInfo{Status: iso18626.TypeStatusRetryPossible},
deliveryInfo)
if result.OutgoingMessage.SupplyingAgencyMessage != nil {
setSupplierMessage(*result.OutgoingMessage.SupplyingAgencyMessage, &pr)
}
return a.checkSupplyingResponse(status, eventResult, &result, httpStatus, pr)
}

func (a *PatronRequestActionService) checkSupplyingResponse(status events.EventStatus, eventResult *events.EventResult, result *events.EventResult, httpStatus *int, pr pr_db.PatronRequest) actionExecutionResult {
if httpStatus == nil {
return actionExecutionResult{status: status, result: eventResult, pr: pr}
Expand Down
5 changes: 3 additions & 2 deletions broker/patron_request/service/action_mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ func TestNewReturnableActionMapping(t *testing.T) {
BorrowerStateReceived: {{actionName: BorrowerActionCheckOut}},
BorrowerStateCheckedOut: {{actionName: BorrowerActionCheckIn}},
BorrowerStateCheckedIn: {{actionName: BorrowerActionShipReturn}},
BorrowerStateRetryPending: {{actionName: BorrowerActionAcceptRetry}, {actionName: BorrowerActionRejectRetry}},
}

lenderStateActionMapping := map[pr_db.PatronRequestState][]PatronRequestAction{
LenderStateNew: {{actionName: LenderActionValidate, auto: true}},
LenderStateValidated: {{actionName: LenderActionWillSupply, auto: true}, {actionName: LenderActionCannotSupply}, {actionName: LenderActionAddCondition}},
LenderStateValidated: {{actionName: LenderActionWillSupply, auto: true}, {actionName: LenderActionCannotSupply}, {actionName: LenderActionAddCondition}, {actionName: LenderActionAskRetry}},
LenderStateWillSupply: {{actionName: LenderActionAddCondition}, {actionName: LenderActionShip}, {actionName: LenderActionCannotSupply}},
LenderStateConditionPending: {{actionName: LenderActionAddCondition}, {actionName: LenderActionCannotSupply}},
LenderStateConditionAccepted: {{actionName: LenderActionAddCondition}, {actionName: LenderActionShip}, {actionName: LenderActionCannotSupply}},
Expand Down Expand Up @@ -165,7 +166,7 @@ func mapCompare(t *testing.T, map1 map[pr_db.PatronRequestState][]PatronRequestA
for stateName := range map1 {
listOne := map1[stateName]
listTwo := map2[stateName]
assert.Equal(t, len(listOne), len(listTwo))
assert.Equal(t, len(listOne), len(listTwo), "State %s has different number of actions in the two maps", stateName)
for i := range listOne {
assert.Equal(t, listOne[i].actionName, listTwo[i].actionName)
assert.Equal(t, listOne[i].auto, listTwo[i].auto)
Expand Down
60 changes: 60 additions & 0 deletions broker/patron_request/service/action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,66 @@ func TestHandleInvokeLenderActionAddConditionOK(t *testing.T) {
}
}

func TestHandleInvokeLenderActionAskRetryMinimal(t *testing.T) {
mockPrRepo := new(MockPrRepo)
lmsCreator := new(MockLmsCreator)
lmsCreator.On("GetAdapter", "ISIL:SUP1").Return(lms.CreateLmsAdapterMockOK(), nil)
mockIso18626Handler := new(MockIso18626Handler)
prAction := CreatePatronRequestActionService(mockPrRepo, *new(events.EventBus), mockIso18626Handler, lmsCreator)
illRequest := iso18626.Request{}
mockPrRepo.On("GetPatronRequestById", patronRequestId).Return(pr_db.PatronRequest{IllRequest: illRequest, State: LenderStateValidated, Side: SideLending, SupplierSymbol: getDbText("ISIL:SUP1"), RequesterSymbol: getDbText("ISIL:REQ1")}, nil)
action := LenderActionAskRetry

status, resultData := prAction.handleInvokeAction(appCtx, events.Event{PatronRequestID: patronRequestId, EventData: events.EventData{
CommonEventData: events.CommonEventData{Action: &action},
CustomData: map[string]any{},
}})
assert.Equal(t, events.EventStatusSuccess, status)
assert.NotNil(t, resultData)
assert.Equal(t, LenderStateCompletedWithRetry, mockPrRepo.savedPr.State)

if assert.NotNil(t, mockIso18626Handler.lastSupplyingAgencyMessage) {
assert.Equal(t, iso18626.TypeStatusRetryPossible, mockIso18626Handler.lastSupplyingAgencyMessage.StatusInfo.Status)
assert.Equal(t, string(iso18626.ReasonRetryNotFoundAsCited), mockIso18626Handler.lastSupplyingAgencyMessage.MessageInfo.ReasonRetry.Text)
assert.Equal(t, "", mockIso18626Handler.lastSupplyingAgencyMessage.MessageInfo.Note)
assert.Nil(t, mockIso18626Handler.lastSupplyingAgencyMessage.MessageInfo.OfferedCosts)
assert.Nil(t, mockIso18626Handler.lastSupplyingAgencyMessage.DeliveryInfo)
}
}

func TestHandleInvokeLenderActionAskRetryFull(t *testing.T) {
mockPrRepo := new(MockPrRepo)
lmsCreator := new(MockLmsCreator)
lmsCreator.On("GetAdapter", "ISIL:SUP1").Return(lms.CreateLmsAdapterMockOK(), nil)
mockIso18626Handler := new(MockIso18626Handler)
prAction := CreatePatronRequestActionService(mockPrRepo, *new(events.EventBus), mockIso18626Handler, lmsCreator)
illRequest := iso18626.Request{}
mockPrRepo.On("GetPatronRequestById", patronRequestId).Return(pr_db.PatronRequest{IllRequest: illRequest, State: LenderStateValidated, Side: SideLending, SupplierSymbol: getDbText("ISIL:SUP1"), RequesterSymbol: getDbText("ISIL:REQ1")}, nil)
action := LenderActionAskRetry

status, resultData := prAction.handleInvokeAction(appCtx, events.Event{PatronRequestID: patronRequestId, EventData: events.EventData{
CommonEventData: events.CommonEventData{Action: &action},
CustomData: map[string]any{
"note": "isbn",
"itemId": "0201896834",
"reasonRetry": "Transfer",
},
}})
assert.Equal(t, events.EventStatusSuccess, status)
assert.NotNil(t, resultData)
assert.Equal(t, LenderStateCompletedWithRetry, mockPrRepo.savedPr.State)

if assert.NotNil(t, mockIso18626Handler.lastSupplyingAgencyMessage) {
assert.Equal(t, iso18626.TypeStatusRetryPossible, mockIso18626Handler.lastSupplyingAgencyMessage.StatusInfo.Status)
assert.Equal(t, "Transfer", mockIso18626Handler.lastSupplyingAgencyMessage.MessageInfo.ReasonRetry.Text)
assert.Equal(t, "isbn", mockIso18626Handler.lastSupplyingAgencyMessage.MessageInfo.Note)
assert.Nil(t, mockIso18626Handler.lastSupplyingAgencyMessage.MessageInfo.OfferedCosts)
if assert.NotNil(t, mockIso18626Handler.lastSupplyingAgencyMessage.DeliveryInfo) {
assert.Equal(t, "0201896834", mockIso18626Handler.lastSupplyingAgencyMessage.DeliveryInfo.ItemId)
}
}
}

func TestHandleInvokeLenderActionAddConditionMissingConditionAndCost(t *testing.T) {
mockPrRepo := new(MockPrRepo)
lmsCreator := new(MockLmsCreator)
Expand Down
13 changes: 13 additions & 0 deletions broker/patron_request/service/message-handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ func (m *PatronRequestMessageHandler) handleSupplyingAgencyMessageWithParent(ctx
}

eventName := MessageEvent("")
retryBibInfo := (*iso18626.BibliographicInfo)(nil)
switch sam.StatusInfo.Status {
case iso18626.TypeStatusExpectToSupply:
eventName = SupplierExpectToSupply
Expand Down Expand Up @@ -267,6 +268,15 @@ func (m *PatronRequestMessageHandler) handleSupplyingAgencyMessageWithParent(ctx
}
eventName = SupplierCancelAccepted
}
case iso18626.TypeStatusRetryPossible:
eventName = SupplierRetryConditional
setSupplierMessage(sam, &pr)
// later, we can use MessageInfo.Note to pass bibliographic hints for the retry request
if sam.DeliveryInfo != nil && sam.DeliveryInfo.ItemId != "" {
retryBibInfo = &iso18626.BibliographicInfo{
SupplierUniqueRecordId: sam.DeliveryInfo.ItemId,
}
}
Comment thread
adamdickmeiss marked this conversation as resolved.
}

if eventName == "" {
Expand All @@ -283,6 +293,9 @@ func (m *PatronRequestMessageHandler) handleSupplyingAgencyMessageWithParent(ctx
if !eventDefined {
return statusChangeNotAllowed()
}
if retryBibInfo != nil {
updatedPr.RetryBibInfo = retryBibInfo
}
return m.updatePatronRequestAndCreateSamResponse(ctx, updatedPr, sam, stateChanged, parentEventID)
}

Expand Down
9 changes: 9 additions & 0 deletions broker/patron_request/service/message_sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ func (ms *PatronRequestMessageSender) sendBorrowingRequest(ctx common.ExtendedCo
illRequest.PatronInfo = &iso18626.PatronInfo{}
}
illRequest.PatronInfo.PatronId = pr.Patron.String
if illRequest.ServiceInfo == nil {
illRequest.ServiceInfo = &iso18626.ServiceInfo{}
}
requestType := iso18626.TypeRequestTypeNew
if pr.PrevReqID.Valid {
illRequest.ServiceInfo.RequestingAgencyPreviousRequestId = pr.PrevReqID.String
requestType = iso18626.TypeRequestTypeRetry
}
illRequest.ServiceInfo.RequestType = &requestType

var illMessage = iso18626.NewISO18626Message()
illMessage.Request = &illRequest
Expand Down
Loading
Loading