Customising ImportQueue Processing  Topic is solved

Discussions relating to plugin development, and the Jiwa API.

Customising ImportQueue Processing

Postby pricerc » Mon Apr 15, 2019 10:11 pm

So, we have an external process generating XML in JIWA 6 format for quotes and sales orders.

I have transforms to convert them to JIWA 7 format.

So I'm looking at the sample queue processor, and thinking that I need to change from
Code: Select all
      importQueueManager.Read(JiwaImportQManager.ImportQueueItemCollection.ImportQueueItemsReadModes.ReadyForImport)
      importQueueManager.Process()                  


to
Code: Select all
            importQueueManager.Read(JiwaImportQManager.ImportQueueItemCollection.ImportQueueItemsReadModes.ReadyForImport)
            For Each item As ImportQueueItem In importQueueManager
                ' do something to item here to transform old to new XML.
                item.Process()
            Next


Any suggestions?

The XML is actually being inserted into TransformedXML; can I move it into OriginalXML and then transform it into TransformedXML?
/Ryan

ERP Consultant,
Advanced ERP Limited, NZ
https://aerp.co.nz
User avatar
pricerc
Senpai
Senpai
 
Posts: 504
Joined: Mon Aug 10, 2009 12:22 pm
Location: Auckland, NZ
Topics Solved: 20

Re: Customising ImportQueue Processing

Postby pricerc » Tue Apr 16, 2019 9:55 am

Suggestion.

either:
a) Add a public (readonly) property to ImportQueueItem, that after ImportQueueItem.Process(), holds the underlying business object. or
b) Add a alternative function to ImportQueueItem, that returns the object.

My scenario: I'm going to have quotes and orders in my queue, and for some, I would like to do a bit more than just load them into Jiwa. Since ImportQueueItem doesn't expose the details of an item that's been Process()ed, I'm going to have to load them manually. I'll still use ImportQueueItem to get the XML out of the database, but I'll be manually loading up the objects by checking the XML header, and then processing them accordingly.

On the other hand, if ImportQueueItem had say, a 'BusinessObject' property (presumably of type JiwaFinancials.Jiwa.JiwaApplication.BusinessLogic.Maintenance) that contained a JiwaSalesOrder object, then I could just use that object to perform further processing.

Presumably, in Process(), you're instantiating business objects in order to load the XML, so all I'm asking is that the object you instantiate be exposed outside of ImportQueueItem.

Looking at the existing object definition, conceptually, it could be a bit like:
Code: Select all
        Public Function ProcessQueueItem() As Maintenance
            Dim result As Maintenance
            ' <code from Process()>
            Return result
        End Function

        Sub Process()
            ' discard output
            ProcessQueueItem()
        End Sub


The method would have to fail if the item has already been processed (probably an InvalidOperationException).

Also, it would be helpful for troubleshooting to have some more specific feedback going into IM_ImportQueue. Perhaps a 'Class' field and 'RecID' field that are populated as part of the Process function.
/Ryan

ERP Consultant,
Advanced ERP Limited, NZ
https://aerp.co.nz
User avatar
pricerc
Senpai
Senpai
 
Posts: 504
Joined: Mon Aug 10, 2009 12:22 pm
Location: Auckland, NZ
Topics Solved: 20

Re: Customising ImportQueue Processing  Topic is solved

Postby Mike.Sheen » Tue Apr 16, 2019 10:52 am

I've added improvement DEV-7429 to hopefully address most of this.

You might still be able to do what you want with some dynamic event handling...

Before you call the item.Process() you can add a handler in for the Manager.BusinessLogicFactory.AfterBusinessLogicSetup event and at that point add a handler for the business logic objects DeserialiseEnd event - this should give you the ability to do your own processing between the deserialise and save.

pricerc wrote:Also, it would be helpful for troubleshooting to have some more specific feedback going into IM_ImportQueue. Perhaps a 'Class' field and 'RecID' field that are populated as part of the Process function.

Not sure what you mean by this. Is 'Class' the business logic class name that we resolved from the Type attribute of the document? And 'RecID' is the RecID of the imported item?
Mike Sheen
Chief Software Engineer
Jiwa Financials

If I do answer your question to your satisfaction, please mark it as the post solving the topic so others with the same issue can readily identify the solution
User avatar
Mike.Sheen
Overflow Error
Overflow Error
 
Posts: 2440
Joined: Tue Feb 12, 2008 11:12 am
Location: Perth, Republic of Western Australia
Topics Solved: 755

