Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

SAP Developer Challenge - APIs - Task 2 - Calculate Northbreeze product stock

qmacro
Developer Advocate
Developer Advocate

(Check out the SAP Developer Challenge - APIs blog post for everything you need to know about the challenge to which this task relates!)

In this task you'll move from the public Northwind service to a simple version powered by CAP, and explore data with an OData operation and some system query options.

Background

The OASIS curated Northwind service is great, but it's also sometimes useful to have one's own version. There's an extremely simplified version of the classic Northwind service, called Northbreeze (get it?) at https://developer-challenge.cfapps.eu10.hana.ondemand.com/odata/v4/northbreeze.

This Northbreeze service is powered by the SAP Cloud Application Programming Model (CAP) and offers four entity sets:

  • Products
  • Suppliers
  • Categories
  • Summary of sales by years

(Well there's technically a fifth, TotalProducts, but that's just a calculation projection on the count of products).

The reason for running our own version of Northwind is that we can modify and extend it as we see fit, plus being based on CAP, we can learn about and experiment with CAP's rich support for serving OData APIs.

In this task you'll start to become familiar with the data offered.

Specifically for this task, you'll need to become familiar with the Products data. To do that, have a look at the Northbreeze service's metadata document at https://developer-challenge.cfapps.eu10.hana.ondemand.com/odata/v4/northbreeze/$metadata.

Identify the EntityContainer element that describes the entity sets available, in the form of EntitySet elements, and find the element describing the entity set with the name Products, which should look like this:

<EntitySet Name="Products" EntityType="Northbreeze.Products">
 <NavigationPropertyBinding Path="Category" Target="Categories"/>
 <NavigationPropertyBinding Path="Supplier" Target="Suppliers"/>
</EntitySet>

You can see that this entity set is a collection of Northbreeze.Products entity types. The 'Northbreeze' part is essentially the namespace, generated based on the service name. Follow the trail to the Products entity type, which will be an element outside the EntityContainer element, but still within the Northbreeze-namespaced Schema element.

The Products entity type should look like this:

<EntityType Name="Products">
 <Key>
 <PropertyRef Name="ProductID"/>
 </Key>
 <Property Name="ProductID" Type="Edm.Int32" Nullable="false"/>
 <Property Name="ProductName" Type="Edm.String"/>
 <Property Name="QuantityPerUnit" Type="Edm.String"/>
 <Property Name="UnitPrice" Type="Edm.Decimal" Scale="variable"/>
 <NavigationProperty Name="Category" Type="Northbreeze.Categories" Partner="Products">
 <ReferentialConstraint Property="Category_CategoryID" ReferencedProperty="CategoryID"/>
 </NavigationProperty>
 <Property Name="Category_CategoryID" Type="Edm.Int32"/>
 <NavigationProperty Name="Supplier" Type="Northbreeze.Suppliers" Partner="Products">
 <ReferentialConstraint Property="Supplier_SupplierID" ReferencedProperty="SupplierID"/>
 </NavigationProperty>
 <Property Name="Supplier_SupplierID" Type="Edm.Int32"/>
 <Property Name="UnitsInStock" Type="Edm.Int32"/>
 <Property Name="UnitsOnOrder" Type="Edm.Int32"/>
 <Property Name="ReorderLevel" Type="Edm.Int32"/>
 <Property Name="Discontinued" Type="Edm.Boolean"/>
</EntityType>

Amongst other things, you can see that a product has an ID (ProductID), a name (ProductName), a count of the number of units currently in stock (UnitsInStock) and a boolean that is used to indicate whether or not a product is discontinued (Discontinued).

Request the first few products to see data for these and the other properties, via https://developer-challenge.cfapps.eu10.hana.ondemand.com/odata/v4/northbreeze/Products?$top=5. You should see something like this:

