Skip to content

Commit

Permalink
Merge branch 'main' into fix/duplicate-parent-id
Browse files Browse the repository at this point in the history
  • Loading branch information
Sv7enNowitzki committed Jan 17, 2024
2 parents 9c40c65 + a6c2b75 commit 84c30f1
Show file tree
Hide file tree
Showing 14 changed files with 219 additions and 13 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
The format is based on [Keep a Changelog](http://keepachangelog.com/).

## Version 1.0.5 - 15.01.24

### Fixed

- Error on HANA when logging Boolean or Numeric Data

## Version 1.0.4 - 08.01.24

### Added

- Side effect annotation now allows automatic refresh after a custom action caused changes

### Changed

- Added a check to disable change tracking for views with a UNION

### Fixed

- Handling of associations within change tracked entities
- Handling of change log when custom actions on child entities are called

## Version 1.0.3 - 10.11.23

### Added
Expand Down Expand Up @@ -37,3 +58,4 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
### Added

- Initial release

43 changes: 43 additions & 0 deletions cds-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ const isChangeTracked = (entity) => (
|| entity.elements && Object.values(entity.elements).some(e => e['@changelog'])) && entity.query?.SET?.op !== 'union'
)

// Add the appropriate Side Effects attribute to the custom action
const addSideEffects = (actions, flag, element) => {
for (const se of Object.values(actions)) {
const target = flag ? 'TargetProperties' : 'TargetEntities'
const sideEffectAttr = se[`@Common.SideEffects.${target}`]
const property = flag ? 'changes' : { '=': `${element}.changes` }
if (sideEffectAttr?.length >= 0) {
sideEffectAttr.findIndex(
(item) =>
(item['='] ? item['='] : item) ===
(property['='] ? property['='] : property)
) === -1 && sideEffectAttr.push(property)
} else {
se[`@Common.SideEffects.${target}`] = [property]
}
}
}


