Compare commits

...

41 Commits

Author SHA1 Message Date
Christian Georgi
f28bfbb768 Update README.md 2020-04-20 17:12:04 +02:00
Christian Georgi
7d8ca4d4a1 Add package-lock.json, fix readme 2020-04-02 16:15:51 +02:00
Christian Georgi
61aa81a806 Update readme 2020-03-23 17:11:22 +01:00
D065023
e7c395671b rm other packages 2020-03-20 10:54:25 +01:00
Dr. David Kunz
cd245c4641 Update package.json 2020-02-11 11:50:15 +01:00
D065023
d081438a6a default 2020-01-29 15:22:26 +01:00
D065023
79c3a22224 rm amqp and req 2020-01-29 15:21:13 +01:00
D065023
9c30ad7584 package.json 2020-01-29 14:58:14 +01:00
D065023
c58bcf905f rm eventing 2020-01-29 14:51:42 +01:00
D065023
50ab059c13 comment 2020-01-29 14:46:31 +01:00
D065023
46960159d1 cleaner 2020-01-29 14:35:22 +01:00
D065023
02228e5a96 easier 2020-01-29 14:16:34 +01:00
D065023
d4793177fc rm 2020-01-29 14:13:42 +01:00
D065023
2787284aad blocked 2020-01-29 14:13:15 +01:00
D065023
61a318b250 fixed bug 2020-01-29 13:02:23 +01:00
D065023
6e42e5a173 address -> bupa 2020-01-29 12:59:59 +01:00
D065023
bf162c23cc cleaner 2020-01-29 09:55:21 +01:00
D065023
9b41615ac8 file-based not needed 2020-01-29 08:34:49 +01:00
D065023
29840afc0b data 2020-01-28 18:14:24 +01:00
D065023
fa880e2987 rm lock 2020-01-28 18:02:09 +01:00
D065023
90881558dc working 2020-01-28 18:01:53 +01:00
D065023
6d3e9a211a rm bug 2020-01-28 16:04:32 +01:00
D065023
e694fbaf13 messaging 2020-01-28 16:00:01 +01:00
D065023
43d0373d70 rm complexity 2020-01-28 15:21:46 +01:00
D065023
b632013b16 old way 2020-01-28 13:08:20 +01:00
D065023
a6deddf022 added postalcode 2020-01-28 10:41:14 +01:00
D065023
513bf9711f changed data 2020-01-28 10:40:15 +01:00
D065023
00c99c0e0b devdep 2020-01-28 10:27:23 +01:00
D065023
e042317f82 sync API 2020-01-28 09:07:23 +01:00
D065023
04ab69c48f imported 2020-01-28 08:32:37 +01:00
Daniel
c2d0fba1d8 Merge pull request #9 from SAP-samples/cleanup
removed total and netAmount
2019-11-22 17:13:03 +01:00
Daniel
345d7fa37b removed total and netAmount 2019-11-18 14:50:45 +01:00
Daniel
88c1aa0282 Delete .cdsrc.json 2019-11-06 16:31:52 +01:00
Heiko Witteborg
c4cd02dbe9 Merge pull request #7 from SAP-samples/samples-revisited
samples revisited after teched
2019-10-29 09:53:55 +01:00
Christian Georgi
b9269ad437 Fix postman collection 2019-10-25 17:18:09 +02:00
Christian Georgi
2783197f1c Fix typo in sample data 2019-10-25 17:01:00 +02:00
Christian Georgi
3238b8b045 Readme improved
Install instructions, more links
2019-10-25 16:52:50 +02:00
D065023
dcac8fe7d2 added .cdsrc.json 2019-10-25 09:49:34 +02:00
d049904
cc3aca29ef samples revisited after teched 2019-10-24 12:03:37 +02:00
indusankar89
baaa5ef7d7 github repo, license corrrection 2019-09-17 11:54:21 +05:30
Stephen Cherian
e657683322 Fix broken link 2019-09-07 18:31:17 +05:30
55 changed files with 8132 additions and 409 deletions

2
.npmrc
View File

@@ -1 +1 @@
package-lock=false @sap:registry=https://npm.sap.com

42
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,42 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "cds run",
"request": "launch",
"type": "node",
"runtimeExecutable": "npx",
"runtimeArgs": ["-n"],
"args": ["--", "cds", "run", "--with-mocks", "--in-memory?"], // the leading "--" arg ensures it works with as well as without debugging
"cwd": "${workspaceFolder}/packages/${input:service}",
"console": "integratedTerminal",
"serverReadyAction": {
"pattern": "server listening on (https?://\\S+|[0-9]+)",
"uriFormat": "http://localhost:%s",
"action": "openExternally"
},
"skipFiles": ["<node_internals>/**"]
}
],
"inputs": [
{
"type": "pickString",
"id": "service",
"description": "Which service do you want to start?",
"options": [
"bookshop",
"bookstore",
"media-server",
"office-supplies",
"orders-service",
"products-service",
"reviews-service",
"user-service"
],
"default": "bookstore"
}
]
}

7
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"files.exclude": {
"**/.gitignore": false,
"**/.git": false,
"**/.vscode": false
}
}

26
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "shell", "label": "cds run bookshop",
"command": "npx", "args": [ "cds", "watch", "packages/bookshop" ],
"presentation": { "group": "A" },
"problemMatcher": []
},
{
"type": "shell", "label": "cds run bookshop-enhanced",
"command": "npx", "args": [ "cds", "watch", "packages/bookshop-enhanced" ],
"presentation": { "group": "A" },
"problemMatcher": []
},
{
"type": "shell", "label": "cds run reviews-service",
"command": "npx", "args": [ "cds", "watch", "packages/reviews-service" ],
"options": {"env": { "PORT":"5005" }},
"presentation": { "group": "A" },
"problemMatcher": []
}
]
}

View File