Re: Customising ImportQueue Processing

Postby pricerc » Tue Apr 16, 2019 11:31 am

Mike.Sheen wrote:Is 'Class' the business logic class name that we resolved from the Type attribute of the document? And 'RecID' is the RecID of the imported item?


Yes.
/Ryan

ERP Consultant,
Advanced ERP Limited, NZ
https://aerp.co.nz
User avatar
pricerc
Senpai
Senpai
 
Posts: 504
Joined: Mon Aug 10, 2009 12:22 pm
Location: Auckland, NZ
Topics Solved: 20

Re: Customising ImportQueue Processing

Postby pricerc » Tue Apr 16, 2019 11:46 am

Mike.Sheen wrote:You might still be able to do what you want with some dynamic event handling...

Before you call the item.Process() you can add a handler in for the Manager.BusinessLogicFactory.AfterBusinessLogicSetup event and at that point add a handler for the business logic objects DeserialiseEnd event - this should give you the ability to do your own processing between the deserialise and save.


I suspected there might be an event to handle.

Since I've already got code written to deserialise SalesOrder and SalesQuote, I think I'll stick with what I've done (for now at least), I think it will be easier to debug. I'll probably need logic after the Save() (stuff like emailing people and/or processing directly to invoice).

I haven't actually started testing yet (I'm back to generating test data), but I have this logic ready to test:
Code: Select all
       Private Shared Function ProcessQueueItem(item As ImportQueueItem) As ImportQueueItem
            Dim xDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument()
            xDoc.LoadXml(item.TransformedXML)
            Dim jiwaDocumentNode As System.Xml.XmlNode = xDoc.SelectSingleNode("JiwaDocument")

            If jiwaDocumentNode Is Nothing Then
                item.Status = ImportQueueItem.ImportQueueItemStatuses.Failed
                item.Save()
                Return item
            End If

            Dim documentType = jiwaDocumentNode.Attributes.ItemOf("Type")
            If documentType Is Nothing Then
                item.Status = ImportQueueItem.ImportQueueItemStatuses.Failed
                item.Save()
                Return item
            End If

            Select Case documentType.Value
                Case "JiwaFinancials.Jiwa.JiwaSales.SalesOrder.SalesOrder"
                    Try
                        Dim newSalesOrder = JiwaFactory.CreateBusinessLogic(Of JiwaSales.SalesOrder.SalesOrder)(Nothing)
                        newSalesOrder.Deserialise(item.TransformedXML)
                        ' TODO: add custom processing

                        newSalesOrder.Save()
                        item.Status = ImportQueueItem.ImportQueueItemStatuses.Succeeded
                        item.ImportSuccessMessage = String.Format("Order {0} successfully imported", newSalesOrder.InvoiceNo)
                    Catch ex As Exception
                        item.Status = ImportQueueItem.ImportQueueItemStatuses.Failed
                        item.ImportErrorMessage = ex.ToString()
                    End Try
                    item.Save()

                Case "JiwaFinancials.Jiwa.JiwaSales.SalesQuote.SalesQuote"

                    Try
                        Dim newQuote = JiwaFactory.CreateBusinessLogic(Of JiwaSales.SalesQuote.SalesQuote)(Nothing)
                        newQuote.Deserialise(item.TransformedXML)
                        ' TODO: add custom processing

                        newQuote.Save()
                        item.Status = ImportQueueItem.ImportQueueItemStatuses.Succeeded
                        item.ImportSuccessMessage = String.Format("Quote {0} successfully imported", newQuote.QuoteNo)
                    Catch ex As Exception
                        item.Status = ImportQueueItem.ImportQueueItemStatuses.Failed
                        item.ImportErrorMessage = ex.ToString()
                    End Try
                    item.Save()

                Case Else
                    ' default Jiwa behaviour
                    item.Process()
            End Select

            Return item
        End Function


Note: it's a function returning its input parameter because the 'Extract Method' refactoring in CodeRush now extracts a 'Fluent' function, rather than a 'Sub/void function'. Ideally, it should also be an extension method.
/Ryan

ERP Consultant,
Advanced ERP Limited, NZ
https://aerp.co.nz
User avatar
pricerc
Senpai
Senpai
 
Posts: 504
Joined: Mon Aug 10, 2009 12:22 pm
Location: Auckland, NZ
Topics Solved: 20


Return to Technical and or Programming

Who is online

Users browsing this forum: No registered users and 1 guest

cron