Skip to content

Commit

Permalink
Merge pull request #25 from Shinde-nutan/23-fulfilled-order-items-fee…
Browse files Browse the repository at this point in the history
…d-netsuite-to-hotwax

Fulfilled Order Items Feed NetSuite to HotWax
  • Loading branch information
dt2patel authored Feb 21, 2025
2 parents dd2cb66 + 4670cc5 commit eb10a2a
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 0 deletions.
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 @@ -563,4 +563,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>

0 comments on commit eb10a2a

Please sign in to comment.