{
 "@odata.context": "$metadata#Products",
 "value": [
 {
 "ProductID": 1,
 "ProductName": "Chai",
 "QuantityPerUnit": "10 boxes x 20 bags",
 "UnitPrice": 18,
 "Category_CategoryID": 1,
 "Supplier_SupplierID": 1,
 "UnitsInStock": 39,
 "UnitsOnOrder": 0,
 "ReorderLevel": 10,
 "Discontinued": false
 },
 {
 "ProductID": 2,
 "ProductName": "Chang",
 "QuantityPerUnit": "24 - 12 oz bottles",
 "UnitPrice": 19,
 "Category_CategoryID": 1,
 "Supplier_SupplierID": 1,
 "UnitsInStock": 17,
 "UnitsOnOrder": 40,
 "ReorderLevel": 25,
 "Discontinued": false
 },
 {
 "ProductID": 3,
 "ProductName": "Aniseed Syrup",
 "QuantityPerUnit": "12 - 550 ml bottles",
 "UnitPrice": 10,
 "Category_CategoryID": 2,
 "Supplier_SupplierID": 1,
 "UnitsInStock": 13,
 "UnitsOnOrder": 70,
 "ReorderLevel": 25,
 "Discontinued": false
 },
 {
 "ProductID": 4,
 "ProductName": "Chef Anton's Cajun Seasoning",
 "QuantityPerUnit": "48 - 6 oz jars",
 "UnitPrice": 22,
 "Category_CategoryID": 2,
 "Supplier_SupplierID": 2,
 "UnitsInStock": 53,
 "UnitsOnOrder": 0,
 "ReorderLevel": 0,
 "Discontinued": false
 },
 {
 "ProductID": 5,
 "ProductName": "Chef Anton's Gumbo Mix",
 "QuantityPerUnit": "36 boxes",
 "UnitPrice": 21.35,
 "Category_CategoryID": 2,
 "Supplier_SupplierID": 2,
 "UnitsInStock": 0,
 "UnitsOnOrder": 0,
 "ReorderLevel": 0,
 "Discontinued": true
 }
 ]
}

Your task

Your task is to calculate the total stock quantity (i.e. the total units in stock) for all current products, i.e. products that are not been marked as discontinued. The result of this calculation should be a number.

Once you have calculated the number, which should be an integer, you should hash it and post the hash as a new reply to this discussion thread, as described in Task 0 - Learn to share your task results and in a similar way to how you've done this in the previous task.

Hints and tips

