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: return deleted resources object from submitChanges #445

Merged
merged 34 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d4f361d
feat: return deleted resources object from submitChanges
kanikasharma97 Apr 24, 2024
f010024
Merge branch 'master' into task/returnDltdResources
kanikasharma97 Apr 24, 2024
e9df5f1
fixed eslint issues and added test cases
kanikasharma97 Apr 24, 2024
b39fd58
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 Apr 24, 2024
662b0a5
added jsdoc
kanikasharma97 Apr 25, 2024
0a9cbb1
Update FHIRModel.js
kanikasharma97 Apr 25, 2024
9588a89
Update FHIRUtils.js
kanikasharma97 Apr 25, 2024
3670e5e
Update FHIRUtils.js
kanikasharma97 Apr 25, 2024
738fd7d
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 Apr 25, 2024
cab1cec
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 Apr 25, 2024
6e6564e
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 Apr 25, 2024
1d5cd5c
Update FHIRUtils.js
kanikasharma97 Apr 25, 2024
a3ba8fa
Update FHIRUtils.js
kanikasharma97 Apr 25, 2024
92bedfb
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 Apr 25, 2024
481c8d8
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 Apr 25, 2024
e50c425
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 Apr 25, 2024
4db4e26
incorporated review comments
kanikasharma97 May 7, 2024
d0a69a3
Merge branch 'master' into task/returnDltdResources
kanikasharma97 May 7, 2024
022153a
incorporated review comments
kanikasharma97 May 7, 2024
d0dc57d
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 7, 2024
5515e2d
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 7, 2024
be76ac4
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
124f301
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
ed12d5f
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
36c5b47
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
dc224a6
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
69604b9
incorporated review comments
kanikasharma97 May 9, 2024
b8c49bb
incorporated review comments
kanikasharma97 May 9, 2024
61fef49
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
3eaa890
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
16235be
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
02edb9f
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
cb7c6ea
Merge branch 'task/returnDltdResources' of https://github.com/kanikas…
kanikasharma97 May 9, 2024
3769311
Fixed ESLint issue
kanikasharma97 May 13, 2024
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
1 change: 1 addition & 0 deletions docs/tutorials/4 Request Handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ onSavePress: function(){
Depending on the submit mode the callback will be invoked with specific type of parameters.

If the group submit mode is Batch/Transaction then the success callback will contain all the FHIR Resources which were part of the request and in case of failed enteries in Bundle the error callback will be invoked with the successful resources and the operation outcome enteries.
In case of delete if the API doesn't return FHIR resources which got deleted successfuly, while resolving the promise, the removed resources are fetched from the model and assigned to aFHIRResource.

```javascript
onSavePress: function() {
Expand Down
32 changes: 32 additions & 0 deletions src/sap/fhir/model/r4/FHIRModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,7 @@ sap.ui.define([
*/
FHIRModel.prototype.submitChanges =
function(sGroupId, fnSuccessCallback, fnErrorCallback) {
var aRemovedResource = this._getRemovedResourcesObject();
if (typeof sGroupId === "function") {
fnErrorCallback = fnSuccessCallback;
fnSuccessCallback = FHIRUtils.deepClone(sGroupId);
Expand Down Expand Up @@ -693,9 +694,16 @@ sap.ui.define([
);
aPromises.push(oPromise);
oPromise.then(function (aFHIRResource) {
if (aFHIRResource.length == 0) {
aFHIRResource = aRemovedResource;
}
fnSuccessCallback(aFHIRResource);
}).catch(function (oError) {
if (fnErrorCallback && oError.requestHandle) {
if (aRemovedResource.length != 0) {
var aId = FHIRUtils.getIdFromOperationOutcome(oError.operationOutcomes);
oError.resources = FHIRUtils.filterResourcesByIds(aRemovedResource, aId);
}
var mParameters = {
message: oError.requestHandle.getRequest().statusText,
description: oError.requestHandle.getRequest().responseText,
Expand Down Expand Up @@ -806,6 +814,30 @@ sap.ui.define([
return mRequestHandles;
};

/**
* Retrieves an array of resources that have been removed from the FHIR model.
* Iterates through the removed resources,
* retrieves corresponding resources from the model, and returns them.
* @returns {Array<object>} An array containing the removed resources.
* @private
* @since 2.4.0
*/
FHIRModel.prototype._getRemovedResourcesObject = function () {
var aResource = [];
for (var sType in this.mRemovedResources) {
if (this.mRemovedResources.hasOwnProperty(sType)) {
var oRemovedResource = this.mRemovedResources[sType];
for (var sKey in oRemovedResource) {
var oResource = this.getProperty("/" + oRemovedResource[sKey]);
if (oResource) {
aResource.push(oResource);
}
}
}
}
return aResource;
};

/**
* Checks if an update for the existing bindings is necessary due to the <code>mChangedResources</code>
*
Expand Down
47 changes: 46 additions & 1 deletion src/sap/fhir/model/r4/FHIRUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,51 @@ sap.ui.define([
return sFullUrl;
};

/**
* Extracts resource IDs from the error description in FHIR OperationOutcome.
* @param {Array<object>} aOperationOutcome - The array of FHIR OperationOutcome objects.
* @returns {Array<string>} - An array containing the extracted resource IDs.
kanikasharma97 marked this conversation as resolved.
Show resolved Hide resolved
* @protected
* @since 2.4.0
*/
FHIRUtils.getIdFromOperationOutcome = function (aOperationOutcome) {
var aID = [];
var aMatchedId;
var sText;
for (var key in aOperationOutcome) {
if (aOperationOutcome.hasOwnProperty(key)) {
var oOperationOutcome = aOperationOutcome[key];
var oIssue = oOperationOutcome._aIssue[0];
if (oIssue) {
sText = oIssue.details.text;
if (sText) {
aMatchedId = sText.match(/[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}/);
}
if (aMatchedId && aMatchedId.length > 0){
aID.push(aMatchedId[0]);
}
}
}
}
return aID;

};

/**
* Filters an array of FHIR resources by their IDs, removing those that match the provided IDs.
* @param {Array<object>} aResource - The array of FHIR resources to filter.
* @param {Array<string>} aID - The array of resource IDs to exclude from the filtered result.
* @returns {Array<object>} - The filtered array of FHIR resources.
* @protected
* @since 2.4.0
*/
FHIRUtils.filterResourcesByIds = function (aResource, aID) {
function isIdNotIncluded(obj) {
kanikasharma97 marked this conversation as resolved.
Show resolved Hide resolved
return !aID.includes(obj.id);
}
return aResource.filter(isIdNotIncluded);
};

return FHIRUtils;

});
});
43 changes: 43 additions & 0 deletions test/localService/BundleWithDeleteSuccessAndFailureEntries.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"resourceType": "Bundle",
"id": "934953d3-35a3-477d-8c9e-0948a7e553ec",
"links": [],
"type": "batch-response",
"entry": [
{
"response": {
"status": "409 CONFLICT",
"outcome": {
"issue": [
{
"severity": "error",
"code": "conflict",
"details": {
"text": "Referenced resource exist 'e1692049-4bdc-4e40-abb5-4eae27ce0b8b' for resource 'Patient}'"
},
kanikasharma97 marked this conversation as resolved.
Show resolved Hide resolved
"diagnostics": "Referenced resource exist 'e1692049-4bdc-4e40-abb5-4eae27ce0b8b' for resource 'Patient}'"
}
],
"resourceType": "OperationOutcome",
"meta": {
"profile": [
"http://hl7.org/fhir/StructureDefinition/OperationOutcome"
]
}
}
}
},
{
"response": {
"status": "204 NO_CONTENT"
},
"fullUrl": "urn:uuid:cb62c497-ee6c-4c26-9721-2668f797e6c8"
}
],
"total": 2,
"meta": {
"profile": [
"http://hl7.org/fhir/StructureDefinition/Bundle"
]
}
}
18 changes: 18 additions & 0 deletions test/qunit/model/FHIRModel.integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -920,4 +920,22 @@ sap.ui.define([
oListBinding.attachDataReceived(fnDataReceivedCheck);
});

QUnit.test("Test delete containing successful entry and operation outcome", function (assert) {
var oJSONData = TestUtils.loadJSONFile("BundleWithDeleteSuccessAndFailureEntries");
var done = assert.async();
var sResId = this.oFhirModel.create("Patient", {
resourceType: "Patient",
version: "1.0.0",
name: "Billy"
}, "bundle");
this.oFhirModel.mChangedResources = {};
this.oFhirModel.remove(["/Patient/" + sResId], undefined, "bundle");
var fnErrorCallback = function (oMessage, aFHIRResource, aOperationOutcome) {
assert.strictEqual(aOperationOutcome.length, 1, "Bundle error callback contains the opertion outcome of the failed entry ");
done();
};
TestUtilsIntegration.manipulateResponse("http://localhost:8080/fhir/R4", this.oFhirModel, TestUtilsIntegration.setResponseJSON, undefined, oJSONData);
this.oFhirModel.submitChanges("bundle", undefined, fnErrorCallback);
});

});
7 changes: 7 additions & 0 deletions test/qunit/model/FHIRModel.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -1503,4 +1503,11 @@ sap.ui.define([

});

QUnit.test("Test getRemovedResourcesObject returning the correct value", function (assert) {
this.oFhirModel1.mRemovedResources = { Patient: ["Patient/123"] };
this.oFhirModel1.setProperty("/Patient/123", { id: 123, description: "this is a test object", resourceType: "Patient" });
var aResource = this.oFhirModel1._getRemovedResourcesObject();
assert.deepEqual(aResource, [{ id: 123, description: "this is a test object", resourceType: "Patient" }], "Correct resources returned");
});

});
55 changes: 55 additions & 0 deletions test/qunit/model/FHIRUtils.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,4 +516,59 @@ sap.ui.define(["../utils/TestUtils", "sap/fhir/model/r4/FHIRUtils"], function(Te
sFullUrl = FHIRUtils.generateFullUrl(TestUtils.createUri("url"), "/Patient/123", "123", "http://example.com");
assert.strictEqual(sFullUrl, "http://example.com/Patient/123");
});

QUnit.test("Test getIdFromOperationOutcome", function(assert) {
var oOperationOutcome = {
"0": {
"_sResourceType": "OperationOutcome",
"_aIssue": [
{
"severity": "error",
"code": "conflict",
kanikasharma97 marked this conversation as resolved.
Show resolved Hide resolved
"details": {
"text": "Referenced resource exist '7b4abf15-8a93-4e11-8d85-96c945530d05' for resource 'Patient}'"
kanikasharma97 marked this conversation as resolved.
Show resolved Hide resolved
},
"diagnostics": "Referenced resource exist '7b4abf15-8a93-4e11-8d85-96c945530d05' for resource 'Patient}'"
}
]
}
};
var aExpectedId = ["7b4abf15-8a93-4e11-8d85-96c945530d05"];
var aActualId = FHIRUtils.getIdFromOperationOutcome(oOperationOutcome);
assert.deepEqual(aActualId, aExpectedId, "IDs extracted correctly from operationOutcomes");
});

QUnit.test("Test filterResourcesByIds", function (assert) {
var aResource = [
{ id: "1", name: "Resource 1" },
{ id: "2", name: "Resource 2" },
{ id: "3", name: "Resource 3" }
];
var aId = ["2"];
var aFilteredResource = FHIRUtils.filterResourcesByIds(aResource, aId);
assert.deepEqual(aFilteredResource, [{ id: "1", name: "Resource 1" }, { id: "3", name: "Resource 3" }], "Filtered resources should match expected result");
});

QUnit.test("Test getIdFromOperationOutcome when resource ID is not present", function(assert) {
var oOperationOutcome = {
"0": {
"_sResourceType": "OperationOutcome",
"_aIssue": [
{
"severity": "error",
"code": "conflict",
"details": {
"text": "Referenced resource exist for this resource}"
},
"diagnostics": "Referenced resource exist for this resource}"
}
]
}
};

var actualIDs = FHIRUtils.getIdFromOperationOutcome(oOperationOutcome);
assert.deepEqual(actualIDs, [], "Empty array returned");
});


});
Loading