Skip to content
SAP Full-Stack CAP app BTP environment
 https://developers.sap.com/group.cap-application-full-stack.html
https://developers.sap.com/group.deploy-full-stack-cap-application.html
 
https://developers.sap.com/group.fiori-tools-odata-v4-incident.html
 

1. Creare a CAP Project

cd projects
cds init incident-management
open folder /home/user/projects/incident-management
 
2. Add data model schema.cds under /db
 
Example:
using { cuid, managed, sap.common.CodeList } from ‘@sap/cds/common’;
namespace sap.capire.incidents; 
 
/**
* Incidents created by Customers.
*/
entity Incidents : cuid, managed {  
customer     : Association to Customers;
title        : String  @title : ‘Title’;
urgency        : Association to Urgency default ‘M’;
status         : Association to Status default ‘N’;
conversation  : Composition of many {
    key ID    : UUID;
    timestamp : type of managed:createdAt;
    author    : type of managed:createdBy;
    message   : String;
};
}
 
/**
* Customers entitled to create support Incidents.
*/
entity Customers : managed { 
key ID        : String;
firstName     : String;
lastName      : String;
name          : String = firstName ||’ ‘|| lastName;
email         : EMailAddress;
phone         : PhoneNumber;
incidents     : Association to many Incidents on incidents.customer = $self;
creditCardNo  : String(16) @assert.format: ‘^[1-9]\d{15}$’;
addresses     : Composition of many Addresses on addresses.customer = $self;
}
 
entity Addresses : cuid, managed {
customer      : Association to Customers;
city          : String;
postCode      : String;
streetAddress : String;
}
 
entity Status : CodeList {
key code: String enum {
    new = ‘N’;
    assigned = ‘A’; 
    in_process = ‘I’; 
    on_hold = ‘H’; 
    resolved = ‘R’; 
    closed = ‘C’; 
};
criticality : Integer;
}
 
entity Urgency : CodeList {
key code: String enum {
    high = ‘H’;
    medium = ‘M’; 
    low = ‘L’; 
};
}
 
type EMailAddress : String;
type PhoneNumber : String;
 
3.  Define the service services.cds under /srv
 
Example:
using { sap.capire.incidents as my } from ‘../db/schema’;
 
/**
 * Service used by support personell, i.e. the incidents’ ‘processors’.
 */
service ProcessorService { 
    entity Incidents as projection on my.Incidents;
 
    @readonly
    entity Customers as projection on my.Customers;
}
annotate ProcessorService.Incidents with @odata.draft.enabled;
 
/**
 * Service used by administrators to manage customers and incidents.
 */
service AdminService {
    entity Customers as projection on my.Customers;
    entity Incidents as projection on my.Incidents;
    }
 
4. Add initial data
 
cds add data
 
db/data/sap-capire.incidents-Adresses.csv
 
ID,customer_ID,city,postCode,streetAddress
17e00347-dc7e-4ca9-9c5d-06ccef69f064,1004155,Rome,00164,Piazza Adriana
d8e797d9-6507-4aaa-b43f-5d2301df5135,1004161,Munich,80809,Olympia Park
ff13d2fa-e00f-4ee5-951c-3303f490777b,1004100,Walldorf,69190,Dietmar-Hopp-Allee
 
db/data/sap-capire.incidents-Customers.csv
 
ID,firstName,lastName,email,phone
1004155,Daniel,Watts,daniel.watts@demo.com,+39-555-123
1004161,Stormy,Weathers,stormy.weathers@demo.com,+49-020-022
1004100,Sunny,Sunshine,sunny.sunshine@demo.com,+49-555-789
 
db/data/sap-capire.incidents-Incidents.csv
 
ID,customer_ID,title,urgency_code,status_code
3b23bb4b-4ac7-4a24-ac02-aa10cabd842c,1004155,Inverter not functional,H,C
3a4ede72-244a-4f5f-8efa-b17e032d01ee,1004161,No current on a sunny day,H,N
3ccf474c-3881-44b7-99fb-59a2a4668418,1004161,Strange noise when switching off Inverter,M,N
3583f982-d7df-4aad-ab26-301d4a157cd7,1004100,Solar panel broken,H,I
 
db/data/sap-capire.incidents-Status.csv
 
code;descr;criticality
N;New;3
A;Assigned;2
I;In Process;2
H;On Hold;3
R;Resolved;2
C;Closed;4
 
db/data/sap-capire.incidents-Urgency.csv
code;descr
H;High
M;Medium
L;Low
 
 
5. Add custom logic
 
Create a file services.js under folder /srv
 
 const cds = require(‘@sap/cds’)
 
class ProcessorService extends cds.ApplicationService {
  /** Registering custom event handlers */
  init() {
    this.before(“UPDATE”, “Incidents”, (req) => this.onUpdate(req));
    this.before(“CREATE”, “Incidents”, (req) => this.changeUrgencyDueToSubject(req.data));
 
    return super.init();
  }
 
  changeUrgencyDueToSubject(data) {
    if (data) {
      const incidents = Array.isArray(data) ? data : [data];
      incidents.forEach((incident) => {
        if (incident.title?.toLowerCase().includes(“urgent”)) {
          incident.urgency = { code: “H”, descr: “High” };
        }
      });
    }
  }
 
  /** Custom Validation */
  async onUpdate (req) {
    const { status_code } = await SELECT.one(req.subject, i => i.status_code).where({ID: req.data.ID})
    if (status_code === ‘C’)
      return req.reject(`Can’t modify a closed incident`)
  }
}
module.exports = { ProcessorService }
 
6. Add Authorization
 
Specify restrictions, add lines to the srv/service.cds file
 
annotate  AdminService with  @(requires: ‘admin’);
annotate ProcessorService with @(requires: ‘support’);
 
Add user for local testing in package.json
 
“cds”: {
    “requires”: {
      “[development]”: {
        “auth”: {
          “kind”: “mocked”,
          “users”: {
            “admin”: {
              “password”: “initial”,
              “roles”: [“support”]
            },
            “alice”: {
              “roles”: [“support”]
            },
            “bob”: {
              “roles”: [“support”]
            }
          }
        }
      }
    }
 
https://cap.cloud.sap/docs/node.js/authentication
 
 
7. Add SAP HANA Cloud
 
cds add hana –for production
 
{
    “name”: “incident-management”,
    “dependencies”: {
        …
        “@cap-js/hana”: “^x”
    },
    …
    “cds”: {
        “requires”: {
            …
            “[production]”: {
                “db”: “hana”
            }
        },
        “sql”: {
          “native_hana_associations”: false
        }
    }
}
 
cds env requires -4 production
 
{
  middlewares: true,
  auth: { kind: ‘jwt’, vcap: { label: ‘xsuaa’ } },
  db: { impl: ‘@sap/cds/libx/_runtime/hana/Service.js’, kind: ‘hana’ }
}
 
cds add xsuaa –for production
 
{
  “name”: “incident-management”,
  “dependencies”: {
      …
      “@sap/xssec”: “^x”
  },
  …
  “cds”: {
    “requires”: {
      …
      “[production]”: {
        “db”: “hana”,
        “auth”: “xsuaa”
      }
    …
    }
  }
}
 
cds add html5-repo
 
{
  “name”: “incident-management”,
  “dependencies”: {
      …
  },
  …
  “cds”: {
    “requires”: {
      …
      “[production]”: {
        …
      },
      “html5-repo”: true
    }
  …
  }
}
 
npm install
 
cds build –production
[cds] – build completed in 511 ms