@@ -1,58 +1,42 @@
# cloud-cap-samples # Welcome to SAP Cloud Application Programming model samples
This is a monorepository for sample projects on [SAP Cloud Application Programming Model](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/00823f91779d4d42aa29a498e0535cdf.html?q=cloud%20application%20programming%20model). Find here the samples for the openSAP course [Building Applications with the SAP Cloud Application Programming Model](https://open.sap.com/courses/cp7).
## Description ## Get Access to SAP Business Application Studio
The recommended environment for the course is SAP Business Application Studio. Watch [unit 2 of week 1](https://open.sap.com/courses/cp7/items/51pzQUzbXHr2kdbOmVs6jI) for how to get access.
This repository provides a list of samples and reusable packages created based on SAP Cloud Application Programming Model. ## Setup
The SAP Cloud Application Programming Model enables you to quickly create business applications by allowing you to focus on your domain logic. It offers a consistent end-to-end programming model that includes languages, libraries and APIs tailored for full-stack development on SAP Cloud Platform.
The samples provided can be run in a local setup on SQLite Database. In SAP Business Application Studio, open a terminal.
Then clone the repo with this specific branch:
#### Samples: ```sh
* [bookstore](./packages/bookstore) - A variant of the bookshop application, built in a modular fashion on top of products-service and common reuse packages. git clone https://github.com/sap-samples/cloud-cap-samples projects/cloud-cap-samples -b openSAP-week4-unit2-final
* [products-service](./packages/products-service) - A reuse package providing domain models and services to manage product catalogs. cd projects/cloud-cap-samples
```
## Requirements In the `cloud-cap-samples` folder run:
* [Node.js](https://nodejs.org/en/) v8 or higher ```sh
* [Git](https://git-scm.com) npm install
* [SQLite DB](https://www.sqlite.org/download.html) (Windows only; pre-installed on Mac/Linux) ```
#### Optional (if you want to import the code into an editor) ## Run
* [VS Code](https://code.visualstudio.com)
* [Add CDS extension to VS](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/be944d6d51f343f6b3f53c29c44ff00a.html)
## Download and Installation Now you're ready to run the samples, for example:
```sh
cd packages/bookshop
cds watch
```
#### Clone and build the application After that, watch out for the little popup in the lower right corner of SAP Business Application Studio that asks you to open the application in your browser.
`git clone https://github.com/SAP-samples/cloud-cap-samples.git`
`cd samples`
`npm install`
#### Run the samples
`npm run <sample name>`
## Limitations ## Get Support
None Check out the cap docs at https://cap.cloud.sap. <br>
In case you find a bug or need support, please [open an issue in here](https://github.com/SAP-samples/cloud-cap-samples/issues/new).
## Known Issues
None
## How to obtain support
In case you find a bug, or you need additional support, please open an issue [here](https://github.wdf.sap.corp/staging-for-SAP-samples-public/cloud-cap-samples/issues) in GitHub.
## To-Do (upcoming changes)
None
## License ## License
Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under SAP Sample Code License Agreement, except as noted otherwise in the [LICENSE](/LICENSE) file. Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under SAP Sample Code License Agreement, except as noted otherwise in the [LICENSE](/LICENSE) file.

View File

@@ -1,7 +1 @@
{ {"packages":["packages/*"],"version":"1.0.0"}
"packages": [
"packages/*",
"shared/*"
],
"version": "0.0.0"
}

1228
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,28 @@
{ {
"name": "@sap/capire-samples", "name": "@sap/capire-samples",
"description": "The umbrella project for all samples to easily setup for local development and tests.", "description": "The umbrella project for all samples to easily setup for local development and tests.",
"repository": "https://github.wdf.sap.corp/capire/samples.git", "repository": "https://github.com/SAP-samples/cloud-cap-samples.git",
"author": "daniel.hutzel@sap.com", "author": "daniel.hutzel@sap.com",
"private": true, "private": true,
"scripts": { "scripts": {
"install": "(npx --no-install lerna -v || npm i lerna --no-save) && lerna bootstrap --hoist --ignore tests-env --loglevel warn", "cleanup": "lerna clean -y && rm -fr node_modules",
"reset": "lerna clean -y && rm -fr node_modules", "install": "(npm -s run lerna) && lerna bootstrap --hoist",
"lerna": "npx --no-install lerna -v > /dev/null || npm i lerna --no-save",
"test": "jest", "test": "jest",
"bookstore": "cds run packages/bookstore --in-memory", "bookshop-enhanced": "cds watch packages/bookshop-enhanced",
"products-service": "cds run packages/products-service --in-memory", "bookshop": "cds watch packages/bookshop",
"reviews-service": "cds run packages/reviews-service --in-memory" "bookstore": "cds watch packages/bookstore",
"products-service": "cds watch packages/products-service",
"reviews-service": "cds watch packages/reviews-service"
}, },
"license": "ISC" "dependencies": {
"@sap/cds": "^3",
"express": "^4"
},
"--add-these-to-devDependencies-for-tests": {
"@types/jest": "*",
"sqlite3": "*",
"jest": "*"
},
"license": "SAP SAMPLE CODE LICENSE"
} }

View File

@@ -0,0 +1,13 @@
Books = Books
Book = Book
ID = ID
Title = Title
Author = Author
AuthorID = Author ID
Stock = Stock
Name = Name
AuthorName = Author's Name
Authors = Authors
Order = Order
Orders = Orders
Price = Price

View File

@@ -0,0 +1,13 @@
Books = Bücher
Book = Buch
ID = ID
Title = Titel
Authors = Autoren
Author = Autor
AuthorID = ID des Autors
AuthorName = Name des Autors
Name = Name
Stock = Bestand
Order = Bestellung
Orders = Bestellungen
Price = Preis

View File

@@ -0,0 +1,37 @@
using AdminService from '../../srv/admin-service';
////////////////////////////////////////////////////////////////////////////
//
// Books Object Page
//
annotate AdminService.Books with @(
UI: {
Facets: [
{$Type: 'UI.ReferenceFacet', Label: '{i18n>General}', Target: '@UI.FieldGroup#General'},
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Details}', Target: '@UI.FieldGroup#Details'},
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Admin}', Target: '@UI.FieldGroup#Admin'},
],
FieldGroup#General: {
Data: [
{Value: title},
{Value: author_ID},
{Value: descr},
]
},
FieldGroup#Details: {
Data: [
{Value: stock},
{Value: price},
{Value: currency_code, Label: '{i18n>Currency}'},
]
},
FieldGroup#Admin: {
Data: [
{Value: createdBy},
{Value: createdAt},
{Value: modifiedBy},
{Value: modifiedAt}
]
}
}
);

View File

@@ -0,0 +1,22 @@
sap.ui.define(["sap/fe/AppComponent"], ac => ac.extend("admin.Component", {
metadata:{ manifest:'json' }
}))
// sap.ui.define (["sap/ui/core/UIComponent"], ui5 => ui5.extend("bookshop.Component", {
// metadata: { manifest: "json" }
// }))
// sap.ui.define (["sap/ui/generic/app/AppComponent"], ui5 => ui5.extend("bookshop.Component", {
// metadata: { manifest: "json" }
// }))
// jQuery.sap.declare("bookshop.Component");
// sap.ui.getCore().loadLibrary("sap.ui.generic.app");
// jQuery.sap.require("sap.ui.generic.app.AppComponent");
// sap.ui.generic.app.AppComponent.extend("bookshop.Component", {
// metadata: {
// manifest: "json"
// }
// });
/* eslint no-undef:0 */

View File

@@ -0,0 +1,11 @@
# This is the resource bundle of itelo
# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459
# JCI app descriptor contains lower case TITLE
appTitle=Bookshop Sample
# JCI app descriptor contains lower case DESCRIPTION
appSubTitle=CAP Sample Application
# JCI app descriptor contains lower case DESCRIPTION
appDescription=CDS Sample Service

View File

@@ -0,0 +1,128 @@
{
"_version": "1.8.0",
"sap.app": {
"id": "admin",
"type": "application",
"title": "Manage Books",
"description": "Sample Application",
"i18n": "i18n/i18n.properties",
"dataSources": {
"AdminService": {
"uri": "/admin/",
"type": "OData",
"settings": {
"odataVersion": "4.0"
}
}
},
"-sourceTemplate": {
"id": "ui5template.basicSAPUI5ApplicationProject",
"-id": "ui5template.smartTemplate",
"-version": "1.40.12"
}
},
"sap.ui5": {
"dependencies": {
"libs": {
"sap.fe": {}
}
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"uri": "i18n/i18n.properties"
},
"": {
"dataSource": "AdminService",
"settings": {
"synchronizationMode": "None",
"operationMode": "Server",
"autoExpandSelect" : true,
"earlyRequests": true,
"groupProperties": {
"default": {
"submit": "Auto"
}
}
}
}
},
"routing": {
"routes": [
{
"pattern": ":?query:",
"name": "BooksList",
"target": "BooksList"
},
{
"pattern": "Books({key}):?query:",
"name": "BooksDetails",
"target": "BooksDetails"
},
{
"pattern": "Books({key}/author({key2}):?query:",
"name": "AuthorsDetails",
"target": "AuthorsDetails"
}
],
"targets": {
"BooksList": {
"type": "Component",
"id": "BooksList",
"name": "sap.fe.templates.ListReport",
"options": {
"settings" : {
"entitySet" : "Books",
"navigation" : {
"Books" : {
"detail" : {
"route" : "BooksDetails"
}
}
}
}
}
},
"BooksDetails": {
"type": "Component",
"id": "BooksDetailsList",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings" : {
"entitySet" : "Books",
"navigation" : {
"Authors" : {
"detail" : {
"route" : "AuthorsDetails"
}
}
}
}
}
},
"AuthorsDetails": {
"type": "Component",
"id": "AuthorsDetailsList",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings" : {
"entitySet" : "Authors"
}
}
}
}
},
"contentDensities": {
"compact": true,
"cozy": true
}
},
"sap.ui": {
"technology": "UI5",
"fullWidth": false
},
"sap.fiori": {
"registrationIds": [],
"archeType": "transactional"
}
}

