Compare commits

...

34 Commits

Author SHA1 Message Date
Christian Georgi
0e894313c3 Update README.md 2020-04-20 17:11:43 +02:00
Christian Georgi
83ea6a363d Add package-lock.json, fix readme 2020-04-02 16:12:08 +02:00
Christian Georgi
98cf14101a Update readme 2020-03-23 17:10:22 +01:00
D065023
401ff039ff rm other packages 2020-03-20 10:52:10 +01:00
D065023
4d8b887389 Merge branch 'OpenSAP-week4-unit1' of https://github.com/SAP-samples/cloud-cap-samples into OpenSAP-week4-unit1 2020-03-16 09:25:38 +01:00
D065023
8ab6a7ebf6 added package-lock 2020-03-16 09:25:32 +01:00
Dr. David Kunz
09eb51fa32 Update package.json 2020-02-11 11:49:25 +01:00
D065023
7a6a6a0257 rm req 2020-01-29 15:21:47 +01:00
D065023
f17c5bfa57 rm amqp 2020-01-29 15:20:23 +01:00
D065023
85498a9875 added default 2020-01-29 15:18:20 +01:00
D065023
19b09645db rm imported 2020-01-29 15:04:51 +01:00
D065023
9861b05f2d imported 2020-01-29 14:57:38 +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
64 changed files with 1323 additions and 1608 deletions

2
.npmrc
View File

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

View File

