GithubHelp home page GithubHelp logo

cap-js / change-tracking Goto Github PK

View Code? Open in Web Editor NEW
12.0 10.0 5.0 3.87 MB

CDS plugin providing out-of-the box support for automatic capturing, storing, and viewing of the change records of modeled entities.

Home Page: https://cap.cloud.sap/docs

License: Apache License 2.0

CAP CDS 11.71% JavaScript 88.29%
cap cds change-tracking nodejs sap-btp sap-cap

change-tracking's Issues

Changelogs erased for deleted entities

Hello team,

I have noticed that all the changelogs for a parent entity are erased on entity delete:
image

However, we have usecase where we are interested in whole entity lifecycle tracking (including the delete action) and keeping these logs. Is there any way to achieve this?

Thank you,
Hana

Changing history view for two apps

Hi colleagues,

You described, how we can customize the change view (annotating

annotate sap.changelog.ChangeView with @(
UI.LineItem : [....

explicitely in the app annotation.

You described as well how we can set change history to be shown at once:

annotate sap.changelog.aspect @(UI.Facets: [{
$Type : 'UI.ReferenceFacet',
ID : 'ChangeHistoryFacet',
Label : '{i18n>ChangeHistory}',
Target: 'changes/@UI.PresentationVariant',
![@UI.PartOfPreview]
}]);

I tried it out in one of the apps and it worked correctly. I was able to hide some technical columns, to change some column labels.

However when I tried to do the same in the second app annotation I got the following error during npm run build:dev

[ERROR] app\masterData\businessPartners\annotations.cds:6:3-14: Duplicate assignment with “@UI.LineItem” (in annotate:“sap.changelog.ChangeView”)
[ERROR] app\masterData\businessPartners\annotations.cds:68:33-42: Duplicate assignment with “@UI.Facets” (in annotate:“sap.changelog.aspect”)
[ERROR] app\payment\businessTransactions\annotations.cds:5:42-53: Duplicate assignment with “@UI.LineItem” (in annotate:“sap.changelog.ChangeView”)
[ERROR] app\payment\businessTransactions\annotations.cds:64:33-42: Duplicate assignment with “@UI.Facets” (in annotate:“sap.changelog.aspect”)

CDS compilation failed
Command failed: npx cds deploy --to hana:D032660 --store-credentials --auto-undeploy

Could you please advise?

Kind regards,
Elena Gurevitch

Questions about Object ID definition

Hi colleagues,
There was a discussion whether direct DB operations (not via services) should be also considered in the change tracking. Finally a decision was made that a service was necessary. We created such dummy-services like for example

service PaymentWrapperService @(requires: 'system-user') {
entity Payments as projection on db.payments.Payments;
entity Payables as projection on db.payables.Payables;
entity PaymentOrders as projection on db.paymentOrders.PaymentOrders;
entity Receivables as projection on db.receivables.Receivables;
entity BusinessTransactions as projection on db.businessTransactions.BusinessTransactions;
}

And all INSERT/UPDATE operations are now fulfilled via this service like:

INSERT([paymentToInsert]).into(PaymentWrapperService.Entity.Payments)

This works. Moreover, entity BusinessTransactions is a view defined as union of 3 other entities: Payments, Payables and Receivables. But on the UI based on BusinessTransactions the change history of Payment or other entities is shown – this is if course very good.
However some things do not work as expected.
All three entities Payments, Payables and Receivables in the view BusinessTransactions have a field displayId.
For Payables and Receivables it was possible to define Changelog as
@changelog: [displayId]

However for Payments it is not possible (then npm run build would bring an error saying that dependencies exist). It is only possible to define it as
@changelog.ObjectID: [displayId]

But then EntityID on the Changes DB table remains empty and “Payment” is shown as Object ID . I tried
@changelog.entityID: [displayId]

But it does not make any difference. Even in the DB table SAP_CHANGELOG_CHANGES Entity ID is empty.

I suppose that this is happening because the entity Payments has associations to other entities (Payments and PaymentOrders) having changelogs with the same entityID “displayId”:
Type : Association to one codelists.PaymentTypeCodes;
Direction : Association to one PaymentDirectionCodes;
displayId : String; //readable ID
Company : Association to one Companies;
BusinessPartner : Association to one BusinessPartners;
PaymentOrder : Association to one PaymentOrders;
Wallet : Association to one wallets.Wallets;
Transaction : Association to one wallets.Transactions;
cryptoAmount : Decimal;
CryptoAmountCurrency : Association to one Cryptocurrencies;

@changelog
fiatAmount               : Decimal; //Call reuse service to round due to allowed number of digits wherever necessary
FiatAmountCurrency       : Association to one FiatCurrencies;

@changelog
paymentExecutionDateTime : DateTime; //TimeStamp is not used here because we do not need 0,1 microsecond precision (sec precision is enough)

@title    : '{i18n>Status}'
@changelog: [LifecycleStatus.code]
LifecycleStatus          : Association to one codelists.PaymentLifecycleStatusCodes;

Fee                      : Association to one Payments;

Am I right? Does not it work when one entity is associated with another one with the same changelog Entity ID? How should we define ObjectID in this case?

One more question: if we are showing an amount in the change log, how can we add currency to it? Is it possible? I mean not just showing “5.5” but “5.5 USD”.

I am attaching an example from UI.

ChangeLog

Thank you and kind regards,
Elena Gurevitch

How to hide change history?

Hi colleagues,

we have two object pages in the same UI service annotation (app\payment\businessTransactions\annotations.cds) : one is used to show an existng business transaction. another to create or edit a draft business transaction. These are even different apps but they are built on the same UI service.

Non-draft

Draft

We would like to show Change History only for the non-draft view.

I saw that we could use

annotate sap.changelog.aspect @(UI.Facets: [{
$Type : 'UI.ReferenceFacet',
ID : 'ChangeHistoryFacet',
Label : '{i18n>ChangeHistory}',
Target: 'changes/@UI.PresentationVariant',
![@UI.PartOfPreview],
}]);

to make the change history to be shown at once.

Can we somehow use it to define visibility? I saw that UI.Hidden could be also defined here. But how can I provide the condition whether we are dealing with a draft? "IsActiveEntity" path is not valid .

I even tried to describe 'ChangeHistoryFacet' together with appplication facets - there "IsActiveEntity" path is known - but it did not have any affect.

Is there any possibility?

Kind regards,
Elena

Is it possible to change formatting of the changed fields?

Hello colleagues,

We defined changelog for decimal fields, for example

@changelog
cryptoAmount : Decimal;

If the values are very small they are shown like

Cryptocurrency Amount 4e-1

Is it possible to provide some formatting to be used (are there any exits to format the values) ? For example here we would prefer 0.4 because it is more user-friendly.

But I guess it is not possible.

And to combine an amount and a currency is also not possible, am I right?

I think the only way would be to have an additional string field where amount is formatted as desired but this is not good.

Kind regards,
Elena Gurevitch

In the unmanaged case, unmanipulated data also generates a changelog.

Hi,

Here's the situation in incidents-app:

Model:
image

Annotation:

annotate ProcessorService.Incidents with @changelog: [title] {
  conversation @changelog: [conversation.message];
}

As we know, conversation is a inline composition of child entity, This is an unmanaged case. If we want to enable managed for inline composition of child entity, It can be set up as shown below:
image

Above is the background information, then the problem is in the following figure, when we go to an incident page, we will find that there is already a current conversation, so we create a new conversation:
image

And click 'Save' button, you can see that the change history generates two changelogs, but we see that there is an additional changelog generated, which we don't need because we haven't done anything with the original conversation:
image

When we enable aspect managed, generate changelog normally:
image

The reason is:

In req.diff(), the data is logged regardless of whether that data has been manipulated or not, so for the managed case, change-tracking will have a place for logic to filter out data that hasn't been manipulated, because for change-tracking, if it hasn't been manipulated, it shouldn't be logged:

https://github.com/cap-js/change-tracking/blob/main/lib/change-log.js#L189

  // Since req.diff() will record the managed data, change history will filter those logs only be changed managed data
  const managedAttrs = ["modifiedAt", "modifiedBy"]
  if (curChange.modification === "update") {
    const rowOldAttrs = Object.keys(childNodeChange._old)
    const diffAttrs = rowOldAttrs.filter((attr) => managedAttrs.indexOf(attr) === -1)
    if (!diffAttrs.length) {
      return
    }
  }

But for the unmanaged case, the unmanipulated data has no _op in req.diff(), so by the time we get to the logic above, the value of curChange.modification is undefined, so it skips the filtering and is added directly to the changelog, so here's the solution:
image

If you have time, please take a look at this scenario.

Best Regards,
Wenjun

Change Tracking not working for Locale aspects

Hello Team,

We are using a string field localized aspect to store descriptions in multiple languages. We have noticed that this scenario is not supported by change-tracking.

Kindly let us know if there is a roadmap to support this.

CDS Definition

@assert.unique: {businessKey: [name]}
entity PreDefinedText : cuid, managed {
  name : String;
  description : localized String;

Change tracking annotation:

annotate PreDefinedText.PreDefinedText with @title: 'PreDefinedText'{
    name        @changelog ;
    texts       @Changelog: [texts.description] @Common.Label: '{i18n>texts}';
}

Fiori App Screenshot:
We are changing the description. However, the values are not tracked.
image

Best Regards,
Rahul

Performance Issues with draftActivate

We encountered severe performance issues when activating a draft with sub entities, because of change-tracking plugin.

If a composite object with multiple sub entity instances is activated, each instance is read one by one from the database. See https://github.com/cap-js/change-tracking/blob/main/lib/entity-helper.js#L34
This leads to drastic performance issues in case there are a lot of sub entity instances. We encountered this, because a customer created 1000 sub entity instances and it took around a minute to activate the composite. Without having change-tracking plugin enabled it takes a fraction of a second.

I expect that db requests are reduced as much as possible and instances of one entity are read all together instead of a single instance basis.

@cap-js/change-tracking How to remove Change Log table from child entities object page

Hi,

we added this package in our solution and its working fine but we are facing issues that all child entities (Compositions) object page also start showing this change log table but there is no data shown specifically for that child entities and all change logs is being shown in the root level entity (which is fine to show in root entity).

But how to remove this table from the child entities or how to show data only for that child entities?

Issue with numeric key format

Hello,

I have activated change tracking with below version:
"@cap-js/change-tracking": "^1.0.5",

And when activating the change tracking on an entity with numeric key I get following error during save.
The key of entity has integer64 format but the expected format should be a string in sap_changelog_ChangeLog.

[cds] - Error: Cannot set parameter at row: 1. Argument must be a string at next (/home/user/projects/MyWB/node_modules/hdb/lib/protocol/ExecuteTask.js:175:19) at ExecuteTask.getParameters (/home/user/projects/MyWB/node_modules/hdb/lib/protocol/ExecuteTask.js:189:3) at ExecuteTask.sendExecute (/home/user/projects/MyWB/node_modules/hdb/lib/protocol/ExecuteTask.js:196:8) at execute (/home/user/projects/MyWB/node_modules/hdb/lib/protocol/ExecuteTask.js:73:10) at ExecuteTask.run (/home/user/projects/MyWB/node_modules/hdb/lib/protocol/ExecuteTask.js:115:3) at run (/home/user/projects/MyWB/node_modules/hdb/lib/util/Queue.js:96:12) at next (/home/user/projects/MyWB/node_modules/hdb/lib/util/Queue.js:85:7) at receive (/home/user/projects/MyWB/node_modules/hdb/lib/util/Queue.js:114:5) at Connection.receive (/home/user/projects/MyWB/node_modules/hdb/lib/protocol/Connection.js:385:3) at TLSSocket.ondata (/home/user/projects/MyWB/node_modules/hdb/lib/protocol/Connection.js:243:12) { query: 'INSERT INTO sap_changelog_ChangeLog ( entity, entityKey, serviceEntity, createdAt, createdBy, modifiedAt, modifiedBy, ID ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )', values: [ [ 'my.db.Worklist', 110026,

Is there a possible correction or a workaround?

Thank you

Change tracking will capture the wrong objectID in some special cases.

Hello,

When I was debugging change tracking, I found that in the following modeling and annotation, certain special cases resulted in capturing the wrong objectID:
image
image

Because in modeling, Buildings entity has a name field, and the ObjectID annotation also needs to capture the name field of the final entity from goods.goods.goods.name. In fact, the two name fields represent different content.

When we set the value 'test buildings' to the name of the Buildings entity in our app, and Goods is empty, the ObjectID we expect is only: 'test buildings', because all the other values are empty. But in this case, because Buildings have a field called name, and path: 'goods.goods.goods.name' ends up with a field called name, the ObjectID will be: 'test buildings, test buildings'. You can see that we now have the wrong ObjectID.
image
image

And here's the problem:
https://github.com/cap-js/change-tracking/blob/main/lib/entity-helper.js#L99

This is my solution:
image

If you have time, please take a look at this scenario.

Best Regards,
Wenjun

@cap-js/change-tracking: change logs are not captured

Changing "@sap/cds": "6.5.0" to "@sap/cds": "7.5.2".
Before the cds upgrade we used @sap/cap-change-history.
With cds > 7 we thrive for @cap-js/change-tracking instead.

I was able to configure and run everything written for the incidents-app here . However, when applying the exact same steps within our project, I do not see Change History facet automatically added to the Fiori Object Page of my annotated entity. Thus, no changeLog is captured at all.

In the following pictures you will see proper entity level annotations and missing facet over the respective object page:
image

image

Changelog for Entities containing associations as key

Hello Team,

currently we are facing an issue using the change log on entities which have associations as keys defined.
Some cases are even more complex, but real world scenarios.

We have one entity called MatrixCertificates which connects the keys of devisions with document types and adds a property called 'relevant'. Divisions are stored within the same project. Document types are not, they are part of a different micro-service in a different cap project according to our designed micro service architecture.

Please find below CDS model:

@cds.persistence.journal
entity Divisions : CodeList {
  key division : String(20);
}

@readonly
entity DocumentTypes as projection on Doc.DocumentTypes;

entity MatrixCertificates {
  @assert.integrity: false key division     : Association to one Divisions;
  @assert.integrity: false key documentType : Association to one DocumentTypes;
                               relevant     : String(1) enum {
                                 a;
                                 b;
                                 c;
                               }
}

We would like to use change-log annotations like this:

@changelog
@cds.persistence.journal
entity Divisions : CodeList {
  key division : String(20);
}

@readonly
entity DocumentTypes as projection on Doc.DocumentTypes;

@changelog
entity MatrixCertificates {
  @assert.integrity: false key division     : Association to one Divisions @changelog;
  @assert.integrity: false key documentType : Association to one DocumentTypes @changelog;
                               relevant     : String(1) enum {
                                 a;
                                 b;
                                 c;
                               };
}

Issue is, that at startup of the service following error occurs:
image

Are you aware about this behaviour? Is it foreseen to be fixed?

Thanks and best regards
Sandro

A field of type "Date" cannot be used for change tracking

Hi colleagues,

If we are declaring a field in a CDS entity to be saved in the Changelog and this field has Data type:

@changelog
dueDate : Date;

then it causes an error during saving the changes. What happens:

**const _formatCompositionContext = async function (changes, reqData) {
const childNodeChanges = []

for (const change of changes) {
if (typeof change.valueChangedTo === "object") {**

In node_modules@cap-js\change-tracking\lib\change-log.js type of this field is considered to be an object (valueChangedTo is shown as “Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)”; valueDataType is "cds.Date") and is coverted to an Array:

if (!Array.isArray(change.valueChangedTo)) {
change.valueChangedTo = [change.valueChangedTo]
}

Then an attempt is done:
for (const childNodeChange of change.valueChangedTo) {
const curChange = Object.assign({}, change)
const path = childNodeChange._path.split('/')

However childNodeChange is a string, not a real object, and does not have any path. So it dumps.

Could you please check why cds,Date is considered to be an object? May be it is concerning also other types?

Kind regards,
Elena Gurevitch

CDS Compilation fails on mbt build when change-tracking is included

More details of the initial problem are to be found here: cap-issue-15399.

However, I was able to isolate the problem a bit further in the following branch: chore-change-tracking/working-cds-build.

Steps to reproduce:
git clone https://github.tools.sap/customer-data-hub/cockpit.git
git fetch
git checkout chore-change-tracking/working-cds-build
npm i -g typescript ts-node
npm i -g @sap/cds-dk
npm i
npm i --prefix approuter

mbt build

As a result npm run build phase passes successfully when no change-tracking is involved:
image

With slightest change, e.g. including change tracking within package.json and uncommenting the contents of db/ext-changes.cds:
image

image

CDS compilation fails. Complete log is to be found here: failing_logs.txt

Change logs not captured on composition level

As continuation of #64

On the calesi/incidents-app, with the following code changes:

image

I am able to achieve the following:
image

In other words, the end user is aware that changes are made for the composition "Conversation".

When I try to achieve the same thing within our project:
image

It is not the case. You cannot see any change made on the composition.
If i directly annotate the entity the composition points to, e.g.
image

And run the project as described here https://github.tools.sap/cap/issues/issues/15214

When I navigate to
image

And modify the customerTenantAssignment through the value help:

image

I get a log that tenant_id is logged
image

But this information is scarce and I do not see from which composition the change is coming from.
How can I overcome that?

Adding the facet manually

Hello,

We have our app with annotations etc. change-tracking is not added to the view automatically.
Can it be added explicitly?

BR,
Jacek

Change tracking not showing

Hi Team,
We have managebusinesspartners/webapp/index.html application which when edited, the change tracking disappears and we can see no data in the change history , on commenting out the specified annotation for to show the 'show more' in change history.
The annotation in the change tracking file:

annotate sap.changelog.aspect @(UI.Facets: [{ $Type : 'UI.ReferenceFacet', ID : 'ChangeHistoryFacet', Label : '{i18n>ChangeHistory}', Target: 'changes/@UI.PresentationVariant', ![@UI.PartOfPreview], }]);
Could you please look into the above.

Regards,
Nandini

Save fails on HANA when tracking is enabled for Boolean fields

Hi,

I get the following exception when I enabled change tracking for a Boolean field when using HANA db.

[cds] - Error: Cannot set parameter at row: 1. Argument must be a string
    at next (/home/user/projects/testApp/node_modules/hdb/lib/protocol/ExecuteTask.js:175:19)
    at ExecuteTask.getParameters (/home/user/projects/testApp/node_modules/hdb/lib/protocol/ExecuteTask.js:189:3)
    at ExecuteTask.sendExecute (/home/user/projects/testApp/node_modules/hdb/lib/protocol/ExecuteTask.js:196:8)
    at execute (/home/user/projects/testApp/node_modules/hdb/lib/protocol/ExecuteTask.js:73:10)
    at ExecuteTask.run (/home/user/projects/testApp/node_modules/hdb/lib/protocol/ExecuteTask.js:115:3)
    at run (/home/user/projects/testApp/node_modules/hdb/lib/util/Queue.js:97:12)
    at next (/home/user/projects/testApp/node_modules/hdb/lib/util/Queue.js:86:7)
    at done (/home/user/projects/testApp/node_modules/hdb/lib/protocol/ExecuteTask.js:53:5)
    at finalize (/home/user/projects/testApp/node_modules/hdb/lib/protocol/ExecuteTask.js:58:14)
    at execute (/home/user/projects/testApp/node_modules/hdb/lib/protocol/ExecuteTask.js:71:14) {
  query: 'INSERT INTO sap_changelog_Changes ( serviceEntityPath, entity, serviceEntity, attribute, valueChangedFrom, valueChangedTo, valueDataType, modification, keys, entityID, parentEntityID, parentKey, changeLog_ID, ID ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )',
  values: [
    [
      'my.Books(301)',
      'my.Books',
      'CatalogService.Books',
      'yesOrNo',
      '',
      true,
      'cds.Boolean',
      'update',
      'ID=301',
      '',
      '',
      '',
      '4eff86ee-c60f-4031-a64d-ef45db9f9aac',
      '08d9d030-46cb-433e-ac44-1ad660762bfc'
    ]
  ],
  numericSeverity: 4,
  id: '1989256',
  level: 'ERROR',
  timestamp: 1700054785696
}

Potential solution:
Please refer here. Values of to and from are not ensured to be string. This is fine for sqlite. But Hana is not so forgiving.

Regards,
Dinu

Error Message with CDS 7 / lean_draft:false and change-tracking Plugin

Dear team,

We have installed the plugin (https://github.com/cap-js/change-tracking) in our project and are using the latest version of CDS 7. Although we are using the current CDS 7 version, we are still using the old draft mode for our entities. This is currently supported by the attribute ("lean_draft": false).

The combination of CDS 7 / lean_draft:false and the plugin leads to problems. The error is located in the CDS 7 standard code, as shown in the screenshot attached to this note. The error message and the content of the object are also detailed in the screenshot.

Issue:
Error message when using CDS 7 / lean_draft:false with the change-tracking plugin

Cause:
Incompatibility between the plugin and CDS 7 standard code when using lean_draft:false

Steps to Reproduce:
Install the change-tracking plugin (https://github.com/cap-js/change-tracking)
Set "lean_draft": false in your CDS entity definitions
Create or update an entity
Observe the error message in the console
Expected Behavior:
The plugin should work seamlessly with CDS 7 / lean_draft:false
Actual Behavior:
An error message is displayed in the console

Screenshot:
Attached screenshot showing the error message and the content of the object
code

Additional Information:
Link to the GitHub repository of the change-tracking plugin (https://github.com/cap-js/change-tracking)

Request:
Please provide a solution for this issue.
Thank you for your time and support.

Sincerely

Object ID is filled as Object Type

Hi colleagues,

We declared changelog with object ID:

@title : '{i18n>BusinessPartner}'
@changelog.objectID: [
displayId,
name
]
entity BusinessPartners : cuid, managed, SourceReferences, Usage {
@title : '{i18n>ID}'
@changelog
displayId : String; //readable ID

@changelog
name                                 : String;

@mandatory  @changelog: [BusinessPartnerRoleCodes.name]
Role                                 : Association to one BusinessPartnerRoleCodes;

@title    : '{i18n>ContactPerson}'
@changelog
contactPersonFormattedName           : String;

@title    : '{i18n>Email}'
@changelog
contactPersonEmail                   : String;

@title    : '{i18n>Phone}'
@changelog
contactPersonTelephoneNumber         : String;
OutgoingPaymentAgreements            : Composition of many PaymentAgreementsOutgoing
                                           on OutgoingPaymentAgreements.Parent = $self;
IncomingPaymentAgreements            : Composition of many PaymentAgreementsIncoming
                                           on IncomingPaymentAgreements.Parent = $self;

//    Changes                              : Association to many ChangeView
//on Changes.entityKey = ID;

@changelog: [Countries.name]
@title    : '{i18n>Country}' Country : Association to one Countries;

}

With the old plugin change-history Object ID in the ChangeView was shown as defined (for example "BP_1, BP_1_name").

Now, with the new plugin, it is shown with the sane content as the column Object Type.

Is the definition of Object ID wrong?

Kind regards,
Elena Gurevitch

Change History

"Update" change logs are not created in the main test system

Hi colleagues,

We are working on the project https://github.tools.sap/erp4sme/crypto-for-business.

Some time ago we have discussed missing possibility to add changelog changes for an entity that is being processed not from a service (for example, UI service) but is inserted or updated directly on DB.

Meanwhile this issue was solved: we created Wrapper-Services for the involved entities and this solved even the second issue where a view was defined as a union of three different entities and we were not sure how to define change tracking for this.

It looks like (srv\payment\wrapper\wrapper-service.cds):

service PaymentWrapperService @(requires: 'system-user') {
entity Payments as projection on db.payments.Payments;
entity Payables as projection on db.payables.Payables;
entity PaymentOrders as projection on db.paymentOrders.PaymentOrders;
entity Receivables as projection on db.receivables.Receivables;
entity BusinessTransactions as projection on db.businessTransactions.BusinessTransactions;
}

BusinessTransactions is the mentioned view which is a union of Payments, Receivables and Payables.

Now all our DB operations relevant for change-tracking are defined via this service, for example

UPDATE.entity(WrapperService.Entity.Payments).where({ ID: paymentToUpdate.ID }).with(paymentToUpdate);

This works; the changes for all involved entities are written back and shown in the app “business Transactions” based on an UI service defined on the entityBusinessTransactions.

However there is one strange thing.

For creating the entities change logs are written both if you test locally or in the main test system https://c4b-main02-subscriber-1.c4b-main02.dev01.eu.canary.clusters.cs.services.sap/.
However these entities can be also updated. This is happening not from UI but from an Event Handler reacting on some events. For example if a Transfer Order which was created for a Payment becomes completed then the corresponding Payment gets status “Completed” as well. The event is thrown during a job run. Updating the Payment is fulfilled via WrapperService in lib\payment\payments\DbPaymentRepository.ts.

Now if I am testing this event processing locally then I see that the changes with modification = “update” are inserted into CHANGELOG and CHANGES. Unfortunately I cannot execute the mentioned job (it is running only in MAIN system). But I tested this from a unit test firing the same event and the update changes were created.

When the job is running in MAIN and payments are updated with the new status “Completed” it is however not reflected in CHANGELOG and CHANGES.

Do you have any idea what can be the difference? We supposed that this was due to the job execution. But we have other events which are creating new instances of Payment – and this works; the “create” changes are created.

What in MAIN environment could inhibit creating “update” change logs?

Kind regards,
Elena Gurevich

ChangeLog.ID shown in Filter and Sort of View Settings

Hi Team,

please check the attached screenshot. Technical field name ChangeLog.ID is shown for Filter and Sort of View Settings. I assume that should be either hidden or a readable label should be added.

Cheers, Giovanni
ChangeLogID

How to handle the visibility of Change History Section?

Hi Team, Can we handle the visibility of the Change History Section based on the user role?
I tried the Show Page Map feature of SAP Fiori Element, but the section is not visible (I guess because the section is created at the runtime). Is there any other way?

Please suggest.

Change Log for a CDS view

Hello colleagues!

We are working on this project.

We want to show change log for an entity which is not persisted as a table but is a view representing a union of several selects from DB tables.

This view is declared in db\payment\businessTransactions\BusinessTransactions.cds.

UI Service view is defined in srv\payment\businessTransactions\ui-service-businesstransactions.cds.

I tried to define change log in BusinessTransactions.cds as following declaring the corresponding field in each select for the change log (However it does not work):

**@changelog.objectID: [
    displayId,
    Type.code
]**
entity BusinessTransactions          as(
    select from payment.payments.Payments {
        key ID,
            Usage,
            createdAt,
            createdBy,
            modifiedAt,
            modifiedBy,
            Type.code            as Type_code,
            Direction.code       as Direction_code,
            displayId,
            Company,
            BusinessPartner,
            PaymentOrder,
            Wallet,
            Transaction,
            cryptoAmount,
            CryptoAmountCurrency,
            fiatAmount,
            FiatAmountCurrency,
            paymentExecutionDateTime,
            **@changelog**
            LifecycleStatus.code as LifecycleStatus_code,
            case
                when
                    LifecycleStatus.code    = 'IN_PROCESS'
                    or LifecycleStatus.code = 'ERRONEOUS'
                then
                    'OPEN'
                when
                    LifecycleStatus.code    = 'COMPLETED'
                    or LifecycleStatus.code = 'COMPLETED_N_MATCHED'
                    or LifecycleStatus.code = 'CANCELED'
                then
                    'COMPLETED'
                else
                    null
            end                  as completeness           : String,

            case
                when
                    (
                        Transaction.ID    =  ''
                        or Transaction.ID is null
                    )
                then
                    PaymentOrder.ID
                else
                    Transaction.ID
            end                  as transactionReferenceId : String,
            Fee,
            null                 as externalId             : String,
            null                 as documentDate           : Date,
            null                 as dueDate                : Date,
            Type                                           : Association to one codelists.BusinessTransactionTypeCodes on Type.code = Type_code,
            LifecycleStatus                                : Association to one codelists.BusinessTransactionLifecycleStatusCodes on LifecycleStatus.code = LifecycleStatus_code,
            Network,
            Account,
            Account.name         as AccountName,
            ExchangeRate,
            PaymentAgreementOutgoing,
            PaymentAgreementIncoming,

    }
)
union all
(
    select from payment.payables.Payables {
        key ID,
            Usage,
            createdAt,
            createdBy,
            modifiedAt,
            modifiedBy,
            'FOREC_OUTG_PAYMENT' as Type_code,
            'OUTGOING'           as Direction_code,
            displayId,
            Company,
            BusinessPartner,
            null                 as PaymentOrder,
            null                 as Wallet,
            null                 as Transaction,
            cryptoAmount,
            CryptoAmountCurrency,
            fiatAmount,
            FiatAmountCurrency,
            null                 as paymentExecutionDateTime,
            **@changelog**
            case
                when
                    LifecycleStatus.code    = 'OPEN'
                    or LifecycleStatus.code = 'SCHEDULED'
                then
                    'OPEN'
                else
                    LifecycleStatus.code
            end                  as LifecycleStatus_code,
            case
                when
                    LifecycleStatus.code    = 'OPEN'
                    or LifecycleStatus.code = 'SCHEDULED'
                    or LifecycleStatus.code = 'PARTIALLY_PAID'
                then
                    'OPEN'
                else
                    null
            end                  as completeness           : String,
            null                 as transactionReferenceId,
            null                 as Fee,
            externalId,
            documentDate,
            dueDate,
            Type                                           : Association to one codelists.BusinessTransactionTypeCodes on Type.code = Type_code,
            LifecycleStatus                                : Association to one codelists.BusinessTransactionLifecycleStatusCodes on LifecycleStatus.code = LifecycleStatus_code,
            Network,
            Account,
            Account.name         as AccountName,
            ExchangeRate,
            PaymentAgreementOutgoing,
            null                 as PaymentAgreementIncoming,
    }
)
union all
(
    select from payment.receivables.Receivables {
        key ID,
            Usage,
            createdAt,
            createdBy,
            modifiedAt,
            modifiedBy,
            'FOREC_INC_PAYMENT'  as Type_code,
            'INCOMING'           as Direction_code,
            displayId,
            Company,
            BusinessPartner,
            null                 as PaymentOrder,
            null                 as Wallet,
            null                 as Transaction,
            cryptoAmount,
            CryptoAmountCurrency,
            fiatAmount,
            FiatAmountCurrency,
            null                 as paymentExecutionDateTime,
            **@changelog**
            LifecycleStatus.code as LifecycleStatus_code,
            case
                when
                    LifecycleStatus.code    = 'OPEN'
                    or LifecycleStatus.code = 'PARTIALLY_PAID'
                then
                    'OPEN'
                else
                    null
            end                  as completeness           : String,
            null                 as transactionReferenceId,
            null                 as Fee,
            externalId,
            documentDate,
            dueDate,
            Type                                           : Association to one codelists.BusinessTransactionTypeCodes on Type.code = Type_code,
            LifecycleStatus                                : Association to one codelists.BusinessTransactionLifecycleStatusCodes on LifecycleStatus.code = LifecycleStatus_code,
            Network,
            Account,
            Account.name         as AccountName,
            ExchangeRate,
            null                 as PaymentAgreementOutgoing,
            PaymentAgreementIncoming,
    }
);

I tried to define change log for every selected entity as well but this does not work as well.

Could you please advise how we can track change history for such an entity?

I am working in this branch.

Thank you and kind regards,
Elena

How to disable Change History for some UI service annotation

Hi colleagues,

This question is similar to my previous ticket #75 but nevertheless another one.

If Change History is declared for some entity then the tab "Change History" seems to appear on any object page which is dealing with this entity - for different UI services and apps.

This is very generic and of course comfortable (the application itself must not define anything - no any association to changes, no any facet etc.). But nevertheless sometimes it is not desired to show the change history on a certain screen or in a certain view.

Is there any possibility to disable Change History within one UI service annotation? If I set the aspect for ChangeHistoryFacet and set it to "hidden" then Change History disappears for all apps, not only for mine and not only for those dealing with the same entity.

Change History is somehow too generic and too global. It would be great to have a possibility to handle it for different apps and views individually.

Kind regards,
Elena

App reports Error when change tracking enabled for Entities with a key field not named ID

I generated a sample application using cds add samples.
I renamed the field ID of Books to BookID in db/schema.cds and updated test data too.

entity Books : managed {
  key BookID : Integer;
  @mandatory title  : localized String(111);
  descr  : localized String(1111);
  @mandatory author : Association to Authors;
  genre  : Association to Genres;
  stock  : Integer;
  price  : Decimal;
  currency : Currency;
  image : LargeBinary @Core.MediaType : 'image/png';
}

I enabled change tracking for the entity Books of AdminService with annotations:

annotate AdminService.Books with @changelog : [BookID] {
	title @changelog;
	descr @changelog;	
	price @changelog;
	currency @changelog;	
	stock @changelog;
}

Now when I try to change the title of Book with title "Catweazle" using fiori preview for Books entity, the application reports error.: Error: "ID" not found in the elements of "AdminService.Books"

I see in the console the following error.

odata] - POST /odata/v4/admin/$batch 
[odata] - > PATCH Books(BookID=271,IsActiveEntity=false) 
[odata] - > draftPrepare Books(BookID=271,IsActiveEntity=false)/AdminService.draftPrepare 
[odata] - > draftActivate Books(BookID=271,IsActiveEntity=false)/AdminService.draftActivate {
  '$select': 'BookID,HasActiveEntity,HasDraftEntity,IsActiveEntity,author_AuthorID,createdAt,createdBy,currency_code,descr,genre_code,modifiedAt,modifiedBy,price,stock,title',
  '$expand': 'DraftAdministrativeData($select=DraftIsCreatedByMe,DraftUUID,InProcessByUser),author($select=ID,name),genre($select=ID,name)'
}
[cds] - Error: "ID" not found in the elements of "AdminService.Books"
    at stepNotFoundInCombinedElements (D:\book-shop\node_modules\@cap-js\db-service\lib\infer\index.js:807:15)
    at D:\book-shop\node_modules\@cap-js\db-service\lib\infer\index.js:543:13
    at Array.forEach (<anonymous>)
    at inferQueryElement (D:\book-shop\node_modules\@cap-js\db-service\lib\infer\index.js:489:18)
    at processToken (D:\book-shop\node_modules\@cap-js\db-service\lib\infer\index.js:371:11)
    at Array.forEach (<anonymous>)
    at walkTokenStream (D:\book-shop\node_modules\@cap-js\db-service\lib\infer\index.js:375:19)
    at inferQueryElements (D:\book-shop\node_modules\@cap-js\db-service\lib\infer\index.js:344:16)
    at infer (D:\book-shop\node_modules\@cap-js\db-service\lib\infer\index.js:69:22)
    at cqn4sql (D:\book-shop\node_modules\@cap-js\db-service\lib\cqn4sql.js:47:20) {
  id: '1344032',
  level: 'ERROR',
  timestamp: 1701262020937
}

There were no issues before I renamed the field.

Change history/tracking does not work on multiple records

Hi Team,

I am trying to post the data via CQL after enabling change tracking for the service and connecting to it.
const srv = await cds.connect.to("MasterDataMapService");
const masterEntity = srv.entities[entity];
const insertResult = await INSERT.into(masterEntity).entries(aInsertData);

Above Insert Query shows the change tracking only if I insert one record into it, otherwise it does not show any change tracking.
Can you please check on this?

Change tracking annotation file source code:
using { MasterDataMapService } from './masterdatamap-service';
using from '@cap-js/change-tracking';

annotate MasterDataMapService.TaxCodeMap with @title: 'Tax Code' @changelog: [author, timestamp]{
companyCode @changelog;
sourceTaxCode @changelog;
targetTaxCode @changelog;

}
annotate sap.changelog.aspect @(UI.Facets: [{
$Type : 'UI.ReferenceFacet',
ID : 'ChangeHistoryFacet',
Label : '{i18n>ChangeHistory}',
Target: 'changes/@UI.PresentationVariant',
![@UI.PartOfPreview]
}]);

annotate sap.changelog.ChangeView with @(
UI.LineItem : [
{ Value: modification, @HTML5.CssDefaults: { width: 'auto' }},
{ Value: createdAt, @HTML5.CssDefaults: { width: 'auto' }},
{ Value: createdBy, @HTML5.CssDefaults: { width:'auto' }},
{ Value : attribute, @HTML5.CssDefaults: { width:'auto' }},
{ Value : valueChangedFrom, @HTML5.CssDefaults: { width:'auto' }},
{ Value : valueChangedTo, @HTML5.CssDefaults: { width:'auto' }},

]
);

Regards,
Vishal Kwatra

Change tracking not working in Multi-tenant CAP Nodejs Project

I am trying to add the plugin @cap-js/change-tracking to store change logs for an Entity in my CAP Nodejs multi tenant Project.

I have followed the guide to implement this Change Tracking Plugin for SAP Cloud Application Programming Model (CAP).

I have added the @changelog annotations to an entity for which I am trying to track changes. This brings the facet in the fiori elements object page. And when I trying to edit a record and save it from the app I am getting below error:

no such table: sap_changelog_ChangeLog in: INSERT INTO sap_changelog_ChangeLog

Below is how I have added the annotation to my service entity in file app/managebooks/annotations.cds :

annotate service.Books with {
title @changelog;
};

It needs the table sap_changelog_ChangeLog to persist the change log entries but just by adding the module in package.json and adding annotation to properties is not generating the table while doing local testing with sqlite. Please let me know if there are some steps missed here.

Thanks & Regards,
Vishal Sharma

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.