Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fulfilled Order Items Feed NetSuite to HotWax #25

Merged
9 changes: 9 additions & 0 deletions data/ServiceJobData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,13 @@
<parameters parameterName="systemMessageRemoteId" parameterValue=""/>
<parameters parameterName="partyId" parameterValue=""/>
</moqui.service.job.ServiceJob>

<!-- ServiceJob data for polling csv file from sftp location -->
<moqui.service.job.ServiceJob jobName="poll_fulfilledItemsNetsuiteToHotwax"
description="Poll Csv file from sftp location of fulfilled order items feed netsuite to hotwax"
serviceName="co.hotwax.ofbiz.SystemMessageServices.poll#SystemMessageFileSftp" cronExpression="0 0 * * * ?" paused="Y">
<parameters parameterName="systemMessageTypeId" parameterValue="FulfilledOrderItemsFeedNetsuiteToHotwax"/>
<parameters parameterName="systemMessageRemoteId" parameterValue="RemoteSftp"/>
</moqui.service.job.ServiceJob>

</entity-facade-xml>
22 changes: 22 additions & 0 deletions data/SystemMessageData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,26 @@

<moqui.basic.Enumeration description="Send Required filed missing fields sales orders" enumId="ReqFieldMisOrderItems" enumTypeId="NetsuiteMessageTypeEnum"/>
<moqui.basic.Enumeration description="Product Updates Feed" enumId="NetSuiteOrderItemsFeed" enumTypeId="ShopifyMessageTypeEnum" relatedEnumId="ReqFieldMisOrderItems" relatedEnumTypeId="NetsuiteMessageTypeEnum"/>
<moqui.service.message.SystemMessageType systemMessageTypeId="FulfilledOrderItemsFeedNetsuiteToHotwax"
description="Fetch Fulfilled Order Items feed Netsuite to Hotwax"
parentTypeId="LocalFeedFile"
receiveResponseEnumId="MsgRrMove"
sendPath="${contentRoot}/Netsuite/FulfilledOrderItems"
receivePath="/home/${sftpUsername}/netsuite/salesorder/import/fulfillment-nifi"
receiveMovePath="/home/${sftpUsername}/netsuite/salesorder/import/fulfillment-nifi/archive"
consumeServiceName="co.hotwax.netsuite.OrderServices.consume#FulfilledOrderItemFeed">
<parameters parameterName="sendSmrId" parameterValue="RemoteSftp" systemMessageRemoteId=""/>
</moqui.service.message.SystemMessageType>

<moqui.service.message.SystemMessageType systemMessageTypeId="SendFulfilledOrderItemsFeed"
description="Send Fulfilled Order Items feed Netsuite to Hotwax"
parentTypeId="LocalFeedFile"
receivePath="${contentRoot}/Netsuite/Fulfillment/fulfilledOrderItemFeed-${dateTime}.json"
sendPath="/home/${sftpUsername}/netsuite/salesorder/import/fulfillment/FulfilledOrderItemsFeed-${systemMessageId}-${dateTime}.json"
sendServiceName="co.hotwax.ofbiz.SystemMessageServices.send#SystemMessageFileSftp"/>

<!-- Enumeration to create relation between FulfilledOrderItemsFeedNetsuiteToHotwax and SendFulfilledOrderItemsFeed SystemMessageType(s) -->
<moqui.basic.Enumeration description="Send fulfilledOrderItem Feed" enumId="SendFulfilledOrderItemsFeed" enumTypeId="NetsuiteMessageTypeEnum"/>
<moqui.basic.Enumeration description="Product Updates Feed" enumId="FulfilledOrderItemsFeedNetsuiteToHotwax" enumTypeId="ShopifyMessageTypeEnum" relatedEnumId="SendFulfilledOrderItemsFeed" relatedEnumTypeId="NetsuiteMessageTypeEnum"/>

