some corrections and optimizations
This commit is contained in:
@@ -8,6 +8,14 @@ extend service S4 with {
|
|||||||
entity Suppliers as projection on S4.A_BusinessPartner {
|
entity Suppliers as projection on S4.A_BusinessPartner {
|
||||||
key BusinessPartner as ID,
|
key BusinessPartner as ID,
|
||||||
BusinessPartnerFullName as name,
|
BusinessPartnerFullName as name,
|
||||||
|
// REVISIT: following is not supported so far in cds compiler...
|
||||||
|
// to_BusinessPartnerAddress as city {
|
||||||
|
// CityCode as code,
|
||||||
|
// CityName as name
|
||||||
|
// }
|
||||||
|
// REVISIT: following is not supported so far in cqn2odata...
|
||||||
|
// to_BusinessPartnerAddress.CityCode as city,
|
||||||
|
// to_BusinessPartnerAddress.CityName as city_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,49 +4,54 @@
|
|||||||
//
|
//
|
||||||
module.exports = async()=>{ // called by server.js
|
module.exports = async()=>{ // called by server.js
|
||||||
|
|
||||||
if (!cds.services.AdminService) return //> mocking SAP S4/HANA service only
|
if (!cds.services.AdminService) return //> mocking S4 service only
|
||||||
|
|
||||||
// Connect to services we want to mashup below...
|
// Connect to services we want to mashup below...
|
||||||
const S4bupa = await cds.connect.to('API_BUSINESS_PARTNER') //> external SAP S4/HANA service
|
const S4bupa = await cds.connect.to('API_BUSINESS_PARTNER') //> external S4 service
|
||||||
const admin = await cds.connect.to('AdminService') //> local domain service
|
const admin = await cds.connect.to('AdminService') //> local domain service
|
||||||
const db = await cds.connect.to('db') //> our primary database
|
const db = await cds.connect.to('db') //> our primary database
|
||||||
|
|
||||||
// Reflect CDS definition of the Suppliers entity
|
// Reflect CDS definition of the Suppliers entity
|
||||||
const { Suppliers } = S4bupa.entities
|
const { Suppliers } = S4bupa.entities
|
||||||
|
|
||||||
admin.prepend (()=>{
|
admin.prepend (()=>{ //> to ensure our .on handlers below go before the default ones
|
||||||
|
|
||||||
// Delegate Value Help reads for Suppliers to SAP S4/HANA backend
|
// Delegate Value Help reads for Suppliers to S4 backend
|
||||||
admin.on ('READ', 'Suppliers', async req => {
|
admin.on ('READ', 'Suppliers', req => {
|
||||||
console.log ('>> delegating to S4 service...')
|
console.log ('>> delegating to S4 service...')
|
||||||
return await S4bupa.run(req.query)
|
return S4bupa.run(req.query)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Replicate Supplier data when edited Books have suppliers
|
||||||
// Replicate Supplier data when Books are edited
|
admin.on (['CREATE','UPDATE'], 'Books', ({data:{supplier}}, next) => {
|
||||||
admin.on (['CREATE','UPDATE'], 'Books', async (req,next) => {
|
// Using Promise.all(...) to parallelize local write, i.e. next(), and replication
|
||||||
let { supplier } = req.data
|
if (supplier) return Promise.all ([ next(), async()=>{
|
||||||
if (supplier) {
|
let replicated = await db.exists (Suppliers, supplier)
|
||||||
let cached = await db.exists (Suppliers, supplier)
|
if (!replicated) await replicate (supplier, 'initial')
|
||||||
if (!cached) await replicate (supplier,'initial')
|
}])
|
||||||
}
|
else return next() //> don't forget to pass down the interceptor stack
|
||||||
return next()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Subscribe to changes in the SAP S4/HANA origin of Suppliers data
|
// Subscribe to changes in the S4 origin of Suppliers data
|
||||||
S4bupa.on ('BusinessPartner/Changed', async msg => {
|
S4bupa.on ('BusinessPartners/Changed', async msg => { //> would be great if we had batch events from S/4
|
||||||
let cached = await SELECT('ID').from (Suppliers)
|
let replicas = await SELECT('ID').from (Suppliers) .where ('ID in', msg.businessPartners)
|
||||||
.where ('ID in', msg.businessPartner.KEYS)
|
return replicate (replicas.map(each => each.ID))
|
||||||
for (let each of cached) replicate (each)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Helper function to replicate Suppliers data
|
/**
|
||||||
async function replicate (ID,_initial) {
|
* Helper function to replicate Suppliers data.
|
||||||
let data = await S4bupa.read (Suppliers, ID)
|
* @param {string|string[]} IDs a single ID or an array of IDs
|
||||||
if (_initial) return db.insert (data) .into (Suppliers)
|
* @param {truthy|falsy} _initial indicates whether an insert or an update is required
|
||||||
else return db.update (Suppliers,ID) .with (data)
|
*/
|
||||||
|
async function replicate (IDs,_initial) {
|
||||||
|
if (!Array.isArray(IDs)) IDs = [ IDs ]
|
||||||
|
let suppliers = await S4bupa.read (Suppliers).where('ID in',IDs)
|
||||||
|
if (_initial) return db.insert (suppliers) .into (Suppliers) //> using bulk insert
|
||||||
|
else return Promise.all(suppliers.map ( //> parallelizing updates
|
||||||
|
each => db.update (Suppliers,each.ID) .with (each)
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user