View File

@@ -0,0 +1,47 @@
using CatalogService from '../../srv/cat-service';
////////////////////////////////////////////////////////////////////////////
//
// Books Object Page
//
annotate CatalogService.Books with @(
UI: {
HeaderInfo: {
Description: {Value: author}
},
HeaderFacets: [
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Description}', Target: '@UI.FieldGroup#Descr'},
],
Facets: [
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Details}', Target: '@UI.FieldGroup#Price'},
],
FieldGroup#Descr: {
Data: [
{Value: descr},
]
},
FieldGroup#Price: {
Data: [
{Value: price},
{Value: currency.symbol, Label: '{i18n>Currency}'},
]
},
}
);
////////////////////////////////////////////////////////////////////////////
//
// Books Object Page
//
annotate CatalogService.Books with @(
UI: {
SelectionFields: [ ID, price, currency_code ],
LineItem: [
{Value: title},
{Value: author, Label:'{i18n>Author}'},
{Value: price},
{Value: currency.symbol, Label:' '},
]
},
);

View File

@@ -0,0 +1,22 @@
sap.ui.define(["sap/fe/AppComponent"], ac => ac.extend("bookshop.Component", {
metadata:{ manifest:'json' }
}))
// sap.ui.define (["sap/ui/core/UIComponent"], ui5 => ui5.extend("bookshop.Component", {
// metadata: { manifest: "json" }
// }))
// sap.ui.define (["sap/ui/generic/app/AppComponent"], ui5 => ui5.extend("bookshop.Component", {
// metadata: { manifest: "json" }
// }))
// jQuery.sap.declare("bookshop.Component");
// sap.ui.getCore().loadLibrary("sap.ui.generic.app");
// jQuery.sap.require("sap.ui.generic.app.AppComponent");
// sap.ui.generic.app.AppComponent.extend("bookshop.Component", {
// metadata: {
// manifest: "json"
// }
// });
/* eslint no-undef:0 */

View File

@@ -0,0 +1,11 @@
# This is the resource bundle of itelo
# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459
# JCI app descriptor contains lower case TITLE
appTitle=Bookshop Sample
# JCI app descriptor contains lower case DESCRIPTION
appSubTitle=CAP Sample Application
# JCI app descriptor contains lower case DESCRIPTION
appDescription=CDS Sample Service

View File

@@ -0,0 +1,106 @@
{
"_version": "1.8.0",
"sap.app": {
"id": "bookshop",
"type": "application",
"title": "Browse Books",
"description": "Sample Application",
"i18n": "i18n/i18n.properties",
"dataSources": {
"CatalogService": {
"uri": "/browse/",
"type": "OData",
"settings": {
"odataVersion": "4.0"
}
}
},
"-sourceTemplate": {
"id": "ui5template.basicSAPUI5ApplicationProject",
"-id": "ui5template.smartTemplate",
"-version": "1.40.12"
}
},
"sap.ui5": {
"dependencies": {
"libs": {
"sap.fe": {}
}
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"uri": "i18n/i18n.properties"
},
"": {
"dataSource": "CatalogService",
"settings": {
"synchronizationMode": "None",
"operationMode": "Server",
"autoExpandSelect": true,
"earlyRequests": true,
"groupProperties": {
"default": {
"submit": "Auto"
}
}
}
}
},
"routing": {
"routes": [
{
"pattern": ":?query:",
"name": "BooksList",
"target": "BooksList"
},
{
"pattern": "Books({key}):?query:",
"name": "BooksDetails",
"target": "BooksDetails"
}
],
"targets": {
"BooksList": {
"type": "Component",
"id": "BooksList",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": {
"entitySet": "Books",
"navigation": {
"Books": {
"detail": {
"route": "BooksDetails"
}
}
}
}
}
},
"BooksDetails": {
"type": "Component",
"id": "BooksDetailsList",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings": {
"entitySet": "Books"
}
}
}
}
},
"contentDensities": {
"compact": true,
"cozy": true
}
},
"sap.ui": {
"technology": "UI5",
"fullWidth": false
},
"sap.fiori": {
"registrationIds": [],
"archeType": "transactional"
}
}