</entity-facade-xml>
26 changes: 26 additions & 0 deletions data/Upgrade_upcomming.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-facade-xml type="ext-upgrade">
<moqui.service.message.SystemMessageType systemMessageTypeId="FulfilledOrderItemsFeedNetsuiteToHotwax"
description="Fetch Fulfilled Order Items feed Netsuite to Hotwax"
parentTypeId="LocalFeedFile"
receiveResponseEnumId="MsgRrMove"
sendPath="${contentRoot}/Netsuite/FulfilledOrderItems"
receivePath="/home/${sftpUsername}/netsuite/salesorder/import/fulfillment-nifi"
receiveMovePath="/home/${sftpUsername}/netsuite/salesorder/import/fulfillment-nifi/archive"
consumeServiceName="co.hotwax.netsuite.OrderServices.consume#FulfilledOrderItemFeed">
<parameters parameterName="sendSmrId" parameterValue="RemoteSftp" systemMessageRemoteId=""/>
</moqui.service.message.SystemMessageType>

<moqui.service.message.SystemMessageType systemMessageTypeId="SendFulfilledOrderItemsFeed"
description="Send Fulfilled Order Items feed Netsuite to Hotwax"
parentTypeId="LocalFeedFile"
receivePath="${contentRoot}/Netsuite/Fulfillment/fulfilledOrderItemFeed-${dateTime}.json"
sendPath="/home/${sftpUsername}/netsuite/salesorder/import/fulfillment/FulfilledOrderItemsFeed-${systemMessageId}-${dateTime}.json"
sendServiceName="co.hotwax.ofbiz.SystemMessageServices.send#SystemMessageFileSftp"/>

<!-- Enumeration to create relation between FulfilledOrderItemsFeedNetsuiteToHotwax and SendFulfilledOrderItemsFeed SystemMessageType(s) -->
<moqui.basic.EnumerationType description="Netsuite System message Type" enumTypeId="NetsuiteMessageTypeEnum"/>
<moqui.basic.Enumeration description="Send fulfilledOrderItem Feed" enumId="SendFulfilledOrderItemsFeed" enumTypeId="NetsuiteMessageTypeEnum"/>
<moqui.basic.Enumeration description="Product Updates Feed" enumId="FulfilledOrderItemsFeedNetsuiteToHotwax" enumTypeId="ShopifyMessageTypeEnum" relatedEnumId="SendFulfilledOrderItemsFeed" relatedEnumTypeId="NetsuiteMessageTypeEnum"/>

</entity-facade-xml>
123 changes: 123 additions & 0 deletions service/co/hotwax/netsuite/OrderServices.xml
Original file line number Diff line number Diff line change
Expand Up @@ -554,4 +554,127 @@
<set field="orderMapDetail" from="processedOrderMap"/>
</actions>
</service>
<service verb="consume" noun="FulfilledOrderItemFeed" authenticate="anonymous-all">
<implements service="org.moqui.impl.SystemMessageServices.consume#SystemMessage"/>
<actions>
<!-- Fetch System Message -->
<entity-find-one entity-name="moqui.service.message.SystemMessage" value-field="systemMessage"/>

<if condition="!systemMessage.messageText">
<return type="warning" message="System message [${systemMessageId}] for Type ${systemMessage?.systemMessageTypeId} has no message text, not consuming."/>
</if>

<entity-find-one entity-name="moqui.service.message.SystemMessageTypeParameter" value-field="sendSmrParam">
<field-map field-name="systemMessageTypeId" from="systemMessage.systemMessageTypeId"/>
<field-map field-name="parameterName" value="sendSmrId"/>
</entity-find-one>
<if condition="sendSmrParam">
<set field="sendSmrId" from="sendSmrParam.parameterValue"/>
</if>

<if condition="sendSmrId">
<!-- Find SystemMessageType related to systemMessage.systemMessageType to produce corresponding system message -->
<entity-find-one entity-name="moqui.basic.Enumeration" value-field="enumValue">
<field-map field-name="enumId" from="systemMessage.systemMessageTypeId"/>
</entity-find-one>

<if condition="enumValue &amp;&amp; enumValue.relatedEnumId">
<entity-find-one entity-name="moqui.service.message.SystemMessageType" value-field="relatedSystemMessageType">
<field-map field-name="systemMessageTypeId" from="enumValue.relatedEnumId"/>
</entity-find-one>
<if condition="!relatedSystemMessageType"><log level="warn" message="Could not find SystemMessageType with ID ${enumValue.relatedEnumId}, not producing related system message."/></if>
<else>
<log level="warn" message="Related SystemMessageType to produce for ${systemMessage.systemMessageTypeId} not defined, not producing related system message."/>
</else>
</if>
<else>
<log level="warn" message="sendSmrId not defined for ${systemMessage.systemMessageTypeId} not defined, not producing related system message."/>
</else>
</if>

