From 6a669b1235a595ed2efda61034f6e3c58c47ba0e Mon Sep 17 00:00:00 2001 From: Gayal Dassanayake Date: Wed, 1 Nov 2023 13:32:47 +0530 Subject: [PATCH 1/3] Send sap product create request --- .../Ballerina.toml | 8 + .../Dependencies.toml | 298 ++++++++++++++++++ database-product-to-sap-product/README.md | 0 database-product-to-sap-product/main.bal | 108 +++++++ database-product-to-sap-product/types.bal | 36 +++ 5 files changed, 450 insertions(+) create mode 100644 database-product-to-sap-product/Ballerina.toml create mode 100644 database-product-to-sap-product/Dependencies.toml create mode 100644 database-product-to-sap-product/README.md create mode 100644 database-product-to-sap-product/main.bal create mode 100644 database-product-to-sap-product/types.bal diff --git a/database-product-to-sap-product/Ballerina.toml b/database-product-to-sap-product/Ballerina.toml new file mode 100644 index 0000000..6ec6abb --- /dev/null +++ b/database-product-to-sap-product/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +org = "integration_samples" +name = "database_product_to_sap_product" +version = "0.1.0" +distribution = "2201.8.2" + +[build-options] +observabilityIncluded = true diff --git a/database-product-to-sap-product/Dependencies.toml b/database-product-to-sap-product/Dependencies.toml new file mode 100644 index 0000000..4985838 --- /dev/null +++ b/database-product-to-sap-product/Dependencies.toml @@ -0,0 +1,298 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.8.2" + +[[package]] +org = "ballerina" +name = "auth" +version = "2.10.0" +dependencies = [ + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "log"} +] + +[[package]] +org = "ballerina" +name = "cache" +version = "3.7.0" +dependencies = [ + {org = "ballerina", name = "constraint"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "task"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "constraint" +version = "1.5.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "crypto" +version = "2.5.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "file" +version = "1.9.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "os"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "http" +version = "2.10.3" +dependencies = [ + {org = "ballerina", name = "auth"}, + {org = "ballerina", name = "cache"}, + {org = "ballerina", name = "constraint"}, + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "file"}, + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "jwt"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.decimal"}, + {org = "ballerina", name = "lang.int"}, + {org = "ballerina", name = "lang.regexp"}, + {org = "ballerina", name = "lang.runtime"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "lang.value"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "mime"}, + {org = "ballerina", name = "oauth2"}, + {org = "ballerina", name = "observe"}, + {org = "ballerina", name = "time"}, + {org = "ballerina", name = "url"} +] +modules = [ + {org = "ballerina", packageName = "http", moduleName = "http"}, + {org = "ballerina", packageName = "http", moduleName = "http.httpscerr"} +] + +[[package]] +org = "ballerina" +name = "io" +version = "1.6.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.value"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" + +[[package]] +org = "ballerina" +name = "jwt" +version = "2.10.0" +dependencies = [ + {org = "ballerina", name = "cache"}, + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.int"}, + {org = "ballerina", name = "lang.string"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.decimal" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.int" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" + +[[package]] +org = "ballerina" +name = "lang.regexp" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.runtime" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.string" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.regexp"} +] + +[[package]] +org = "ballerina" +name = "lang.value" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "log" +version = "2.9.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.value"}, + {org = "ballerina", name = "observe"} +] +modules = [ + {org = "ballerina", packageName = "log", moduleName = "log"} +] + +[[package]] +org = "ballerina" +name = "mime" +version = "2.9.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.int"} +] + +[[package]] +org = "ballerina" +name = "oauth2" +version = "2.10.0" +dependencies = [ + {org = "ballerina", name = "cache"}, + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "time"}, + {org = "ballerina", name = "url"} +] + +[[package]] +org = "ballerina" +name = "observe" +version = "1.2.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "os" +version = "1.8.0" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "task" +version = "2.5.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "time"} +] + +[[package]] +org = "ballerina" +name = "time" +version = "2.4.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "url" +version = "2.4.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerinai" +name = "observe" +version = "0.0.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "observe"} +] +modules = [ + {org = "ballerinai", packageName = "observe", moduleName = "observe"} +] + +[[package]] +org = "gayaldassanayake" +name = "database_product_to_sap_product" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "http"}, + {org = "ballerina", name = "log"}, + {org = "ballerinai", name = "observe"} +] +modules = [ + {org = "gayaldassanayake", packageName = "database_product_to_sap_product", moduleName = "database_product_to_sap_product"} +] + diff --git a/database-product-to-sap-product/README.md b/database-product-to-sap-product/README.md new file mode 100644 index 0000000..e69de29 diff --git a/database-product-to-sap-product/main.bal b/database-product-to-sap-product/main.bal new file mode 100644 index 0000000..cc13dfc --- /dev/null +++ b/database-product-to-sap-product/main.bal @@ -0,0 +1,108 @@ +import ballerina/http; +import ballerina/log; + +const SAP_REQUEST_PATH = "/sap/API_PRODUCT_SRV/A_Product"; +const SAP_URL = "https://my401785.s4hana.cloud.sap/sap/opu/odata"; +const HEADER_KEY_CSRF_TOKEN = "x-csrf-token"; +const HEADER_FETCH_VALUE = "fetch"; + +final map & readonly productIdMap = {"001": "F-10B"}; +final map & readonly productTypeMap = {"Finished Product": "FERT"}; +final map & readonly productGroupMap = {"Finished Goods": "L004"}; +final map & readonly baseUnitMap = {"Piece": "PC"}; +final map & readonly industryMap = {"Computer Hardware": "M"}; + +final http:Client sapHttpClient = check getSAPHttpClient(); + +configurable SAPAuthConfig sapAuthConfig = ?; + +public function main() { + ProductFromDatabase[]|error dbProducts = getProductDataFromDatabase(); + if dbProducts is error { + log:printError(string `Error while retrieving products from the database: ${dbProducts.message()}`); + return; + } + log:printInfo(string `Successfully retrieved products from the database`); + SAPProduct[]|error sapProducts = transformProductData(dbProducts); + if sapProducts is error { + log:printError(string `Error while transforming products: ${sapProducts.message()}`); + return; + } + error? sapProductError = createSAPProducts(sapProducts); + if sapProductError is error { + log:printError(string `Error while creating products: ${sapProductError.message()}`); + } +} + +isolated function getSAPHttpClient() returns http:Client|error { + http:CredentialsConfig basicAuthHandler = {username: sapAuthConfig.username, password: sapAuthConfig.password}; + return new (url = SAP_URL, auth = basicAuthHandler, cookieConfig = {enabled: true}); +} + +isolated function getProductDataFromDatabase() returns ProductFromDatabase[]|error { + // TODO: retrieve data from the database + return [{ + id: "001", + description: "MacBookPro", + 'type: "Finished Product", + baseUnit: "Piece", + group: "Finished Goods", + grossWeight: 1.75, + netWeight: 1.5, + industry: "Computer Hardware", + weightUnit: "KG" + }]; +} + +isolated function transformProductData(ProductFromDatabase[] dbProducts) returns SAPProduct[]|error { + return from ProductFromDatabase dbProduct in dbProducts select { + Product: productIdMap.get(dbProduct.id), + ProductType: productTypeMap.get(dbProduct.'type), + ProductGroup: productGroupMap.get(dbProduct.group), + BaseUnit: baseUnitMap.get(dbProduct.baseUnit), + GrossWeight: dbProduct.grossWeight.toBalString(), + NetWeight: dbProduct.netWeight.toBalString(), + WeightUnit: dbProduct.weightUnit, + IndustrySector: industryMap.get(dbProduct.industry), + to_Description: {results: []} + }; +} + +isolated function createSAPProducts(SAPProduct[] sapProducts) returns error? { + string csrfToken = check getCsrfToken(); + map headerParams = {[HEADER_KEY_CSRF_TOKEN] : csrfToken, "Accept" : "application/json"}; + foreach SAPProduct sapProduct in sapProducts { + string productId = sapProduct.Product; + http:Response|http:ClientError response = sapHttpClient->post( + path = SAP_REQUEST_PATH, + message = sapProduct, + headers = headerParams + ); + if response is http:ClientError { + log:printInfo(string `Error while creating product ${productId}: ${response.message()}`); + continue; + } + if response.statusCode != http:STATUS_CREATED { + log:printInfo(string `Error: ${check response.getTextPayload()}`); + continue; + } + json responseBody = check response.getJsonPayload(); + string sapProductId = check responseBody.d.Product; + log:printInfo(string `Successfully created an SAP product with id: ${sapProductId}`); + } +} + +isolated function getCsrfToken() returns string|error { + http:Response|http:ClientError response = sapHttpClient->get( + path = SAP_REQUEST_PATH, + headers = {[HEADER_KEY_CSRF_TOKEN] : HEADER_FETCH_VALUE} + ); + if response is http:ClientError { + return response; + } + if response.statusCode == http:STATUS_OK { + return (check response.getHeaders(HEADER_KEY_CSRF_TOKEN))[0]; + + } + return error(string `Error: ${check response.getTextPayload()}`); +} diff --git a/database-product-to-sap-product/types.bal b/database-product-to-sap-product/types.bal new file mode 100644 index 0000000..d523e57 --- /dev/null +++ b/database-product-to-sap-product/types.bal @@ -0,0 +1,36 @@ +type SAPAuthConfig record {| + string username; + string password; +|}; + +type ProductFromDatabase record {| + string id; + string description; + string 'type; + string baseUnit; + string group; + float grossWeight; + float netWeight; + string industry; + string weightUnit; +|}; + +type SAPProduct record { + string Product; + string ProductType; + string ProductGroup; + string BaseUnit; + string GrossWeight; + string NetWeight; + string WeightUnit; + string IndustrySector; + record { + ProductDescription[] results; + } to_Description; +}; + +type ProductDescription record { + string Product; + string Language; + string ProductDescription; +}; From 5d20d78373f7e0e9514e11cd138fae84e4ad785d Mon Sep 17 00:00:00 2001 From: Gayal Dassanayake Date: Thu, 2 Nov 2023 10:30:11 +0530 Subject: [PATCH 2/3] Retrieve data from db using persist --- .../Ballerina.toml | 9 +++ .../Dependencies.toml | 78 ++++++++++++++++++- .../insert-data.sql | 5 ++ database-product-to-sap-product/main.bal | 59 +++++++------- .../persist/model.bal | 13 ++++ database-product-to-sap-product/types.bal | 12 --- 6 files changed, 129 insertions(+), 47 deletions(-) create mode 100644 database-product-to-sap-product/insert-data.sql create mode 100644 database-product-to-sap-product/persist/model.bal diff --git a/database-product-to-sap-product/Ballerina.toml b/database-product-to-sap-product/Ballerina.toml index 6ec6abb..1fa3360 100644 --- a/database-product-to-sap-product/Ballerina.toml +++ b/database-product-to-sap-product/Ballerina.toml @@ -6,3 +6,12 @@ distribution = "2201.8.2" [build-options] observabilityIncluded = true + +[persist] +datastore = "mysql" +module = "database_product_to_sap_product" + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "persist.sql-native" +version = "1.2.0" diff --git a/database-product-to-sap-product/Dependencies.toml b/database-product-to-sap-product/Dependencies.toml index 4985838..356367c 100644 --- a/database-product-to-sap-product/Dependencies.toml +++ b/database-product-to-sap-product/Dependencies.toml @@ -103,6 +103,9 @@ dependencies = [ org = "ballerina" name = "jballerina.java" version = "0.0.0" +modules = [ + {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} +] [[package]] org = "ballerina" @@ -246,6 +249,31 @@ dependencies = [ {org = "ballerina", name = "jballerina.java"} ] +[[package]] +org = "ballerina" +name = "persist" +version = "1.2.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "persist", moduleName = "persist"} +] + +[[package]] +org = "ballerina" +name = "sql" +version = "1.11.1" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerina", packageName = "sql", moduleName = "sql"} +] + [[package]] org = "ballerina" name = "task" @@ -284,15 +312,59 @@ modules = [ ] [[package]] -org = "gayaldassanayake" +org = "ballerinax" +name = "mysql" +version = "1.11.0" +dependencies = [ + {org = "ballerina", name = "crypto"}, + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "sql"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerinax", packageName = "mysql", moduleName = "mysql"} +] + +[[package]] +org = "ballerinax" +name = "mysql.driver" +version = "1.6.0" +modules = [ + {org = "ballerinax", packageName = "mysql.driver", moduleName = "mysql.driver"} +] + +[[package]] +org = "ballerinax" +name = "persist.sql" +version = "1.2.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "persist"}, + {org = "ballerina", name = "sql"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerinax", packageName = "persist.sql", moduleName = "persist.sql"} +] + +[[package]] +org = "integration_samples" name = "database_product_to_sap_product" version = "0.1.0" dependencies = [ {org = "ballerina", name = "http"}, + {org = "ballerina", name = "jballerina.java"}, {org = "ballerina", name = "log"}, - {org = "ballerinai", name = "observe"} + {org = "ballerina", name = "persist"}, + {org = "ballerina", name = "sql"}, + {org = "ballerinai", name = "observe"}, + {org = "ballerinax", name = "mysql"}, + {org = "ballerinax", name = "mysql.driver"}, + {org = "ballerinax", name = "persist.sql"} ] modules = [ - {org = "gayaldassanayake", packageName = "database_product_to_sap_product", moduleName = "database_product_to_sap_product"} + {org = "integration_samples", packageName = "database_product_to_sap_product", moduleName = "database_product_to_sap_product"} ] diff --git a/database-product-to-sap-product/insert-data.sql b/database-product-to-sap-product/insert-data.sql new file mode 100644 index 0000000..144fa3a --- /dev/null +++ b/database-product-to-sap-product/insert-data.sql @@ -0,0 +1,5 @@ +-- Insert data into ProductFromDatabase table +INSERT INTO Product(id, description, type, baseUnit, `group`, grossWeight, netWeight, industry, weightUnit) +VALUES + ('001', 'Piston', 'Finished Product', 'Piece', 'Finished Goods', 1.75, 1.5, 'Manufacturing', 'KG'), + ('002', 'Steel Pipe 1/2', 'Metal Tubing', 'Liter', 'Raw Material', 6.32, 6.32, 'Manufacturing', 'KG'); diff --git a/database-product-to-sap-product/main.bal b/database-product-to-sap-product/main.bal index cc13dfc..1632297 100644 --- a/database-product-to-sap-product/main.bal +++ b/database-product-to-sap-product/main.bal @@ -1,23 +1,24 @@ import ballerina/http; import ballerina/log; +import ballerina/persist; const SAP_REQUEST_PATH = "/sap/API_PRODUCT_SRV/A_Product"; const SAP_URL = "https://my401785.s4hana.cloud.sap/sap/opu/odata"; const HEADER_KEY_CSRF_TOKEN = "x-csrf-token"; const HEADER_FETCH_VALUE = "fetch"; -final map & readonly productIdMap = {"001": "F-10B"}; -final map & readonly productTypeMap = {"Finished Product": "FERT"}; -final map & readonly productGroupMap = {"Finished Goods": "L004"}; -final map & readonly baseUnitMap = {"Piece": "PC"}; -final map & readonly industryMap = {"Computer Hardware": "M"}; +final map & readonly productIdMap = {"001": "F-10B", "002": "PIP01"}; +final map & readonly productTypeMap = {"Finished Product": "FERT", "Metal Tubing": "PIPE"}; +final map & readonly productGroupMap = {"Finished Goods": "L004", "Raw Material": "L002"}; +final map & readonly baseUnitMap = {"Piece": "PC", "Liter": "L"}; +final map & readonly industryMap = {"Manufacturing": "M"}; final http:Client sapHttpClient = check getSAPHttpClient(); configurable SAPAuthConfig sapAuthConfig = ?; public function main() { - ProductFromDatabase[]|error dbProducts = getProductDataFromDatabase(); + Product[]|error dbProducts = getProductDataFromDatabase(); if dbProducts is error { log:printError(string `Error while retrieving products from the database: ${dbProducts.message()}`); return; @@ -39,38 +40,32 @@ isolated function getSAPHttpClient() returns http:Client|error { return new (url = SAP_URL, auth = basicAuthHandler, cookieConfig = {enabled: true}); } -isolated function getProductDataFromDatabase() returns ProductFromDatabase[]|error { - // TODO: retrieve data from the database - return [{ - id: "001", - description: "MacBookPro", - 'type: "Finished Product", - baseUnit: "Piece", - group: "Finished Goods", - grossWeight: 1.75, - netWeight: 1.5, - industry: "Computer Hardware", - weightUnit: "KG" - }]; +isolated function getProductDataFromDatabase() returns Product[]|error { + Client sClient = check new (); + stream products = sClient->/products(); + return from var product in products + where product is Product + select product; } -isolated function transformProductData(ProductFromDatabase[] dbProducts) returns SAPProduct[]|error { - return from ProductFromDatabase dbProduct in dbProducts select { - Product: productIdMap.get(dbProduct.id), - ProductType: productTypeMap.get(dbProduct.'type), - ProductGroup: productGroupMap.get(dbProduct.group), - BaseUnit: baseUnitMap.get(dbProduct.baseUnit), - GrossWeight: dbProduct.grossWeight.toBalString(), - NetWeight: dbProduct.netWeight.toBalString(), - WeightUnit: dbProduct.weightUnit, - IndustrySector: industryMap.get(dbProduct.industry), - to_Description: {results: []} - }; +isolated function transformProductData(Product[] dbProducts) returns SAPProduct[]|error { + return from Product dbProduct in dbProducts + select { + Product: productIdMap.get(dbProduct.id), + ProductType: productTypeMap.get(dbProduct.'type), + ProductGroup: productGroupMap.get(dbProduct.group), + BaseUnit: baseUnitMap.get(dbProduct.baseUnit), + GrossWeight: dbProduct.grossWeight.toBalString(), + NetWeight: dbProduct.netWeight.toBalString(), + WeightUnit: dbProduct.weightUnit, + IndustrySector: industryMap.get(dbProduct.industry), + to_Description: {results: []} + }; } isolated function createSAPProducts(SAPProduct[] sapProducts) returns error? { string csrfToken = check getCsrfToken(); - map headerParams = {[HEADER_KEY_CSRF_TOKEN] : csrfToken, "Accept" : "application/json"}; + map headerParams = {[HEADER_KEY_CSRF_TOKEN] : csrfToken, "Accept": "application/json"}; foreach SAPProduct sapProduct in sapProducts { string productId = sapProduct.Product; http:Response|http:ClientError response = sapHttpClient->post( diff --git a/database-product-to-sap-product/persist/model.bal b/database-product-to-sap-product/persist/model.bal new file mode 100644 index 0000000..f0c36cd --- /dev/null +++ b/database-product-to-sap-product/persist/model.bal @@ -0,0 +1,13 @@ +import ballerina/persist as _; + +public type Product record {| + readonly string id; + string description; + string 'type; + string baseUnit; + string group; + float grossWeight; + float netWeight; + string industry; + string weightUnit; +|}; diff --git a/database-product-to-sap-product/types.bal b/database-product-to-sap-product/types.bal index d523e57..4a66eb5 100644 --- a/database-product-to-sap-product/types.bal +++ b/database-product-to-sap-product/types.bal @@ -3,18 +3,6 @@ type SAPAuthConfig record {| string password; |}; -type ProductFromDatabase record {| - string id; - string description; - string 'type; - string baseUnit; - string group; - float grossWeight; - float netWeight; - string industry; - string weightUnit; -|}; - type SAPProduct record { string Product; string ProductType; From 9fa629178f09a5ec0aa6c9286812ac28603dad9c Mon Sep 17 00:00:00 2001 From: Gayal Dassanayake Date: Thu, 2 Nov 2023 11:07:41 +0530 Subject: [PATCH 3/3] Introduce readme --- database-product-to-sap-product/README.md | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/database-product-to-sap-product/README.md b/database-product-to-sap-product/README.md index e69de29..eac65f1 100644 --- a/database-product-to-sap-product/README.md +++ b/database-product-to-sap-product/README.md @@ -0,0 +1,58 @@ +# Database Product to SAP Product + +This project integrates a database containing product data and [SAP S/4HANA](https://www.sap.com/products/erp/s4hana.html), an ERP system. It automates the process of creating new products in SAP based on the product data stored in the database. + +## Use Case + +In business operations, it's common to maintain product data in a database, and this data may need to be migrated to an ERP system like SAP. This integration streamlines the process by automatically creating new products in SAP based on the product information stored in the database. + +## Prerequisites + +Before setting up this integration, you'll need an SAP S/4HANA account with permissions to products. + +### Setting up persist client + +1. Within the project run, `bal persist generate`. + +### Setting up the MySQL Database + +1. Set up and create a MySQL database. + +2. Create a table called `Product` by executing `generated/script.sql` generated by persist. +``` +mysql> source +``` + +3. Insert a sample product into the `Product` table with `insert-data.sql`. +``` +mysql> source +``` + +### Setting up an SAP Account + +1. If you don't have an SAP account, create one and ensure you have the necessary permissions to create products. + +2. Obtain your SAP API credentials, including the username and password required for authenticating with the SAP client. + +3. Configure your project settings and credentials by creating a `Config.toml` file, following the template provided in the Configuration section. + +## Configuration + +Create a file called `Config.toml` at the root of the project with the following content: + +```toml +[.sapAuthConfig] +username = "" +password = "" + +[database_product_to_sap_product] +host = "" +port = +user = "" +password = "" +database = "" +``` + +## Testing +1. Run `bal run` to start the integration. +2. Check the SAP S/4HANA system for the newly created products.