View File

@@ -0,0 +1,74 @@
/*
Common Annotations shared by all apps
*/
using { sap.capire.bookshop as my } from '../db/schema';
////////////////////////////////////////////////////////////////////////////
//
// Books Lists
//
annotate my.Books with @(
UI: {
Identification: [{Value:title}],
SelectionFields: [ ID, author_ID, price, currency_code ],
LineItem: [
{Value: ID},
{Value: title},
{Value: author.name, Label:'{i18n>Author}'},
{Value: stock},
{Value: price},
{Value: currency.symbol, Label:' '},
]
}
) {
author @ValueList.entity:'Authors';
};
annotate my.Authors with @(
UI: {
Identification: [{Value:name}],
}
);
////////////////////////////////////////////////////////////////////////////
//
// Books Details
//
annotate my.Books with @(
UI: {
HeaderInfo: {
TypeName: '{i18n>Book}',
TypeNamePlural: '{i18n>Books}',
Title: {Value: title},
Description: {Value: author.name}
},
}
);
////////////////////////////////////////////////////////////////////////////
//
// Books Elements
//
annotate my.Books with {
ID @title:'{i18n>ID}' @UI.HiddenFilter;
title @title:'{i18n>Title}';
author @title:'{i18n>AuthorID}';
price @title:'{i18n>Price}';
stock @title:'{i18n>Stock}';
descr @UI.MultiLineText;
}
////////////////////////////////////////////////////////////////////////////
//
// Authors Elements
//
annotate my.Authors with {
ID @title:'{i18n>ID}' @UI.HiddenFilter;
name @title:'{i18n>AuthorName}';
}

View File

@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bookshop</title>
<script>
window["sap-ushell-config"] = {
defaultRenderer: "fiori2",
applications: {
"browse-books": {
title: "Browse Books",
description: "... testing FE v42",
additionalInformation: "SAPUI5.Component=bookshop",
applicationType : "URL",
url: "/browse/webapp",
navigationMode: "embedded"
},
"manage-books": {
title: "Manage Books",
description: "... testing FE v42",
additionalInformation: "SAPUI5.Component=admin",
applicationType : "URL",
url: "/admin/webapp",
navigationMode: "embedded"
},
"manage-orders": {
title: "Manage Orders",
description: "... testing FE v42",
additionalInformation: "SAPUI5.Component=orders",
applicationType : "URL",
url: "/orders/webapp",
navigationMode: "embedded"
}
}
};
</script>
<script src="https://sapui5.hana.ondemand.com/test-resources/sap/ushell/bootstrap/sandbox.js"></script>
<script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.m, sap.ushell, sap.collaboration, sap.ui.layout"
data-sap-ui-compatVersion="edge"
data-sap-ui-theme="sap_belize"
data-sap-ui-frameOptions="allow"
></script>
<script>
sap.ui.getCore().attachInit(()=> sap.ushell.Container.createRenderer().placeAt("content"))
</script>
</head>
<body class="sapUiBody" id="content"></body>
</html>

View File

@@ -0,0 +1,8 @@
/*
This model controls what gets served to Fiori frontends...
*/
using from './admin/fiori-service';
using from './browse/fiori-service';
using from './orders/fiori-service';
using from './common';

View File

@@ -0,0 +1,117 @@
using AdminService from '../../srv/admin-service';
annotate AdminService.Books with {
price @Common.FieldControl: #ReadOnly;
}
////////////////////////////////////////////////////////////////////////////
//
// Common
//
annotate AdminService.OrderItems with {
book @(
Common: {
Text: book.title,
FieldControl: #Mandatory
},
ValueList.entity:'Books',
);
amount @(
Common.FieldControl: #Mandatory
);
}
annotate AdminService.Orders with @(
UI: {
////////////////////////////////////////////////////////////////////////////
//
// Lists of Orders
//
SelectionFields: [ createdAt, createdBy ],
LineItem: [
{Value: createdBy, Label:'Customer'},
{Value: createdAt, Label:'Date'}
],
////////////////////////////////////////////////////////////////////////////
//
// Order Details
//
HeaderInfo: {
TypeName: 'Order', TypeNamePlural: 'Orders',
Title: {
Label: 'Order number ', //A label is possible but it is not considered on the ObjectPage yet
Value: OrderNo
},
Description: {Value: createdBy}
},
Identification: [ //Is the main field group
{Value: createdBy, Label:'Customer'},
{Value: createdAt, Label:'Date'},
{Value: OrderNo },
],
HeaderFacets: [
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Created}', Target: '@UI.FieldGroup#Created'},
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Modified}', Target: '@UI.FieldGroup#Modified'},
],
Facets: [
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Details}', Target: '@UI.FieldGroup#Details'},
{$Type: 'UI.ReferenceFacet', Label: '{i18n>OrderItems}', Target: 'Items/@UI.LineItem'},
],
FieldGroup#Details: {
Data: [
{Value: currency_code, Label:'Currency'}
]
},
FieldGroup#Created: {
Data: [
{Value: createdBy},
{Value: createdAt},
]
},
FieldGroup#Modified: {
Data: [
{Value: modifiedBy},
{Value: modifiedAt},
]
},
},
) {
createdAt @UI.HiddenFilter:false;
createdBy @UI.HiddenFilter:false;
};
//The enity types name is AdminService.my_bookshop_OrderItems
//The annotations below are not generated in edmx WHY?
annotate AdminService.OrderItems with @(
UI: {
HeaderInfo: {
TypeName: 'Order Item', TypeNamePlural: ' ',
Title: {
Value: book.title
},
Description: {Value: book.descr}
},
// There is no filterbar for items so the selctionfileds is not needed
SelectionFields: [ book_ID ],
////////////////////////////////////////////////////////////////////////////
//
// Lists of OrderItems
//
LineItem: [
{Value: book_ID, Label:'Book'},
//The following entry is only used to have the assoication followed in the read event
{Value: book.price, Label:'Book Price'},
{Value: amount, Label:'Quantity'},
],
Identification: [ //Is the main field group
//{Value: ID, Label:'ID'}, //A guid shouldn't be on the UI
{Value: book_ID, Label:'Book'},
{Value: amount, Label:'Amount'},
],
Facets: [
{$Type: 'UI.ReferenceFacet', Label: '{i18n>OrderItems}', Target: '@UI.Identification'},
],
},
);

