-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3481b62
commit eb6ed91
Showing
8 changed files
with
421 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
const { | ||
ChangeWorkItemStateService | ||
} = require("./service/change-workItem-state.service"); | ||
const { ApiLogger } = require("../../../../utils/logs/api-logger"); | ||
const { Controller } = require("../../../controller.class"); | ||
const { DicomWebServiceError } = require("@error/dicom-web-service"); | ||
|
||
class ChangeWorkItemStateController extends Controller { | ||
constructor(req, res) { | ||
super(req, res); | ||
} | ||
|
||
async mainProcess() { | ||
let apiLogger = new ApiLogger(this.request, "UPS-RS"); | ||
|
||
apiLogger.addTokenValue(); | ||
apiLogger.logger.info(`Update workItem, params: ${this.paramsToString()}`); | ||
|
||
try { | ||
let service = new ChangeWorkItemStateService(this.request, this.response); | ||
let workItems = await service.changeWorkItemState(); | ||
return this.response | ||
.set("Content-Type", "application/dicom+json") | ||
.status(200) | ||
.end(); | ||
} catch (e) { | ||
let errorStr = JSON.stringify(e, Object.getOwnPropertyNames(e)); | ||
apiLogger.logger.error(errorStr); | ||
|
||
if (e instanceof DicomWebServiceError) { | ||
return this.response.status(e.code).json({ | ||
status: e.status, | ||
message: e.message | ||
}); | ||
} | ||
|
||
this.response.writeHead(500, { | ||
"Content-Type": "application/dicom+json" | ||
}); | ||
this.response.end(JSON.stringify({ | ||
code: 500, | ||
message: "An Server Exception Occurred" | ||
})); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* | ||
* @param {import('express').Request} req | ||
* @param {import('express').Response} res | ||
*/ | ||
module.exports = async function (req, res) { | ||
let controller = new ChangeWorkItemStateController(req, res); | ||
|
||
await controller.doPipeline(); | ||
}; |
211 changes: 211 additions & 0 deletions
211
api/dicom-web/controller/UPS-RS/service/change-workItem-state.service.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
const _ = require("lodash"); | ||
const moment = require("moment"); | ||
const { DicomJsonModel } = require("@models/DICOM/dicom-json-model"); | ||
const { DicomCode } = require("@models/DICOM/code"); | ||
const workItemModel = require("@models/mongodb/models/workItems"); | ||
const { | ||
DicomWebServiceError, | ||
DicomWebStatusCodes | ||
} = require("@error/dicom-web-service"); | ||
|
||
class ChangeWorkItemStateService { | ||
/** | ||
* | ||
* @param {import('express').Request} req | ||
* @param {import('express').Response} res | ||
*/ | ||
constructor(req, res) { | ||
this.request = req; | ||
this.response = res; | ||
this.requestState = /** @type {Object[]} */(this.request.body).pop(); | ||
/** @type {DicomJsonModel} */ | ||
this.requestState = new DicomJsonModel(this.requestState); | ||
this.workItem = null; | ||
this.workItemState = ""; | ||
} | ||
|
||
async changeWorkItemState() { | ||
await this.findOneWorkItem(); | ||
|
||
this.workItemState = this.workItem.getString("00741000"); | ||
let requestState = this.requestState.getString("00741000"); | ||
|
||
if (requestState === "IN PROGRESS") { | ||
this.inProgressChange(); | ||
} else if (requestState === "CANCELED") { | ||
this.cancelChange(); | ||
} else if (requestState === "COMPLETED") { | ||
this.completeChange(); | ||
} | ||
|
||
await workItemModel.findOneAndUpdate({ | ||
upsInstanceUID: this.request.params.workItem | ||
}, { | ||
...this.requestState.dicomJson | ||
}); | ||
} | ||
|
||
async findOneWorkItem() { | ||
|
||
let workItem = await workItemModel.findOne({ | ||
upsInstanceUID: this.request.params.workItem | ||
}); | ||
|
||
if (!workItem) { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSDoesNotExist, | ||
"The UPS instance not exist", | ||
404 | ||
); | ||
} | ||
|
||
this.workItem = new DicomJsonModel(workItem); | ||
|
||
} | ||
|
||
inProgressChange() { | ||
if (this.workItemState === "IN PROGRESS") { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSAlreadyInProgress, | ||
"The request is inconsistent with the current state of the Target Workitem", | ||
409 | ||
); | ||
} else if (this.workItemState === "COMPLETED" || this.workItemState === "CANCELED") { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSMayNoLongerBeUpdated, | ||
"The request is inconsistent with the current state of the Target Workitem", | ||
409 | ||
); | ||
} | ||
} | ||
|
||
cancelChange() { | ||
if (this.workItemState === "SCHEDULED") { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSNotYetInProgress, | ||
"The request is inconsistent with the current state of the Target Workitem", | ||
409 | ||
); | ||
} else if (this.workItemState === "COMPLETED") { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSMayNoLongerBeUpdated, | ||
"The request is inconsistent with the current state of the Target Workitem", | ||
409 | ||
); | ||
} else if (this.workItemState === "CANCELED") { | ||
this.response.set("Warning", "299 Raccoon: The UPS is already in the requested state of CANCELED."); | ||
} | ||
|
||
let transactionUID = this.requestState.getString("00081195"); | ||
let workItemTransactionUID = this.requestState.getString("00081195"); | ||
if (transactionUID !== workItemTransactionUID) { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSTransactionUIDNotCorrect, | ||
"Refused: The correct Transaction UID was not provided", | ||
400 | ||
); | ||
} | ||
this.supplementDiscontinuationReasonCode(); | ||
} | ||
|
||
completeChange() { | ||
if (this.workItemState === "SCHEDULED") { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSNotYetInProgress, | ||
"The request is inconsistent with the current state of the Target Workitem (UPS Not Yet In Progress)", | ||
409 | ||
); | ||
} else if (this.workItemState === "CANCELED") { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSMayNoLongerBeUpdated, | ||
"The request is inconsistent with the current state of the Target Workitem (The CANCELED UPS can not change to COMPLETED)", | ||
409 | ||
); | ||
} else if (this.workItemState === "COMPLETED") { | ||
this.response.set("Warning", "299 Raccoon: The UPS is already in the requested state of COMPLETED."); | ||
} | ||
|
||
let transactionUID = this.requestState.getString("00081195"); | ||
let workItemTransactionUID = this.requestState.getString("00081195"); | ||
if (transactionUID !== workItemTransactionUID) { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSTransactionUIDNotCorrect, | ||
"Refused: The correct Transaction UID was not provided", | ||
400 | ||
); | ||
} | ||
if (!this.meetFinalStateRequirementsOfCompleted()) { | ||
throw new DicomWebServiceError( | ||
DicomWebStatusCodes.UPSNotMetFinalStateRequirements, | ||
"The request is inconsistent with the current state of the Target Workitem (The workitem is not meet final state requirements of completed)", | ||
409 | ||
); | ||
} | ||
} | ||
|
||
ensureProgressInformationSequence() { | ||
let progressInformation = _.get(this.workItem.dicomJson, "00741002.Value"); | ||
if (!progressInformation) { | ||
_.set(this.workItem.dicomJson, "00741002", { | ||
vr: "SQ", | ||
Value: [] | ||
}); | ||
} | ||
} | ||
|
||
supplementDiscontinuationReasonCode() { | ||
this.ensureProgressInformationSequence(); | ||
let procedureStepCancellationDateTime = _.get(this.workItem.dicomJson, "00741002.Value.0.00404052"); | ||
if (!procedureStepCancellationDateTime) { | ||
_.set(this.workItem.dicomJson, "00741002.Value.0.00404052", { | ||
vr: "DT", | ||
Value: [ | ||
moment().format("YYYYMMDDhhmmss.SSSSSSZZ") | ||
] | ||
}); | ||
} | ||
|
||
let reasonCodeMeaning = _.get(this.workItem.dicomJson, "00741002.Value.0.0074100E.Value.0.00080104"); | ||
if (!reasonCodeMeaning) { | ||
_.set(this.workItem.dicomJson, "00741002.Value.0.0074100E.Value.0", { | ||
vr: "SQ", | ||
Value: [ | ||
{ | ||
"00081000": { | ||
"vr": "SH", | ||
"Value": ["110513"] | ||
}, | ||
"00080102": { | ||
"vr": "SH", | ||
"Value": ["DCM"] | ||
}, | ||
"00080104": { | ||
"vr": "LO", | ||
"Value": ["Discontinued for unspecified reason"] | ||
} | ||
} | ||
] | ||
}); | ||
} | ||
} | ||
|
||
meetFinalStateRequirementsOfCompleted() { | ||
let performedProcedure = _.get(this.workItem.dicomJson, "00741216"); | ||
if (performedProcedure && | ||
_.get(performedProcedure, "Value.0.00404050") && | ||
_.get(performedProcedure, "Value.0.00404051")) { | ||
|
||
try { | ||
let stationNameCode = new DicomCode(_.get(performedProcedure, "Value.0.00404028.Value.0")); | ||
let workItemCode = new DicomCode(_.get(performedProcedure, "Value.0.00404019.Value.0")); | ||
|
||
return true; | ||
} catch(e) { | ||
console.log(`Invalid Dicom Code ${e}`); | ||
} | ||
} | ||
return false; | ||
} | ||
} | ||
|
||
module.exports.ChangeWorkItemStateService = ChangeWorkItemStateService; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.