<!-- Prepare JSON File Path -->
<set field="jsonFilePathRef" from="ec.resource.expand(relatedSystemMessageType.receivePath, null,
[contentRoot: ec.user.getPreference('mantle.content.root') ?: 'dbresource://datamanager', date:ec.l10n.format(nowDate, 'yyyy-MM-dd'), dateTime:ec.l10n.format(nowDate, 'yyyy-MM-dd-HH-mm-ss-SSS'),
productStoreId:productStoreId], false)"/>
<set field="jsonFilePath" from="ec.resource.getLocationReference(jsonFilePathRef).getUri().getPath()"/>

<script><![CDATA[
import org.apache.commons.csv.*
import com.fasterxml.jackson.core.JsonFactory
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.ObjectMapper
import java.nio.charset.StandardCharsets

try {
// Prepare JSON file
File fulfilledOrderItemJsonFile = new File(jsonFilePath)
if (!fulfilledOrderItemJsonFile.parentFile.exists()) fulfilledOrderItemJsonFile.parentFile.mkdirs()

JsonFactory jsonFactory = new JsonFactory()

/* Use try-with-resources to automatically close PrintWriter & JsonGenerator */
try (PrintWriter pw = new PrintWriter(StandardCharsets.UTF_8, fulfilledOrderItemJsonFile);
JsonGenerator generator = jsonFactory.createGenerator(pw)) {

generator.writeStartArray()
/* Use try-with-resources to automatically close BufferedReader & CSVParser */
try (BufferedReader reader = new BufferedReader(new StringReader(ec.resource.getLocationReference(systemMessage.messageText).getText()));
CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(reader)) {

def orderMap = [:]

for (CSVRecord record : parser) {
def orderId = record.get("orderId")

shippedDate = ec.l10n.format(ec.l10n.parseDateTime(record.get("shippedDate"), "M/d/yyyy h:mm a"), "yyyy-MM-dd HH:mm:ss")

def orderItem = [
orderItemSeqId : record.get("orderItemSeqId"),
externalFacilityId: record.get("externalFacilityId"),
shippedDate : shippedDate ,
quantity : record.get("quantity"),
trackingNumber : record.get("trackingNumber") ?: "",
"validation-result": "success"
]

def carrierName = record.get("shiphawkCarrierName")?.trim()?.toLowerCase()?.replaceAll("\\s+", "_") ?: ""

if (!orderMap.containsKey(orderId)) {
orderMap[orderId] = [
orderId : orderId,
shipHawkShipmentId: record.get("shipHawkShipmentId") ?: "",
shiphawkCarrierName: carrierName,
items : []
]
}
orderMap[orderId].items << orderItem
}

// Write each order as a separate object in the JSON array
ObjectMapper mapper = new ObjectMapper()
for (orderEntry in orderMap) {
def orderJson = [orderMap: orderEntry.value]
mapper.writerWithDefaultPrettyPrinter().writeValue(generator, orderJson)
}
}
generator.writeEndArray()
}

} catch (IOException e) {
logger.error("Error preparing Fulfilled Order Item Feed JSON file", e)
ec.message.addError("Error preparing order feed file ${e}")
}
]]></script>

<if condition="relatedSystemMessageType">
<service-call name="org.moqui.impl.SystemMessageServices.queue#SystemMessage"
in-map="[systemMessageTypeId:relatedSystemMessageType.systemMessageTypeId, systemMessageRemoteId:sendSmrId,
messageText:jsonFilePathRef, remoteMessageId: jsonFilePathRef.substring(jsonFilePathRef.lastIndexOf('/')+1), sendNow:true]"
out-map="queueSystemMessageOut" ignore-error="true" transaction="force-new"/>
</if>

<return message="Created the fulfilledOrderItems Feed file at time ${ec.user.nowTimestamp} with type ${relatedSystemMessageType.systemMessageTypeId}
and remote ${sendSmrId} saved response in messages ${queueSystemMessageOut?.systemMessageId}"/>
</actions>
</service>
</services>