View File

@@ -0,0 +1,22 @@
sap.ui.define(["sap/fe/AppComponent"], ac => ac.extend("orders.Component", {
metadata:{ manifest:'json' }
}))
// sap.ui.define (["sap/ui/core/UIComponent"], ui5 => ui5.extend("bookshop.Component", {
// metadata: { manifest: "json" }
// }))
// sap.ui.define (["sap/ui/generic/app/AppComponent"], ui5 => ui5.extend("bookshop.Component", {
// metadata: { manifest: "json" }
// }))
// jQuery.sap.declare("bookshop.Component");
// sap.ui.getCore().loadLibrary("sap.ui.generic.app");
// jQuery.sap.require("sap.ui.generic.app.AppComponent");
// sap.ui.generic.app.AppComponent.extend("bookshop.Component", {
// metadata: {
// manifest: "json"
// }
// });
/* eslint no-undef:0 */

View File

@@ -0,0 +1,11 @@
# This is the resource bundle of itelo
# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459
# JCI app descriptor contains lower case TITLE
appTitle=Bookshop Sample
# JCI app descriptor contains lower case DESCRIPTION
appSubTitle=CAP Sample Application
# JCI app descriptor contains lower case DESCRIPTION
appDescription=CDS Sample Service

View File

@@ -0,0 +1,170 @@
{
"_version": "1.8.0",
"sap.app": {
"id": "orders",
"type": "application",
"title": "Manage Orders",
"description": "Sample Application",
"i18n": "i18n/i18n.properties",
"dataSources": {
"AdminService": {
"uri": "/admin/",
"type": "OData",
"settings": {
"odataVersion": "4.0"
}
}
},
"-sourceTemplate": {
"id": "ui5template.basicSAPUI5ApplicationProject",
"-id": "ui5template.smartTemplate",
"-version": "1.40.12"
}
},
"sap.ui5": {
"dependencies": {
"libs": {
"sap.fe": {}
}
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"uri": "i18n/i18n.properties"
},
"": {
"dataSource": "AdminService",
"settings": {
"synchronizationMode": "None",
"operationMode": "Server",
"autoExpandSelect" : true,
"earlyRequests": true,
"groupProperties": {
"default": {
"submit": "Auto"
}
}
}
}
},
"routing": {
"routes": [
{
"pattern": ":?query:",
"name": "OrdersList",
"target": "OrdersList"
},
{
"pattern": "Orders({key}):?query:",
"name": "OrdersDetails",
"target": "OrdersDetails"
},
{
"pattern": "Orders({boo})/Items({boo2}):?query:",
"name": "OrderItemsDetails",
"target": "OrderItemsDetails"
},
{
"pattern": "Books({key}):?query:",
"name": "BooksDetails",
"target": "BooksDetails"
}
],
"targets": {
"OrdersList": {
"type": "Component",
"id": "OrdersList",
"name": "sap.fe.templates.ListReport",
"options": {
"settings" : {
"entitySet" : "Orders",
"navigation" : {
"Orders" : {
"detail" : {
"route" : "OrdersDetails"
}
}
}
}
}
},
"OrdersDetails": {
"type": "Component",
"id": "OrdersDetails",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings" : {
"entitySet": "Orders",
"navigation" : {
"Items": {
"detail": {
"route": "OrderItemsDetails"
}
},
"book": {
"detail": {
"route": "BooksDetails"
}
},
"dummy": {
"detail": {
"route": "BooksDetails"
}
}
}
}
}
},
"OrderItemsDetails": {
"type": "Component",
"id": "OrderItemsDetails",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings" : {
"entitySet": "OrderItems"
}
}
},
"BooksDetails": {
"type": "Component",
"id": "BooksDetails",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings" : {
"entitySet": "Books",
"navigation": {
"author": {
"detail": {
"route": "AuthorsDetails"
}
}
}
}
}
},
"AuthorsDetails": {
"type": "Component",
"id": "AuthorsDetails",
"name": "sap.fe.templates.ObjectPage",
"options": {
"settings" : {
"entitySet": "Authors"
}
}
}
}
},
"contentDensities": {
"compact": true,
"cozy": true
}
},
"sap.ui": {
"technology": "UI5",
"fullWidth": false
},
"sap.fiori": {
"registrationIds": [],
"archeType": "transactional"
}
}

View File

@@ -0,0 +1,5 @@
ID;name;dateOfBirth;placeOfBirth;dateOfDeath;placeOfDeath
101;Emily Brontë;1818-07-30;Thornton, Yorkshire;1848-12-19;Haworth, Yorkshire
107;Charlotte Brontë;1818-04-21;Thornton, Yorkshire;1855-03-31;Haworth, Yorkshire
150;Edgar Allen Poe;1809-01-19;Boston, Massachusetts;1849-10-07;Baltimore, Maryland
170;Richard Carpenter;1929-08-14;Kings Lynn, Norfolk;2012-02-26;Hertfordshire, England
1 ID name dateOfBirth placeOfBirth dateOfDeath placeOfDeath
2 101 Emily Brontë 1818-07-30 Thornton, Yorkshire 1848-12-19 Haworth, Yorkshire
3 107 Charlotte Brontë 1818-04-21 Thornton, Yorkshire 1855-03-31 Haworth, Yorkshire
4 150 Edgar Allen Poe 1809-01-19 Boston, Massachusetts 1849-10-07 Baltimore, Maryland
5 170 Richard Carpenter 1929-08-14 King’s Lynn, Norfolk 2012-02-26 Hertfordshire, England

View File

@@ -0,0 +1,6 @@
ID;title;descr;author_ID;stock;price;currency_code
201;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.";101;12;11.11;GBP
207;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.";107;11;12.34;GBP
251;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.";150;333;13.13;USD
252;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.";150;555;14;USD
271;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.;170;22;15;EUR
1 ID title descr author_ID stock price currency_code
2 201 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. 101 12 11.11 GBP
3 207 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. 107 11 12.34 GBP
4 251 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. 150 333 13.13 USD
5 252 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. 150 555 14 USD
6 271 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. 170 22 15 EUR

View File

