<xsl:template name="transform">
<xsl:variable name="LastModifiedDate" select="utils2:handleSQLString(string(/vpf:Msg/vpf:Body/vpf:Payload[./@Role='S']/bfa:io/bfa:object/bfa:string[./@name='LastModifiedDate']))"></xsl:variable>
<xsl:variable name="QueryHitsMaximumValue" select="utils2:handleSQLString(string(/vpf:Msg/vpf:Body/vpf:Payload[./@Role='S']/bfa:io/bfa:object/bfa:string[./@name='QueryHitsMaximumValue']))"></xsl:variable>
<xsl:variable name="LastReturnedObjectId" select="utils2:handleSQLString(string(/vpf:Msg/vpf:Body/vpf:Payload[./@Role='S']/bfa:io/bfa:object/bfa:string[./@name='LastReturnedObjectId']))"></xsl:variable>
<xsl:choose>
<xsl:when test="count(/vpf:Msg/vpf:Body/vpf:Payload[./@Role='S']/bfa:io/bfa:object/bfa:string[./@name='CardCode']) > 0">
<hanasql>SELECT T0."CardCode", IFNULL(T0."U_LoyFac", 1) as "U_LoyFac" from "OCRD" T0 Where T0."CardCode" ='<xsl:value-of select="utils2:handleSQLString(string(/vpf:Msg/vpf:Body/vpf:Payload[./@Role='S']/bfa:io/bfa:object/bfa:string[./@name='CardCode']))"></xsl:value-of>'</hanasql>
<sql> SELECT T0.CardCode, ISNULL(T0.U_LoyFac, 1) as 'U_LoyFac' from OCRD T0 Where T0.CardCode = '<xsl:value-of select="utils2:handleSQLString(string(/vpf:Msg/vpf:Body/vpf:Payload[./@Role='S']/bfa:io/bfa:object/bfa:string[./@name='CardCode']))"></xsl:value-of>'</sql>
</xsl:when>
<xsl:otherwise>
<hanasql> Select * FROM (Select ROW_NUMBER() OVER (ORDER BY "CardCode") as Rownumber, "CardCode", IFNULL("U_LoyFac", 1) as "U_LoyFac" FROM OCRD where ("CreateDate" >= '<xsl:value-of select="$LastModifiedDate"></xsl:value-of>' or "UpdateDate" >= '<xsl:value-of select="$LastModifiedDate"></xsl:value-of>')) as QueryResult where QueryResult.Rownumber > <xsl:value-of select="$LastReturnedObjectId"></xsl:value-of> AND QueryResult.Rownumber <= <xsl:value-of select="$LastReturnedObjectId"></xsl:value-of> + <xsl:value-of select="$QueryHitsMaximumValue"></xsl:value-of></hanasql>
<sql> Select * FROM (Select ROW_NUMBER() OVER (ORDER BY "CardCode") as Rownumber, "CardCode", ISNULL("U_LoyFac", 1) as "U_LoyFac" FROM OCRD where ("CreateDate" >= '<xsl:value-of select="$LastModifiedDate"></xsl:value-of>' or "UpdateDate" >= '<xsl:value-of select="$LastModifiedDate"></xsl:value-of>')) as QueryResult where QueryResult.Rownumber > <xsl:value-of select="$LastReturnedObjectId"></xsl:value-of> AND QueryResult.Rownumber <= <xsl:value-of select="$LastReturnedObjectId"></xsl:value-of> + <xsl:value-of select="$QueryHitsMaximumValue"></xsl:value-of></sql>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="transform">
<xsl:attribute name="pltype">json</xsl:attribute>
<io xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:com.sap.b1i.bizprocessor:bizatoms" pltype="json" xsi:schemaLocation="urn:com.sap.b1i.bizprocessor:bizatoms json_pltype.xsd">
<array>
<!--optional multiple of the following elements-->
<xsl:for-each select="/vpf:Msg/vpf:Body/vpf:Payload[./@id='atom2']/jdbc:ResultSets/jdbc:ResultSet/jdbc:Row">
<object>
<string name="CardCode">
<xsl:value-of select="./jdbc:CardCode"></xsl:value-of>
</string>
<string name="U_LoyFac">
<xsl:value-of select="./jdbc:U_LoyFac"></xsl:value-of>
</string>
</object>
<xsl:if test="position() = last()">
<object>
<string name="LastReturnedObjectId">
<xsl:value-of select="./jdbc:Rownumber"></xsl:value-of>
</string>
</object>
</xsl:if>
</xsl:for-each>
</array>
</io>
</xsl:template>
{
"SYSID" : "0010000100",
"CardCode" : "C20000"
}
public class LoyaltyFactorDao {
// use the logger from cco
private static final Logger logger = Logger.getLogger(LoyaltyFactorDao.class);
// name our table
private static final String TABLE_NAME = "B1E_LOYALTYFACTOR";
// create query
private static final String QUERY_CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " ("
+ "CARDCODE varchar(20) not null PRIMARY KEY,"
+ "LOYALTYFACTOR decimal(18,4) not null)";
// query for adding
private static final String QUERY_INSERT_ROW = "INSERT INTO " + TABLE_NAME + " VALUES(?,?)";
// query for updating
private static final String QUERY_UPDATE_ROW = "UPDATE " + TABLE_NAME
+ " SET LOYALTYFACTOR = ?2 WHERE CARDCODE = ?1";
// query for find all
private static final String QUERY_FIND_ALL = "SELECT CARDCODE, LOYALTYFACTOR FROM " + TABLE_NAME;
// query for find one
private static final String QUERY_FIND_ONE = "SELECT CARDCODE, LOYALTYFACTOR FROM " + TABLE_NAME
+ " where CARDCODE = ?";
// query to drop one
private static final String QUERY_DROP_ONE = "DELETE FROM " + TABLE_NAME + " WHERE CARDCODE = ?";
/**
* Create the table if not existing
*/
public void setupTable() {
// lets open a session
CDBSession session = CDBSessionFactory.instance.createSession();
try {
session.beginTransaction();
EntityManager em = session.getEM();
Query q = em.createNativeQuery(QUERY_CREATE_TABLE);
q.executeUpdate();
session.commitTransaction();
logger.info("Created table " + TABLE_NAME);
} catch (Exception e) {
session.rollbackDBSession();
logger.info("Error or table " + TABLE_NAME + " already existing");
} finally {
session.closeDBSession();
}
}
/**
* Create or update an entry in our table.
*
* @param loyaltyFactor
*/
private void save(LoyaltyFactorDto loyaltyFactor, boolean isAlreadyInDB) {
CDBSession session = CDBSessionFactory.instance.createSession();
String query = isAlreadyInDB ? QUERY_UPDATE_ROW : QUERY_INSERT_ROW;
try {
session.beginTransaction();
EntityManager em = session.getEM();
Query q = em.createNativeQuery(query);
q.setParameter(1, loyaltyFactor.getCardCode());
q.setParameter(2, loyaltyFactor.getLoyaltyFactor().doubleValue());
q.executeUpdate();
session.commitTransaction();
} catch (Exception e) {
session.rollbackDBSession();
logger.info("Could not create LoyaltyFactor");
logger.info(e.getLocalizedMessage());
} finally {
session.closeDBSession();
}
}
/**
* Get all Customer LoyaltyFactors
*
* @return
*/
public List<LoyaltyFactorDto> findAll() {
CDBSession session = CDBSessionFactory.instance.createSession();
ArrayList<LoyaltyFactorDto> resultList = new ArrayList<LoyaltyFactorDto>();
try {
session.beginTransaction();
EntityManager em = session.getEM();
Query q = em.createNativeQuery(QUERY_FIND_ALL);
@SuppressWarnings("unchecked")
List<Object[]> results = q.getResultList();
if (results.isEmpty()) {
// return an empty list rather than null
return resultList;
}
for (Object[] resultRow : results) {
resultList.add(new LoyaltyFactorDto((String) resultRow[0], (BigDecimal) resultRow[1]));
}
} catch (Exception e) {
logger.info("Error while getting results from table " + TABLE_NAME);
} finally {
session.closeDBSession();
}
return resultList;
}
/**
* Get one loyaltyfactor
*
* @param cardCode
* @return
*/
public LoyaltyFactorDto findOne(String cardCode) {
CDBSession session = CDBSessionFactory.instance.createSession();
LoyaltyFactorDto loyaltyFactor = new LoyaltyFactorDto();
try {
EntityManager em = session.getEM();
Query q = em.createNativeQuery(QUERY_FIND_ONE);
q.setParameter(1, cardCode);
@SuppressWarnings("unchecked")
List<Object[]> results = q.getResultList();
if (results.isEmpty()) {
// return empty dto
return loyaltyFactor;
}
loyaltyFactor.setCardCode((String) results.get(0)[0]);
loyaltyFactor.setLoyaltyFactor((BigDecimal) results.get(0)[1]);
} catch (Exception e) {
logger.info("Error while getting " + cardCode + " from table " + TABLE_NAME);
} finally {
session.closeDBSession();
}
return loyaltyFactor;
}
/**
* Drop one loyalty factor
*
* @param cardCode
*/
public void dropOne(String cardCode) {
CDBSession session = CDBSessionFactory.instance.createSession();
try {
session.beginTransaction();
EntityManager em = session.getEM();
Query q = em.createNativeQuery(QUERY_DROP_ONE);
q.setParameter(1, cardCode);
q.executeUpdate();
session.commitTransaction();
} catch (Exception ex) {
} finally {
session.closeDBSession();
}
}
/**
* Drop all loyaltyfactors
*/
public void dropAll() {
List<LoyaltyFactorDto> list = this.findAll();
for (LoyaltyFactorDto entry : list) {
this.dropOne(entry.getCardCode());
}
}
/**
* Save a loyaltyFactor
*
* @param loyaltyFactor
* @return
*/
public void save(LoyaltyFactorDto loyaltyFactor) {
LoyaltyFactorDto loyaltyInDB = this.findOne(loyaltyFactor.getCardCode());
boolean isAlreadyInDb = loyaltyFactor.getCardCode().equals(loyaltyInDB.getCardCode());
// check if entity is already in database, so that we update rather than insert.
this.save(loyaltyFactor, isAlreadyInDb);
}
}
public class LoyaltyFactorDto {
private String cardCode;
private BigDecimal loyaltyFactor;
public LoyaltyFactorDto() {}
public LoyaltyFactorDto(String inCardCode, BigDecimal inLoyaltyFactor) {
this.cardCode = inCardCode;
this.loyaltyFactor = inLoyaltyFactor;
}
public String getCardCode() {
return cardCode;
}
public void setCardCode(String cardCode) {
this.cardCode = cardCode;
}
public BigDecimal getLoyaltyFactor() {
return loyaltyFactor;
}
public void setLoyaltyFactor(BigDecimal loyaltyFactor) {
this.loyaltyFactor = loyaltyFactor;
}
@Override
public String toString() {
return "LoyaltyFactorDTO [cardCode=" + cardCode + ", loyaltyFactor=" + loyaltyFactor + "]";
}
}
public class App extends BasePlugin {
private static final Logger logger = Logger.getLogger(App.class);
private LoyaltyFactorDao loyaltyFactorDao;
@Override
public String getId() {
return "pluginpartthree";
}
@Override
public String getName() {
return "CCO Plugin Part 3";
}
@Override
public String getVersion() {
return getClass().getPackage().getImplementationVersion();
}
@Override
public void startup() {
loyaltyFactorDao = new LoyaltyFactorDao();
loyaltyFactorDao.setupTable();
super.startup();
}
}
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>10.0.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>10.0.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>10.0.1</version>
</dependency>
public interface LoyaltyFactorRestInterface {
@RequestLine("POST /B1iXcellerator/exec/ipo/vP.001sap0013.in_HCSX/com.sap.b1i.vplatform.runtime/INB_HT_CALL_SYNC_XPT/INB_HT_CALL_SYNC_XPT.ipo/proc?action=getLoyaltyFactor&bpm.pltype=json")
List<LoyaltyFactorResponseDto> requestLoyaltyData(LoyaltyFactorRequestDto request);
}
@Override
public void startup() {
// setting up the local user-defined-table
loyaltyFactorDao = new LoyaltyFactorDao();
loyaltyFactorDao.setupTable();
// getting the host and port of our b1i server
String b1iHost = ConfigurationHelper.INSTANCE.getB1ServiceDestination().getHost();
int b1iPort = ConfigurationHelper.INSTANCE.getB1ServiceDestination().getPort();
// getting the http basic auth credentials
String httpBasicAuthUser = ConfigurationHelper.INSTANCE.getB1ServiceDestination().getUserName();
String httpBasicAuthPassword = new String(ConfigurationHelper.INSTANCE.getB1ServiceDestination().getPassword());
// use the string builder to create host + port
StringBuilder sb = new StringBuilder();
sb.append(b1iHost);
sb.append(":");
sb.append(b1iPort);
// get the sysid
this.sysId = ConfigurationHelper.INSTANCE.getB1IntegrationSettings().getSystemId();
// setting up our REST Interface
restInterface = Feign.builder()
.client(new ApacheHttpClient())
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.requestInterceptor(new BasicAuthRequestInterceptor(httpBasicAuthUser, httpBasicAuthPassword))
.target(LoyaltyFactorRestInterface.class, sb.toString());
super.startup();
}
@JsonInclude(Include.NON_NULL)
public class LoyaltyFactorRequestDto {
@JsonProperty("SYSID")
private String sysId;
@JsonProperty("LastModifiedDate")
private String lastModifiedDate;
@JsonProperty("QueryHitsMaximumValue")
private String queryHitsMaximumValue;
@JsonProperty("LastReturnedObjectId")
private String lastReturnedObjectId;
@JsonProperty("CardCode")
private String cardCode;
public String getSysId() {
return sysId;
}
public void setSysId(String sYSID) {
this.sysId = sYSID;
}
public String getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(String lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
public String getQueryHitsMaximumValue() {
return queryHitsMaximumValue;
}
public void setQueryHitsMaximumValue(String queryHitsMaximumValue) {
this.queryHitsMaximumValue = queryHitsMaximumValue;
}
public String getLastReturnedObjectId() {
return lastReturnedObjectId;
}
public void setLastReturnedObjectId(String lastReturnedObjectId) {
this.lastReturnedObjectId = lastReturnedObjectId;
}
public String getCardCode() {
return cardCode;
}
public void setCardCode(String cardCode) {
this.cardCode = cardCode;
}
}
@JsonInclude(Include.NON_NULL)
public class LoyaltyFactorResponseDto {
@JsonProperty("CardCode")
private String cardCode;
@JsonProperty("U_LoyFac")
private String uLoyFac;
@JsonProperty("LastReturnedObjectId")
private String lastReturnedObjectId;
public String getCardCode() {
return cardCode;
}
public void setCardCode(String cardCode) {
this.cardCode = cardCode;
}
public String getULoyFac() {
return uLoyFac;
}
public void setULoyFac(String uLoyFac) {
this.uLoyFac = uLoyFac;
}
public String getLastReturnedObjectId() {
return lastReturnedObjectId;
}
public void setLastReturnedObjectId(String lastReturnedObjectId) {
this.lastReturnedObjectId = lastReturnedObjectId;
}
}
@Schedulable("LoyaltyFactor Sync")
public void syncLoyaltyFactor(PluginJob job, TriggerParameter triggerParam, I14YContext context, Object[] params){
// We get the SyncStatusmanager from the database
CDBSession session = CDBSessionFactory.instance.createSession();
SynchStatusManager syncStatusManager = new SynchStatusManager(session);
Date lastUpdate = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
// We use the customerquerymax results for this. Maybe a plugin configuration would also be suitable.
Integer batchSize = ConfigurationHelper.INSTANCE.getB1IntegrationSettings().getCustomerQueryMaxResults();
// Is it a fully snyc?
if(triggerParam.isCleanSync())
{
try {
lastUpdate = dateFormat.parse("1970-01-01");
} catch (ParseException e) {
logger.severe(e.getLocalizedMessage());
}
}
else
{
lastUpdate = syncStatusManager.readLastUpdateOfObject(PluginJob.createObjectId(triggerParam.getPluginId(), triggerParam.getPluginMethodId()));
}
// Create the sync thread.
try {
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new LoyaltyFactorSyncThread(this.restInterface, this.sysId, dateFormat.format(lastUpdate), batchSize));
} catch (Exception e) {
logger.info("Error while sync");
} finally {
session.closeDBSession();
}
}
public class LoyaltyFactorSyncThread implements Runnable {
private LoyaltyFactorRestInterface restClient;
private LoyaltyFactorDao loyaltyFactorDao;
private String sysId;
private String lastUpdate;
private Integer messageSize;
private String lastReturnedObjectId = "0";
public LoyaltyFactorSyncThread(LoyaltyFactorRestInterface restClient, String sysId, String lastUpdate, Integer messageSize) {
this.restClient = restClient;
this.sysId = sysId;
this.lastUpdate = lastUpdate;
this.messageSize = messageSize;
this.loyaltyFactorDao = new LoyaltyFactorDao();
}
public void run() {
boolean syncComplete = false;
do {
LoyaltyFactorRequestDto request = new LoyaltyFactorRequestDto();
request.setLastModifiedDate(this.lastUpdate);
request.setSysId(this.sysId);
request.setQueryHitsMaximumValue(this.messageSize.toString());
request.setLastReturnedObjectId(lastReturnedObjectId);
List<LoyaltyFactorResponseDto> response = this.restClient.requestLoyaltyData(request);
if(!response.isEmpty()) {
for(int i = 0; i < response.size(); i++) {
if(i == response.size() - 1) {
this.lastReturnedObjectId = response.get(i).getLastReturnedObjectId();
break;
}
this.loyaltyFactorDao.save(new LoyaltyFactorDto(response.get(i).getCardCode(), new BigDecimal(response.get(i).getULoyFac())));
}
} else {
syncComplete = true;
}
} while (!syncComplete);
}
}
@PluginAt(pluginClass = IReceiptManager.class, method ="setBusinessPartner", where = POSITION.AFTER)
public Object checkForLoyaltyFactor(Object proxy, Object[] args, Object ret, StackTraceElement caller) {
try {
BusinessPartnerEntity bp = (BusinessPartnerEntity) args[1];
LoyaltyFactorDto loyaltyFactorDto = this.loyaltyFactorDao.findOne(bp.getExternalId());
// If cardcode is empty, then it is not in the database...
if(StringUtils.isEmpty(loyaltyFactorDto.getCardCode())) {
LoyaltyFactorRequestDto request = new LoyaltyFactorRequestDto();
request.setSysId(this.sysId);
request.setCardCode(bp.getExternalId());
List<LoyaltyFactorResponseDto> response = restInterface.requestLoyaltyData(request);
if(!response.isEmpty()) {
this.loyaltyFactorDao.save(new LoyaltyFactorDto((String) response.get(0).getCardCode(), new BigDecimal(response.get(0).getULoyFac())));
}
}
} catch (Exception e) {
logger.info(e.getLocalizedMessage());
}
return ret;
}
public class LoyaltyPointCalculation implements PointCalculationLogic {
public BigDecimal calculatePointValue(ReceiptEntity receipt) {
BigDecimal overallAmount = BigDecimal.ZERO;
// get the overall amount for this receipt
for(SalesItemEntity item : receipt.getSalesItems()) {
overallAmount = overallAmount.add(item.getLoyaltyPoints());
}
// if a businesspartner is set, get the factor and multiply
if(receipt.getBusinessPartner() != null) {
LoyaltyFactorDao loyaltyFactorDao = new LoyaltyFactorDao();
// get the loyaltyFactor for this business partner
LoyaltyFactorDto loyaltyFactorDto = loyaltyFactorDao.findOne(receipt.getBusinessPartner().getExternalId());
overallAmount = overallAmount.multiply(loyaltyFactorDto.getLoyaltyFactor());
}
return overallAmount;
}
public BigDecimal calculatePointValue(SalesItemEntity salesItem) {
return SalesItemEntity.SalesItemTypeCode.MATERIAL.equals(salesItem.getTypeCode()) ? salesItem.getPaymentGrossAmount() : BigDecimal.ONE;
}
public void distributePointsToItems(ReceiptEntity arg0) {
}
public String getId() {
return "LoyaltyPointCalc";
}
}
CDBSession session = CDBSessionFactory.instance.createSession();
try {
LoyaltyPosService loyaltyPosService = new LoyaltyPosServiceImpl(session);
loyaltyPosService.registerPointCalculationLogic(new LoyaltyPointCalculation());
} catch (Exception e) {
logger.info(e.getMessage());
} finally {
session.closeDBSession();
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
2 | |
1 | |
1 | |
1 | |
1 | |
1 |