Like all tasks in this challenge, you are free to approach this one however you see fit. One way would be to request all the products (https://developer-challenge.cfapps.eu10.hana.ondemand.com/odata/v4/northbreeze/Products) and manually sum the values of the relevant UnitsInStock properties.

But where's the fun in that?

How about requesting the entire products entity set in your favorite language and obtaining result by parsing the response and using that language to make the calculation?

You could also use OData's $filter system query option to first reduce the entity set result to only those products that have the value false for the Discontinued property.

And what about the $count facility, which in OData V4 is now a system query option as well something you can append to a resource path?

This would also be a good opportunity to take your first steps exploring some great new OData V4 features supported by CAP, such as data aggregation.

For discussion

How did you approach this task? If you used a programming language, which one did you use, and how did you do it? If you used an $apply based data aggregation feature, what was it, and was was your experience using it?

209 REPLIES 209

dakoller
Discoverer
0 Kudos

d14a3592b9654bb5c17d74134edbca1a03a5ff5bd37df5c93281d75db5bf7155

sandeepmalhotra
Participant
0 Kudos

d4df14c729fa52eb5d10adcee8a552603a5ab6b9908e63d45c99840499329269

eshrinivasan
Developer Advocate
Developer Advocate
0 Kudos

6ea5cd9417ffc232026158c3af39eae1c5798e0f186dbf50a6ba3adf7bdf3985

rohantiwari
Participant
0 Kudos

a8cc7b6d8fab8084577a1bc6ed1e69382df55a60099fa21f1ce265cabffc88f8

I used $apply aggregate and grouped it by Property Discontinued instead of passing it in Filters 🙂 , I would also try same with Python

former_member156175
Discoverer
0 Kudos

ca3f16a22dd4d2d6ba5d67bac81d115570abb8bc750b44e5ceffae74099b97dc

kasch-code
Participant
0 Kudos

80169899f948149c3f83f4305e871671c292c672b0b26ed7757d51defdae49a8

pedropeixoto
Discoverer
0 Kudos

776bb303a1d01406d6ec56f09e0e75ee6af0ed72ffd056878b34249af054cf98

AAncos
Participant

d22ea25937b052642fe0a25aab970722e9d76fdf82d5cfbd485ae4ad95b1f35a

aslan1906
Participant
0 Kudos

1522146e9551068d7d04a645842bbb750a81722f1d7d8e2cb1af30bc2e7ec8c4

Chaitanyat
Participant
0 Kudos

dd3a68c9588a15a6a6cbec48b180e8d506a0babf273a613cd5e7e22ae3d8e793

Ruthiel
Product and Topic Expert
Product and Topic Expert
0 Kudos

bf311a75f90bcadcda12ed5d21732380b3cca015f3c92faf3b6b51b619567b7a

nilsb
Explorer
0 Kudos

ab6451e4d16da614013c65dacf30650419361d42187a8f20cf82d07c69feb1fa

erickgrilo
Explorer
0 Kudos

326727914e6a28cbb3ae5ce4660f9eedf39199d349f2b8a70defc53d62c121c0

0 Kudos

I have done with Java by creating a Requisition class to process the HttpURLConnection steps (to make GET requests to the APIs) and then using  org.json to deserialize the JSON response. I have also done with python (where I have lots more experience with json and API development with Flask/Django and by golly, Python is quite easier haha).

Planning to do it with ABAP too to refresh a bit of the concepts. been working with ABAP since 2018.

ilyass
Explorer
0 Kudos

2766f4029699182c0ca001d0e24bab317e06877bd4b0b2004fad0a1e07c661f1

encarrero
Participant
0 Kudos

5ae9f82439603f78fba6340b90b7655376e478c8837f5c19430a2fc7a151b015

imancour
Explorer
0 Kudos

75db455ec8b4ecae7053e35237176f36262403de6e1bcb988cc249747fecdedc

stephancalmindo
Explorer
0 Kudos
2d639c42d17a5dd354f94a0730a6cfbf898f59a1f1b75d37c116f3ffed55e8c2

Ashok459
Participant
0 Kudos

50cd8f85d00666a66f82a45c72874d26c5955c261e56bfddb9f6f8d07ad720b4

flo_conrad
Explorer
0 Kudos

974dd0729990e6d2fe09e227410e302190375ddd0807f1b4bffb09f0183c78db

kjyothiraditya
Participant
0 Kudos

10b998481a72fb527a2e24e143c2eaeced5d6391cbe0b9d273b1fef276a64865

yassine
Explorer
0 Kudos

b43ef3975b881bf76822a26670594205b7a693812fb88056054162bbd666565b

dvontress
Explorer
0 Kudos

d4a643f7483b80fc5c3f8c78661cffebab4d94cdfd37e0ce2da5b9521a0c1a40

spassaro
Participant

630c68955cb7ccf9ba47b876e9e23961760719435b8d9f151969accf5f97bccc

 

 

qmacro
Developer Advocate
Developer Advocate

 You might want to double check the hash reply posting instructions - your current hash reply is invalid 😉

The aggregation capabilities of Odata V4 definitely rocks! Nice to meet you @@odata.count!

ManojSutar
Explorer
0 Kudos

00c6d644bd1653b45c2dd5f90de2c4820536bd9b12674a9a6b50d3059e36bda4

Jitendra_Kansal
Product and Topic Expert
Product and Topic Expert
0 Kudos

22a06330ce6d87a2ddd4eab558ab5bcaac95fb4a4aa1b5455b7cb4f445503576

Regards, Jitendra

satya-dev
Participant
0 Kudos

created a cap app :-  19e43e7ad550c8e25074c6a7af551b6b6a9f8552187fecf8b52a05ca3cb0a65d

qmacro
Developer Advocate
Developer Advocate
0 Kudos

 Hey @satya-dev - you might want to double check the hash reply posting instructions - your current hash reply is invalid 😉

gphadnis2000
Participant
0 Kudos

Used OData V4 aggregate in python here is the hash id for Units in Stock sum .

61cbb0a24f451a912de2a65c74b2c7463f050e481fd4cf51e202edbd98ab4a60

qmacro
Developer Advocate
Developer Advocate
0 Kudos

Hey @gphadnis2000 - you might want to double check the hash reply posting instructions - your current hash reply is invalid 😉

0 Kudos

Sure let me check it

0 Kudos

correct hash value

61cbb0a24f451a912de2a65c74b2c7463f050e481fd4cf51e202edbd98ab4a60

qmacro
Developer Advocate
Developer Advocate
0 Kudos

I'd encourage you to re-read the instructions again 😉

sabarna17
Contributor
0 Kudos

3f426bdc0ce8ba96315075e42c1181140dbdc9f5b75fc8b6889fcd1d02b7fcde

Anyways, I tried a new thing with this. Introducing Node-Red to SAP Developers .....

It's one of the best Low-Code free platforms for API integrations, powered by NodeJS.
Also inform me if I missed anything..

Here is a quick demo:

garyzuo
Explorer
0 Kudos

3740e748561f72d6b50b9ed1705af7a0dbd3c9cff948749d9cb6bf6a48e77a29

jens_borau
Explorer
0 Kudos

d6f1e66dab66b89399e3668ffb3baa950682b1a36675de191e5f07550dbbd7be