@@ -1,73 +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://cap.cloud.sap).
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.
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.
## Setup
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:
## Requirements
* [Node.js](https://nodejs.org/en/) v8 or higher
* [Git](https://git-scm.com)
* [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)
* [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
#### Install `cds` development kit
```sh
# sets the registry for `@sap` packages
npm set @sap:registry=https://npm.sap.com
npm install -g @sap/cds-dk
cds #> test-run it
git clone https://github.com/sap-samples/cloud-cap-samples projects/cloud-cap-samples -b openSAP-week4-unit1
cd projects/cloud-cap-samples
```
Got issues? Check out the [documentation](https://cap.cloud.sap/docs/get-started/).
#### Clone and build the application
`git clone https://github.com/SAP-samples/cloud-cap-samples samples && cd samples && npm i`
In the `cloud-cap-samples` folder run:
```sh
npm install
```
#### Run the samples
## Run
With that you're ready to run the samples, e.g. start the [_bookshop_](./packages/bookshop) sample as follows:
Now you're ready to run the samples, for example:
```sh
cd packages/bookshop
cds watch
```
`npm run bookshop`
## Test
For example, try these links in your browser:
- <http://localhost:4004> to test with generic index page.
- <http://localhost:4004/fiori.html> to test with Fiori sandbox.
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.
## Debug
## Get Support
For example, in [VS Code](https://code.visualstudio.com) switch to _Debug_ view and launch one of the prepared _cds run_ launch configurations.
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).
## Limitations
None
## Known Issues
None
## How to obtain support
Check out the documentation on https://cap.cloud.sap. In case you find a bug, or you need additional support, please open an issue [here](https://github.com/SAP-samples/cloud-cap-samples/issues/new) in GitHub.
## To-Do (upcoming changes)
None
## 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.

1228
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -16,8 +16,8 @@
"reviews-service": "cds watch packages/reviews-service"
},
"dependencies": {
"@sap/cds": "latest",
"express": "*"
"@sap/cds": "^3",
"express": "^4"
},
"--add-these-to-devDependencies-for-tests": {
"@types/jest": "*",

View File

@@ -1 +0,0 @@
using from '@sap/capire-bookshop/app';

View File

@@ -1,25 +0,0 @@
/*
In this model we demonstrate how to add Genres to Books in
as if it was an external extension. For example we use
CDS Aspects' to extend the core domain model's Books entity
as well as the AdminService.
*/
namespace sap.capire.bookshop;
using { sap.capire.reviews.ReviewsService as external } from '@sap/capire-reviews';
using { sap.capire.bookshop.Books } from '@sap/capire-bookshop/db/schema';
using { sap.common.CodeList } from '@sap/cds/common';
// Extending Books by Reviews and Genres
extend Books with {
reviews : Composition of many external.Reviews on reviews.subject = ID;
rating : external.Reviews.rating;
genre : Association to Genres;
}
// Hierarchical Code List for Genres
entity Genres : CodeList {
key ID : Integer;
children : Composition of many Genres on children.parent = $self;
parent : Association to Genres;
}

View File

@@ -1,27 +0,0 @@
{
"name": "@sap/capire-bookshop-enhanced",
"version": "1.0.0",
"description": "A sample for extending a base application package, in this case bookshop, e.g. in context of verticalization or customization.",
"repository": "https://github.com/SAP-samples/cloud-cap-samples.git",
"license": "SAP SAMPLE CODE LICENSE",
"dependencies": {
"@sap/capire-bookshop": "^1.0.0",
"@sap/capire-reviews": "^1.0.0",
"@sap/cds": "latest",
"express": "*"
},
"scripts": {
"start": "npx cds run"
},
"cds": {
"requires": {
"sap.capire.reviews.ReviewsService": {
"kind": "odata",
"model": "@sap/capire-reviews"
},
"messaging": {
"kind": "file-based-messaging"
}
}
}
}

View File

@@ -1,9 +0,0 @@
namespace sap.capire.bookshop;
using { AdminService } from '@sap/capire-bookshop/srv/admin-service';
using { sap.capire.bookshop } from '../db/schema';
@impl:'srv/services'
extend service AdminService with {
entity Genres as projection on bookshop.Genres;
}

View File

@@ -1,30 +0,0 @@
const cds = require ('@sap/cds')
module.exports = cds.service.impl (async()=>{
const ReviewsService = await cds.connect.to ('sap.capire.reviews.ReviewsService')
const CatalogService = await cds.connect.to ('CatalogService')
const db = await cds.connect.to ('db')
// import model definitions from connected services to work with subsequently
const { Books } = db.entities
const { Reviews } = ReviewsService.entities
CatalogService.impl (srv => {
// delegate requests to read reviews to ReviewsService
srv.on ('READ', 'Books/reviews', (req) => {
const [ subject ] = req.params
const tx = ReviewsService.transaction (req)
return tx.run (SELECT.from (Reviews) .where ({subject}))
})
})
// react on event messages from reviews service
ReviewsService.on ('reviewed', (msg) => {
console.debug ('> received:', msg.event, msg.data)
const { subject, rating } = msg.data
const tx = db // TODO: db.transaction (msg)
return tx.run (UPDATE (Books, subject) .with ({rating}))
// return tx.update (Books, subject) .with ({rating})
})
})

View File

@@ -1,33 +0,0 @@
#################################################
#
# Genres
#
GET http://localhost:4004/admin/Genres?
###
POST http://localhost:4004/admin/Genres?
Content-Type: application/json
{ "ID":100, "name":"Some Sample Genres...", "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" }
]}
###
GET http://localhost:4004/admin/Genres(100)?
# &$expand=children
# &$expand=children($expand=children($expand=children($expand=children)))
###
DELETE http://localhost:4004/admin/Genres(103)
###
DELETE http://localhost:4004/admin/Genres(100)
###

View File

@@ -1,32 +0,0 @@
#################################################
#
# Reviews Service
#
### Use this one for ReviewsService running as a separate process
# Note: use 5005 instead of 4004 in case of separate service
POST http://localhost:5005/reviews/Reviews
# POST http://localhost:4004/reviews/Reviews
Content-Type: application/json;IEEE754Compatible=true
{"subject":"201", "rating":"5", "title":"boo"}
### Direct Request to ReviewsService
# Note: use 5005 instead of 4004 in case of separate service
GET http://localhost:5005/reviews/Reviews?
# GET http://localhost:4004/reviews/Reviews?
# &$filter=subject eq '201'
### Request to CatalogService > delegated to ReviewsService
GET http://localhost:4004/browse/Books(201)/reviews
### Alternative OData URL
GET http://localhost:4004/browse/Books/201/reviews
###
GET http://localhost:4004/browse/Books(201)?
&$select=ID,title,rating
# &$expand=reviews
# Note: the latter only works in case of ReviewsService in same process

View File

@@ -1,3 +1,5 @@
ID;modifiedAt;createdAt;createdBy;modifiedBy;OrderNo;currency_code
7e2f2640-6866-4dcf-8f4d-3027aa831cad;;2019-01-31;john.doe@test.com;;1;EUR
64e718c9-ff99-47f1-8ca3-950c850777d4;;2019-01-30;jane.doe@test.com;;2;EUR
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 7e2f2640-6866-4dcf-8f4d-3027aa831cad da86efd0-4ba1-4078-b7f0-5c9c530297f7 2019-01-31 john.doe@test.com ALICE 1 EUR processing
3 64e718c9-ff99-47f1-8ca3-950c850777d4 2f2f2640-6866-4dcf-8f4d-3027aa831cad 2019-01-30 2019-03-25 jane.doe@test.com ALICE 2 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

@@ -1,35 +1,50 @@
namespace sap.capire.bookshop;
using { Currency, managed, cuid } from '@sap/cds/common';
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;
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;
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
Items : Composition of many OrderItems on Items.parent = $self;
total : Decimal(9,2) @readonly;
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);
}
netAmount : Decimal(9, 2);
}

View File

@@ -4,8 +4,12 @@
"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": "latest",
"express": "*"
"@sap/cds": "^3",
"express": "^4",
"@sap/xb-msg-amqp-v100": "^0.9.35"
},
"devDependencies": {
"sqlite3": "^4.1.1"
},
"scripts": {
"start": "npx cds run"

View File

@@ -1,26 +1,26 @@
const cds = require('@sap/cds')
const { Books } = cds.entities
/** Service implementation for CatalogService */
module.exports = cds.service.impl(function() {
this.after ('READ', 'Books', each => each.stock > 111 && _addDiscount2(each,11))
this.before ('CREATE', 'Orders', _reduceStock)
module.exports = cds.service.impl(function () {
const { Books, Orders } = this.entities
this.after('READ', Books, each => each.stock > 111 && _addDiscount2(each, 11))
this.before('CREATE', Orders, _reduceStock)
/** 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}`
)
}))
}
})
/** 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}`
)
}))
}

View File

@@ -1,5 +0,0 @@
ID;firstname;lastname;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;King’s Lynn, Norfolk;2012-02-26;Hertfordshire, England
Internal Server Error - Bruno's Gitea
500 Internal Server Error

Gitea Version: 1.24.4