├── db
├── .gitignore
├── src
│ ├── .hdinamespace
│ ├── data
│ │ ├── Stock.hdbtable
│ │ ├── Products.hdbtable
│ │ ├── stocks.csv
│ │ ├── FreightOrder.hdbtable
│ │ ├── Products.hdbtabledata
│ │ └── product.csv
│ └── .hdiconfig
├── manifest.yaml
├── package.json
└── package-lock.json
├── approuter
├── .gitignore
├── ui
│ ├── .gitignore
│ ├── uimodule
│ │ ├── webapp
│ │ │ ├── css
│ │ │ │ └── style.css
│ │ │ ├── IMAGES
│ │ │ │ ├── master.png
│ │ │ │ ├── AD-1000.jpg
│ │ │ │ ├── HT-1000.jpg
│ │ │ │ ├── HT-1001.jpg
│ │ │ │ ├── HT-1002.jpg
│ │ │ │ ├── HT-1003.jpg
│ │ │ │ ├── HT-1007.jpg
│ │ │ │ ├── HT-1010.jpg
│ │ │ │ ├── HT-1011.jpg
│ │ │ │ ├── HT-1020.jpg
│ │ │ │ ├── HT-1021.jpg
│ │ │ │ ├── HT-1022.jpg
│ │ │ │ ├── HT-1023.jpg
│ │ │ │ ├── HT-1030.jpg
│ │ │ │ ├── HT-1031.jpg
│ │ │ │ ├── HT-1032.jpg
│ │ │ │ ├── HT-1035.jpg
│ │ │ │ ├── HT-1036.jpg
│ │ │ │ ├── HT-1037.jpg
│ │ │ │ ├── HT-1040.jpg
│ │ │ │ ├── HT-1041.jpg
│ │ │ │ ├── HT-1042.jpg
│ │ │ │ ├── HT-1050.jpg
│ │ │ │ ├── HT-1051.jpg
│ │ │ │ ├── HT-1052.jpg
│ │ │ │ ├── HT-1055.jpg
│ │ │ │ ├── HT-1056.jpg
│ │ │ │ ├── HT-1060.jpg
│ │ │ │ ├── HT-1061.jpg
│ │ │ │ ├── HT-1062.jpg
│ │ │ │ ├── HT-1063.jpg
│ │ │ │ ├── HT-1064.jpg
│ │ │ │ ├── HT-1065.jpg
│ │ │ │ ├── HT-1066.jpg
│ │ │ │ ├── HT-1067.jpg
│ │ │ │ ├── HT-1068.jpg
│ │ │ │ ├── HT-1069.jpg
│ │ │ │ ├── HT-1070.jpg
│ │ │ │ ├── HT-1071.jpg
│ │ │ │ ├── HT-1072.jpg
│ │ │ │ ├── HT-1073.jpg
│ │ │ │ ├── HT-1080.jpg
│ │ │ │ ├── HT-1081.jpg
│ │ │ │ ├── HT-1082.jpg
│ │ │ │ ├── HT-1083.jpg
│ │ │ │ ├── HT-1085.jpg
│ │ │ │ ├── HT-1090.jpg
│ │ │ │ ├── HT-1091.jpg
│ │ │ │ ├── HT-1092.jpg
│ │ │ │ ├── HT-1095.jpg
│ │ │ │ ├── HT-1096.jpg
│ │ │ │ ├── HT-1097.jpg
│ │ │ │ ├── HT-1100.jpg
│ │ │ │ ├── HT-1101.jpg
│ │ │ │ ├── HT-1102.jpg
│ │ │ │ ├── HT-1103.jpg
│ │ │ │ ├── HT-1104.jpg
│ │ │ │ ├── HT-1105.jpg
│ │ │ │ ├── HT-1106.jpg
│ │ │ │ ├── HT-1107.jpg
│ │ │ │ ├── HT-1110.jpg
│ │ │ │ ├── HT-1111.jpg
│ │ │ │ ├── HT-1112.jpg
│ │ │ │ ├── HT-1113.jpg
│ │ │ │ ├── HT-1114.jpg
│ │ │ │ ├── HT-1115.jpg
│ │ │ │ ├── HT-1116.jpg
│ │ │ │ ├── HT-1117.jpg
│ │ │ │ ├── HT-1118.jpg
│ │ │ │ ├── HT-1119.jpg
│ │ │ │ ├── HT-1120.jpg
│ │ │ │ ├── HT-1137.jpg
│ │ │ │ ├── HT-1138.jpg
│ │ │ │ ├── HT-1210.jpg
│ │ │ │ ├── HT-1500.jpg
│ │ │ │ ├── HT-1501.jpg
│ │ │ │ ├── HT-1502.jpg
│ │ │ │ ├── HT-1600.jpg
│ │ │ │ ├── HT-1601.jpg
│ │ │ │ ├── HT-1602.jpg
│ │ │ │ ├── HT-1603.jpg
│ │ │ │ ├── HT-2000.jpg
│ │ │ │ ├── HT-2001.jpg
│ │ │ │ ├── HT-2002.jpg
│ │ │ │ ├── HT-2020.jpg
│ │ │ │ ├── HT-2025.jpg
│ │ │ │ ├── HT-2026.jpg
│ │ │ │ ├── HT-2027.jpg
│ │ │ │ ├── HT-2500.jpg
│ │ │ │ ├── HT-2501.jpg
│ │ │ │ ├── HT-2502.jpg
│ │ │ │ ├── HT-6100.jpg
│ │ │ │ ├── HT-6101.jpg
│ │ │ │ ├── HT-6102.jpg
│ │ │ │ ├── HT-6110.jpg
│ │ │ │ ├── HT-6111.jpg
│ │ │ │ ├── HT-6120.jpg
│ │ │ │ ├── HT-6121.jpg
│ │ │ │ ├── HT-6122.jpg
│ │ │ │ ├── HT-6123.jpg
│ │ │ │ ├── HT-6130.jpg
│ │ │ │ ├── HT-6131.jpg
│ │ │ │ ├── HT-6132.jpg
│ │ │ │ ├── HT-7000.jpg
│ │ │ │ ├── HT-7010.jpg
│ │ │ │ ├── HT-7020.jpg
│ │ │ │ ├── HT-7030.jpg
│ │ │ │ ├── HT-8000.jpg
│ │ │ │ ├── HT-8001.jpg
│ │ │ │ ├── HT-8002.jpg
│ │ │ │ ├── HT-8003.jpg
│ │ │ │ ├── american.png
│ │ │ │ ├── mastero.png
│ │ │ │ └── resilience.png
│ │ │ ├── resources
│ │ │ │ └── img
│ │ │ │ │ └── favicon.ico
│ │ │ ├── i18n
│ │ │ │ ├── i18n.properties
│ │ │ │ └── i18n_en.properties
│ │ │ ├── test
│ │ │ │ ├── testsuite.qunit.html
│ │ │ │ ├── integration
│ │ │ │ │ ├── opaTests.qunit.js
│ │ │ │ │ ├── AllJourneys.js
│ │ │ │ │ ├── arrangements
│ │ │ │ │ │ └── Startup.js
│ │ │ │ │ ├── BasicJourney.js
│ │ │ │ │ ├── opaTests.qunit.html
│ │ │ │ │ └── pages
│ │ │ │ │ │ └── MainView.js
│ │ │ │ └── testsuite.qunit.js
│ │ │ ├── model
│ │ │ │ ├── models.js
│ │ │ │ └── formatter.js
│ │ │ ├── Component.js
│ │ │ ├── index.html
│ │ │ ├── view
│ │ │ │ ├── MainView.view.xml
│ │ │ │ ├── ReviewPage.fragment.xml
│ │ │ │ └── orderView.fragment.xml
│ │ │ ├── manifest.json
│ │ │ └── controller
│ │ │ │ └── BaseController.js
│ │ └── ui5.yaml
│ ├── .eslintignore
│ ├── manifest.yaml
│ ├── readme.md
│ ├── debug.log
│ ├── .editorconfig
│ ├── karma.conf.js
│ ├── .yo-rc.json
│ ├── karma-ci.conf.js
│ ├── .eslintrc
│ └── package.json
├── package.json
├── xs-app.json
└── manifest.yml
├── test
├── .gitignore
├── package.json
├── util.js
├── config.js
├── test-suite.test.js
└── test-suite.js
├── freight-manager
├── .npmrc
├── sap-cloud-sdk-analytics.json
├── .prettierrc
├── nest-cli.json
├── systems.json
├── tsconfig.build.json
├── manifest.yml
├── src
│ ├── freight-service
│ │ ├── freight.module.ts
│ │ ├── freight.controller.spec.ts
│ │ ├── freight.service.ts
│ │ └── freight.controller.ts
│ └── main.ts
├── tsconfig.json
├── .gitignore
├── .eslintrc.js
├── test
│ ├── jest-e2e.json
│ └── app.e2e-spec.ts
├── xs-security.json
└── package.json
├── product-service
├── .npmrc
├── .prettierrc
├── nest-cli.json
├── systems.json
├── tsconfig.build.json
├── sap-cloud-sdk-analytics.json
├── src
│ ├── app.service.ts
│ ├── app.controller.ts
│ ├── products
│ │ ├── stock.module.ts
│ │ ├── product.module.ts
│ │ ├── product.service.ts
│ │ ├── stock.service.ts
│ │ ├── product.controller.ts
│ │ └── stock.controller.ts
│ ├── app.module.ts
│ └── main.ts
├── manifest.yml
├── tsconfig.json
├── .gitignore
├── .eslintrc.js
├── test
│ ├── jest-e2e.json
│ ├── app.controller.spec.ts
│ └── app.e2e-spec.ts
└── package.json
├── logistics-service
├── .npmrc
├── .prettierrc
├── nest-cli.json
├── systems.json
├── tsconfig.build.json
├── sap-cloud-sdk-analytics.json
├── src
│ ├── app.service.ts
│ ├── app.controller.ts
│ ├── logistics
│ │ ├── order.module.ts
│ │ ├── quote.module.ts
│ │ ├── order.service.ts
│ │ ├── order.controller.ts
│ │ ├── quote.controller.ts
│ │ └── quote.service.ts
│ ├── providers
│ │ ├── security-credentials.provider.ts
│ │ └── destination.provider.ts
│ ├── app.module.ts
│ ├── app.controller.spec.ts
│ ├── main.ts
│ └── model
│ │ └── quotemodel.dto.ts
├── tsconfig.json
├── manifest.yml
├── .gitignore
├── .eslintrc.js
├── test
│ ├── jest-e2e.json
│ └── app.e2e-spec.ts
└── package.json
├── images
├── hr.gif
├── tam.PNG
├── dbid.png
├── hana.PNG
├── bullet.png
├── nav-bg.gif
├── swagger.png
├── login page.png
├── create-order.png
├── destination.png
├── hana-cockpit.png
├── postman-token.png
├── request-quote.png
├── swagger-post.png
├── address-details.png
├── select-product.png
├── shipment orders.png
├── solutiondiagram.PNG
├── swagger-execute.png
├── selected-product.png
├── env-logistics-service.png
└── solutiondiagram_updated.png
├── .vscode
└── settings.json
├── .reuse
└── dep5
├── security-config
└── xs-security.json
├── Jenkinsfile
├── LICENSES
└── Apache-2.0.txt
└── LICENSE
/db/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
--------------------------------------------------------------------------------
/approuter/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 |
--------------------------------------------------------------------------------
/test/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | package-lock.json
--------------------------------------------------------------------------------
/freight-manager/.npmrc:
--------------------------------------------------------------------------------
1 | @sap:registry=https://registry.npmjs.org
--------------------------------------------------------------------------------
/freight-manager/sap-cloud-sdk-analytics.json:
--------------------------------------------------------------------------------
1 | {"enabled":false}
--------------------------------------------------------------------------------
/approuter/ui/.gitignore:
--------------------------------------------------------------------------------
1 | # compiled output
2 |
3 | /node_modules
4 |
--------------------------------------------------------------------------------
/product-service/.npmrc:
--------------------------------------------------------------------------------
1 | @sap:registry=https://registry.npmjs.org
2 |
--------------------------------------------------------------------------------
/logistics-service/.npmrc:
--------------------------------------------------------------------------------
1 | @sap:registry=https://registry.npmjs.org
2 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/css/style.css:
--------------------------------------------------------------------------------
1 | /* Enter your custom styles here */
2 |
--------------------------------------------------------------------------------
/db/src/.hdinamespace:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "subfolder": "ignore"
4 | }
--------------------------------------------------------------------------------
/freight-manager/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all"
4 | }
--------------------------------------------------------------------------------
/images/hr.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/hr.gif
--------------------------------------------------------------------------------
/images/tam.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/tam.PNG
--------------------------------------------------------------------------------
/logistics-service/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all"
4 | }
--------------------------------------------------------------------------------
/product-service/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all"
4 | }
--------------------------------------------------------------------------------
/images/dbid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/dbid.png
--------------------------------------------------------------------------------
/images/hana.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/hana.PNG
--------------------------------------------------------------------------------
/images/bullet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/bullet.png
--------------------------------------------------------------------------------
/images/nav-bg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/nav-bg.gif
--------------------------------------------------------------------------------
/images/swagger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/swagger.png
--------------------------------------------------------------------------------
/approuter/ui/.eslintignore:
--------------------------------------------------------------------------------
1 | templates/
2 | deployer/resources/
3 | node_modules/
4 | approuter/webapp/
5 |
--------------------------------------------------------------------------------
/images/login page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/login page.png
--------------------------------------------------------------------------------
/freight-manager/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": "@nestjs/schematics",
3 | "sourceRoot": "src"
4 | }
5 |
--------------------------------------------------------------------------------
/images/create-order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/create-order.png
--------------------------------------------------------------------------------
/images/destination.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/destination.png
--------------------------------------------------------------------------------
/images/hana-cockpit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/hana-cockpit.png
--------------------------------------------------------------------------------
/images/postman-token.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/postman-token.png
--------------------------------------------------------------------------------
/images/request-quote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/request-quote.png
--------------------------------------------------------------------------------
/images/swagger-post.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/swagger-post.png
--------------------------------------------------------------------------------
/logistics-service/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": "@nestjs/schematics",
3 | "sourceRoot": "src"
4 | }
5 |
--------------------------------------------------------------------------------
/product-service/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": "@nestjs/schematics",
3 | "sourceRoot": "src"
4 | }
5 |
--------------------------------------------------------------------------------
/images/address-details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/address-details.png
--------------------------------------------------------------------------------
/images/select-product.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/select-product.png
--------------------------------------------------------------------------------
/images/shipment orders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/shipment orders.png
--------------------------------------------------------------------------------
/images/solutiondiagram.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/solutiondiagram.PNG
--------------------------------------------------------------------------------
/images/swagger-execute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/swagger-execute.png
--------------------------------------------------------------------------------
/images/selected-product.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/selected-product.png
--------------------------------------------------------------------------------
/images/env-logistics-service.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/env-logistics-service.png
--------------------------------------------------------------------------------
/images/solutiondiagram_updated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/images/solutiondiagram_updated.png
--------------------------------------------------------------------------------
/freight-manager/systems.json:
--------------------------------------------------------------------------------
1 | {
2 | "systems": [{
3 | "alias": "EXAMPLE",
4 | "uri": "https://example.com"
5 | }]
6 | }
7 |
--------------------------------------------------------------------------------
/logistics-service/systems.json:
--------------------------------------------------------------------------------
1 | {
2 | "systems": [{
3 | "alias": "EXAMPLE",
4 | "uri": "https://example.com"
5 | }]
6 | }
7 |
--------------------------------------------------------------------------------
/product-service/systems.json:
--------------------------------------------------------------------------------
1 | {
2 | "systems": [{
3 | "alias": "EXAMPLE",
4 | "uri": "https://example.com"
5 | }]
6 | }
7 |
--------------------------------------------------------------------------------
/freight-manager/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/product-service/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/logistics-service/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "git.ignoreLimitWarning": true,
3 | "SAP HANA Database Explorer.displaySapWebAnalyticsStartupNotification": false
4 | }
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/master.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/master.png
--------------------------------------------------------------------------------
/logistics-service/sap-cloud-sdk-analytics.json:
--------------------------------------------------------------------------------
1 | {
2 | "enabled": true,
3 | "salt": "8ff41abb176a3749269a145728eba7b7c87c7cce82c2a02c6d6e61f653d495d3"
4 | }
--------------------------------------------------------------------------------
/product-service/sap-cloud-sdk-analytics.json:
--------------------------------------------------------------------------------
1 | {
2 | "enabled": true,
3 | "salt": "f6936c8b5df78f00c63e803e0dba3a299d32a6898710c6929d475aebe6a86d0d"
4 | }
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/AD-1000.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/AD-1000.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1000.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1000.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1001.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1001.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1002.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1002.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1003.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1003.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1007.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1007.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1010.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1010.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1011.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1011.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1020.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1020.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1021.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1021.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1022.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1022.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1023.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1023.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1030.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1030.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1031.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1031.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1032.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1032.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1035.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1035.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1036.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1036.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1037.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1037.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1040.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1040.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1041.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1041.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1042.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1042.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1050.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1050.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1051.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1051.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1052.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1052.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1055.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1055.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1056.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1056.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1060.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1060.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1061.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1061.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1062.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1062.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1063.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1063.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1064.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1064.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1065.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1065.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1066.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1066.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1067.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1067.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1068.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1068.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1069.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1069.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1070.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1070.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1071.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1071.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1072.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1072.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1073.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1073.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1080.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1080.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1081.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1081.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1082.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1082.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1083.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1083.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1085.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1085.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1090.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1090.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1091.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1091.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1092.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1092.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1095.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1095.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1096.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1096.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1097.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1097.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1100.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1101.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1101.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1102.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1102.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1103.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1103.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1104.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1104.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1105.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1105.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1106.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1106.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1107.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1107.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1110.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1110.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1111.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1111.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1112.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1112.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1113.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1113.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1114.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1114.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1115.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1115.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1116.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1116.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1117.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1117.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1118.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1118.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1119.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1119.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1120.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1120.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1137.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1137.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1138.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1138.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1210.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1210.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1500.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1500.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1501.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1501.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1502.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1502.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1600.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1600.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1601.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1601.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1602.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1602.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-1603.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-1603.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2000.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2000.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2001.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2001.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2002.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2002.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2020.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2020.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2025.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2025.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2026.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2026.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2027.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2027.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2500.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2500.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2501.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2501.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-2502.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-2502.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6100.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6100.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6101.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6101.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6102.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6102.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6110.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6110.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6111.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6111.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6120.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6120.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6121.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6121.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6122.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6122.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6123.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6123.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6130.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6130.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6131.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6131.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-6132.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-6132.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-7000.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-7000.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-7010.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-7010.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-7020.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-7020.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-7030.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-7030.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-8000.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-8000.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-8001.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-8001.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-8002.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-8002.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/HT-8003.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/HT-8003.jpg
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/american.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/american.png
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/mastero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/mastero.png
--------------------------------------------------------------------------------
/approuter/ui/manifest.yaml:
--------------------------------------------------------------------------------
1 | applications:
2 | - name: oflm
3 | path: uimodule/
4 | buildpacks:
5 | - staticfile_buildpack
6 | memory: 64M
7 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/IMAGES/resilience.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/IMAGES/resilience.png
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/resources/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/cloud-nodejs-oflm/HEAD/approuter/ui/uimodule/webapp/resources/img/favicon.ico
--------------------------------------------------------------------------------
/db/src/data/Stock.hdbtable:
--------------------------------------------------------------------------------
1 | COLUMN TABLE "Products.stock" (
2 | PRODUCTID VARCHAR(40) NOT NULL,
3 | QUANTITY INTEGER,
4 | PRIMARY KEY(PRODUCTID)
5 | );
6 |
7 |
--------------------------------------------------------------------------------
/db/manifest.yaml:
--------------------------------------------------------------------------------
1 | applications:
2 | - name: freight_db
3 | no-route: true
4 | type: hdb
5 | health-check-type: process
6 | memory: 128M
7 | services:
8 | - nodeapp_db
9 |
--------------------------------------------------------------------------------
/logistics-service/src/app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 |
3 | @Injectable()
4 | export class AppService {
5 | getHello(): string {
6 | return 'Hello SAP!';
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/approuter/ui/readme.md:
--------------------------------------------------------------------------------
1 | # oflm
2 | Insert the purpose of this project and some intersting infos here
3 |
4 |
5 | ## Credits
6 | This project has been generated with 💙 and [easy-ui5](https://github.com/SAP)
7 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/i18n/i18n.properties:
--------------------------------------------------------------------------------
1 | title=Outbound Freight and Logistics Management
2 | appTitle=Outbound Freight and Logistics Management
3 | appDescription=Outbound Freight and Logistics Management
4 |
--------------------------------------------------------------------------------
/product-service/src/app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 |
3 | @Injectable()
4 | export class AppService {
5 | getHello(): string {
6 | return 'Hello Product Service!';
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/i18n/i18n_en.properties:
--------------------------------------------------------------------------------
1 | title=Outbound Freight and Logistics Management
2 | appTitle=Outbound Freight and Logistics Management
3 | appDescription=Outbound Freight and Logistics Management
4 |
--------------------------------------------------------------------------------
/db/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "deploy",
3 | "dependencies": {
4 | "@sap/hdi-deploy": "^4.8.2"
5 | },
6 | "scripts": {
7 | "start": "node node_modules/@sap/hdi-deploy/deploy.js"
8 | }
9 | }
--------------------------------------------------------------------------------
/approuter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "approuter",
3 | "dependencies": {
4 | "@sap/approuter": "^14.4.3"
5 | },
6 | "scripts": {
7 | "start": "node node_modules/@sap/approuter/approuter.js"
8 | }
9 | }
--------------------------------------------------------------------------------
/approuter/ui/debug.log:
--------------------------------------------------------------------------------
1 | [0730/130359.410:ERROR:crash_report_database_win.cc(428)] unexpected header
2 | [0813/130757.206:ERROR:crash_report_database_win.cc(428)] unexpected header
3 | [0813/140421.871:ERROR:crash_report_database_win.cc(428)] unexpected header
4 |
--------------------------------------------------------------------------------
/freight-manager/manifest.yml:
--------------------------------------------------------------------------------
1 | applications:
2 | - name: freight-manager
3 | path: deployment/
4 | buildpacks:
5 | - nodejs_buildpack
6 | memory: 256M
7 | command: npm run start:prod
8 | random-route: true
9 | services:
10 | - freight-xsuaa
11 |
--------------------------------------------------------------------------------
/approuter/ui/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 | end_of_line = lf
10 | # editorconfig-tools is unable to ignore longs strings or urls
11 | max_line_length = off
--------------------------------------------------------------------------------
/product-service/manifest.yml:
--------------------------------------------------------------------------------
1 | applications:
2 | - name: product-service
3 | path: deployment/
4 | buildpacks:
5 | - nodejs_buildpack
6 | memory: 256M
7 | command: npm run start:prod
8 | random-route: true
9 | services:
10 | - businessuser-authentication
11 | - nodeapp_db
12 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/test/testsuite.qunit.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | QUnit test suite for Worklist
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/test/integration/opaTests.qunit.js:
--------------------------------------------------------------------------------
1 | /* global QUnit */
2 |
3 | QUnit.config.autostart = false;
4 |
5 | sap.ui.getCore().attachInit(function() {
6 | "use strict";
7 |
8 | sap.ui.require([
9 | "com/sap/oflm/test/integration/AllJourneys"
10 | ], function() {
11 | QUnit.start();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/freight-manager/src/freight-service/freight.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { AppController } from './freight.controller';
3 | import { AppService } from './freight.service';
4 |
5 | @Module({
6 | imports: [],
7 | controllers: [AppController],
8 | providers: [AppService],
9 | })
10 | export class AppModule {}
11 |
--------------------------------------------------------------------------------
/.reuse/dep5:
--------------------------------------------------------------------------------
1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2 | Upstream-Name: cloud-nodejs-oflm
3 | Upstream-Contact: Gopal Anand (gopal.anand@sap.com)
4 | Source: https://github.com/SAP-samples/cloud-nodejs-oflm
5 |
6 | Files: *
7 | Copyright: 2020 SAP SE or an SAP affiliate company and cloud-nodejs-oflm
8 | License: Apache-2.0
--------------------------------------------------------------------------------
/product-service/src/app.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get } from '@nestjs/common';
2 | import { AppService } from './app.service';
3 |
4 | @Controller()
5 | export class AppController {
6 | constructor(private readonly appService: AppService) {}
7 |
8 | @Get()
9 | getHello(): string {
10 | return this.appService.getHello();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/logistics-service/src/app.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get } from '@nestjs/common';
2 | import { AppService } from './app.service';
3 |
4 | @Controller()
5 | export class AppController {
6 | constructor(private readonly appService: AppService) {}
7 |
8 | @Get()
9 | getHello(): string {
10 | return this.appService.getHello();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "integration_test",
3 | "version": "1.0.0",
4 | "description": "",
5 | "scripts": {
6 | "test": "jest"
7 | },
8 | "author": "",
9 | "license": "ISC",
10 | "dependencies": {
11 | "node-fetch": "^2.6.1",
12 | "qs": "^6.10.1"
13 | },
14 | "devDependencies": {
15 | "jest": "^27.0.6"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/product-service/src/products/stock.module.ts:
--------------------------------------------------------------------------------
1 | import { StockService } from './stock.service';
2 | import { StockController } from './stock.controller';
3 | import { Module } from '@nestjs/common';
4 |
5 | @Module({
6 | imports: [],
7 | controllers: [
8 | StockController],
9 | providers: [
10 | StockService],
11 | })
12 | export class StockModule { }
13 |
--------------------------------------------------------------------------------
/logistics-service/src/logistics/order.module.ts:
--------------------------------------------------------------------------------
1 | import { OrderController } from './order.controller';
2 | import { OrderService } from './order.service';
3 | import { Module } from '@nestjs/common';
4 |
5 | @Module({
6 | imports: [],
7 | controllers: [
8 | OrderController],
9 | providers: [
10 | OrderService],
11 | })
12 | export class OrderModule { }
13 |
--------------------------------------------------------------------------------
/logistics-service/src/providers/security-credentials.provider.ts:
--------------------------------------------------------------------------------
1 | import * as xsenv from '@sap/xsenv';
2 | const xsCredentials = xsenv.cfServiceCredentials({tag: 'xsuaa'});
3 | /**
4 | * exports client credentials from vcap
5 | */
6 | export const ServiceCredentials = [{ "clientId": xsCredentials.clientid, "clientSecret": xsCredentials.clientsecret,"url": xsCredentials.url }];
7 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/model/models.js:
--------------------------------------------------------------------------------
1 | sap.ui.define([
2 | "sap/ui/model/json/JSONModel",
3 | "sap/ui/Device"
4 | ], function(JSONModel, Device) {
5 | "use strict";
6 |
7 | return {
8 | createDeviceModel: function() {
9 | var oModel = new JSONModel(Device);
10 | oModel.setDefaultBindingMode("OneWay");
11 | return oModel;
12 | }
13 | };
14 | });
15 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/test/integration/AllJourneys.js:
--------------------------------------------------------------------------------
1 | sap.ui.define([
2 | "sap/ui/test/Opa5",
3 | "com/sap/oflm/test/integration/arrangements/Startup",
4 | "com/sap/oflm/test/integration/BasicJourney"
5 | ], function(Opa5, Startup) {
6 | "use strict";
7 |
8 | Opa5.extendConfig({
9 | arrangements: new Startup(),
10 | pollingInterval: 1
11 | });
12 |
13 | });
14 |
--------------------------------------------------------------------------------
/product-service/src/products/product.module.ts:
--------------------------------------------------------------------------------
1 | import { ProductService } from './product.service';
2 | import { ProductController } from './product.controller';
3 | import { Module } from '@nestjs/common';
4 |
5 | @Module({
6 | imports: [],
7 | controllers: [
8 | ProductController],
9 | providers: [
10 | ProductService],
11 | })
12 | export class ProductModule { }
13 |
--------------------------------------------------------------------------------
/logistics-service/src/logistics/quote.module.ts:
--------------------------------------------------------------------------------
1 | import { QuoteController } from './quote.controller';
2 | import { Module } from '@nestjs/common';
3 | import { HttpModule } from '@nestjs/axios';
4 | import {QuoteService} from './quote.service';
5 | @Module({
6 | imports: [HttpModule],
7 | controllers: [
8 | QuoteController],
9 | providers: [QuoteService],
10 | })
11 | export class QuoteModule {}
12 |
--------------------------------------------------------------------------------
/approuter/ui/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function (config) {
2 | "use strict";
3 |
4 | config.set({
5 | frameworks: ["ui5"], ui5: {
6 | type: "application",
7 | configPath: "uimodule/ui5.yaml",
8 | paths: {
9 | webapp: "uimodule/webapp"
10 | }
11 | },
12 | browsers: ["Chrome"],
13 | browserConsoleLogOptions: {
14 | level: "error"
15 | }
16 | });
17 | };
18 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/test/testsuite.qunit.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line
2 | window.suite = function() {
3 | "use strict";
4 |
5 | // eslint-disable-next-line
6 | var oSuite = new parent.jsUnitTestSuite(),
7 | sContextPath = location.pathname.substring(0, location.pathname.lastIndexOf("/") + 1);
8 |
9 | oSuite.addTestPage(sContextPath + "integration/opaTests.qunit.html");
10 |
11 | return oSuite;
12 | };
13 |
--------------------------------------------------------------------------------
/freight-manager/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "removeComments": true,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "allowSyntheticDefaultImports": true,
9 | "target": "es2017",
10 | "sourceMap": true,
11 | "outDir": "./dist",
12 | "baseUrl": "./",
13 | "incremental": true
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/logistics-service/src/providers/destination.provider.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Exports destination service
3 | */
4 | import { useOrFetchDestination } from '@sap-cloud-sdk/connectivity';
5 |
6 | const destionationObject = useOrFetchDestination({ destinationName: 'freight-manager' }).then(destination => {
7 | return destination;
8 | }).catch(err => {
9 | return err;
10 | });
11 | export const destination = destionationObject;
--------------------------------------------------------------------------------
/logistics-service/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "removeComments": true,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "allowSyntheticDefaultImports": true,
9 | "target": "es2017",
10 | "sourceMap": true,
11 | "outDir": "./dist",
12 | "baseUrl": "./",
13 | "incremental": true
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/approuter/ui/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-easy-ui5": {
3 | "projectname": "oflm",
4 | "namespace": "com.sap",
5 | "platform": "Static webserver",
6 | "viewtype": "XML",
7 | "viewname": "MainView",
8 | "ui5libs": "Content delivery network (SAPUI5)",
9 | "newdir": false,
10 | "namespaceURI": "com/sap",
11 | "uimodules": [
12 | "uimodule"
13 | ],
14 | "setupCompleted": true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/logistics-service/manifest.yml:
--------------------------------------------------------------------------------
1 | applications:
2 | - name: logistics-service
3 | path: deployment/
4 | buildpacks:
5 | - nodejs_buildpack
6 | memory: 256M
7 | command: npm run start:prod
8 | random-route: true
9 | services:
10 | - businessuser-authentication
11 | - nodeapp_db
12 | - freight-manager
13 | env:
14 | product_service: https://product-service-zany-wallaby-ns.cfapps.eu10-004.hana.ondemand.com
15 |
--------------------------------------------------------------------------------
/product-service/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "removeComments": true,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "allowSyntheticDefaultImports": true,
9 | "target": "es2017",
10 | "sourceMap": true,
11 | "outDir": "./dist",
12 | "baseUrl": "./",
13 | "incremental": true,
14 | "resolveJsonModule": true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/model/formatter.js:
--------------------------------------------------------------------------------
1 | sap.ui.define([], function () {
2 | "use strict";
3 | return {
4 | dateFormatter: function (date) {
5 | return new Date(date.slice(0, 4) + "/" + date.slice(4, 6) + "/" + date.slice(6, 8)).toDateString();
6 | },
7 | statusFormatter: function (state) {
8 | var status;
9 | if (state === "A") {
10 | status = "Accepted";
11 | } else {
12 | status = "Declined";
13 | }
14 | return status;
15 | }
16 | };
17 | });
18 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/test/integration/arrangements/Startup.js:
--------------------------------------------------------------------------------
1 | sap.ui.define([
2 | "sap/ui/test/Opa5"
3 | ], function(Opa5) {
4 | "use strict";
5 |
6 | return Opa5.extend("com.sap.oflm.test.integration.arrangements.Startup", {
7 |
8 | iStartMyApp: function () {
9 | this.iStartMyUIComponent({
10 | componentConfig: {
11 | name: "com.sap.oflm",
12 | async: true,
13 | manifest: true
14 | }
15 | });
16 | }
17 |
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/test/integration/BasicJourney.js:
--------------------------------------------------------------------------------
1 | sap.ui.define([
2 | "sap/ui/test/opaQunit",
3 | "com/sap/oflm/test/integration/pages/MainView"
4 | ], function (opaTest) {
5 | "use strict";
6 |
7 | opaTest("should show correct number of nested pages", function (Given, When, Then) {
8 |
9 | // Arrangements
10 | Given.iStartMyApp();
11 |
12 | // Assertions
13 | Then.onTheAppPage.iShouldSeePageCount(1);
14 |
15 | // Cleanup
16 | Then.iTeardownMyApp();
17 | });
18 |
19 | });
20 |
--------------------------------------------------------------------------------
/approuter/ui/karma-ci.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function (config) {
2 | "use strict";
3 |
4 | require("./karma.conf")(config);
5 | config.set({
6 |
7 | // test results reporter to use
8 | // possible values: "dots", "progress", "coverage"
9 | reporters: ["progress"],
10 |
11 | // start these browsers
12 | browsers: ["ChromeHeadless"],
13 |
14 | // Continuous Integration mode
15 | // if true, Karma captures browsers, runs the tests and exits
16 | singleRun: true
17 |
18 | });
19 | };
20 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/ui5.yaml:
--------------------------------------------------------------------------------
1 | specVersion: "2.0"
2 | metadata:
3 | name: oflm_uimodule
4 | type: application
5 | resources:
6 | configuration:
7 | paths:
8 | webapp: uimodule/webapp
9 | framework:
10 | name: SAPUI5
11 | version: 1.77.0
12 | libraries:
13 | - name: sap.ui.core
14 | - name: sap.m
15 | - name: sap.ui.layout
16 | - name: themelib_sap_fiori_3
17 | server:
18 | customMiddleware:
19 | - name: ui5-middleware-livereload
20 | afterMiddleware: compression
21 | configuration:
22 | port: 35729
23 | path: uimodule/webapp
24 |
--------------------------------------------------------------------------------
/freight-manager/.gitignore:
--------------------------------------------------------------------------------
1 | # compiled output
2 | /dist
3 | /node_modules
4 |
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 | lerna-debug.log*
12 |
13 | # OS
14 | .DS_Store
15 |
16 | # Tests
17 | /coverage
18 | /.nyc_output
19 |
20 | # IDEs and editors
21 | /.idea
22 | .project
23 | .classpath
24 | .c9/
25 | *.launch
26 | .settings/
27 | *.sublime-workspace
28 |
29 | # IDE - VSCode
30 | .vscode/*
31 | !.vscode/settings.json
32 | !.vscode/tasks.json
33 | !.vscode/launch.json
34 | !.vscode/extensions.json
35 | credentials.json
36 | /s4hana_pipeline
37 | /deployment
38 |
--------------------------------------------------------------------------------
/logistics-service/.gitignore:
--------------------------------------------------------------------------------
1 | # compiled output
2 | /dist
3 | /node_modules
4 |
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 | lerna-debug.log*
12 |
13 | # OS
14 | .DS_Store
15 |
16 | # Tests
17 | /coverage
18 | /.nyc_output
19 |
20 | # IDEs and editors
21 | /.idea
22 | .project
23 | .classpath
24 | .c9/
25 | *.launch
26 | .settings/
27 | *.sublime-workspace
28 |
29 | # IDE - VSCode
30 | .vscode/*
31 | !.vscode/settings.json
32 | !.vscode/tasks.json
33 | !.vscode/launch.json
34 | !.vscode/extensions.json
35 | credentials.json
36 | /s4hana_pipeline
37 | /deployment
38 |
--------------------------------------------------------------------------------
/product-service/.gitignore:
--------------------------------------------------------------------------------
1 | # compiled output
2 | /dist
3 | /node_modules
4 |
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 | lerna-debug.log*
12 |
13 | # OS
14 | .DS_Store
15 |
16 | # Tests
17 | /coverage
18 | /.nyc_output
19 |
20 | # IDEs and editors
21 | /.idea
22 | .project
23 | .classpath
24 | .c9/
25 | *.launch
26 | .settings/
27 | *.sublime-workspace
28 |
29 | # IDE - VSCode
30 | .vscode/*
31 | !.vscode/settings.json
32 | !.vscode/tasks.json
33 | !.vscode/launch.json
34 | !.vscode/extensions.json
35 | credentials.json
36 | /s4hana_pipeline
37 | /deployment
38 |
--------------------------------------------------------------------------------
/product-service/src/app.module.ts:
--------------------------------------------------------------------------------
1 |
2 | import { Module } from '@nestjs/common';
3 | import { AppController } from './app.controller';
4 | import { AppService } from './app.service';
5 | import { ProductModule } from './products/product.module';
6 | import { ProductService } from './products/product.service';
7 | import { StockService } from './products/stock.service';
8 | import { StockModule } from './products/stock.module';
9 | @Module({
10 | imports: [
11 | ProductModule, StockModule],
12 | controllers: [AppController],
13 | providers: [AppService, ProductService, StockService],
14 | })
15 | export class AppModule { }
16 |
--------------------------------------------------------------------------------
/approuter/xs-app.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcomeFile": "ui/index.html",
3 | "routes": [
4 | {
5 | "source": "^/productService",
6 | "target": "/",
7 | "destination": "product-service",
8 | "scope": "$XSAPPNAME.Supplier"
9 | },{
10 | "source": "^/logisticsService",
11 | "target": "/",
12 | "destination": "logisticsService",
13 | "scope": "$XSAPPNAME.Supplier"
14 | },
15 | {
16 | "source": "^/ui/(.*)",
17 | "target" :"$1",
18 | "localDir": "ui/uimodule/webapp",
19 | "replace": {
20 | "pathSuffixes": [
21 | "index.html"
22 | ]
23 | },
24 | "scope": "$XSAPPNAME.Supplier"
25 | }
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/approuter/manifest.yml:
--------------------------------------------------------------------------------
1 | applications:
2 | - name: oflm-approuter
3 | path: .
4 | memory: 128M
5 | buildpacks:
6 | - nodejs_buildpack
7 | env:
8 | TENANT_HOST_PATTERN: >-
9 | "oflm-approuter-(.*).cfapps.eu10-004.hana.ondemand.com"
10 | destinations: >-
11 | [
12 | {"name": "product-service","url": "https://product-service-zany-wallaby-ns.cfapps.eu10-004.hana.ondemand.com", "forwardAuthToken":true},
13 | {"name": "logisticsService","url":"https://logistics-service-exhausted-gnu-bs.cfapps.eu10-004.hana.ondemand.com", "forwardAuthToken":true}
14 | ]
15 | services:
16 | - businessuser-authentication
17 |
--------------------------------------------------------------------------------
/logistics-service/src/app.module.ts:
--------------------------------------------------------------------------------
1 |
2 | import { Module } from '@nestjs/common';
3 | import { HttpModule } from '@nestjs/axios';
4 | import { AppController } from './app.controller';
5 | import { AppService } from './app.service';
6 | import { QuoteModule } from './logistics/quote.module';
7 | import { QuoteService } from './logistics/quote.service';
8 | import {OrderModule} from './logistics/order.module';
9 | import {OrderService} from './logistics/order.service';
10 | @Module({
11 | imports: [
12 | QuoteModule, HttpModule, OrderModule],
13 | controllers: [AppController],
14 | providers: [
15 | QuoteService, AppService, OrderService],
16 | })
17 | export class AppModule { }
18 |
--------------------------------------------------------------------------------
/freight-manager/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: '@typescript-eslint/parser',
3 | parserOptions: {
4 | project: 'tsconfig.json',
5 | sourceType: 'module',
6 | },
7 | plugins: ['@typescript-eslint/eslint-plugin'],
8 | extends: [
9 | 'plugin:@typescript-eslint/eslint-recommended',
10 | 'plugin:@typescript-eslint/recommended',
11 | 'prettier',
12 | 'prettier/@typescript-eslint',
13 | ],
14 | root: true,
15 | env: {
16 | node: true,
17 | jest: true,
18 | },
19 | rules: {
20 | '@typescript-eslint/interface-name-prefix': 'off',
21 | '@typescript-eslint/explicit-function-return-type': 'off',
22 | '@typescript-eslint/no-explicit-any': 'off',
23 | },
24 | };
25 |
--------------------------------------------------------------------------------
/product-service/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: '@typescript-eslint/parser',
3 | parserOptions: {
4 | project: 'tsconfig.json',
5 | sourceType: 'module',
6 | },
7 | plugins: ['@typescript-eslint/eslint-plugin'],
8 | extends: [
9 | 'plugin:@typescript-eslint/eslint-recommended',
10 | 'plugin:@typescript-eslint/recommended',
11 | 'prettier',
12 | 'prettier/@typescript-eslint',
13 | ],
14 | root: true,
15 | env: {
16 | node: true,
17 | jest: true,
18 | },
19 | rules: {
20 | '@typescript-eslint/interface-name-prefix': 'off',
21 | '@typescript-eslint/explicit-function-return-type': 'off',
22 | '@typescript-eslint/no-explicit-any': 'off',
23 | },
24 | };
25 |
--------------------------------------------------------------------------------
/freight-manager/test/jest-e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "moduleFileExtensions": [
3 | "js",
4 | "json",
5 | "ts"
6 | ],
7 | "rootDir": ".",
8 | "testEnvironment": "node",
9 | "testRegex": ".e2e-spec.ts$",
10 | "transform": {
11 | "^.+\\.(t|j)s$": "ts-jest"
12 | },
13 | "reporters": [
14 | "default",
15 | [
16 | "jest-junit",
17 | {
18 | "suiteName": "backend unit tests",
19 | "outputDirectory": "./s4hana_pipeline/reports/backend-integration"
20 | }
21 | ]
22 | ],
23 | "collectCoverage": true,
24 | "coverageReporters": [
25 | "text",
26 | "cobertura"
27 | ],
28 | "coverageDirectory": "../s4hana_pipeline/reports/coverage-reports/backend-integration"
29 | }
--------------------------------------------------------------------------------
/logistics-service/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: '@typescript-eslint/parser',
3 | parserOptions: {
4 | project: 'tsconfig.json',
5 | sourceType: 'module',
6 | },
7 | plugins: ['@typescript-eslint/eslint-plugin'],
8 | extends: [
9 | 'plugin:@typescript-eslint/eslint-recommended',
10 | 'plugin:@typescript-eslint/recommended',
11 | 'prettier',
12 | 'prettier/@typescript-eslint',
13 | ],
14 | root: true,
15 | env: {
16 | node: true,
17 | jest: true,
18 | },
19 | rules: {
20 | '@typescript-eslint/interface-name-prefix': 'off',
21 | '@typescript-eslint/explicit-function-return-type': 'off',
22 | '@typescript-eslint/no-explicit-any': 'off',
23 | },
24 | };
25 |
--------------------------------------------------------------------------------
/logistics-service/test/jest-e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "moduleFileExtensions": [
3 | "js",
4 | "json",
5 | "ts"
6 | ],
7 | "rootDir": ".",
8 | "testEnvironment": "node",
9 | "testRegex": ".e2e-spec.ts$",
10 | "transform": {
11 | "^.+\\.(t|j)s$": "ts-jest"
12 | },
13 | "reporters": [
14 | "default",
15 | [
16 | "jest-junit",
17 | {
18 | "suiteName": "backend unit tests",
19 | "outputDirectory": "./s4hana_pipeline/reports/backend-integration"
20 | }
21 | ]
22 | ],
23 | "collectCoverage": true,
24 | "coverageReporters": [
25 | "text",
26 | "cobertura"
27 | ],
28 | "coverageDirectory": "../s4hana_pipeline/reports/coverage-reports/backend-integration"
29 | }
--------------------------------------------------------------------------------
/product-service/test/jest-e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "moduleFileExtensions": [
3 | "js",
4 | "json",
5 | "ts"
6 | ],
7 | "rootDir": ".",
8 | "testEnvironment": "node",
9 | "testRegex": ".e2e-spec.ts$",
10 | "transform": {
11 | "^.+\\.(t|j)s$": "ts-jest"
12 | },
13 | "reporters": [
14 | "default",
15 | [
16 | "jest-junit",
17 | {
18 | "suiteName": "backend unit tests",
19 | "outputDirectory": "./s4hana_pipeline/reports/backend-integration"
20 | }
21 | ]
22 | ],
23 | "collectCoverage": true,
24 | "coverageReporters": [
25 | "text",
26 | "cobertura"
27 | ],
28 | "coverageDirectory": "../s4hana_pipeline/reports/coverage-reports/backend-integration"
29 | }
--------------------------------------------------------------------------------
/logistics-service/src/app.controller.spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { AppController } from './app.controller';
3 | import { AppService } from './app.service';
4 |
5 | describe('AppController', () => {
6 | let appController: AppController;
7 |
8 | beforeEach(async () => {
9 | const app: TestingModule = await Test.createTestingModule({
10 | controllers: [AppController],
11 | providers: [AppService],
12 | }).compile();
13 |
14 | appController = app.get(AppController);
15 | });
16 |
17 | describe('root', () => {
18 | it('should return "Hello World!"', () => {
19 | expect(appController.getHello()).toBe('Hello World!');
20 | });
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/product-service/test/app.controller.spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { AppController } from '../src/app.controller';
3 | import { AppService } from '../src/app.service';
4 |
5 | describe('AppController', () => {
6 | let appController: AppController;
7 |
8 | beforeEach(async () => {
9 | const app: TestingModule = await Test.createTestingModule({
10 | controllers: [AppController],
11 | providers: [AppService],
12 | }).compile();
13 |
14 | appController = app.get(AppController);
15 | });
16 |
17 | describe('root', () => {
18 | it('should return "Hello World!"', () => {
19 | expect(appController.getHello()).toBe('Hello World!');
20 | });
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/product-service/test/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { INestApplication } from '@nestjs/common';
3 | import * as request from 'supertest';
4 | import { AppModule } from './../src/app.module';
5 |
6 | describe('AppController (e2e)', () => {
7 | let app: INestApplication;
8 |
9 | beforeEach(async () => {
10 | const moduleFixture: TestingModule = await Test.createTestingModule({
11 | imports: [AppModule],
12 | }).compile();
13 |
14 | app = moduleFixture.createNestApplication();
15 | await app.init();
16 | });
17 |
18 | it('/ (GET)', () => {
19 | return request(app.getHttpServer())
20 | .get('/')
21 | .expect(200)
22 | .expect('Hello World!');
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/db/src/data/Products.hdbtable:
--------------------------------------------------------------------------------
1 | COLUMN TABLE "Products.product" (
2 | PRODUCTID VARCHAR(40) ,
3 | PRODUCTNAME VARCHAR(40) ,
4 | CURRENCYCODE VARCHAR(3) ,
5 | CATEGORY VARCHAR(40) ,
6 | WEIGHT Decimal(13,2) ,
7 | WEIGHTUNIT VARCHAR(3) ,
8 | SHORTDESCRIPTION VARCHAR(200) ,
9 | PICTUREURL VARCHAR(255) ,
10 | PRICE Decimal(23,3) ,
11 | DIMENSIONWIDTH Decimal(13,4) ,
12 | DIMENSIONDEPTH Decimal(13,4) ,
13 | DIMENSIONHEIGHT Decimal(13,4) ,
14 | DIMENSIONUNIT VARCHAR(3) ,
15 | PRIMARY KEY ("PRODUCTID"));
16 |
17 |
--------------------------------------------------------------------------------
/logistics-service/test/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { INestApplication } from '@nestjs/common';
3 | import * as request from 'supertest';
4 | import { AppModule } from './../src/app.module';
5 |
6 | describe('AppController (e2e)', () => {
7 | let app: INestApplication;
8 |
9 | beforeEach(async () => {
10 | const moduleFixture: TestingModule = await Test.createTestingModule({
11 | imports: [AppModule],
12 | }).compile();
13 |
14 | app = moduleFixture.createNestApplication();
15 | await app.init();
16 | });
17 |
18 | it('/ (GET)', () => {
19 | return request(app.getHttpServer())
20 | .get('/')
21 | .expect(200)
22 | .expect('Hello World!');
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/freight-manager/xs-security.json:
--------------------------------------------------------------------------------
1 | {
2 | "xsappname": "freight-xsuaa",
3 | "tenant-mode": "dedicated",
4 | "scopes": [
5 | {
6 | "name": "$XSAPPNAME.Access",
7 | "description": "access freight service ",
8 | "grant-as-authority-to-apps": ["$XSAPPNAME(application,businessuser-authentication)"]
9 | }
10 | ],
11 | "role-templates": [
12 | {
13 | "name": "freightservice",
14 | "description": "access freight service ",
15 | "scope-references": [
16 | "$XSAPPNAME.Access"
17 | ]
18 | }
19 | ],
20 | "oauth2-configuration": {
21 | "redirect-uris": [
22 | "https://*.cfapps.eu10-004.hana.ondemand.com/**",
23 | "https://*.cfapps.eu10.hana.ondemand.com/**"
24 | ]
25 | }
26 | }
--------------------------------------------------------------------------------
/freight-manager/src/freight-service/freight.controller.spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { AppController } from './freight.controller';
3 | import { AppService } from './freight.service';
4 |
5 | describe('AppController', () => {
6 | let appController: AppController;
7 |
8 | beforeEach(async () => {
9 | const app: TestingModule = await Test.createTestingModule({
10 | controllers: [AppController],
11 | providers: [AppService],
12 | }).compile();
13 |
14 | appController = app.get(AppController);
15 | });
16 |
17 | describe('root', () => {
18 | // it('should return "Hello World!"', () => {
19 | // expect(appController.getHello()).toBe('Hello World!');
20 | // });
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/freight-manager/test/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { INestApplication } from '@nestjs/common';
3 | import * as request from 'supertest';
4 | import { AppModule } from '../src/freight-service/freight.module';
5 |
6 | describe('AppController (e2e)', () => {
7 | let app: INestApplication;
8 |
9 | beforeEach(async () => {
10 | const moduleFixture: TestingModule = await Test.createTestingModule({
11 | imports: [AppModule],
12 | }).compile();
13 |
14 | app = moduleFixture.createNestApplication();
15 | await app.init();
16 | });
17 |
18 | it('/ (GET)', () => {
19 | return request(app.getHttpServer())
20 | .get('/')
21 | .expect(200)
22 | .expect('Hello World!');
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/test/util.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const fetch = require('node-fetch');
3 | const qs = require('qs');
4 |
5 | class Util {
6 |
7 | static urlEncodeParams(params){
8 | return qs.stringify(params)
9 | }
10 |
11 | static parameteriseUrl(url,params){
12 | params = this.urlEncodeParams(params)
13 | return url+'?'+params
14 | }
15 |
16 | static async requestHandler(options){
17 | try {
18 | let res = await fetch(options.url, {
19 | method: options.method,
20 | headers: options.headers,
21 | body: options.body
22 | })
23 | return res;
24 |
25 | } catch (err) {
26 | throw err;
27 | }
28 | }
29 | }
30 |
31 | module.exports = Util
--------------------------------------------------------------------------------
/db/src/data/stocks.csv:
--------------------------------------------------------------------------------
1 | HT-1000,10000
2 | HT-1001,10
3 | HT-1002,10
4 | HT-1003,10
5 | HT-1010,10
6 | HT-1011,10
7 | HT-1030,10
8 | HT-1031,10
9 | HT-1032,10
10 | HT-1035,10
11 | HT-1036,10
12 | HT-1037,10
13 | HT-1041,10
14 | HT-1042,10
15 | HT-1050,10
16 | HT-1051,10
17 | HT-1052,10
18 | HT-1055,10
19 | HT-1056,10
20 | HT-1063,10
21 | HT-1064,10
22 | HT-1065,10
23 | HT-1069,10
24 | HT-1080,10
25 | HT-1081,10
26 | HT-1082,10
27 | HT-1083,10
28 | HT-1085,10
29 | HT-1090,10
30 | HT-1091,10
31 | HT-1092,10
32 | HT-1120,10
33 | HT-1138,10
34 | HT-1210,10
35 | HT-1500,10
36 | HT-1501,10
37 | HT-1502,10
38 | HT-6130,10
39 | HT-6131,10
40 | HT-6132,10
41 | HT-6102,10
42 | HT-6101,10
43 | HT-6100,10
44 | HT-1603,10
45 | HT-1602,10
46 | HT-1601,10
47 | HT-1600,10
48 | HT-8000,10
49 | HT-8001,10
50 | HT-8002,10
51 | HT-8003,10
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/Component.js:
--------------------------------------------------------------------------------
1 | sap.ui.define([
2 | "sap/ui/core/UIComponent",
3 | "sap/ui/Device",
4 | "com/sap/oflm/model/models"
5 | ], function(UIComponent, Device, models) {
6 | "use strict";
7 |
8 | return UIComponent.extend("com.sap.oflm.Component", {
9 |
10 | metadata: {
11 | manifest: "json"
12 | },
13 |
14 | /**
15 | * The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
16 | * @public
17 | * @override
18 | */
19 | init: function() {
20 | // call the base component's init function
21 | UIComponent.prototype.init.apply(this, arguments);
22 |
23 | // enable routing
24 | this.getRouter().initialize();
25 |
26 | // set the device model
27 | this.setModel(models.createDeviceModel(), "device");
28 | }
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/approuter/ui/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true
4 | },
5 | "parserOptions": {
6 | "ecmaVersion": 2019
7 | },
8 | "globals": {
9 | "sap": true,
10 | "jQuery": true
11 | },
12 | "rules": {
13 | "block-scoped-var": 1,
14 | "keyword-spacing": 2,
15 | "space-unary-ops": 2,
16 | "camelcase": 1,
17 | "consistent-return": 1,
18 | "no-warning-comments": 1,
19 | "default-case": 1,
20 | "no-console": 2,
21 | "no-unused-vars": 2,
22 | "no-trailing-spaces": 2,
23 | "no-debugger": 2,
24 | "semi": [
25 | 1,
26 | "always"
27 | ],
28 | "quotes": [
29 | 1,
30 | "double"
31 | ],
32 | "key-spacing": [
33 | 1,
34 | {
35 | "beforeColon": false
36 | }
37 | ],
38 | "comma-spacing": [
39 | 1,
40 | {
41 | "before": false,
42 | "after": true
43 | }
44 | ],
45 | "no-shadow": 2,
46 | "no-irregular-whitespace": 2
47 | }
48 | }
--------------------------------------------------------------------------------
/security-config/xs-security.json:
--------------------------------------------------------------------------------
1 | {
2 | "xsappname": "businessuser-authentication",
3 | "tenant-mode": "dedicated",
4 | "description": "Security profile of logistics service",
5 | "authorities":["$ACCEPT_GRANTED_AUTHORITIES"],
6 | "scopes": [
7 | {
8 | "name": "$XSAPPNAME.Supplier",
9 | "description": "Display Suppliers"
10 | }
11 | ],
12 | "role-templates": [
13 | {
14 | "name": "Supplier",
15 | "description": "View Suppliers",
16 | "scope-references": [
17 | "$XSAPPNAME.Supplier"
18 | ]
19 | }
20 | ],
21 | "oauth2-configuration": {
22 | "redirect-uris": [
23 | "https://*.cfapps.eu10-004.hana.ondemand.com/**",
24 | "https://*.cfapps.eu10.hana.ondemand.com/**"
25 | ]
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | oflm
11 |
12 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/test/integration/opaTests.qunit.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Integration tests for Todo App
7 |
8 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/test/integration/pages/MainView.js:
--------------------------------------------------------------------------------
1 | sap.ui.require([
2 | "sap/ui/test/Opa5",
3 | "sap/ui/test/matchers/AggregationLengthEquals"
4 | ], function (Opa5, AggregationLengthEquals) {
5 | "use strict";
6 |
7 | var sViewName = "com.sap.oflm.view.MainView";
8 | var sAppId = "idAppControl";
9 |
10 | Opa5.createPageObjects({
11 | onTheAppPage: {
12 |
13 | assertions: {
14 |
15 | iShouldSeePageCount: function(iItemCount) {
16 | return this.waitFor({
17 | id: sAppId,
18 | viewName: sViewName,
19 | matchers: [new AggregationLengthEquals({
20 | name: "pages",
21 | length: iItemCount
22 | })],
23 | success: function() {
24 | Opa5.assert.ok(true, "The app contains one page");
25 | },
26 | errorMessage: "App does not have expected number of pages '" + iItemCount + "'."
27 | });
28 | }
29 | }
30 |
31 | }
32 | });
33 |
34 | });
35 |
--------------------------------------------------------------------------------
/freight-manager/src/main.ts:
--------------------------------------------------------------------------------
1 | import { NestFactory } from '@nestjs/core';
2 | import { AppModule } from './freight-service/freight.module';
3 | import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
4 |
5 | import { getServices } from '@sap/xsenv';
6 | const xsuaa = getServices({ xsuaa: { tag: 'xsuaa' } }).xsuaa;
7 | import * as passport from 'passport';
8 | import { JWTStrategy } from '@sap/xssec';
9 | passport.use(new JWTStrategy(xsuaa));
10 |
11 | async function bootstrap() {
12 | const app = await NestFactory.create(AppModule);
13 |
14 | //swagger Initialization
15 | const options = new DocumentBuilder()
16 | .setTitle('Freight Manager')
17 | .setDescription('APIs for Freight Manager')
18 | .setVersion('1.0').addBearerAuth()
19 | .build();
20 | const document = SwaggerModule.createDocument(app, options);
21 | SwaggerModule.setup('api', app, document);
22 | //security implementation
23 | app.use(passport.initialize());
24 | app.use(passport.authenticate('JWT', { session: false }));
25 | await app.listen(process.env.PORT || 3000);
26 | }
27 | bootstrap();
28 |
--------------------------------------------------------------------------------
/db/src/data/FreightOrder.hdbtable:
--------------------------------------------------------------------------------
1 | COLUMN TABLE "FreightOrder.freightOrder" (
2 | ID VARCHAR(36),
3 | CREATED_BY VARCHAR(80),
4 | CREATED_AT VARCHAR(8),
5 | CONTACTPERSON VARCHAR(80),
6 | ADDRESS VARCHAR(100),
7 | PHONENUMBER VARCHAR(10),
8 | COUNTRYCODE VARCHAR(2),
9 | EMAIL VARCHAR(241),
10 | TOTALDISTANCEMEASURED Decimal(10,2),
11 | PRODUCTNAME VARCHAR(40),
12 | PRODUCTID VARCHAR(40),
13 | QUANTITY Integer,
14 | GROSSWEIGHT Decimal(13,2),
15 | TRANSPORTATIONMEANSTYPECODE VARCHAR(4),
16 | LIFECYCLESTATUSCODE VARCHAR(5),
17 | PICKUPDATE VARCHAR(8),
18 | DELIVERYDATE VARCHAR(8),
19 | TRANSPORTATIONCHARGES Decimal(23,2),
20 | CURRENCYCODE VARCHAR(3),
21 | PRIMARY KEY ("ID") )
--------------------------------------------------------------------------------
/approuter/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oflm",
3 | "version": "0.0.1",
4 | "scripts": {
5 | "start": "ui5 serve --config=uimodule/ui5.yaml --open index.html",
6 | "build:ui": "run-s build:uimodule",
7 | "test": "run-s lint karma",
8 | "karma-ci": "karma start karma-ci.conf.js",
9 | "clearCoverage": "shx rm -rf coverage",
10 | "karma": "run-s clearCoverage karma-ci",
11 | "lint": "eslint .",
12 | "serve:uimodule": "ui5 serve --config=uimodule/ui5.yaml",
13 | "build:uimodule": "ui5 build --config=uimodule/ui5.yaml --clean-dest --dest uimodule/dist --include-task=generateManifestBundle"
14 | },
15 | "devDependencies": {
16 | "@ui5/cli": "^3.0.7",
17 | "decode-uri-component": ">=0.2.1",
18 | "eslint": "^8.10.0",
19 | "karma": "^6.3.17",
20 | "karma-chrome-launcher": "^3.1.1",
21 | "karma-coverage": "^2.2.0",
22 | "karma-ui5": "^3.0.2",
23 | "npm-run-all": "^4.1.5",
24 | "shx": "^0.3.4",
25 | "ui5-middleware-livereload": "^0.5.9"
26 | },
27 | "ui5": {
28 | "dependencies": [
29 | "ui5-middleware-livereload"
30 | ]
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/config.js:
--------------------------------------------------------------------------------
1 | const logistics_cred = require('./logistic_env')
2 | const product_cred = require('./product_env')
3 | const freight_cred = require('./freight_env')
4 | const vcap = logistics_cred.system_env_json.VCAP_SERVICES;
5 | const vcap2 = freight_cred.system_env_json.VCAP_SERVICES;
6 | const logistics_appenv = logistics_cred.application_env_json.VCAP_APPLICATION;
7 | const product_appenv = product_cred.application_env_json.VCAP_APPLICATION;
8 | const freight_appenv = freight_cred.application_env_json.VCAP_APPLICATION;
9 |
10 |
11 | module.exports = {
12 | "token_url": vcap.xsuaa[0].credentials.url + '/oauth/token',
13 | "logistic_service_url": 'https://' + logistics_appenv.application_uris[0],
14 | "product_service_url": 'https://' + product_appenv.application_uris[0],
15 | "freight_service_url": 'https://' + freight_appenv.application_uris[0],
16 | "xsuaa": {
17 | "grant_type": "password",
18 | "client_id": vcap.xsuaa[0].credentials.clientid,
19 | "client_secret": vcap.xsuaa[0].credentials.clientsecret,
20 | "username": process.env.pusername,
21 | "password": process.env.puserpwd
22 | },
23 | "freight_service_config": {
24 | "grant_type": "client_credentials",
25 | "client_id": vcap.xsuaa[0].credentials.clientid,
26 | "client_secret": vcap.xsuaa[0].credentials.clientsecret
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/logistics-service/src/main.ts:
--------------------------------------------------------------------------------
1 | import { NestFactory} from '@nestjs/core';
2 | import { AppModule } from './app.module';
3 | import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
4 | import { getServices, cfServiceCredentials } from '@sap/xsenv';
5 |
6 | /**
7 | * Security middleware
8 | */
9 | const xsuaa = getServices({ xsuaa: { tag: 'xsuaa' } }).xsuaa;
10 | import * as passport from 'passport';
11 | import { JWTStrategy } from '@sap/xssec';
12 | passport.use(new JWTStrategy(xsuaa));
13 |
14 | /**
15 | * HANA DB configuration
16 | */
17 | import * as hana from '@sap/hdbext';
18 | const hanacreds = cfServiceCredentials({ tag: 'hana' });
19 |
20 | async function bootstrap() {
21 | const app = await NestFactory.create(AppModule);
22 | /**
23 | * Swagger Defination
24 | */
25 | const options = new DocumentBuilder()
26 | .setTitle('Logistics Service')
27 | .setDescription('APIs for logistics service')
28 | .setVersion('1.0').addBearerAuth().addTag('Logistics Service')
29 | .build();
30 | const document = SwaggerModule.createDocument(app, options);
31 | SwaggerModule.setup('api', app, document);
32 | //HANA middleware
33 | app.use(hana.middleware(hanacreds));
34 | //security
35 | app.use(passport.initialize());
36 | app.use(passport.authenticate('JWT', { session: false }));
37 |
38 | await app.listen(process.env.PORT || 3000);
39 | }
40 | bootstrap();
41 |
--------------------------------------------------------------------------------
/product-service/src/main.ts:
--------------------------------------------------------------------------------
1 | import { NestFactory} from '@nestjs/core';
2 | import { AppModule } from './app.module';
3 | import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
4 | import { getServices, cfServiceCredentials } from '@sap/xsenv';
5 | /**
6 | * Security Configuration
7 | */
8 | const xsuaa = getServices({ xsuaa: { tag: 'xsuaa' } }).xsuaa;
9 | import * as passport from 'passport';
10 | import { JWTStrategy } from '@sap/xssec';
11 | passport.use(new JWTStrategy(xsuaa));
12 |
13 | /**
14 | * HANA DB configuration
15 | */
16 | import * as hana from '@sap/hdbext';
17 | const hanacreds = cfServiceCredentials({ tag: 'hana' });
18 |
19 | async function bootstrap() {
20 | const app = await NestFactory.create(AppModule);
21 | /**
22 | * Swagger Defination
23 | */
24 | const options = new DocumentBuilder()
25 | .setTitle('Product Service')
26 | .setDescription('APIs for logistics service')
27 | .setVersion('1.0').addBearerAuth().addTag('Product Service')
28 | .build();
29 | const document = SwaggerModule.createDocument(app, options);
30 | SwaggerModule.setup('api', app, document);
31 |
32 | //HANA middleware
33 | app.use(hana.middleware(hanacreds));
34 |
35 | //security middleware
36 | app.use(passport.initialize());
37 | app.use(passport.authenticate('JWT', { session: false }));
38 |
39 | await app.listen(process.env.PORT || 3000);
40 | }
41 | bootstrap();
42 |
--------------------------------------------------------------------------------
/product-service/src/products/product.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | @Injectable()
3 | export class ProductService {
4 |
5 | /**
6 | * Returns list of all the products
7 | */
8 | async getAllProducts(hanaClient : any): Promise {
9 | const query = `SELECT * FROM "Products.product"`;
10 | return await this.executeQuery(query, hanaClient).then(data => {
11 | return data;
12 | }).catch(err => {
13 | throw (err);
14 | });
15 | }
16 |
17 | /**
18 | *
19 | * @param id Product Id
20 | * Returns product detials if product id is passed
21 | */
22 | async getProductDetails(id: any, hanaClient: any): Promise {
23 | const query = `SELECT * FROM "Products.product" where PRODUCTID='${id.productId}'`;
24 | return await this.executeQuery(query, hanaClient).then(data => {
25 | return data;
26 | }).catch(err => {
27 | throw (err);
28 | });
29 | }
30 |
31 | /**
32 | *
33 | * @param query HANA query
34 | */
35 | async executeQuery(query: string, hanaClient: any): Promise {
36 | return new Promise((resolve, reject) => {
37 | hanaClient.exec(query, (err: unknown, result: Object) => {
38 | if (err) reject(err);
39 | resolve(result);
40 | });
41 | });
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/freight-manager/src/freight-service/freight.service.ts:
--------------------------------------------------------------------------------
1 | import { HttpException, Injectable } from '@nestjs/common';
2 | const quote = { "RAIL": 1000, "ROAD": 2000, "SHIP": 3000, "AIR": 4000 }
3 | const standardShippingCost = 3;
4 | const distanceCostPerKM = 0.1;
5 | const weightPerKG = 2;
6 | @Injectable()
7 | export class AppService {
8 | getQuote(transportationMeans: string, weight: number, dimension: string, totalDistanceMeasured: number, quantity: number): number {
9 | if(dimension.split(",").length === 3){
10 | let dim = dimension.split(',');
11 | let dimestionFactor = 166;
12 | let dimensionWeight = Math.ceil(((parseFloat(dim[0]) * parseFloat(dim[1]) * parseFloat(dim[2])) * 39.37) / dimestionFactor); // convert meter into inches. 1 m = 39.37 inch
13 | // formula : if pick the greatest among dimenstionWeight and weight and multiply it with cost per weight in kg(ensure the weight is in celi format)
14 | let calculationWeight = dimensionWeight > Math.ceil(weight) ? dimensionWeight : Math.ceil(weight);
15 | let distanceCost = totalDistanceMeasured > 400 ? 0 : (totalDistanceMeasured - 400) * distanceCostPerKM;
16 | let transportationCharges = calculationWeight * weightPerKG + distanceCost + standardShippingCost + quote[transportationMeans] * quantity;
17 | return transportationCharges;
18 | }else{
19 | throw new HttpException('Invalid Dimension', 400);
20 | }
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/logistics-service/src/logistics/order.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | import { v4 as uuidv4 } from 'uuid';
3 | @Injectable()
4 | export class OrderService {
5 | async createFreightOrder(data: any, user:string, hanaClient : any): Promise {
6 | const query = `INSERT INTO "FreightOrder.freightOrder" VALUES('${uuidv4()}','${user}',
7 | '${data.pickupdate}','${data.contactPerson}','${data.address}','${data.phone}','${data.countryCode}','${data.email}',
8 | '${data.totalDistanceMeasured}','${data.productName}',
9 | '${data.productId}','${data.quantity}','${data.grossWeight}','${data.transportationMeansType}','${data.lifecyclestatus}',
10 | '${data.pickupdate}','${data.deliverydate}','${data.transportationCharges}','${data.currencycode}')`;
11 | return await this.query(query,hanaClient).then(res => {
12 | return "Order Created";
13 | }).catch(err => {
14 | console.log(err);
15 | throw err;
16 | });
17 | }
18 | async getOrders(hanaClient: any): Promise {
19 | const query = `SELECT * FROM "FreightOrder.freightOrder"`;
20 | return await this.query(query,hanaClient).then(res => {
21 | return res;
22 | }).catch(err => {
23 | throw err;
24 | });
25 | }
26 | /**
27 | *
28 | * @param query String HANA Query
29 | * returns the query execution result
30 | */
31 | async query(query: string, hanaClient: any) {
32 | return new Promise((resolve, reject) => {
33 | hanaClient.exec(query, (err: unknown, result: Object) => {
34 | if (err) reject(err);
35 | resolve(result);
36 | });
37 | })
38 | }
39 | }
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/view/MainView.view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/product-service/src/products/stock.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | @Injectable()
3 | export class StockService {
4 | /**
5 | * Checks stock. Return true is the requested quantity is greater or equal to the required stock
6 | *
7 | * @param productId product id
8 | * @param quantity quantity to be shipped
9 | */
10 | async checkStock(productId: string, quantity: number, hanaClient: any): Promise {
11 | let query = `SELECT "QUANTITY" FROM "Products.stock" where PRODUCTID='${productId}'`;
12 | return await this.executeQuery(query,hanaClient).then(stock => {
13 | if (stock[0].QUANTITY >= quantity){
14 | return true;
15 | }else {
16 | return false;
17 | }
18 | }).catch(err => {
19 | throw err;
20 | });
21 | }
22 | /**
23 | * this method is used to update the quantity value
24 | * @param productId product id
25 | * @param quantity Quantity
26 | */
27 | async updateStock(productId: string, quantity: number, hanaClient: any): Promise {
28 | let query = `Update "Products.stock" set QUANTITY=QUANTITY-${quantity} where PRODUCTID='${productId}'`;
29 | return await this.executeQuery(query,hanaClient).then(stock => {
30 | return 'Stock Updated';
31 | }).catch(err => {
32 | throw err;
33 | });
34 | }
35 | /**
36 | * Query Execution
37 | * @param query SQL query
38 | */
39 | async executeQuery(query: string, hanaClient: any): Promise < any > {
40 | return new Promise((resolve, reject) => {
41 | hanaClient.exec(query, (err: unknown, result: Object) => {
42 | if (err) reject(err);
43 | resolve(result);
44 | });
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/product-service/src/products/product.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get, Param, Req, UnauthorizedException} from '@nestjs/common';
2 | import {ProductService} from './product.service';
3 | import {ApiBearerAuth, ApiTags,ApiOperation, ApiParam } from '@nestjs/swagger';
4 | @Controller('getProducts')
5 | export class ProductController {
6 | constructor(private productService: ProductService){}
7 | /**
8 | * Get List of all the products
9 | */
10 | @Get()
11 | @ApiBearerAuth()
12 | @ApiTags('Product Service')
13 | @ApiOperation({ summary: 'Get list of all Products' })
14 | getAllProducts(@Req() req: any): any{
15 |
16 | const isAuthorized = req.authInfo.checkLocalScope('Supplier');
17 | if(isAuthorized){
18 | const hanaClient = req.db;
19 | return this.productService.getAllProducts(hanaClient).then(data=>{
20 | return data;
21 | }).catch(error=>{
22 | throw(error);
23 | });
24 | }else{
25 | throw new UnauthorizedException();
26 | }
27 | }
28 |
29 | /**
30 | *
31 | * @param id Product ID
32 | */
33 | @Get(':productId')
34 | @ApiTags('Product Service')
35 | @ApiBearerAuth()
36 | @ApiOperation({summary: 'Returns product details based on product id'})
37 | @ApiParam({name:'productId',description:'Product Id' })
38 | getProduct(@Req()req: any,@Param() productId: any): any{
39 | const isAuthorized = req.authInfo.checkLocalScope('Supplier');
40 | if(isAuthorized){
41 | const hanaClient = req.db;
42 | return this.productService.getProductDetails(productId,hanaClient).then(data=>{
43 | return data;
44 | }).catch(error=>{
45 | throw(error);
46 | });
47 | }else{
48 | throw new UnauthorizedException();
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/freight-manager/src/freight-service/freight.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get, Query, ParseIntPipe, Req, UnauthorizedException } from '@nestjs/common';
2 | import { AppService } from './freight.service';
3 | import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger';
4 | @Controller()
5 | export class AppController {
6 | constructor(private readonly appService: AppService) { }
7 | /**
8 | * Swagger defination starts here
9 | */
10 | @Get()
11 | @ApiBearerAuth()
12 | @ApiTags('Freight Service')
13 | @ApiQuery({
14 | name: 'transportationmeans',
15 | description: 'Mode of transportation (AIR, ROAD, SHIP, RAIL)',
16 | type: String
17 | })
18 | @ApiQuery({
19 | name: 'quantity',
20 | description: 'Number of items to be shipped',
21 | type: Number
22 | })
23 | @ApiQuery({
24 | name: 'totalDistanceMeasured',
25 | description: 'Distance for delivery',
26 | type: String
27 | })
28 | @ApiQuery({
29 | name: 'weight',
30 | description: 'Product Weight',
31 | type: String
32 | })
33 | @ApiQuery({
34 | name: 'dimension',
35 | description: 'Product dimension(Height,length,width)',
36 | type: String
37 | })
38 | // end of swagger defination
39 |
40 | /**
41 | * Gets query parameters required for calucation for freight order
42 | */
43 | getQuote(@Req() req: any,@Query('transportationmeans') transportationMeans: string, @Query('weight', ParseIntPipe) weight: number,
44 | @Query('dimension') dimension: string, @Query('totalDistanceMeasured', ParseIntPipe) totalDistanceMeasured: number,
45 | @Query('quantity', ParseIntPipe) quantity: number): number {
46 |
47 | const isAuthorized = req.authInfo.checkLocalScope('Access');
48 | if(isAuthorized){
49 | let transportationCharges = this.appService.getQuote(transportationMeans, weight, dimension, totalDistanceMeasured, quantity);
50 | return transportationCharges;
51 | }else{
52 | throw new UnauthorizedException();
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/logistics-service/src/logistics/order.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Post, Body, Get, Req, ForbiddenException } from '@nestjs/common';
2 | import { OrderService } from './order.service';
3 | import { ApiBearerAuth, ApiOperation, ApiTags} from '@nestjs/swagger';
4 | import { FreightOrder } from '../model/quotemodel.dto';
5 | @Controller('order')
6 | export class OrderController {
7 | constructor(private readonly orderService: OrderService) { }
8 | @Post()
9 | /**
10 | * API annotations are used for swagger implementation
11 | * API Tags help the endpoints in their grouping
12 | */
13 | @ApiBearerAuth()
14 | @ApiTags('Logistics Service')
15 | @ApiOperation({ summary: 'Create freight order' })
16 | /**
17 | * To create a new freight order
18 | * @Req {object} gets the request details
19 | * @Body is having Implementation of freightOrder class which specifies what are all the required payloads
20 | */
21 | async createFreightOrder(@Req() req: any, @Body() freightOder: FreightOrder) {
22 | const isAuthorized = req.authInfo.checkLocalScope('Supplier');
23 | if (isAuthorized) {
24 | const hanaClient = req.db;
25 | return await this.orderService.createFreightOrder(freightOder,req.user.id, hanaClient).then(result=>{
26 | return result;
27 | }).catch(err=>{
28 | throw err;
29 | });
30 | } else {
31 | throw new ForbiddenException();
32 | }
33 | }
34 |
35 | /**
36 | *
37 | * @param req gets request object containing authorization information
38 | * this method returns in getting all the freight orders created
39 | */
40 | @Get()
41 | @ApiBearerAuth()
42 | @ApiTags('Logistics Service')
43 | @ApiOperation({ summary: 'Get all Order' })
44 | async getFreightOrder(@Req() req: any) {
45 | const isAuthorized = req.authInfo.checkLocalScope('Supplier');
46 | if (isAuthorized) {
47 | const hanaClient = req.db;
48 | return await this.orderService.getOrders(hanaClient);
49 | } else {
50 | throw new ForbiddenException();
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "_version": "1.12.0",
3 | "sap.app": {
4 | "id": "com.sap.oflm",
5 | "type": "application",
6 | "i18n": "i18n/i18n.properties",
7 | "applicationVersion": {
8 | "version": "1.0.0"
9 | },
10 | "title": "{{appTitle}}",
11 | "description": "{{appDescription}}"
12 | },
13 | "sap.ui": {
14 | "technology": "UI5",
15 | "icons": {
16 | "icon": "",
17 | "favIcon": "",
18 | "phone": "",
19 | "phone@2": "",
20 | "tablet": "",
21 | "tablet@2": ""
22 | },
23 | "deviceTypes": {
24 | "desktop": true,
25 | "tablet": true,
26 | "phone": true
27 | }
28 | },
29 | "sap.ui5": {
30 | "rootView": {
31 | "viewName": "com.sap.oflm.view.MainView",
32 | "type": "XML",
33 | "async": true,
34 | "id": "idAppControl"
35 | },
36 | "dependencies": {
37 | "minUI5Version": "1.60.0",
38 | "libs": {
39 | "sap.ui.core": {},
40 | "sap.m": {},
41 | "sap.ui.layout": {}
42 | }
43 | },
44 | "contentDensities": {
45 | "compact": true,
46 | "cozy": true
47 | },
48 | "models": {
49 | "i18n": {
50 | "type": "sap.ui.model.resource.ResourceModel",
51 | "settings": {
52 | "bundleName": "com.sap.oflm.i18n.i18n"
53 | }
54 | }
55 | },
56 | "resources": {
57 | "css": [
58 | {
59 | "uri": "css/style.css"
60 | }
61 | ]
62 | },
63 | "routing": {
64 | "config": {
65 | "routerClass": "sap.m.routing.Router",
66 | "viewType": "XML",
67 | "viewPath": "com.sap.oflm.view",
68 | "controlId": "idAppControl",
69 | "controlAggregation": "pages",
70 | "async": true
71 | },
72 | "routes": [
73 | {
74 | "name": "RouteMainView",
75 | "pattern": "RouteMainView",
76 | "target": [
77 | "TargetMainView"
78 | ]
79 | }
80 | ],
81 | "targets": {
82 | "TargetMainView": {
83 | "viewType": "XML",
84 | "viewLevel": 1,
85 | "viewId": "idAppControl",
86 | "viewName": "MainView"
87 | }
88 | }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/db/src/data/Products.hdbtabledata:
--------------------------------------------------------------------------------
1 | {
2 | "format_version": 1,
3 | "imports": [
4 | {
5 | "target_table": "Products.product",
6 | "source_data": {
7 | "data_type": "CSV",
8 | "file_name": "product.csv",
9 | "has_header": false,
10 | "type_config": {
11 | "delimiter": ","
12 | }
13 | },
14 | "import_settings": {
15 | "import_columns": [
16 | "PRODUCTID",
17 | "CURRENCYCODE",
18 | "CATEGORY",
19 | "WEIGHT",
20 | "WEIGHTUNIT",
21 | "SHORTDESCRIPTION",
22 | "PRODUCTNAME",
23 | "PICTUREURL",
24 | "PRICE",
25 | "DIMENSIONWIDTH",
26 | "DIMENSIONDEPTH",
27 | "DIMENSIONHEIGHT",
28 | "DIMENSIONUNIT"
29 | ]
30 | },
31 | "column_mappings": {
32 | "PRODUCTID":1,
33 | "CURRENCYCODE":2,
34 | "CATEGORY":3,
35 | "WEIGHT":4,
36 | "WEIGHTUNIT":5,
37 | "SHORTDESCRIPTION":6,
38 | "PRODUCTNAME":7,
39 | "PICTUREURL":8,
40 | "PRICE":9,
41 | "DIMENSIONWIDTH":10,
42 | "DIMENSIONDEPTH":11,
43 | "DIMENSIONHEIGHT":12,
44 | "DIMENSIONUNIT":13
45 | }
46 | },
47 | {
48 | "target_table": "Products.stock",
49 | "source_data": {
50 | "data_type": "CSV",
51 | "file_name": "stocks.csv",
52 | "has_header": false,
53 | "type_config": {
54 | "delimiter": ","
55 | }
56 | },
57 | "import_settings": {
58 | "import_columns": [
59 | "PRODUCTID",
60 | "QUANTITY"
61 | ]
62 | },
63 | "column_mappings": {
64 | "PRODUCTID":1,
65 | "QUANTITY":2
66 | }
67 | }
68 | ]
69 | }
--------------------------------------------------------------------------------
/product-service/src/products/stock.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get, Query, Put, Req, UnauthorizedException } from '@nestjs/common';
2 | import { StockService } from './stock.service';
3 | import { ApiBearerAuth, ApiTags, ApiQuery, ApiOperation } from '@nestjs/swagger';
4 | @Controller('stock')
5 | export class StockController {
6 | constructor(private stockService: StockService) { }
7 | /**
8 | *
9 | * @param req
10 | * @param productId Product ID
11 | * @param quantity Quantity
12 | */
13 | @Get()
14 | //Swagger defination starts here
15 | @ApiTags('Product Service')
16 | @ApiBearerAuth()
17 | @ApiOperation({ summary: 'Gets product id, quantity and checks for stock' })
18 | @ApiQuery({
19 | name: 'productId',
20 | description: 'Id of the product',
21 | type: String
22 | })
23 | @ApiQuery({
24 | name: 'quantity',
25 | description: 'Quantity to be shipped',
26 | type: Number
27 | })
28 | // end of swagger defination
29 |
30 | checkStock(@Req() req: any, @Query('productId') productId: string, @Query('quantity') quantity: number): any {
31 | const isAuthorized = req.authInfo.checkLocalScope('Supplier');
32 | if (isAuthorized) {
33 | const hanaClient = req.db;
34 | return this.stockService.checkStock(productId, quantity, hanaClient);
35 | } else {
36 | throw new UnauthorizedException();
37 | }
38 | }
39 |
40 | /**
41 | * Update stock section
42 | * @param productId product id
43 | * @param quantity quantity
44 | */
45 | @Put()
46 | @ApiTags('Product Service')
47 | @ApiBearerAuth()
48 | @ApiOperation({ summary: 'Gets product id, quantity and checks for stock' })
49 | @ApiQuery({
50 | name: 'productId',
51 | description: 'Id of the product',
52 | type: String
53 | })
54 | @ApiQuery({
55 | name: 'quantity',
56 | description: 'Quantity to be shipped',
57 | type: Number
58 | })
59 | updateStock(@Req() req: any, @Query('productId') productId: string, @Query('quantity') quantity: number): any {
60 | const isAuthorized = req.authInfo.checkLocalScope('Supplier');
61 | if (isAuthorized) {
62 | const hanaClient = req.db;
63 | return this.stockService.updateStock(productId, quantity, hanaClient);
64 | } else {
65 | throw new UnauthorizedException();
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/controller/BaseController.js:
--------------------------------------------------------------------------------
1 | sap.ui.define([
2 | "sap/ui/core/mvc/Controller",
3 | "sap/ui/core/routing/History",
4 | "sap/ui/core/UIComponent",
5 | "com/sap/oflm/model/formatter"
6 | ], function(Controller, History, UIComponent, formatter) {
7 | "use strict";
8 |
9 | return Controller.extend("com.sap.oflm.controller.BaseController", {
10 |
11 | formatter: formatter,
12 |
13 | /**
14 | * Convenience method for getting the view model by name in every controller of the application.
15 | * @public
16 | * @param {string} sName the model name
17 | * @returns {sap.ui.model.Model} the model instance
18 | */
19 | getModel: function(sName) {
20 | return this.getView().getModel(sName);
21 | },
22 |
23 | /**
24 | * Convenience method for setting the view model in every controller of the application.
25 | * @public
26 | * @param {sap.ui.model.Model} oModel the model instance
27 | * @param {string} sName the model name
28 | * @returns {sap.ui.mvc.View} the view instance
29 | */
30 | setModel: function(oModel, sName) {
31 | return this.getView().setModel(oModel, sName);
32 | },
33 |
34 | /**
35 | * Convenience method for getting the resource bundle.
36 | * @public
37 | * @returns {sap.ui.model.resource.ResourceModel} the resourceModel of the component
38 | */
39 | getResourceBundle: function() {
40 | return this.getOwnerComponent().getModel("i18n").getResourceBundle();
41 | },
42 |
43 | /**
44 | * Method for navigation to specific view
45 | * @public
46 | * @param {string} psTarget Parameter containing the string for the target navigation
47 | * @param {mapping} pmParameters? Parameters for navigation
48 | * @param {boolean} pbReplace? Defines if the hash should be replaced (no browser history entry) or set (browser history entry)
49 | */
50 | navTo: function(psTarget, pmParameters, pbReplace) {
51 | this.getRouter().navTo(psTarget, pmParameters, pbReplace);
52 | },
53 |
54 | getRouter: function() {
55 | return UIComponent.getRouterFor(this);
56 | },
57 |
58 | onNavBack: function() {
59 | var sPreviousHash = History.getInstance().getPreviousHash();
60 |
61 | if (sPreviousHash !== undefined) {
62 | window.history.back();
63 | } else {
64 | this.getRouter().navTo("appHome", {}, true /*no history*/ );
65 | }
66 | }
67 |
68 | });
69 |
70 | });
71 |
--------------------------------------------------------------------------------
/Jenkinsfile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 | @Library(['piper-lib', 'piper-lib-os']) _
3 | stage ('Build') {
4 | node{
5 | dockerExecuteOnKubernetes(script: this, dockerImage: 'ppiper/node-browsers:node12', dockerWorkspace: '/home/node') {
6 | sh '''
7 | rm -rf outbound-freight-and-logistics-management
8 | git -c http.sslVerify=false clone https://github.tools.sap/BTP-E2EScenarioValidation/outbound-freight-and-logistics-management.git
9 | cd outbound-freight-and-logistics-management
10 | cd freight-manager
11 | npm i
12 | npm run build
13 | cd ..
14 | pwd
15 | cd logistics-service
16 | npm i
17 | npm run build
18 | cd ..
19 | cd product-service
20 | npm i
21 | npm run build
22 |
23 |
24 | '''
25 | }
26 | }
27 | }
28 | stage ('deploy') {
29 | node{
30 | dockerExecuteOnKubernetes(script: this, dockerImage: 'docker.wdf.sap.corp:51010/sfext:latest', dockerWorkspace: '/home/node') {
31 | sh '''
32 | cf login -u $nodeappuser -p $nodeappwd -a $nodeappurl -o $nodeapporg -s $nodeappspace
33 | cd outbound-freight-and-logistics-management
34 | cd freight-manager
35 | npm run deploy
36 | cd ..
37 | cd product-service
38 | npm run deploy
39 | cd ..
40 | cd logistics-service
41 | ls
42 | rm -rf dist
43 | rm -rf deployment
44 | rm -rf package-lock.json
45 | ls
46 | npm run deploy
47 |
48 |
49 | '''
50 | }
51 | }
52 | }
53 | stage ('test') {
54 | node(){
55 | dockerExecuteOnKubernetes(script: this,dockerEnvVars: ['pusername':pusername, 'puserpwd':puserpwd], dockerImage: 'docker.wdf.sap.corp:51010/sfext:latest', dockerWorkspace: '/home/node') {
56 | sh '''
57 | cf login -u $nodeappuser -p $nodeappwd -a $nodeappurl -o $nodeapporg -s $nodeappspace
58 | logistics_guid=`cf app logistics-service --guid`
59 | echo $logistics_guid
60 | product_guid=`cf app product-service --guid`
61 | echo $product_guid
62 | freight_guid=`cf app freight-manager --guid`
63 | echo $freight_guid
64 | cd outbound-freight-and-logistics-management
65 | cd test
66 | npm i
67 | cf curl /v2/apps/$logistics_guid/env > logistic_env.json
68 | cf curl /v2/apps/$product_guid/env > product_env.json
69 | cf curl /v2/apps/$freight_guid/env > freight_env.json
70 | ls
71 | jest ./test
72 |
73 |
74 | '''
75 | }
76 | }
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/logistics-service/src/model/quotemodel.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsNotEmpty, IsString, IsNumber, MaxLength, IsEmail } from 'class-validator';
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /**
5 | * Class implementation for freight order
6 | * class validators are used to validate the coming data and datatype using nest.js pipes
7 | *
8 | */
9 | export class FreightOrder {
10 | //Swagger annotation starts here
11 | @IsNotEmpty()
12 | @IsString()
13 | @ApiProperty({ description: 'Contact Person Name'})
14 | //End of swagger defincation
15 | contactPerson: string;
16 |
17 | @IsNotEmpty()
18 | @IsString()
19 | @ApiProperty({ description: 'Address' })
20 | address: string;
21 |
22 | @IsNotEmpty()
23 | @IsString()
24 | @MaxLength(10)
25 | @ApiProperty({ description: 'Phone Number', maxLength: 10 })
26 | phone: string;
27 |
28 |
29 | @IsNotEmpty()
30 | @IsString()
31 | @MaxLength(2)
32 | @ApiProperty({ description: 'Country Code', maxLength: 2 })
33 | countryCode: string;
34 |
35 | @IsNotEmpty()
36 | @IsString()
37 | @IsEmail()
38 | @ApiProperty({ description: 'Email' })
39 | email: string;
40 |
41 | @IsNotEmpty()
42 | @IsNumber()
43 | @ApiProperty({ description: 'Total Distance Measured' })
44 | totalDistanceMeasured: number;
45 |
46 | @IsNotEmpty()
47 | @IsString()
48 | @ApiProperty({ description: 'productName'})
49 | productName: string;
50 |
51 | @IsNotEmpty()
52 | @IsString()
53 | @ApiProperty({ description: 'Product ID'})
54 | productId: string;
55 |
56 | @IsNotEmpty()
57 | @IsString()
58 | @ApiProperty({ description: 'Quantity'})
59 | quantity: number;
60 |
61 | @IsNotEmpty()
62 | @IsNumber()
63 | @ApiProperty({ description: 'Gross weight' })
64 | grossWeight: number;
65 |
66 | @IsNotEmpty()
67 | @IsNumber()
68 | @MaxLength(5)
69 | @ApiProperty({ description: 'Transportation Means Type Code', maxLength: 5 })
70 | transportationMeansType: string;
71 |
72 | @IsNotEmpty()
73 | @IsString()
74 | @MaxLength(4)
75 | @ApiProperty({ description: 'Lifecycle means', maxLength: 4 })
76 | lifecyclestatus: string;
77 |
78 | @IsNotEmpty()
79 | @IsString()
80 | @MaxLength(8)
81 | @ApiProperty({ description: 'Pickup Date', maxLength: 8 })
82 | pickupdate: string;
83 |
84 |
85 | @IsNotEmpty()
86 | @IsString()
87 | @MaxLength(8)
88 | @ApiProperty({ description: 'Delivery Date', maxLength: 8 })
89 | deliverydate: string;
90 |
91 | @IsNotEmpty()
92 | @IsNumber()
93 | @ApiProperty({ description: 'Transportation Charges' })
94 | transportationCharges: number;
95 |
96 | @IsNotEmpty()
97 | @IsString()
98 | @MaxLength(3)
99 | @ApiProperty({ description: 'Currency Code', maxLength: 3 })
100 | currencycode: string;
101 | }
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/view/ReviewPage.fragment.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/logistics-service/src/logistics/quote.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get, Query, Catch, HttpException, HttpStatus, Req, UnauthorizedException, ParseIntPipe } from '@nestjs/common';
2 | import { QuoteService } from './quote.service';
3 | import { ApiBearerAuth, ApiOperation, ApiTags, ApiQuery, ApiResponse } from '@nestjs/swagger';
4 | @Controller('getQuote')
5 | @Catch()
6 | export class QuoteController {
7 | constructor(private readonly quoteService: QuoteService) { }
8 | /**
9 | *
10 | * @param req authorization header
11 | * @param mode mode of transport
12 | * @param productId
13 | * @param quantity
14 | * @param totalDistanceMeasured
15 | * @param weight
16 | * @param dimension
17 | * @Get annotation is used for swagger implementation
18 | */
19 |
20 | /**
21 | * Swagger defination goes here
22 | */
23 | @Get()
24 | @ApiBearerAuth()
25 | @ApiTags('Logistics Service')
26 | @ApiOperation({ summary: 'Get Quote from freight service using technical user authentication' })
27 | @ApiQuery({
28 | name: 'mode',
29 | description: 'Mode of transportation (Air, Water, Rail, Road)',
30 | type: String
31 | })
32 | @ApiQuery({
33 | name: 'quantity',
34 | description: 'Number of items to be shipped',
35 | type: Number
36 | })
37 | @ApiQuery({
38 | name: 'productId',
39 | description: 'Product ID',
40 | type: String
41 | })
42 | @ApiQuery({
43 | name: 'totalDistanceMeasured',
44 | description: 'Distance for delivery',
45 | type: String
46 | })
47 | @ApiQuery({
48 | name: 'weight',
49 | description: 'Product Weight',
50 | type: String
51 | })
52 | @ApiQuery({
53 | name: 'dimension',
54 | description: 'Product dimension(Height,length,width)',
55 | type: String
56 | })
57 | @ApiResponse({ status: 204, description: 'Out of stock' })
58 | @ApiResponse({ status: 200, description: 'Ok' })
59 | // end of swagger defination
60 |
61 | // Pipe methods are used for validation
62 | async getQuote(@Req() req: any, @Query('mode') mode: string, @Query('productId') productId: string, @Query('quantity', ParseIntPipe) quantity: number,
63 | @Query('totalDistanceMeasured',ParseIntPipe) totalDistanceMeasured: number, @Query('weight',ParseIntPipe) weight: number, @Query('dimension') dimension: string,
64 | ): Promise {
65 | const authorization = req.headers.authorization;
66 | const isAuthorized = req.authInfo.checkLocalScope('Supplier');
67 | // checks for authorization before executing next block, if unauthorized, returns exception
68 | if(isAuthorized){
69 | return await this.quoteService.checkProductStock(authorization, mode.toUpperCase(), productId, quantity,
70 | weight, totalDistanceMeasured, dimension).then(data => {
71 | return { Cost: data };
72 | }).catch(error => {
73 | /**
74 | * if error is false, its a out of stock error
75 | */
76 | if (error === false) {
77 | throw new HttpException('Product Out Of Stock',HttpStatus.NO_CONTENT);
78 | }
79 | console.log(error);
80 | throw new HttpException({"status": 500,"error": "Unable to handle request"}, HttpStatus.INTERNAL_SERVER_ERROR);
81 | });
82 | }else{
83 | throw new UnauthorizedException();
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/freight-manager/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "freight-manager",
3 | "version": "0.0.1",
4 | "description": "",
5 | "author": "",
6 | "private": true,
7 | "license": "UNLICENSED",
8 | "scripts": {
9 | "prebuild": "rimraf dist",
10 | "build": "nest build",
11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
12 | "start": "nest start",
13 | "start:dev": "nest start --watch",
14 | "start:debug": "nest start --debug --watch",
15 | "start:prod": "node dist/main",
16 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
17 | "test": "jest",
18 | "test:watch": "jest --watch",
19 | "test:cov": "jest --coverage",
20 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
21 | "test:e2e": "jest --config ./test/jest-e2e.json",
22 | "deploy": "npm run build && sap-cloud-sdk package && cf push",
23 | "ci-build": "npm run build",
24 | "ci-package": "sap-cloud-sdk package",
25 | "ci-integration-test": "jest --ci --config ./test/jest-e2e.json",
26 | "ci-backend-unit-test": "jest --ci"
27 | },
28 | "dependencies": {
29 | "@nestjs/common": "^9.1.4",
30 | "@nestjs/core": "^9.1.4",
31 | "@nestjs/platform-express": "^9.1.4",
32 | "@nestjs/swagger": "^6.1.2",
33 | "@sap/xsenv": "^4.2.0",
34 | "@sap/xssec": "^3.6.0",
35 | "passport": "^0.6.0",
36 | "reflect-metadata": "^0.1.13",
37 | "rimraf": "^3.0.2",
38 | "rxjs": "^7.3.1"
39 | },
40 | "devDependencies": {
41 | "@nestjs/cli": "^9.1.4",
42 | "@nestjs/schematics": "^9.0.3",
43 | "@nestjs/testing": "^9.1.4",
44 | "@types/express": "^4.17.13",
45 | "@types/jest": "27.0.2",
46 | "@types/node": "^18.15.11",
47 | "@types/supertest": "^2.0.11",
48 | "@typescript-eslint/eslint-plugin": "3.0.2",
49 | "@typescript-eslint/parser": "3.0.2",
50 | "eslint": "^7.32.0",
51 | "eslint-config-prettier": "^8.3.0",
52 | "eslint-plugin-import": "^2.20.1",
53 | "jest-junit": "^13.0.0",
54 | "prettier": "^1.19.1",
55 | "supertest": "^4.0.2",
56 | "swagger-ui-express": "^4.3.0",
57 | "ts-jest": "27.0.5",
58 | "ts-loader": "^9.2.6",
59 | "ts-node": "^10.2.1",
60 | "tsconfig-paths": "^3.11.0",
61 | "typescript": "^4.3.5"
62 | },
63 | "jest": {
64 | "moduleFileExtensions": [
65 | "js",
66 | "json",
67 | "ts"
68 | ],
69 | "rootDir": "src",
70 | "testRegex": ".spec.ts$",
71 | "transform": {
72 | "^.+\\.(t|j)s$": "ts-jest"
73 | },
74 | "coverageDirectory": "../s4hana_pipeline/reports/coverage-reports/backend-unit",
75 | "testEnvironment": "node",
76 | "reporters": [
77 | "default",
78 | [
79 | "jest-junit",
80 | {
81 | "suiteName": "backend unit tests",
82 | "outputDirectory": "./s4hana_pipeline/reports/backend-unit"
83 | }
84 | ]
85 | ],
86 | "collectCoverage": true,
87 | "coverageReporters": [
88 | "text",
89 | "cobertura"
90 | ]
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/product-service/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "product-service",
3 | "version": "0.0.1",
4 | "description": "",
5 | "author": "",
6 | "private": true,
7 | "license": "UNLICENSED",
8 | "scripts": {
9 | "prebuild": "rimraf dist",
10 | "build": "nest build",
11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
12 | "start": "nest start",
13 | "start:dev": "nest start --watch",
14 | "start:debug": "nest start --debug --watch",
15 | "start:prod": "node dist/main",
16 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
17 | "test": "jest",
18 | "test:watch": "jest --watch",
19 | "test:cov": "jest --coverage",
20 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
21 | "test:e2e": "jest --config ./test/jest-e2e.json",
22 | "deploy": "npm run build && sap-cloud-sdk package && cf push",
23 | "ci-build": "npm run build",
24 | "ci-package": "sap-cloud-sdk package --ci",
25 | "ci-integration-test": "jest --ci --config ./test/jest-e2e.json",
26 | "ci-backend-unit-test": "jest --ci"
27 | },
28 | "dependencies": {
29 | "@nestjs/common": "^9.1.4",
30 | "@nestjs/core": "^9.1.4",
31 | "@nestjs/platform-express": "^9.1.4",
32 | "@nestjs/swagger": "^6.1.2",
33 | "@sap/hdbext": "^7.6.6",
34 | "@sap/xsenv": "^4.2.0",
35 | "@sap/xssec": "^3.6.0",
36 | "passport": "^0.6.0",
37 | "reflect-metadata": "^0.1.13",
38 | "rimraf": "^3.0.2",
39 | "rxjs": "^7.3.1",
40 | "swagger-ui-express": "^4.1.6"
41 | },
42 | "devDependencies": {
43 | "@compodoc/compodoc": "^1.1.15",
44 | "@nestjs/cli": "^9.1.4",
45 | "@nestjs/schematics": "^9.0.3",
46 | "@nestjs/testing": "^9.1.4",
47 | "@types/express": "^4.17.13",
48 | "@types/jest": "27.0.2",
49 | "@types/node": "^18.15.11",
50 | "@types/supertest": "^2.0.11",
51 | "@typescript-eslint/eslint-plugin": "3.0.2",
52 | "@typescript-eslint/parser": "3.0.2",
53 | "eslint": "^7.32.0",
54 | "eslint-config-prettier": "^8.3.0",
55 | "eslint-plugin-import": "^2.20.1",
56 | "jest": "27.2.4",
57 | "jest-junit": "^13.0.0",
58 | "prettier": "^1.19.1",
59 | "supertest": "^4.0.2",
60 | "ts-jest": "27.0.5",
61 | "ts-loader": "^9.2.6",
62 | "ts-node": "^10.2.1",
63 | "tsconfig-paths": "^3.11.0",
64 | "typescript": "^4.3.5"
65 | },
66 | "jest": {
67 | "moduleFileExtensions": [
68 | "js",
69 | "json",
70 | "ts"
71 | ],
72 | "rootDir": "src",
73 | "testRegex": ".spec.ts$",
74 | "transform": {
75 | "^.+\\.(t|j)s$": "ts-jest"
76 | },
77 | "coverageDirectory": "../s4hana_pipeline/reports/coverage-reports/backend-unit",
78 | "testEnvironment": "node",
79 | "reporters": [
80 | "default", [
81 | "jest-junit",
82 | {
83 | "suiteName": "backend unit tests",
84 | "outputDirectory": "./s4hana_pipeline/reports/backend-unit"
85 | }
86 | ]
87 | ],
88 | "collectCoverage": true,
89 | "coverageReporters": [
90 | "text",
91 | "cobertura"
92 | ]
93 | }
94 | }
--------------------------------------------------------------------------------
/logistics-service/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "",
3 | "dependencies": {
4 | "@nestjs/axios": "^0.1.0",
5 | "@nestjs/common": "^9.1.4",
6 | "@nestjs/core": "^9.1.4",
7 | "@nestjs/platform-express": "^9.1.4",
8 | "@nestjs/swagger": "^6.1.2",
9 | "@sap-cloud-sdk/connectivity": "^3.9.0",
10 | "@sap/hdbext": "^8.0.2",
11 | "@sap/xsenv": "^4.2.0",
12 | "@sap/xssec": "^3.6.0",
13 | "axios": "^0.22.0",
14 | "class-validator": "^0.14.0",
15 | "passport": "^0.6.0",
16 | "reflect-metadata": "^0.1.13",
17 | "rimraf": "^3.0.2",
18 | "rxjs": "^7.3.0",
19 | "swagger-ui-express": "^4.0.2",
20 | "uuid": "^8.3.2"
21 | },
22 | "description": "",
23 | "devDependencies": {
24 | "@nestjs/cli": "^9.1.4",
25 | "@nestjs/schematics": "^9.0.3",
26 | "@nestjs/testing": "^9.1.4",
27 | "@types/express": "^4.17.13",
28 | "@types/jest": "27.0.1",
29 | "@types/node": "^18.15.11",
30 | "@types/supertest": "^2.0.11",
31 | "@typescript-eslint/eslint-plugin": "3.0.2",
32 | "@typescript-eslint/parser": "3.0.2",
33 | "eslint": "^7.32.0",
34 | "eslint-config-prettier": "^6.10.0",
35 | "eslint-plugin-import": "^2.20.1",
36 | "jest": "27.1.0",
37 | "jest-junit": "^13.0.0",
38 | "prettier": "^2.3.2",
39 | "supertest": "^6.1.6",
40 | "ts-jest": "27.0.5",
41 | "ts-loader": "^9.2.5",
42 | "ts-node": "^10.2.0",
43 | "tsconfig-paths": "^3.10.1",
44 | "typescript": "^4.3.5"
45 | },
46 | "jest": {
47 | "collectCoverage": true,
48 | "coverageDirectory": "../s4hana_pipeline/reports/coverage-reports/backend-unit",
49 | "coverageReporters": [
50 | "text",
51 | "cobertura"
52 | ],
53 | "moduleFileExtensions": [
54 | "js",
55 | "json",
56 | "ts"
57 | ],
58 | "reporters": [
59 | "default",
60 | [
61 | "jest-junit",
62 | {
63 | "outputDirectory": "./s4hana_pipeline/reports/backend-unit",
64 | "suiteName": "backend unit tests"
65 | }
66 | ]
67 | ],
68 | "rootDir": "src",
69 | "testEnvironment": "node",
70 | "testRegex": ".spec.ts$",
71 | "transform": {
72 | "^.+\\.(t|j)s$": "ts-jest"
73 | }
74 | },
75 | "license": "UNLICENSED",
76 | "name": "logistics-service",
77 | "private": true,
78 | "scripts": {
79 | "build": "nest build",
80 | "ci-backend-unit-test": "jest --ci",
81 | "ci-build": "npm run build",
82 | "ci-integration-test": "jest --ci --config ./test/jest-e2e.json",
83 | "ci-package": "sap-cloud-sdk package --ci",
84 | "deploy": "npm run build && sap-cloud-sdk package && cf push",
85 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
86 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
87 | "prebuild": "rimraf dist",
88 | "start": "nest start",
89 | "start:debug": "nest start --debug --watch",
90 | "start:dev": "nest start --watch",
91 | "start:prod": "node dist/main",
92 | "test": "jest",
93 | "test:cov": "jest --coverage",
94 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
95 | "test:e2e": "jest --config ./test/jest-e2e.json",
96 | "test:watch": "jest --watch"
97 | },
98 | "version": "0.0.1"
99 | }
100 |
--------------------------------------------------------------------------------
/logistics-service/src/logistics/quote.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | import { ServiceCredentials } from '../providers/security-credentials.provider';
3 | import { destination } from '../providers/destination.provider';
4 | const axios = require('axios').default;
5 | @Injectable()
6 | export class QuoteService {
7 | processQuote(mode: string, quantity: number, weight: number, totalDistanceMeasured: number, dimension: string) {
8 | return new Promise((resolve, reject) => {
9 | this.getClientToken(ServiceCredentials[0]).then(token => {
10 | let header = { "Authorization": 'Bearer ' + token };
11 | this.getFreight(header, quantity, weight, totalDistanceMeasured, dimension, mode).then((data: any) => {
12 | console.log("Request Came here");
13 | resolve(data);
14 | }).catch(error => {
15 | console.log("Error Getting Quote");
16 | reject(error);
17 | });
18 | }).catch(error => {
19 | console.log("Error Handling token", error);
20 | reject(error);
21 | });
22 | });
23 | }
24 | /**
25 | * Calls the frieght Manager service using this method
26 | * @param authHeader Bearet Token
27 | * @param quantity Quantity represents the weight
28 | */
29 | async getFreight(authHeader: any, quantity: number, weight: number, totalDistanceMeasured: number, dimension: string, mode: string) {
30 | return new Promise((resolve, reject) => {
31 | destination.then(async destinationObject =>{
32 | var config = {
33 | method: 'get',
34 | url: destinationObject.url + '/destination-configuration/v1/subaccountDestinations',
35 | headers: {
36 | 'Authorization':'Bearer' + destinationObject.authTokens[0].value
37 | }
38 | };
39 | let dest = await axios(config).then(function (response) {
40 | return response.data;
41 | }).catch(function (error) {
42 | reject(error);
43 | });
44 | let url = dest[0].URL + `?transportationmeans=${mode}&weight=${weight}&totalDistanceMeasured=${totalDistanceMeasured}&quantity=${quantity}&dimension=${dimension}`;
45 | this.httpService(url, authHeader).then(data => {
46 | console.log("in quote data part");
47 | resolve(data.data);
48 | }).catch(error => {
49 | console.log("in Quote error Part");
50 | console.log(error.response.data);
51 | reject(error.response.data);
52 | });
53 | }).catch(err => {
54 | reject(err);
55 | });
56 | });
57 | }
58 | /**
59 | * This method is used to generate client credentials
60 | * @param clientCredentials XSUAA credentials returned from credentials provider
61 | */
62 | async getClientToken(clientCredentials: any) {
63 | return new Promise((resolve, reject) => {
64 | const url = `${clientCredentials.url}/oauth/token`;
65 | axios.post(url, `grant_type=client_credentials&client_id=${clientCredentials.clientId}&client_secret=${clientCredentials.clientSecret}`).then((res: any) => {
66 | resolve(res.data.access_token);
67 | }).catch((error: any) => {
68 | console.log(error);
69 | reject(error);
70 | });
71 | });
72 | }
73 | /**
74 | * this calls product service to check the stock availablity status
75 | * @param authHeader Authentication Token
76 | * @param item Product ID to be shipped
77 | * @param quantity Number of items
78 | */
79 | async checkProductStock(authorization: any, mode: string, productId: string, quantity: number,
80 | weight: number, totalDistanceMeasured: number, dimension: string): Promise {
81 | return new Promise((resolve, reject) => {
82 | let url = process.env.product_service + `/stock?productId=${productId}&quantity=${quantity}`;
83 | let header = { "Authorization": authorization };
84 | this.httpService(url, header).then(data => {
85 | console.log(data.data);
86 | if (data.data === true) {
87 | this.processQuote(mode, quantity, weight, totalDistanceMeasured, dimension).then(data => {
88 | resolve(data);
89 | }).catch(error => {
90 | console.error("in check product Stock");
91 | reject(error);
92 | });
93 | } else {
94 | reject(false)
95 | }
96 | }).catch(error => {
97 | reject(error);
98 | });
99 | });
100 | }
101 | async httpService(url: string, header: any): Promise {
102 | try {
103 | const request = await axios.get(url, { headers: header });
104 | return request;
105 | } catch (error) {
106 | throw error;
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/db/src/.hdiconfig:
--------------------------------------------------------------------------------
1 | {
2 | "file_suffixes": {
3 | "csv": {
4 | "plugin_name": "com.sap.hana.di.tabledata.source"
5 | },
6 | "hdbafllangprocedure": {
7 | "plugin_name": "com.sap.hana.di.afllangprocedure"
8 | },
9 | "hdbanalyticprivilege": {
10 | "plugin_name": "com.sap.hana.di.analyticprivilege"
11 | },
12 | "hdbcalculationview": {
13 | "plugin_name": "com.sap.hana.di.calculationview"
14 | },
15 | "hdbcds": {
16 | "plugin_name": "com.sap.hana.di.cds"
17 | },
18 | "hdbcollection": {
19 | "plugin_name": "com.sap.hana.di.collection"
20 | },
21 | "hdbconstraint": {
22 | "plugin_name": "com.sap.hana.di.constraint"
23 | },
24 | "hdbdropcreatetable": {
25 | "plugin_name": "com.sap.hana.di.dropcreatetable"
26 | },
27 | "hdbflowgraph": {
28 | "plugin_name": "com.sap.hana.di.flowgraph"
29 | },
30 | "hdbfulltextindex": {
31 | "plugin_name": "com.sap.hana.di.fulltextindex"
32 | },
33 | "hdbfunction": {
34 | "plugin_name": "com.sap.hana.di.function"
35 | },
36 | "hdbgraphworkspace": {
37 | "plugin_name": "com.sap.hana.di.graphworkspace"
38 | },
39 | "hdbhadoopmrjob": {
40 | "plugin_name": "com.sap.hana.di.virtualfunctionpackage.hadoop"
41 | },
42 | "hdbindex": {
43 | "plugin_name": "com.sap.hana.di.index"
44 | },
45 | "hdblibrary": {
46 | "plugin_name": "com.sap.hana.di.library"
47 | },
48 | "hdbmigrationtable": {
49 | "plugin_name": "com.sap.hana.di.table.migration"
50 | },
51 | "hdbprocedure": {
52 | "plugin_name": "com.sap.hana.di.procedure"
53 | },
54 | "hdbprojectionview": {
55 | "plugin_name": "com.sap.hana.di.projectionview"
56 | },
57 | "hdbprojectionviewconfig": {
58 | "plugin_name": "com.sap.hana.di.projectionview.config"
59 | },
60 | "hdbreptask": {
61 | "plugin_name": "com.sap.hana.di.reptask"
62 | },
63 | "hdbresultcache": {
64 | "plugin_name": "com.sap.hana.di.resultcache"
65 | },
66 | "hdbrole": {
67 | "plugin_name": "com.sap.hana.di.role"
68 | },
69 | "hdbroleconfig": {
70 | "plugin_name": "com.sap.hana.di.role.config"
71 | },
72 | "hdbsearchruleset": {
73 | "plugin_name": "com.sap.hana.di.searchruleset"
74 | },
75 | "hdbsequence": {
76 | "plugin_name": "com.sap.hana.di.sequence"
77 | },
78 | "hdbstatistics": {
79 | "plugin_name": "com.sap.hana.di.statistics"
80 | },
81 | "hdbstructuredprivilege": {
82 | "plugin_name": "com.sap.hana.di.structuredprivilege"
83 | },
84 | "hdbsynonym": {
85 | "plugin_name": "com.sap.hana.di.synonym"
86 | },
87 | "hdbsynonymconfig": {
88 | "plugin_name": "com.sap.hana.di.synonym.config"
89 | },
90 | "hdbsystemversioning": {
91 | "plugin_name": "com.sap.hana.di.systemversioning"
92 | },
93 | "hdbtable": {
94 | "plugin_name": "com.sap.hana.di.table"
95 | },
96 | "hdbtabledata": {
97 | "plugin_name": "com.sap.hana.di.tabledata"
98 | },
99 | "hdbtabletype": {
100 | "plugin_name": "com.sap.hana.di.tabletype"
101 | },
102 | "hdbtextconfig": {
103 | "plugin_name": "com.sap.hana.di.textconfig"
104 | },
105 | "hdbtextdict": {
106 | "plugin_name": "com.sap.hana.di.textdictionary"
107 | },
108 | "hdbtextinclude": {
109 | "plugin_name": "com.sap.hana.di.textrule.include"
110 | },
111 | "hdbtextlexicon": {
112 | "plugin_name": "com.sap.hana.di.textrule.lexicon"
113 | },
114 | "hdbtextminingconfig": {
115 | "plugin_name": "com.sap.hana.di.textminingconfig"
116 | },
117 | "hdbtextrule": {
118 | "plugin_name": "com.sap.hana.di.textrule"
119 | },
120 | "hdbtrigger": {
121 | "plugin_name": "com.sap.hana.di.trigger"
122 | },
123 | "hdbview": {
124 | "plugin_name": "com.sap.hana.di.view"
125 | },
126 | "hdbvirtualfunction": {
127 | "plugin_name": "com.sap.hana.di.virtualfunction"
128 | },
129 | "hdbvirtualfunctionconfig": {
130 | "plugin_name": "com.sap.hana.di.virtualfunction.config"
131 | },
132 | "hdbvirtualpackagehadoop": {
133 | "plugin_name": "com.sap.hana.di.virtualpackage.hadoop"
134 | },
135 | "hdbvirtualpackagesparksql": {
136 | "plugin_name": "com.sap.hana.di.virtualpackage.sparksql"
137 | },
138 | "hdbvirtualprocedure": {
139 | "plugin_name": "com.sap.hana.di.virtualprocedure"
140 | },
141 | "hdbvirtualprocedureconfig": {
142 | "plugin_name": "com.sap.hana.di.virtualprocedure.config"
143 | },
144 | "hdbvirtualtable": {
145 | "plugin_name": "com.sap.hana.di.virtualtable"
146 | },
147 | "hdbvirtualtableconfig": {
148 | "plugin_name": "com.sap.hana.di.virtualtable.config"
149 | },
150 | "jar": {
151 | "plugin_name": "com.sap.hana.di.virtualfunctionpackage.hadoop"
152 | },
153 | "properties": {
154 | "plugin_name": "com.sap.hana.di.tabledata.properties"
155 | },
156 | "tags": {
157 | "plugin_name": "com.sap.hana.di.tabledata.properties"
158 | },
159 | "txt": {
160 | "plugin_name": "com.sap.hana.di.copyonly"
161 | }
162 | }
163 | }
--------------------------------------------------------------------------------
/test/test-suite.test.js:
--------------------------------------------------------------------------------
1 | const tests = require('./test-suite')
2 | jest.setTimeout(30000)
3 |
4 | describe('Access Tokens', () => {
5 | test('get access token for xsuaa', async () => {
6 | console.log('TEST 1 : Get access token for XSUAA')
7 | const result = await tests.getAuthTokenXSUAA()
8 | console.log('EXPECTED RESULT : XSUAA Access Token')
9 | if(result.error) console.error('ACTUAL RESULT: Issue :',result.error)
10 | else if(result.access_token) console.log('ACTUAL RESULT: XSUAA Access Token')
11 | else console.error('ACTUAL RESULT : Error :',result)
12 | expect(result).toMatchObject({
13 | "access_token": expect.any(String),
14 | "token_type": "bearer",
15 | "id_token": expect.any(String),
16 | "refresh_token": expect.any(String),
17 | "expires_in": expect.any(Number),
18 | "scope": expect.any(String),
19 | "jti": expect.any(String)
20 | })
21 | })
22 | })
23 |
24 | describe('Products', () => {
25 | test('get products', async () => {
26 | console.log('TEST 2 : Get products')
27 | const result = await tests.getProducts()
28 | console.log('EXPECTED RESULT : Products fetched')
29 | if(result.error) console.error('ACTUAL RESULT: Issue :',result.error)
30 | else if(Array.isArray(result) && result.length > 0) console.log('ACTUAL RESULT: Products fetched')
31 | else if(Array.isArray(result) && result.length <= 0) console.log('ACTUAL RESULT: No products fetched')
32 | else console.error('ACTUAL RESULT : Error :',result)
33 | expect(result).toEqual(expect.arrayContaining([
34 | expect.objectContaining({
35 | "PRODUCTID": expect.any(String),
36 | "PRODUCTNAME": expect.any(String),
37 | "CURRENCYCODE": expect.any(String),
38 | "CATEGORY": expect.any(String),
39 | "WEIGHT": expect.any(String),
40 | "WEIGHTUNIT": expect.any(String),
41 | "SHORTDESCRIPTION": expect.any(String),
42 | "PICTUREURL": expect.any(String),
43 | "PRICE": expect.any(String),
44 | "DIMENSIONWIDTH": expect.any(String),
45 | "DIMENSIONDEPTH": expect.any(String),
46 | "DIMENSIONHEIGHT": expect.any(String),
47 | "DIMENSIONUNIT": expect.any(String)
48 | })
49 | ]))
50 | })
51 |
52 | test('get stock', async () => {
53 | console.log('TEST 3 : Get Stock')
54 | const result = await tests.getStock()
55 | console.log('EXPECTED RESULT : Product quantity available')
56 | if(result.error) console.error('ACTUAL RESULT: Issue :',result.error)
57 | else if(result) console.log('ACTUAL RESULT: Product quantity available')
58 | else if(!result) console.log('ACTUAL RESULT: Product quantity not in stock')
59 | else console.error('ACTUAL RESULT : Error :',result)
60 | expect(result).toBeTruthy()
61 | })
62 | })
63 |
64 | describe('Quotations', () => {
65 | test('get quote', async () => {
66 | console.log('TEST 4 : Get quotation amount')
67 | const result = await tests.getQuote()
68 | console.log('EXPECTED RESULT : Quotation Amount is 970')
69 | if(result.error) console.error('ACTUAL RESULT: Issue :',result.error)
70 | else if(result.Cost) console.log('ACTUAL RESULT: Quotation Amount is '+result.Cost)
71 | else console.error('ACTUAL RESULT : Error :',result)
72 | expect(result).toMatchObject({ "Cost": '970' })
73 | })
74 | })
75 |
76 | describe('Orders', () => {
77 | test('create order', async () => {
78 | console.log('TEST 5 : Create Order')
79 | const result = await tests.createOrder()
80 | console.log('EXPECTED RESULT : Order Created')
81 | if(result == 'Order Created') console.log('ACTUAL RESULT: Order Created')
82 | else if(result.includes('error')){
83 | const res = JSON.parse(result)
84 | console.error('ACTUAL RESULT: Issue :',res.error)
85 | }
86 | else console.error('ACTUAL RESULT : Error :',result)
87 | expect(result).toBe('Order Created')
88 | })
89 |
90 | test('update stock', async () => {
91 | console.log('TEST 6 : Update Stock')
92 | const result = await tests.updateStock()
93 | console.log('EXPECTED RESULT : Stock Updated')
94 | if(result == 'Stock Updated') console.log('ACTUAL RESULT: Stock Updated')
95 | else if(result.includes('error')){
96 | const res = JSON.parse(result)
97 | console.error('ACTUAL RESULT: Issue :',res.error)
98 | }
99 | else console.error('ACTUAL RESULT : Error :',result)
100 | expect(result).toBe('Stock Updated')
101 | })
102 | })
103 |
104 | describe('Freight Manager', () => {
105 | test('get access token for freight service', async() => {
106 | console.log('TEST 7 : Get access token for Freight Service')
107 | const result = await tests.getAuthTokenFreightService()
108 | console.log('EXPECTED RESULT : XSUAA Access Token for Freight Service')
109 | if(result.error) console.error('ACTUAL RESULT: Issue :',result.error)
110 | else if(result.access_token) console.log('ACTUAL RESULT: XSUAA Access Token for Freight Service')
111 | else console.error('ACTUAL RESULT : Error :',result)
112 | expect(result).toMatchObject({
113 | "access_token": expect.any(String),
114 | "token_type": "bearer",
115 | "expires_in": expect.any(Number),
116 | "scope": expect.any(String),
117 | "jti": expect.any(String)
118 | })
119 | })
120 |
121 | test('check freight service', async () => {
122 | console.log('TEST 8 : Check Freight Service')
123 | const result = await tests.checkFreightService()
124 | console.log('EXPECTED RESULT : Quotation Amount is 970')
125 | if(result.includes('error')){
126 | const res = JSON.parse(result)
127 | console.error('ACTUAL RESULT: Issue :',res.error)
128 | }
129 | else if(result) console.log('ACTUAL RESULT: Quotation Amount is '+result)
130 | else console.error('ACTUAL RESULT : Error :',result)
131 | expect(result).toBe('970')
132 | })
133 | })
134 |
--------------------------------------------------------------------------------
/approuter/ui/uimodule/webapp/view/orderView.fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/test/test-suite.js:
--------------------------------------------------------------------------------
1 | const config = require('./config')
2 | const util = require('./util')
3 |
4 | let xsuaa_access_token, access_token_freight_service;
5 |
6 | async function getAuthTokenXSUAA(){
7 | const req_url = config.token_url
8 | const req_headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
9 | console.log('REQUEST URL: POST', req_url)
10 | console.log('REQUEST HEADERS:', req_headers)
11 | try{
12 | const response = await util.requestHandler({
13 | url: req_url,
14 | method: 'POST',
15 | body: util.urlEncodeParams(config.xsuaa),
16 | headers: req_headers
17 | })
18 | console.log('RESPONSE STATUS:', response.status)
19 | const json = await response.json()
20 | console.log('RESPONSE BODY:',json)
21 | if(json.access_token) xsuaa_access_token = json.access_token
22 | return json
23 | } catch(err) {
24 | return err
25 | }
26 | }
27 |
28 | async function getProducts(){
29 | const req_url = config.product_service_url+'/getProducts'
30 | const req_headers = { 'Authorization':'Bearer '+ xsuaa_access_token }
31 | console.log('REQUEST URL: GET', req_url)
32 | try{
33 | const response = await util.requestHandler({
34 | url: req_url,
35 | method: 'GET',
36 | headers: req_headers
37 | })
38 | console.log('RESPONSE STATUS:', response.status)
39 | const json = await response.json()
40 | console.log('RESPONSE BODY:',json)
41 | return json
42 | }
43 | catch(err) {
44 | return err
45 | }
46 | }
47 |
48 | async function getStock(){
49 | let req_url = config.product_service_url+'/stock'
50 | const req_headers = { 'Authorization':'Bearer '+ xsuaa_access_token }
51 | let params = { productId: 'HT-1000', quantity: 1 }
52 | req_url = util.parameteriseUrl(req_url, params)
53 | console.log('REQUEST URL: GET', req_url)
54 | try {
55 | const response = await util.requestHandler({
56 | url: req_url,
57 | method: 'GET',
58 | headers: req_headers
59 | })
60 | console.log('RESPONSE STATUS:', response.status)
61 | const json = await response.json()
62 | console.log('RESPONSE BODY:',json)
63 | return json
64 | }
65 | catch(err){
66 | return err
67 | }
68 | }
69 |
70 | async function getQuote(){
71 | let req_url = config.logistic_service_url+'/getQuote'
72 | const req_headers = { 'Authorization':'Bearer '+ xsuaa_access_token }
73 | let params = {
74 | mode: 'RAIL',
75 | productId: 'HT-1000',
76 | quantity: 1,
77 | totalDistanceMeasured: 50,
78 | weight: 0.4,
79 | dimension: '0.2410,0.1050,0.1190'
80 | }
81 | req_url = util.parameteriseUrl(req_url,params)
82 | console.log('REQUEST URL: GET', req_url)
83 | try{
84 | const response = await util.requestHandler({
85 | url: req_url,
86 | method: 'GET',
87 | headers: req_headers
88 | })
89 | console.log('RESPONSE STATUS:', response.status)
90 | let json;
91 | if(response.status == '200') json = await response.json()
92 | else json = { 'error' : 'Product is out of stock'}
93 | console.log('RESPONSE BODY:',json)
94 | return json
95 | }
96 | catch(err){
97 | return err
98 | }
99 | }
100 |
101 | async function createOrder(){
102 | const req_url = config.logistic_service_url+'/order'
103 | const req_headers = {
104 | 'Content-Type': 'application/json',
105 | 'Authorization': 'Bearer '+xsuaa_access_token
106 | }
107 | const req_body = {
108 | "contactPerson":"Steve",
109 | "address":"444 ABC TOWN, MUNICH",
110 | "phone":"9876543210",
111 | "countryCode":"DU",
112 | "email":"steve.wozniak@sap.com",
113 | "totalDistanceMeasured":50,
114 | "productName":"ADSL progress T1",
115 | "productId":"HT-1117",
116 | "quantity":1,
117 | "grossWeight":0.4,
118 | "transportationMeansType":"RAIL",
119 | "lifecyclestatus":"A",
120 | "pickupdate":"20200721",
121 | "deliverydate":"20200721",
122 | "transportationCharges":970,
123 | "currencycode":"EUR"
124 | }
125 | console.log('REQUEST URL: POST', req_url)
126 | console.log('REQUEST BODY:', req_body)
127 | try{
128 | const response = await util.requestHandler({
129 | url: req_url,
130 | method: 'POST',
131 | headers: req_headers,
132 | body: JSON.stringify(req_body)
133 | })
134 | console.log('RESPONSE STATUS:', response.status)
135 | const text = await response.text()
136 | console.log('RESPONSE BODY:',text)
137 | return text
138 | }
139 | catch(err){
140 | return err
141 | }
142 | }
143 |
144 | async function updateStock(){
145 | let req_url = config.product_service_url+'/stock'
146 | const req_headers = {
147 | 'Content-Type': 'application/json',
148 | 'Authorization': 'Bearer '+xsuaa_access_token
149 | }
150 | let params = {
151 | productId : 'HT-1000',
152 | quantity : 1
153 | }
154 | req_url = util.parameteriseUrl(req_url,params)
155 | console.log('REQUEST URL: PUT', req_url)
156 | try{
157 | const response = await util.requestHandler({
158 | url: req_url,
159 | method: 'PUT',
160 | headers: req_headers
161 | })
162 | console.log('RESPONSE STATUS:', response.status)
163 | const text = await response.text()
164 | console.log('RESPONSE BODY:',text)
165 | return text
166 | }
167 | catch(err){
168 | return err
169 | }
170 | }
171 |
172 | async function getAuthTokenFreightService(){
173 | const req_url = config.token_url
174 | const req_headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
175 | console.log('REQUEST URL: POST', req_url)
176 | console.log('REQUEST HEADERS:', req_headers)
177 | try{
178 | const response = await util.requestHandler({
179 | url: req_url,
180 | method: 'POST',
181 | body: util.urlEncodeParams(config.freight_service_config),
182 | headers: req_headers
183 | })
184 | console.log('RESPONSE STATUS:', response.status)
185 | const json = await response.json()
186 | console.log('RESPONSE BODY:',json)
187 | if(json.access_token) access_token_freight_service = json.access_token
188 | return json
189 | }
190 | catch(err){
191 | return err
192 | }
193 | }
194 |
195 | async function checkFreightService(){
196 | let req_url = config.freight_service_url+'/'
197 | const req_headers = { 'Authorization':'Bearer '+ access_token_freight_service }
198 | let params = {
199 | transportationmeans: 'RAIL',
200 | quantity: 1,
201 | totalDistanceMeasured: 50,
202 | weight: 0.4,
203 | dimension: '0.2410,0.1050,0.1190'
204 | }
205 | req_url = util.parameteriseUrl(req_url,params)
206 | console.log('REQUEST URL: GET', req_url)
207 | try{
208 | const response = await util.requestHandler({
209 | url: req_url,
210 | method: 'GET',
211 | headers: req_headers
212 | })
213 | console.log('RESPONSE STATUS:', response.status)
214 | const text = await response.text()
215 | console.log('RESPONSE BODY:',text)
216 | return text
217 | }
218 | catch(err){
219 | return err
220 | }
221 | }
222 |
223 | module.exports = { getAuthTokenXSUAA, getProducts, getStock, getQuote, createOrder, updateStock, getAuthTokenFreightService, checkFreightService }
--------------------------------------------------------------------------------
/db/src/data/product.csv:
--------------------------------------------------------------------------------
1 | HT-1000,EUR,Notebooks,4.2,KG,"Notebook Basic 15 with 1,7GHz - 15"" XGA - 1024MB DDR2 SDRAM - 40GB Hard Disc",Notebook Basic 15,IMAGES/HT-1000.jpg,956,0.3,0.18,0.03,m
2 | HT-1001,EUR,Notebooks,4.5,KG,"Notebook Basic 17 with 1,7GHz - 17"" XGA - 1024MB DDR2 SDRAM - 40GB Hard Disc",Notebook Basic 17,IMAGES/HT-1001.jpg,1249,0.29,0.17,0.031,m
3 | HT-1002,EUR,Notebooks,4.2,KG,"Notebook Basic 18 with 1,7GHz - 18"" LCD - 1024MB DDR2 SDRAM - 40GB Hard Disc",Notebook Basic 18,IMAGES/HT-1002.jpg,1570,0.28,0.19,0.025,m
4 | HT-1003,EUR,Notebooks,4.2,KG,"Notebook Basic 19 with 1,7GHz - 19"" LCD - 1024MB DDR2 SDRAM - 40GB Hard Disc",Notebook Basic 19,IMAGES/HT-1003.jpg,1650,0.32,0.21,0.04,m
5 | HT-1010,EUR,Notebooks,4.3,KG,"Notebook Professional 15 with 2,3GHz - 15"" XGA - 2048MB DDR2 SDRAM - 40GB Hard Disc - DVD-Writer (DVD-R/+R/-RW/-RAM)",Notebook Professional 15,IMAGES/HT-1010.jpg,1999,0.33,0.2,0.03,m
6 | HT-1011,EUR,Notebooks,4.1,KG,"Notebook Professional 17 with 2,3GHz - 17"" XGA - 2048MB DDR2 SDRAM - 40GB Hard Disc - DVD-Writer (DVD-R/+R/-RW/-RAM)",Notebook Professional 17,IMAGES/HT-1011.jpg,2299,0.33,0.23,0.02,m
7 | HT-1030,EUR,Flat screens,18,KG,"17"" Optimum Resolution 1024 x 768 @ 85Hz, Max resolution 1280 x 960 @ 75Hz, Dot Pitch: 0.27mm",Ergo Screen,IMAGES/HT-1030.jpg,230,0.37,0.12,0.36,m
8 | HT-1031,EUR,Flat screens,22,KG,"19"" Optimum Resolution 1280 x 960 @ 85Hz, Max resolution 1600 x 1200 @ 75Hz, Dot Pitch: 0.26mm",Easy Pixel,IMAGES/HT-1031.jpg,285,0.408,0.19,0.43,m
9 | HT-1032,EUR,Flat screens,21,KG,"21"" Optimum Resolution 1600 x 1200 @ 85Hz, Max resolution 1984 x 1488 @ 75Hz, Dot Pitch: 0.25mm",Beam Screen,IMAGES/HT-1032.jpg,345,0.408,0.19,0.43,m
10 | HT-1035,EUR,Flat screens,14,KG,"19"" Optimum Resolution 1600 x 1200 @ 85Hz, Max resolution 1984 x 1488 @ 75Hz, Dot Pitch: 0.24mm",Flat Basic 15,IMAGES/HT-1035.jpg,399,0.39,0.2,0.41,m
11 | HT-1036,EUR,Flat screens,15,KG,"21"" Optimum Resolution 1984 x 1488 @ 85Hz, Max resolution 1720 x 1280 @ 75Hz, Dot Pitch: 0.24mm",Flat Future,IMAGES/HT-1036.jpg,430,0.45,0.26,0.46,m
12 | HT-1037,EUR,Flat screens,17,KG,"23"" Optimum Resolution 2016 x 1512 @ 85Hz, Max resolution 2048 x 1536 @ 75Hz, Dot Pitch: 0.24mm",Flat X-large,IMAGES/HT-1037.jpg,1430,0.545,0.221,0.391,m
13 | HT-1041,EUR,Laser printers,23,KG,"Up to 22 ppm color or 24 ppm monochrome letter, powerful 500 MHz processor and 128MB of memory",Laser Basic,IMAGES/HT-1041.jpg,490,0.48,0.42,0.26,m
14 | HT-1042,EUR,Laser printers,15,KG,"Print up to 25 ppm letter and 24 ppm A4 color or monochrome, with a first-page-out-time of less than 13 seconds for monochrome and less than 15 seconds for color",Laser Allround,IMAGES/HT-1042.jpg,349,0.53,0.5,0.65,m
15 | HT-1050,EUR,Ink jet printers,3,KG,"1200 dpi x 1200 dpi - up to 19 ppm (mono) / up to 18 ppm (colour) - capacity: 80 sheets - Hi-Speed USB, Ethernet",Deskjet Super Color,IMAGES/HT-1050.jpg,139,0.45,0.342,0.18,m
16 | HT-1051,EUR,Ink jet printers,1.9,KG,1000 dpi x 1000 dpi - up to 15 ppm (mono) / up to 13 ppm (colour) - capacity: 40 sheets - Hi-Speed USB - excellent dimesions for the small office,Deskjet Mobile,IMAGES/HT-1051.jpg,99,0.46,0.32,0.25,m
17 | HT-1052,EUR,Ink jet printers,18,KG,"1200 dpi x 1200 dpi - up to 25 ppm (mono) / up to 24 ppm (colour) - capacity: 100 sheets - Hi-Speed USB2.0, Ethernet",Deskjet Super Highspeed,IMAGES/HT-1052.jpg,170,0.41,0.42,0.28,m
18 | HT-1055,EUR,Multifunction printers,6.3,KG,"1000 dpi x 1000 dpi - up to 16 ppm (mono) / up to 15 ppm (colour)- capacity 80 sheets - scanner (216 x 297 mm, 1200dpi x 2400dpi)",Multi Print,IMAGES/HT-1055.jpg,99,0.55,0.45,0.29,m
19 | HT-1056,EUR,Multifunction printers,4.3,KG,"1200 dpi x 1200 dpi - up to 25 ppm (mono) / up to 24 ppm (colour)- capacity 80 sheets - scanner (216 x 297 mm, 2400dpi x 4800dpi, high resolution)",Multi Color,IMAGES/HT-1056.jpg,119,0.51,0.413,0.22,m
20 | HT-1063,EUR,Keyboards,2.1,KG,"Ergonomic USB PS/2 Keyboard for Desktop, Plug&Play",Ergonomic Keyboard,IMAGES/HT-1063.jpg,14,0.5,0.21,0.035,m
21 | HT-1064,EUR,Keyboards,1.8,KG,"Corded Keyboard with special keys for Internet Usability, USB",Internet Keyboard,IMAGES/HT-1064.jpg,16,0.52,0.25,0.03,m
22 | HT-1065,EUR,Keyboards,2.3,KG,"Corded Keyboard with special keys for Media Usability, USB",Media Keyboard,IMAGES/HT-1065.jpg,26,0.514,0.23,0.04,m
23 | HT-1069,EUR,Flat screens,170,G,"Replacement display for all 14'' IBM Thinkpad, Gercom Webboy. and HP Omnibook computers.",Notebook LCD Display,IMAGES/HT-1069.jpg,800,0.32,0.002,0.23,m
24 | HT-1080,EUR,Scanners,2.3,KG,Flatbed scanner - 1200 dpi x 1000 dpi - 216 x 297 mm - Hi-Speed USB - Bluetooth Ver. 1.2,Photo Scan,IMAGES/HT-1080.jpg,51,0.34,0.48,0.05,m
25 | HT-1081,EUR,Scanners,2.4,KG,Flatbed scanner - 1200 dpi x 1200 dpi - 216 x 297 mm - Hi-Speed USB - Bluetooth Ver. 1.2,Power Scan,IMAGES/HT-1081.jpg,89,0.31,0.43,0.07,m
26 | HT-1082,EUR,Scanners,3.2,KG,Flatbed scanner - Letter - 2400 dpi x 2400 dpi - 216 x 297 mm - Hi-Speed USB - Bluetooth Ver. 1.2,Jet Scan Professional,IMAGES/HT-1082.jpg,169,0.33,0.41,0.12,m
27 | HT-1083,EUR,Scanners,3.2,KG,Flatbed scanner - Letter - 2400 dpi x 2400 dpi - ADF ( 50 sheets ) - Hi-Speed USB - Bluetooth Ver. 1.2,Jet Scan Professional,IMAGES/HT-1083.jpg,520,0.35,0.4,0.1,m
28 | HT-1085,EUR,Multifunction printers,23.2,KG,Copymaster,Copymaster,IMAGES/HT-1085.jpg,1499,0.45,0.42,0.22,m
29 | HT-1090,EUR,Speakers,3,KG,PC multimedia speakers - 5 Watt (Total),Surround Sound,IMAGES/HT-1090.jpg,39,0.12,0.1,0.16,m
30 | HT-1091,EUR,Speakers,1.4,KG,PC multimedia speakers - 10 Watt (Total) - 2-way,Blaster Extreme,IMAGES/HT-1091.jpg,26,0.13,0.11,0.175,m
31 | HT-1092,EUR,Speakers,2.1,KG,PC multimedia speakers - 30 Watt (Total) - 2-way,Sound Booster,IMAGES/HT-1092.jpg,45,0.124,0.104,0.181,m
32 | HT-1120,EUR,Keyboards,1,KG,Corded Keyboard with english keys,"Keybord, english international",IMAGES/HT-1120.jpg,260,0.45,0.194,0.032,m
33 | HT-1138,EUR,Flat screens,4.2,KG,"23"" Optimum Resolution 2016 x 1512 @ 85Hz, Max resolution 2048 x 1536 @ 75Hz, Dot Pitch: 0.24mm",Flat XL,IMAGES/HT-1138.jpg,1211,0.53,0.2,0.44,m
34 | HT-1210,EUR,PCs,2.3,KG,"PC Power Station with 2,6 quad-core, 2 GB RAM, feels like a PC",PC Power Station,IMAGES/HT-1210.jpg,2399,0.28,0.31,0.43,m
35 | HT-1500,EUR,Servers,18,KG,"Dual socket, quad-core processing server with 1333 MHz Front Side Bus with 10Gb connectivity",Server Basic,IMAGES/HT-1500.jpg,5000,0.34,0.35,0.23,m
36 | HT-1501,EUR,Servers,25,KG,"Dual socket, quad-core processing server with 1644 MHz Front Side Bus with 10Gb connectivity",Server Professional,IMAGES/HT-1501.jpg,15000,0.29,0.3,0.27,m
37 | HT-1502,EUR,Servers,35,KG,"Dual socket, quad-core processing server with 1644 MHz Front Side Bus with 100Gb connectivity",Server Power Pro,IMAGES/HT-1502.jpg,25000,0.22,0.273,0.37,m
38 | HT-6130,EUR,TV flat screens,2.6,KG,"32 Zoll, 1366x768 Pixel, 16:9, HDTV ready",Flat Watch HD32,IMAGES/HT-6130.jpg,1459,0.78,0.221,0.55,m
39 | HT-6131,EUR,TV flat screens,2.2,KG,"37 Zoll, 1366x768 Pixel, 16:9, HDTV ready",Flat Watch HD37,IMAGES/HT-6131.jpg,1199,0.991,0.26,0.61,m
40 | HT-6132,EUR,TV flat screens,1.8,KG,"41 Zoll, 1366x768 Pixel, 16:9, HDTV ready",Flat Watch HD41,IMAGES/HT-6132.jpg,899,1.28,0.23,0.791,m
41 | HT-6102,EUR,Beamers,2.5,KG,"2500 ANSI-Lumen, max.12,3Meter, 800 Pixel, 600 Pixel",Beam Breaker B-3,,889,0.304,0.231,0.23,m
42 | HT-6101,EUR,Beamers,2,KG,"2200 ANSI-Lumen, max.9,34 Meter, 800 Pixel, 600 Pixel",Beam Breaker B-2,,679,0.32,0.21,0.18,m
43 | HT-6100,EUR,Beamers,1.7,KG,"1900 ANSI-Lumen, max. 8,45 Meter, 800 Pixel, 600 Pixel",Beam Breaker B-1,,469,0.18,0.15,0.12,m
44 | HT-1603,EUR,PCs,6.8,KG,"2,5 Ghz, quad core, 8 GB RAM, 700 GB Hdd, Graphic Card: Hurricane GX",Gaming Monster Pro,IMAGES/HT-1601.jpg,1700,0.27,0.28,0.42,m
45 | HT-1602,EUR,PCs,5.9,KG,"2,2 Ghz, dual core, 2 GB RAM, 400 GB Hdd, Graphic Card: Gladiator MX",Gaming Monster,IMAGES/HT-1602.jpg,1200,0.265,0.34,0.47,m
46 | HT-1601,EUR,PCs,5.3,KG,"2 Ghz, dual core, 1 GB RAM, 250 GB Hdd, Graphic Card: Gladiator MX",Family PC Pro,IMAGES/HT-1601.jpg,900,0.25,0.317,0.402,m
47 | HT-1600,EUR,PCs,4.8,KG,"1.8 Ghz, dual core,512 MB Ram, 100 GB HDD, Graphic Card: Proctra X",Family PC Basic,IMAGES/HT-1600.jpg,600,0.214,0.29,0.38,m
48 | HT-8000,EUR,Notebooks,4,KG,"1,5 Ghz, single core, 40 GB HDD, Windows Vista Home Basic, 512 MB RAM",ITelO FlexTop I4000,IMAGES/HT-8000.jpg,799,0.31,0.19,0.031,m
49 | HT-8001,EUR,Notebooks,4.2,KG,"1,6 Ghz, dual core, 60 GB HDD, Windows Vista Home Basic, 512 MB RAM+",ITelO FlexTop I6300c,IMAGES/HT-8001.jpg,999,0.32,0.2,0.034,m
50 | HT-8002,EUR,Notebooks,3.5,KG,"2,2 Ghz, quad core, 80 GB HDD, Windows Vista Home Premium, 1024 MB RAM",ITelO FlexTop I9100,IMAGES/HT-8002.jpg,1199,0.38,0.21,0.041,m
51 | HT-8003,EUR,Notebooks,3.8,KG,"2,8 Ghz, quad core, 120 GB HDD, Windows Vista Home Premium, 2048 MB RAM",ITelO FlexTop I9800,IMAGES/HT-8003.jpg,1388,0.48,0.31,0.045,m
52 |
--------------------------------------------------------------------------------
/LICENSES/Apache-2.0.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
9 |
10 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
11 |
12 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
13 |
14 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
15 |
16 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
17 |
18 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
19 |
20 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
21 |
22 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
23 |
24 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
25 |
26 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
27 |
28 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
29 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
30 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
31 | (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
32 | (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
33 | (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
34 | (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
35 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
36 |
37 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
38 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
39 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
40 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
41 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
42 | END OF TERMS AND CONDITIONS
43 |
44 | APPENDIX: How to apply the Apache License to your work.
45 |
46 | To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
47 |
48 | Copyright 2020 SAP SE
49 |
50 | Licensed under the Apache License, Version 2.0 (the "License");
51 | you may not use this file except in compliance with the License.
52 | You may obtain a copy of the License at
53 |
54 | http://www.apache.org/licenses/LICENSE-2.0
55 |
56 | Unless required by applicable law or agreed to in writing, software
57 | distributed under the License is distributed on an "AS IS" BASIS,
58 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
59 | See the License for the specific language governing permissions and
60 | limitations under the License.
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2021 SAP
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/db/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "deploy",
3 | "lockfileVersion": 2,
4 | "requires": true,
5 | "packages": {
6 | "": {
7 | "name": "deploy",
8 | "dependencies": {
9 | "@sap/hdi-deploy": "^4.8.2"
10 | }
11 | },
12 | "node_modules/@sap/hdi-deploy": {
13 | "version": "4.8.2",
14 | "resolved": "https://registry.npmjs.org/@sap/hdi-deploy/-/hdi-deploy-4.8.2.tgz",
15 | "integrity": "sha512-LDouJ0i6oTLOrYWLeyp4PKF5cIBeKnn70gksdlg/bq3q5G/UNgGmqL62TEHbXehbeJfc0DKfEp9yal4IFD5k1Q==",
16 | "hasShrinkwrap": true,
17 | "dependencies": {
18 | "@sap/hana-client": "2.18.24",
19 | "@sap/hdi": "4.5.1",
20 | "@sap/xsenv": "3.4.0",
21 | "async": "3.2.3",
22 | "dotenv": "10.0.0",
23 | "handlebars": "4.7.7",
24 | "hdb": "0.19.3",
25 | "micromatch": "4.0.4"
26 | },
27 | "engines": {
28 | "node": "^12.0.0 || ^14.0.0 || ^16.0.0 || ^18.0.0 || ^20.0.0"
29 | }
30 | },
31 | "node_modules/@sap/hdi-deploy/node_modules/@sap/hana-client": {
32 | "version": "2.18.24",
33 | "dependencies": {
34 | "debug": "3.1.0"
35 | }
36 | },
37 | "node_modules/@sap/hdi-deploy/node_modules/@sap/hana-client/node_modules/debug": {
38 | "version": "3.1.0",
39 | "dependencies": {
40 | "ms": "2.0.0"
41 | }
42 | },
43 | "node_modules/@sap/hdi-deploy/node_modules/@sap/hana-client/node_modules/ms": {
44 | "version": "2.0.0"
45 | },
46 | "node_modules/@sap/hdi-deploy/node_modules/@sap/hdi": {
47 | "version": "4.5.1",
48 | "dependencies": {
49 | "async": "3.2.3"
50 | }
51 | },
52 | "node_modules/@sap/hdi-deploy/node_modules/@sap/xsenv": {
53 | "version": "3.4.0",
54 | "dependencies": {
55 | "debug": "4.3.3",
56 | "node-cache": "^5.1.0",
57 | "verror": "1.10.0"
58 | }
59 | },
60 | "node_modules/@sap/hdi-deploy/node_modules/@sap/xsenv/node_modules/assert-plus": {
61 | "version": "1.0.0"
62 | },
63 | "node_modules/@sap/hdi-deploy/node_modules/@sap/xsenv/node_modules/clone": {
64 | "version": "2.1.2"
65 | },
66 | "node_modules/@sap/hdi-deploy/node_modules/@sap/xsenv/node_modules/core-util-is": {
67 | "version": "1.0.2"
68 | },
69 | "node_modules/@sap/hdi-deploy/node_modules/@sap/xsenv/node_modules/debug": {
70 | "version": "4.3.3",
71 | "dependencies": {
72 | "ms": "2.1.2"
73 | }
74 | },
75 | "node_modules/@sap/hdi-deploy/node_modules/@sap/xsenv/node_modules/extsprintf": {
76 | "version": "1.4.1"
77 | },
78 | "node_modules/@sap/hdi-deploy/node_modules/@sap/xsenv/node_modules/ms": {
79 | "version": "2.1.2"
80 | },
81 | "node_modules/@sap/hdi-deploy/node_modules/@sap/xsenv/node_modules/node-cache": {
82 | "version": "5.1.2",
83 | "dependencies": {
84 | "clone": "2.x"
85 | }
86 | },
87 | "node_modules/@sap/hdi-deploy/node_modules/@sap/xsenv/node_modules/verror": {
88 | "version": "1.10.0",
89 | "dependencies": {
90 | "assert-plus": "^1.0.0",
91 | "core-util-is": "1.0.2",
92 | "extsprintf": "^1.2.0"
93 | }
94 | },
95 | "node_modules/@sap/hdi-deploy/node_modules/async": {
96 | "version": "3.2.3"
97 | },
98 | "node_modules/@sap/hdi-deploy/node_modules/braces": {
99 | "version": "3.0.2",
100 | "dependencies": {
101 | "fill-range": "^7.0.1"
102 | }
103 | },
104 | "node_modules/@sap/hdi-deploy/node_modules/dotenv": {
105 | "version": "10.0.0"
106 | },
107 | "node_modules/@sap/hdi-deploy/node_modules/fill-range": {
108 | "version": "7.0.1",
109 | "dependencies": {
110 | "to-regex-range": "^5.0.1"
111 | }
112 | },
113 | "node_modules/@sap/hdi-deploy/node_modules/handlebars": {
114 | "version": "4.7.7",
115 | "dependencies": {
116 | "minimist": "^1.2.5",
117 | "neo-async": "^2.6.0",
118 | "source-map": "^0.6.1",
119 | "wordwrap": "^1.0.0"
120 | },
121 | "optionalDependencies": {
122 | "uglify-js": "^3.1.4"
123 | }
124 | },
125 | "node_modules/@sap/hdi-deploy/node_modules/hdb": {
126 | "version": "0.19.3",
127 | "dependencies": {
128 | "iconv-lite": "^0.4.18"
129 | }
130 | },
131 | "node_modules/@sap/hdi-deploy/node_modules/iconv-lite": {
132 | "version": "0.4.24",
133 | "dependencies": {
134 | "safer-buffer": ">= 2.1.2 < 3"
135 | }
136 | },
137 | "node_modules/@sap/hdi-deploy/node_modules/is-number": {
138 | "version": "7.0.0"
139 | },
140 | "node_modules/@sap/hdi-deploy/node_modules/micromatch": {
141 | "version": "4.0.4",
142 | "dependencies": {
143 | "braces": "^3.0.1",
144 | "picomatch": "^2.2.3"
145 | }
146 | },
147 | "node_modules/@sap/hdi-deploy/node_modules/minimist": {
148 | "version": "1.2.8"
149 | },
150 | "node_modules/@sap/hdi-deploy/node_modules/neo-async": {
151 | "version": "2.6.2"
152 | },
153 | "node_modules/@sap/hdi-deploy/node_modules/picomatch": {
154 | "version": "2.3.1"
155 | },
156 | "node_modules/@sap/hdi-deploy/node_modules/safer-buffer": {
157 | "version": "2.1.2"
158 | },
159 | "node_modules/@sap/hdi-deploy/node_modules/source-map": {
160 | "version": "0.6.1"
161 | },
162 | "node_modules/@sap/hdi-deploy/node_modules/to-regex-range": {
163 | "version": "5.0.1",
164 | "dependencies": {
165 | "is-number": "^7.0.0"
166 | }
167 | },
168 | "node_modules/@sap/hdi-deploy/node_modules/uglify-js": {
169 | "version": "3.17.4",
170 | "optional": true
171 | },
172 | "node_modules/@sap/hdi-deploy/node_modules/wordwrap": {
173 | "version": "1.0.0"
174 | }
175 | },
176 | "dependencies": {
177 | "@sap/hdi-deploy": {
178 | "version": "4.8.2",
179 | "resolved": "https://registry.npmjs.org/@sap/hdi-deploy/-/hdi-deploy-4.8.2.tgz",
180 | "integrity": "sha512-LDouJ0i6oTLOrYWLeyp4PKF5cIBeKnn70gksdlg/bq3q5G/UNgGmqL62TEHbXehbeJfc0DKfEp9yal4IFD5k1Q==",
181 | "requires": {
182 | "@sap/hana-client": "2.18.24",
183 | "@sap/hdi": "4.5.1",
184 | "@sap/xsenv": "3.4.0",
185 | "async": "3.2.3",
186 | "dotenv": "10.0.0",
187 | "handlebars": "4.7.7",
188 | "hdb": "0.19.3",
189 | "micromatch": "4.0.4"
190 | },
191 | "dependencies": {
192 | "@sap/hana-client": {
193 | "version": "2.18.24",
194 | "requires": {
195 | "debug": "3.1.0"
196 | },
197 | "dependencies": {
198 | "debug": {
199 | "version": "3.1.0",
200 | "requires": {
201 | "ms": "2.0.0"
202 | }
203 | },
204 | "ms": {
205 | "version": "2.0.0"
206 | }
207 | }
208 | },
209 | "@sap/hdi": {
210 | "version": "4.5.1",
211 | "requires": {
212 | "async": "3.2.3"
213 | }
214 | },
215 | "@sap/xsenv": {
216 | "version": "3.4.0",
217 | "requires": {
218 | "debug": "4.3.3",
219 | "node-cache": "^5.1.0",
220 | "verror": "1.10.0"
221 | },
222 | "dependencies": {
223 | "assert-plus": {
224 | "version": "1.0.0"
225 | },
226 | "clone": {
227 | "version": "2.1.2"
228 | },
229 | "core-util-is": {
230 | "version": "1.0.2"
231 | },
232 | "debug": {
233 | "version": "4.3.3",
234 | "requires": {
235 | "ms": "2.1.2"
236 | }
237 | },
238 | "extsprintf": {
239 | "version": "1.4.1"
240 | },
241 | "ms": {
242 | "version": "2.1.2"
243 | },
244 | "node-cache": {
245 | "version": "5.1.2",
246 | "requires": {
247 | "clone": "2.x"
248 | }
249 | },
250 | "verror": {
251 | "version": "1.10.0",
252 | "requires": {
253 | "assert-plus": "^1.0.0",
254 | "core-util-is": "1.0.2",
255 | "extsprintf": "^1.2.0"
256 | }
257 | }
258 | }
259 | },
260 | "async": {
261 | "version": "3.2.3"
262 | },
263 | "braces": {
264 | "version": "3.0.2",
265 | "requires": {
266 | "fill-range": "^7.0.1"
267 | }
268 | },
269 | "dotenv": {
270 | "version": "10.0.0"
271 | },
272 | "fill-range": {
273 | "version": "7.0.1",
274 | "requires": {
275 | "to-regex-range": "^5.0.1"
276 | }
277 | },
278 | "handlebars": {
279 | "version": "4.7.7",
280 | "requires": {
281 | "minimist": "^1.2.5",
282 | "neo-async": "^2.6.0",
283 | "source-map": "^0.6.1",
284 | "uglify-js": "^3.1.4",
285 | "wordwrap": "^1.0.0"
286 | }
287 | },
288 | "hdb": {
289 | "version": "0.19.3",
290 | "requires": {
291 | "iconv-lite": "^0.4.18"
292 | }
293 | },
294 | "iconv-lite": {
295 | "version": "0.4.24",
296 | "requires": {
297 | "safer-buffer": ">= 2.1.2 < 3"
298 | }
299 | },
300 | "is-number": {
301 | "version": "7.0.0"
302 | },
303 | "micromatch": {
304 | "version": "4.0.4",
305 | "requires": {
306 | "braces": "^3.0.1",
307 | "picomatch": "^2.2.3"
308 | }
309 | },
310 | "minimist": {
311 | "version": "1.2.8"
312 | },
313 | "neo-async": {
314 | "version": "2.6.2"
315 | },
316 | "picomatch": {
317 | "version": "2.3.1"
318 | },
319 | "safer-buffer": {
320 | "version": "2.1.2"
321 | },
322 | "source-map": {
323 | "version": "0.6.1"
324 | },
325 | "to-regex-range": {
326 | "version": "5.0.1",
327 | "requires": {
328 | "is-number": "^7.0.0"
329 | }
330 | },
331 | "uglify-js": {
332 | "version": "3.17.4",
333 | "optional": true
334 | },
335 | "wordwrap": {
336 | "version": "1.0.0"
337 | }
338 | }
339 | }
340 | }
341 | }
342 |
--------------------------------------------------------------------------------