// Unfold @changelog annotations in loaded model
cds.on('loaded', m => {
Expand Down Expand Up @@ -36,6 +54,31 @@ cds.on('loaded', m => {

// Add UI.Facet for Change History List
entity['@UI.Facets']?.push(facet)

// The changehistory list should be refreshed after the custom action is triggered
if (entity.actions) {

// Update the changehistory list on the current entity when the custom action of the entity is triggered
if (entity['@UI.Facets']) {
addSideEffects(entity.actions, true)
}

// When the custom action of the child entity is performed, the change history list of the parent entity is updated
if (entity.elements) {
//ToDo: Revisit Breaklook with node.js Expert
breakLoop: for (const [ele, eleValue] of Object.entries(entity.elements)) {
const parentEntity = m.definitions[eleValue.target]
if (parentEntity && parentEntity['@UI.Facets'] && eleValue.type === 'cds.Association') {
for (const value of Object.values(parentEntity.elements)) {
if (value.target === name) {
addSideEffects(entity.actions, false, ele)
break breakLoop
}
}
}
}
}
}
}
}
})
Expand Down
12 changes: 8 additions & 4 deletions lib/change-log.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ function _trackedChanges4 (srv, target, diff) {
entity: getDBEntity(element.parent).name,
serviceEntity: element.parent.name,
attribute: element["@odata.foreignKey4"] || key,
valueChangedFrom: from || '',
valueChangedTo: to || '',
valueChangedFrom: from?? '',
valueChangedTo: to?? '',
valueDataType: element.type,
modification: row._op,
keys,
Expand Down Expand Up @@ -359,15 +359,19 @@ async function track_changes (req) {
if (!changes) return

await _formatChangeLog(changes, req)
if (isComposition && !isDraftEnabled) {
if (isComposition) {
[ target, entityKey ] = await _prepareChangeLogForComposition(target, entityKey, changes, this)
}
const dbEntity = getDBEntity(target)
await INSERT.into("sap.changelog.ChangeLog").entries({
entity: dbEntity.name,
entityKey: entityKey,
serviceEntity: target.name,
changes: changes.filter(c => c.valueChangedFrom || c.valueChangedTo),
changes: changes.filter(c => c.valueChangedFrom || c.valueChangedTo).map((c) => ({
...c,
valueChangedFrom: `${c.valueChangedFrom ?? ''}`,
valueChangedTo: `${c.valueChangedTo ?? ''}`,
})),
})
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cap-js/change-tracking",
"version": "1.0.3",
"version": "1.0.4",
"description": "CDS plugin providing out-of-the box support for automatic capturing, storing, and viewing of the change records of modeled entities.",
"repository": "cap-js/change-tracking",
"author": "SAP SE (https://www.sap.com)",
Expand Down
11 changes: 11 additions & 0 deletions tests/bookshop/db/codelists.cds
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using {sap.common.CodeList as CodeList} from '@sap/cds/common';

namespace sap.capire.bookshop;

entity PaymentAgreementStatusCodes : CodeList {
key code : String(10);
}

entity ActivationStatusCode : CodeList {
key code : String(20);
}
4 changes: 4 additions & 0 deletions tests/bookshop/db/common/codeLists.cds
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ entity LifecycleStatusCodes : CodeList {
entity BookTypeCodes : CodeList {
key code : String(3);
}

entity ActivationStatusCode : CodeList {
key code : String(20);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
code;name
INACTIVE;Inactive
ACTIVE;Active
12 changes: 6 additions & 6 deletions tests/bookshop/db/data/sap.capire.bookshop-Books.csv
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ID;title;descr;author_ID;stock;price;genre_ID;bookStore_ID
9d703c23-54a8-4eff-81c1-cdce6b8376b1;Wuthering Heights;"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.";d4d4a1b3-5b83-4814-8a20-f039af6f0387;12;11.11;11;64625905-c234-4d0d-9bc1-283ee8946770
676059d4-8851-47f1-b558-3bdc461bf7d5;Jane Eyre;"Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name ""Currer Bell"", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism.";47f97f40-4f41-488a-b10b-a5725e762d5e;11;12.34;11;5ab2a87b-3a56-4d97-a697-7af72334a384
42bc7997-f6ce-4ae9-8a64-ee5e02ef1087;The Raven;"""The Raven"" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word ""Nevermore"". The poem makes use of folk, mythological, religious, and classical references.";5c30d395-db0a-4095-bd7e-d4de34646607;333;13.13;16;5ab2a87b-3a56-4d97-a697-7af72334a384
9297e4ea-396e-47a4-8815-cd4622dea8b1;Eleonora;"""Eleonora"" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively ""happy"" ending.";5c30d395-db0a-4095-bd7e-d4de34646607;555;14;16;8aaed432-8336-4b0d-be7e-3ef1ce7f13ea
574c8add-0ee3-4175-ab62-ca09a92c723c;Catweazle;Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.;a45da28a-7f55-4b53-8a63-48b61132d1b9;22;15;13;8aaed432-8336-4b0d-be7e-3ef1ce7f13ea
ID;title;descr;isUsed;author_ID;stock;price;genre_ID;bookStore_ID
9d703c23-54a8-4eff-81c1-cdce6b8376b1;Wuthering Heights;"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.";true;d4d4a1b3-5b83-4814-8a20-f039af6f0387;12;11.11;11;64625905-c234-4d0d-9bc1-283ee8946770
676059d4-8851-47f1-b558-3bdc461bf7d5;Jane Eyre;"Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name ""Currer Bell"", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism.";true;47f97f40-4f41-488a-b10b-a5725e762d5e;11;12.34;11;5ab2a87b-3a56-4d97-a697-7af72334a384
42bc7997-f6ce-4ae9-8a64-ee5e02ef1087;The Raven;"""The Raven"" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word ""Nevermore"". The poem makes use of folk, mythological, religious, and classical references.";true;5c30d395-db0a-4095-bd7e-d4de34646607;333;13.13;16;5ab2a87b-3a56-4d97-a697-7af72334a384
9297e4ea-396e-47a4-8815-cd4622dea8b1;Eleonora;"""Eleonora"" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively ""happy"" ending.";true;5c30d395-db0a-4095-bd7e-d4de34646607;555;14;16;8aaed432-8336-4b0d-be7e-3ef1ce7f13ea
574c8add-0ee3-4175-ab62-ca09a92c723c;Catweazle;Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.;true;a45da28a-7f55-4b53-8a63-48b61132d1b9;22;15;13;8aaed432-8336-4b0d-be7e-3ef1ce7f13ea
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
code;name
EXPIRED;Expired
VALID;Valid
VALIDLATER;Valid Later
INACTIVE;Inactive
10 changes: 10 additions & 0 deletions tests/bookshop/db/schema.cds
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ using {
sap.capire.common.types.LifecycleStatusCode as LifecycleStatusCode,
sap.capire.common.types.BookTypeCodes as BookTypeCodes,
} from './common/types.cds';
using {sap.capire.bookshop.ActivationStatusCode} from './codelists';
using {sap.capire.bookshop.PaymentAgreementStatusCodes as PaymentAgreementStatusCodes} from './codelists';

namespace sap.capire.bookshop;

Expand Down Expand Up @@ -118,6 +120,7 @@ entity Books : managed, cuid {
genre : Association to Genres;
stock : Integer;
price : Decimal;
isUsed : Boolean;
image : LargeBinary @Core.MediaType : 'image/png';
@title : '{i18n>books.bookType}'
bookType : BookTypeCodes;
Expand Down Expand Up @@ -148,6 +151,10 @@ entity Volumns : managed, cuid {
@title : '{i18n>volumns.sequence}'
sequence : Integer;
book : Association to one Books;
@title : '{i18n>Status}'
@changelog : [ActivationStatus.name]
ActivationStatus : Association to one ActivationStatusCode;
PaymentAgreementStatus : Association to one PaymentAgreementStatusCodes on PaymentAgreementStatus.code = ActivationStatus.code;
}

@title : '{i18n>bookStoreRegistry.objectTitle}'
Expand Down Expand Up @@ -211,6 +218,9 @@ entity OrderItem : cuid {
entity OrderItemNote : cuid {
orderItem : Association to one OrderItem;
content : String;
@title : '{i18n>Status}'
ActivationStatus : Association to one ActivationStatusCode;
PaymentAgreementStatus : Association to one PaymentAgreementStatusCodes on PaymentAgreementStatus.code = ActivationStatus.code;
}

entity City : cuid {
Expand Down
18 changes: 16 additions & 2 deletions tests/bookshop/srv/admin-service.cds
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using {sap.capire.bookshop as my} from '../db/schema';
using {sap.capire.bookshop.PaymentAgreementStatusCodes as PaymentAgreementStatusCodes} from '../db/codelists';

service AdminService {
@odata.draft.enabled
Expand All @@ -21,8 +22,19 @@ service AdminService {
entity Report as projection on my.Report;
entity Order as projection on my.Order;
entity OrderItem as projection on my.OrderItem;
entity OrderItemNote as projection on my.OrderItemNote;
entity Volumns as projection on my.Volumns;

entity OrderItemNote as projection on my.OrderItemNote actions {
@cds.odata.bindingparameter.name: 'self'
@Common.SideEffects : {TargetEntities: [self]}
action activate();
};

entity Volumns as projection on my.Volumns actions {
@cds.odata.bindingparameter.name: 'self'
@Common.SideEffects : {TargetEntities: [self]}
action activate();
};

entity Customers as projection on my.Customers;
}

Expand Down Expand Up @@ -103,6 +115,7 @@ annotate AdminService.Books with @changelog : [
]{
title @changelog;
descr @changelog;
isUsed @changelog;
author @changelog : [
author.name.firstName,
author.name.lastName
Expand Down Expand Up @@ -149,6 +162,7 @@ annotate AdminService.OrderItem with {

annotate AdminService.OrderItemNote with {
content @changelog;
ActivationStatus @changelog : [ActivationStatus.name];
}

annotate AdminService.Customers with {
Expand Down
19 changes: 19 additions & 0 deletions tests/bookshop/srv/admin-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,23 @@ module.exports = cds.service.impl(async (srv) => {
const newRootEntity = req.data;
newRootEntity.lifecycleStatus_code = "IP";
});

const onActivateVolumns = async (req) => {
const entity = req.entity;
const entityID = req._params[req._params.length - 1].ID;
await UPDATE.entity(entity)
.where({ ID: entityID })
.set({ ActivationStatus_code: "VALID" });
};

const onActivateOrderItemNote = async (req) => {
const entity = req.entity;
const entityID = req._params[req._params.length - 1];
await UPDATE.entity(entity)
.where({ ID: entityID })
.set({ ActivationStatus_code: "VALID" });
};

srv.on("activate", "Volumns", onActivateVolumns);
srv.on("activate", "OrderItemNote", onActivateOrderItemNote);
});
18 changes: 18 additions & 0 deletions tests/integration/fiori-draft-disabled.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -517,4 +517,22 @@ describe("change log draft disabled test", () => {
expect(headerChange.parentObjectID).to.equal("Post");
delete cds.services.AdminService.entities.Order["@changelog"];
});

it("11.2 The change log should be captured when a child entity in draft-disabled mode triggers a custom action (ERP4SMEPREPWORKAPPPLAT-6211)", async () => {
await POST(
`/odata/v4/admin/Order(ID=0a41a187-a2ff-4df6-bd12-fae8996e6e31)/orderItems(ID=9a61178f-bfb3-4c17-8d17-c6b4a63e0097)/notes(ID=a40a9fd8-573d-4f41-1111-fa8ea0d8b1bc)/AdminService.activate`,
{
ActivationStatus_code: "VALID",
},
);
let changes = await SELECT.from(ChangeView).where({
entity: "sap.capire.bookshop.OrderItemNote",
attribute: "ActivationStatus",
});
expect(changes.length).to.equal(1);
expect(changes[0].valueChangedFrom).to.equal("");
expect(changes[0].valueChangedTo).to.equal("VALID");
expect(changes[0].entityKey).to.equal("0a41a187-a2ff-4df6-bd12-fae8996e6e31");
expect(changes[0].parentKey).to.equal("9a61178f-bfb3-4c17-8d17-c6b4a63e0097");
});
});
Loading

0 comments on commit 84c30f1

Please sign in to comment.