After looking at those logs, JiwaApplication.Manager.Instance.SysDateTime is definitely out in your case, Perry.
Note: Your log is a little misleading, your message description for both SysDateTime and ServerDateTime is logged as SysDateTime. i.e.:
- Code: Select all
Logger.Write("JiwaApplication.Manager.Instance.SysDateTime : " & JiwaApplication.Manager.Instance.SysDateTime, "general")
Logger.Write("JiwaApplication.Manager.Instance.SysDateTime : " & JiwaApplication.Manager.Instance.Database.ServerDateTime, "general")
Should be:
- Code: Select all
Logger.Write("JiwaApplication.Manager.Instance.SysDateTime : " & JiwaApplication.Manager.Instance.SysDateTime, "general")
Logger.Write("JiwaApplication.Manager.Instance.ServerDateTime: " & JiwaApplication.Manager.Instance.Database.ServerDateTime, "general")
Having said that, I was still able to make sense of your logs because you did provide the logging code - so it all worked out well

When we log into Jiwa, we take the local system date time, the SQL server date time and store those values into variables _SysDateTime and _ServerDateTime - we also compute a difference in seconds between the local and sql date time and store that away into a variable localServerDifference.
Every second we increment the local and server datetime by one second using a System.Timers.Timer.
Every 60 seconds in an attempt to prevent drift with the serverdate, we query the sql server for the time again, store that into the _ServerDateTime variable and set _SysDateTime to be a dateadd of _ServerDateTime and the localServerDifference calculated at login - but we only add the time component, not the date component.
So, for your problem to occur, there are several possible causes:
1. The SQL Server date / time changes after the client has logged in.
Or
2. Our timer code is flawed. This is probably likely - I've looked at the timer code and whilst I can't see anything obvious it does look overly complicated for what it needs to do.
In the meantime you can in fact set the SysDateTime to be your desired value before creating your sales order. It will get overwritten again once the timer ticks over for the 60 second drift adjustment, but if you set it immediately before creating a sales order it should suffice.
The trick is how to set it. SysDateTime is a read-only property of JiwaApplication.Manager.Instance - but that property simply returns Database.SysDateTime which is writable - so you can set it by:
- Code: Select all
JiwaApplication.Manager.Instance.Database.SysDateTime = Now
EDIT: I think I have the cause - our timer is a System.Timers.Timer - and we shouldn't be using that timer if running as a service - System.Threading.Timer is what we should be using. We DID use to have that timer as System.Threading.Timer, but changed to System.Timers.Timer a while ago to try and solve another issue.
At least I think that's the cause -
others seem to be of the opinion System.Timers.Timer is unreliable when running as a service, despite the
guidance to use System.Timers.Timer.
I've logged this as bug
12410EDIT #2: After reading
BUG: The Elapsed event of the System.Timers.Timer class is not raised in a Windows service and
Introduction to Server-Based Timers I'm now even more convinced we should be using System.Threading.Timer.
EDIT #3: I'm a little puzzled by this in your code:
- Code: Select all
salesOrder.OnCreateEnd()
salesOrder.OnSaveStart()
salesOrder.Save()
Logger.Write("salesOrder.InitiatedDate (after) : " & salesOrder.InitiatedDate, "general") 'v1.3.1
salesOrder.OnSaveEnd()
You shouldn't be calling the OnCreateEnd, OnSaveStart or OnSaveEnd methods. They are methods invoked by the sales order methods CreatNew() and Save() - you have no need to invoke those - they simply raise the corresponding events and your code will result in multiple events fired which may lead to undesired results if your code or any other plugin is listening to those.
To illustrate, this is what happens when you call Save():
- Code: Select all
Public Sub Save()
OnSaveStart()
... some SQL queries and other stuff is performed
OnSaveEnding()
... a database commit is performed
OnSaveEnd()
OnSaveStart() simply does this:
- Code: Select all
Public Sub OnSaveStart()
RaiseEvent SaveStart()
End Sub