@@ -0,0 +1,4 @@
ID;locale;title;descr
201;de;Sturmhöhe;Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (18181848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts.
207;de;Jane Eyre;Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte
252;de;Eleonora;“Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit.
1 ID locale title descr
2 201 de Sturmhöhe Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (1818–1848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts.
3 207 de Jane Eyre Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte
4 252 de Eleonora “Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit.

View File

@@ -0,0 +1,4 @@
ID;amount;parent_ID;book_ID;netAmount
58040e66-1dcd-4ffb-ab10-fdce32028b79;1;7e2f2640-6866-4dcf-8f4d-3027aa831cad;201;11.11
64e718c9-ff99-47f1-8ca3-950c850777d4;1;7e2f2640-6866-4dcf-8f4d-3027aa831cad;271;15
e9641166-e050-4261-bfee-d1e797e6cb7f;2;64e718c9-ff99-47f1-8ca3-950c850777d4;252;28
1 ID amount parent_ID book_ID netAmount
2 58040e66-1dcd-4ffb-ab10-fdce32028b79 1 7e2f2640-6866-4dcf-8f4d-3027aa831cad 201 11.11
3 64e718c9-ff99-47f1-8ca3-950c850777d4 1 7e2f2640-6866-4dcf-8f4d-3027aa831cad 271 15
4 e9641166-e050-4261-bfee-d1e797e6cb7f 2 64e718c9-ff99-47f1-8ca3-950c850777d4 252 28

View File

@@ -0,0 +1,5 @@
ID;modifiedAt;createdAt;createdBy;modifiedBy;OrderNo;currency_code;status
da86efd0-4ba1-4078-b7f0-5c9c530297f7;;2019-01-31;ALICE;;1;EUR;processing
2f2f2640-6866-4dcf-8f4d-3027aa831cad;;2019-03-25;ALICE;;10;EUR;completed
64e718c9-ff99-47f1-8ca3-950c850777d4;;2019-01-30;BOB;;2;EUR;processing
1af3322d-3cb1-46be-b312-0ae9ec311537;;2019-03-16;BOB;;9;EUR;completed
1 ID modifiedAt createdAt createdBy modifiedBy OrderNo currency_code status
2 da86efd0-4ba1-4078-b7f0-5c9c530297f7 2019-01-31 ALICE 1 EUR processing
3 2f2f2640-6866-4dcf-8f4d-3027aa831cad 2019-03-25 ALICE 10 EUR completed
4 64e718c9-ff99-47f1-8ca3-950c850777d4 2019-01-30 BOB 2 EUR processing
5 1af3322d-3cb1-46be-b312-0ae9ec311537 2019-03-16 BOB 9 EUR completed

View File

@@ -0,0 +1,7 @@
code;symbol;name;descr
EUR;€;Euro;European Euro
USD;$;US Dollar;United States Dollar
CAD;$;Canadian Dollar;Canadian Dollar
AUD;$;Australian Dollar;Australian Dollar
GBP;£;Pound;Great Britain Pound
ILS;₪;Shekel;Israeli New Shekel
1 code symbol name descr
2 EUR Euro European Euro
3 USD $ US Dollar United States Dollar
4 CAD $ Canadian Dollar Canadian Dollar
5 AUD $ Australian Dollar Australian Dollar
6 GBP £ Pound Great Britain Pound
7 ILS Shekel Israeli New Shekel

View File

@@ -0,0 +1,13 @@
code;locale;name;descr
EUR;de;Euro;European Euro
USD;de;US-Dollar;United States Dollar
CAD;de;Kanadischer Dollar;Kanadischer Dollar
AUD;de;Australischer Dollar;Australischer Dollar
GBP;de;Pfund;Britische Pfund
ILS;de;Schekel;Israelische Schekel
EUR;fr;euro;de la Zone euro
USD;fr;dollar;dollar des États-Unis
CAD;fr;dollar canadien;dollar canadien
AUD;fr;dollar australien;dollar australien
GBP;fr;livre sterling;pound sterling
ILS;fr;Shekel;shekel israelien
1 code locale name descr
2 EUR de Euro European Euro
3 USD de US-Dollar United States Dollar
4 CAD de Kanadischer Dollar Kanadischer Dollar
5 AUD de Australischer Dollar Australischer Dollar
6 GBP de Pfund Britische Pfund
7 ILS de Schekel Israelische Schekel
8 EUR fr euro de la Zone euro
9 USD fr dollar dollar des États-Unis
10 CAD fr dollar canadien dollar canadien
11 AUD fr dollar australien dollar australien
12 GBP fr livre sterling pound sterling
13 ILS fr Shekel shekel israelien

View File

@@ -0,0 +1,50 @@
namespace sap.capire.bookshop;
using {
Currency,
managed,
cuid
} from '@sap/cds/common';
type Status : String enum {
completed;
processing;
blocked;
}
entity Books : managed {
key ID : Integer;
title : localized String(111);
descr : localized String(1111);
author : Association to Authors;
stock : Integer;
price : Decimal(9, 2);
currency : Currency;
}
entity Authors : managed {
key ID : Integer;
name : String(111);
dateOfBirth : Date;
dateOfDeath : Date;
placeOfBirth : String;
placeOfDeath : String;
books : Association to many Books
on books.author = $self;
}
entity Orders : cuid, managed {
OrderNo : String @title : 'Order Number'; //> readable key
status : Status default 'processing';
Items : Composition of many OrderItems
on Items.parent = $self;
total : Decimal(9, 2)@readonly;
currency : Currency;
}
entity OrderItems : cuid {
parent : Association to Orders;
book : Association to Books;
amount : Integer;
netAmount : Decimal(9, 2);
}

View File

@@ -0,0 +1,28 @@
{
"name": "@sap/capire-bookshop",
"version": "1.0.0",
"description": "A simple bookshop application, build in a self-contained all-in-one fashion, i.e. w/o reusing other packages.",
"license": "SAP SAMPLE CODE LICENSE",
"dependencies": {
"@sap/cds": "^3",
"express": "^4",
"@sap/xb-msg-amqp-v100": "^0.9.35"
},
"devDependencies": {
"sqlite3": "^4.1.1"
},
"scripts": {
"start": "npx cds run"
},
"cds": {
"requires": {
"API_BUSINESS_PARTNER": {
"kind": "odata",
"model": "srv/external/API_BUSINESS_PARTNER",
"--credentials": {
"destination": "cap-api098"
}
}
}
}
}

View File

@@ -0,0 +1,16 @@
using { sap.capire.bookshop as my } from '../db/schema';
service AdminService @(_requires:'authenticated-user') {
entity Books as projection on my.Books;
entity Authors as projection on my.Authors;
entity Orders as select from my.Orders;
}
// Enable Fiori Draft for Orders
annotate AdminService.Orders with @odata.draft.enabled;
// annotate AdminService.Books with @odata.draft.enabled;
// Temporary workaround -> https://github.wdf.sap.corp/cap/issues/issues/3121
extend service AdminService with {
entity OrderItems as select from my.OrderItems;
}

View File

@@ -0,0 +1,22 @@
using { sap.capire.bookshop as my } from '../db/schema';
using { API_BUSINESS_PARTNER as external } from './external/API_BUSINESS_PARTNER.csn';
@path:'/browse'
service CatalogService {
@readonly entity Books as SELECT from my.Books {*,
author.name as author
} excluding { createdBy, modifiedBy };
@readonly entity BusinessPartners as projection on external.A_BusinessPartner {
key BusinessPartner as ID,
FirstName,
MiddleName,
LastName,
BusinessPartnerIsBlocked
};
@requires_: 'authenticated-user'
@insertonly entity Orders as projection on my.Orders;
}

View File

@@ -0,0 +1,28 @@
const cds = require('@sap/cds')
/** Service implementation for CatalogService */
module.exports = cds.service.impl(async function () {
const { Books, Orders, BusinessPartners } = this.entities
const bupaSrv = await cds.connect.to('API_BUSINESS_PARTNER')
this.after('READ', Books, each => each.stock > 111 && _addDiscount2(each, 11))
this.before('CREATE', Orders, _reduceStock)
this.on('READ', BusinessPartners, req => bupaSrv.tx(req).run(req.query))
/** Add some discount for overstocked books */
function _addDiscount2(each, discount) {
each.title += ` -- ${discount}% discount!`
}
/** Reduce stock of ordered books if available stock suffices */
async function _reduceStock(req) {
const { Items: OrderItems } = req.data
return cds.transaction(req).run(() => OrderItems.map(order =>
UPDATE(Books).set('stock -=', order.amount)
.where('ID =', order.book_ID).and('stock >=', order.amount)
)).then(all => all.forEach((affectedRows, i) => {
if (affectedRows === 0) req.error(409,
`${OrderItems[i].amount} exceeds stock for book #${OrderItems[i].book_ID}`
)
}))
}
})

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
BusinessPartner;FirstName;MiddleName;LastName;BusinessPartnerIsBlocked
ALICE;Alice;In;Wonderland;false
BOB;Bob;The;Builder;false
JABBA;Jabba;The;Hutt;true
1 BusinessPartner FirstName MiddleName LastName BusinessPartnerIsBlocked
2 ALICE Alice In Wonderland false
3 BOB Bob The Builder false
4 JABBA Jabba The Hutt true

View File

@@ -0,0 +1,18 @@
### Service Document
GET http://localhost:4004/browse
### Service $metadata document
GET http://localhost:4004/browse/$metadata
### Browsing Books
GET http://localhost:4004/browse/Books?
# &$select=title,author
# &$expand=currency
# &sap-language=de
### Browsing Authors
GET http://localhost:4004/admin/Authors?
# &$select=name,dateOfBirth,placeOfBirth
# &$expand=books($select=title;$expand=currency)
# &$filter=ID eq 101
# &sap-language=de

View File

@@ -0,0 +1,18 @@
### List Books with their current stocks
GET http://localhost:4004/admin/Books?$select=ID,stock
### List all Orders
GET http://localhost:4004/admin/Orders?
&$expand=Items
### Submit Orders
POST http://localhost:4004/browse/Orders
Content-Type: application/json
{ "OrderNo":"2019-09...", "Items":[
{ "book_ID":201, "amount":5 },
{ "book_ID":207, "amount":3 }
]}
# Sending this three times should result in a 409: 5 exceeds stock for book #201

View File

@@ -1,6 +0,0 @@
{
"build": {
"target": ".",
"tasks": []
}
}

View File

@@ -1,15 +0,0 @@
.che/
.gen/
gen/
mta_archives/
node_modules/
target/
.cds_gen.log
connection.properties
*.db
.DS_Store
*.orig
_out
default-*.json
package-lock.json

View File

@@ -1,20 +0,0 @@
{
"name": "bookstore",
"description": "Generated by cds init",
"repository": "<Add your repository here>",
"license": "ISC",
"version": "1.0.0",
"engines": {
"node": "^8.9"
},
"dependencies": {
"@sap/cds": "^3.16.3",
"@sap/cds-rest": "latest",
"express": "^4.17.1"
},
"scripts": {
"build": "cds build/all --clean",
"deploy": "cds deploy",
"start": "cds run"
}
}

View File

@@ -1,12 +0,0 @@
gen/
.gen/
node_modules/
target/
*.db
.DS_Store
_out
.che/
.cds_gen.log
package-lock.json
*.orig
mta_archives/

View File

@@ -1,18 +0,0 @@
namespace sap.capire.products;
using { Currency, cuid, managed, sap.common.CodeList } from '@sap/cds/common';
entity Products : cuid, managed {
title : localized String(111);
descr : localized String(1111);
stock : Integer;
price : Decimal(9,2);
currency : Currency;
category : Association to Categories;
}
entity Categories : CodeList {
key ID : Integer;
parent : Association to Categories;
children : Composition of many Categories on children.parent = $self;
}

View File

@@ -1,2 +0,0 @@
using from './db/schema';
using from './srv/admin-service';

View File

@@ -1,16 +0,0 @@
{
"name": "@sap/capire-products",
"version": "1.0.0",
"description": "A reuse package providing domain models and services to manage product catalogs.",
"repository": "https://github.wdf.sap.corp/caps/products-service.git",
"license": "ISC",
"dependencies": {
"@sap/cds": "^3.16.3",
"express": "^4.17.1"
},
"files": [
"db",
"srv",
"index.cds"
]
}

View File

@@ -1,7 +0,0 @@
using { sap.capire.products as db } from '../db/schema';
namespace sap.capire.products;
service AdminService @(_requires:'admin') {
entity Products as projection on db.Products;
entity Categories as projection on db.Categories;
}

View File

@@ -1,68 +0,0 @@
const cds = require ('@sap/cds')
describe('reading/writing hierarchies', ()=>{
it ('should prepare to sqlite in-memory', async()=>{
await cds.deploy (__dirname+'/../db') .to ('sqlite::memory:')
expect (cds.model) .toBeDefined()
})
it ('should insert hierarchy of categories', ()=>{
const { Categories } = cds.entities
return INSERT.into (Categories) .entries (
{ ID:100, name:'Some Sample Categories...', children:[
{ ID:101, name:'Cat', children:[
{ ID:102, name:'Kitty', children:[
{ ID:103, name:'Kitty Cat', children:[
{ ID:104, name:'Aristocat' } ]},
{ ID:105, name:'Kitty Bat' } ]},
{ ID:106, name:'Catwoman', children:[
{ ID:107, name:'Catalina' } ]} ]},
{ ID:108, name:'Catweazle' }
]}
)
})
it ('should read categories with children', async()=>{
const { Categories } = cds.entities
expect (await
SELECT.one.from (Categories, c=>{
c.ID, c.name.as('parent'), c.children (c=>{
c.name.as('child')
})
}) .where ({name:'Cat'})
) .toMatchObject (
{ ID:101, parent:'Cat', children:[
{ child:'Kitty' },
{ child:'Catwoman' },
]}
)
})
it ('should read hierarchy of categories', async()=>{
const { Categories } = cds.entities
expect (await
SELECT.one.from (Categories, c=>{
c.ID, c.name, c.children (c=>{ c.name },{levels:3})
}) .where ({name:'Cat'})
) .toMatchObject (
{ ID:101, name:'Cat', children:[
{ name:'Kitty', children:[
{ name:'Kitty Cat', children:[
{ name:'Aristocat' }, ]},
{ name:'Kitty Bat' }, ]},
{ name:'Catwoman', children:[
{ name:'Catalina' } ]},
]}
)
})
})

View File

@@ -1,10 +0,0 @@
ID;parent_ID;name
0;;Some Sample Categories...
1;;Cat
2;1;Kitty
3;2;Kitty Cat
4;3;Aristocat
5;2;Kitty Bat
6;1;Catwoman
7;6;Catalina
8;;Catweazle
1 ID parent_ID name
2 0 Some Sample Categories...
3 1 Cat
4 2 1 Kitty
5 3 2 Kitty Cat
6 4 3 Aristocat
7 5 2 Kitty Bat
8 6 1 Catwoman
9 7 6 Catalina
10 8 Catweazle

View File

@@ -1,157 +0,0 @@
{
"info": {
"_postman_id": "0f8d4e79-a1c2-47fe-aeab-0319fb4ce180",
"name": "@sap/capire-products",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Categories",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{ \"ID\":0, \"name\":\"Some Sample Categories...\", \"children\":[\n { \"ID\":1, \"name\":\"Cat\", \"children\":[\n { \"ID\":2, \"name\":\"Kitty\", \"children\":[\n { \"ID\":3, \"name\":\"Kitty Cat\", \"children\":[\n { \"ID\":4, \"name\":\"Aristocat\" }\n ]},\n { \"ID\":5, \"name\":\"Kitty Bat\" }\n ]},\n { \"ID\":6, \"name\":\"Catwoman\", \"children\":[\n { \"ID\":7, \"name\":\"Catalina\" }\n ]}\n ] },\n { \"ID\":8, \"name\":\"Catweazle\" }\n]}\n"
},
"url": {
"raw": "http://localhost:4004/admin/cats",
"protocol": "http",
"host": [
"localhost"
],
"port": "4004",
"path": [
"admin",
"cats"
]
}
},
"response": []
},
{
"name": "Categories",
"request": {
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:4004/admin/cats/0?$expand=children($expand=children($expand=children($expand=children)))",
"protocol": "http",
"host": [
"localhost"
],
"port": "4004",
"path": [
"admin",
"cats",
"0"
],
"query": [
{
"key": "$expand",
"value": "children($expand=children($expand=children($expand=children)))"
}
]
}
},
"response": [
{
"name": "Categories",
"originalRequest": {
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:4004/admin/cats/0?$expand=children($expand=children($expand=children($expand=children)))",
"protocol": "http",
"host": [
"localhost"
],
"port": "4004",
"path": [
"admin",
"cats",
"0"
],
"query": [
{
"key": "$expand",
"value": "children($expand=children($expand=children($expand=children)))"
}
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "json",
"header": [
{
"key": "X-Powered-By",
"value": "Express"
},
{
"key": "OData-Version",
"value": "4.0"
},
{
"key": "content-type",
"value": "application/json;odata.metadata=minimal"
},
{
"key": "Date",
"value": "Tue, 21 May 2019 19:20:24 GMT"
},
{
"key": "Connection",
"value": "keep-alive"
},
{
"key": "Content-Length",
"value": "767"
}
],
"cookie": [],
"body": "{\n \"@odata.context\": \"$metadata#cats(children(children(children(children()))))/$entity\",\n \"@odata.metadataEtag\": \"W/\\\"+AAp4JKNOcr+OusjrdQo55RCfM+UHKpTh8EbhsxyPhM=\\\"\",\n \"name\": \"Some Sample Categories...\",\n \"descr\": null,\n \"ID\": 0,\n \"parent_ID\": null,\n \"children\": [\n {\n \"name\": \"Cat\",\n \"descr\": null,\n \"ID\": 1,\n \"parent_ID\": 0,\n \"children\": [\n {\n \"name\": \"Kitty\",\n \"descr\": null,\n \"ID\": 2,\n \"parent_ID\": 1,\n \"children\": [\n {\n \"name\": \"Kitty Cat\",\n \"descr\": null,\n \"ID\": 3,\n \"parent_ID\": 2,\n \"children\": [\n {\n \"name\": \"Aristocat\",\n \"descr\": null,\n \"ID\": 4,\n \"parent_ID\": 3\n }\n ]\n },\n {\n \"name\": \"Kitty Bat\",\n \"descr\": null,\n \"ID\": 5,\n \"parent_ID\": 2,\n \"children\": []\n }\n ]\n },\n {\n \"name\": \"Catwoman\",\n \"descr\": null,\n \"ID\": 6,\n \"parent_ID\": 1,\n \"children\": [\n {\n \"name\": \"Catalina\",\n \"descr\": null,\n \"ID\": 7,\n \"parent_ID\": 6,\n \"children\": []\n }\n ]\n }\n ]\n },\n {\n \"name\": \"Catweazle\",\n \"descr\": null,\n \"ID\": 8,\n \"parent_ID\": 0,\n \"children\": []\n }\n ]\n}"
}
]
},
{
"name": "Categories",
"request": {
"method": "DELETE",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:4004/admin/cats/0",
"protocol": "http",
"host": [
"localhost"
],
"port": "4004",
"path": [
"admin",
"cats",
"0"
]
}
},
"response": []
}
]
}

View File

@@ -1,11 +0,0 @@
{
"name": "dev-env",
"author": "daniel.hutzel@sap.com",
"dependencies": {
"@sap/cds": "^3.16.3"
},
"devDependencies": {
"sqlite3": "^4.0.7"
},
"license": "ISC"
}

View File

@@ -1,10 +0,0 @@
{
"name": "tests-env",
"author": "daniel.hutzel@sap.com",
"devDependencies": {
"@types/jest": "*",
"jest": "^24.8.0",
"supertest": "^4.0.2"
},
"license": "ISC"
}