Creating a new StatusHistory object

StatusHistory history = new StatusHistory();
// Get time as "YYYY-MM-DD hh:mm::ss"
history.DateTime = currentTime();
// This is displayed as the "Comment" in the GUI.
// The GUI gets the content of this field from
// `caseData.EstimationComments.DecisionComments`
// when saving. But here you have a good chance
// of describing what your particular API call
// has done to store in the log.
history.DecisionComments = "Initial case injection from CreditFront";
// This is supposed to be how long the same
// person has worked on a case during a session.
// From an API point of view you are free
// to set any value you wish here.
history.WorkLogMinutes = workInMinutes();
// The status of the case, corresponds to
// `caseData.CalcInformation.Status`
// (Pågår, Beviljat, etc.)
// For a new case this will be `Status.InProgress`
history.Status = Status.InProgress;
// If this is a reconsideration case or not.
// Corresponds to `caseData.CalcInformation.IsReconsideration`
// If true this log entry will be marked "Omprövning" in the GUI.
history.IsReconsideration = caseData.CalcInformation.IsReconsideration;
// Displayed as the username for this log entry in the GUI.
// The GUI automatically gets this information from the authentication.
// A GUI UserName might look like "Jane Doe (jane.doe@somebank.se)"
// In the case of your API calls, you would want to use
// some other identifier here.
history.UserName = "CreditFront";
// Important: Do not send in `SaveState.NEW_SAVE` unless
// this StatusHistory object is entirely new and describes
// changes in the case data.
// `SaveState.NEW_SAVE` will store an "audit copy" in
// the database so that you can use the "Compare" checkbox
// feature in the GUI.
history.SaveState = SaveState.NEW_SAVE;
history.AuditTrailID = null;
// Add the new history object to the end of the StatusHistory array
// before calling SaveCalculation.
appendToArray(caseData.CalcInformation.StatusHistory, history);
InfoResponse response = service.SaveCalculation(caseData);
// Important: Always throw away your local copy of the case
// data and call `FetchCalculation` to get a new copy,
// before calling `SaveCalculation` again.
// If you can't do this for some reason, you MUST update
// the last StatusHistory element with the newly generated
// audit trail ID
StatusHistory lastHistory = caseData.CalcInformation.StatusHistory[caseData.CalcInformation.StatusHistory.length - 1];
if (lastHistory.SaveState == SaveState.NEW_SAVE) {​
// When SaveState.NEW_SAVE is sent in, the response from the call
// to `SaveCalculation` will contain an ID that refers to the
// audit copy.
InfoResponseWithExtraData responseWithExtra = (InfoResponseWithExtraData) response;
lastHistory.AuditTrailID = parseJson(responseWithExtra.ExtraData).getString("AuditTrailID");
// !! Make sure that the `SaveState` is not `SaveState.NEW_SAVE` !!
lastHistory.SaveState = SaveState.SAVED;
// Now the call to `SaveCalculation` will understand
// that the audit copy already exists in the database,
// and the "Compare" checkbox in the GUI should still work
response = service.SaveCalculation(caseData);
}​ else {​
// When calling SaveCalculation and the last StatusHistory object's
// `SaveState` is `SAVED`, the response will not contain extra data.
}​

Step-By-Step Process

To clarify how this might work in simple steps, I would imagine something like this.
When I refer to a "log entry" I mean an object in the StatusHistory array of the case data:

  1. Create the initial case data

  2. Add a log entry to the case. SaveState = SaveState.NEW_SAVE

  3. Call SaveCalculation

  4. Use the ExtraData (formatted as a JSON object) in the response to get AuditTrailID and set it on the recently added log entry

  5. Optional: Make subsequent calls to SaveCalculation

    1. Option 1: Reuse the initial log entry

      1. Set SaveState.OVERWRITE to the most recent log entry

      2. Make other changes to the case

      3. Call SaveCalculation

    2. Option 2: Create a new log entry

      1. Add a new log entry to the case. SaveState = SaveState.NEW_SAVE

      2. Make other changes to the case

      3. Call SaveCalculation

      4. Use the ExtraData in the response to to set AuditTrailID on the recently added log entry

    3. Option 3: Record no changes at all in the case

      1. Set SaveState.SAVED to the most recent log entry

      2. Call SaveCalculation

  6. As the case is handled in the GUI, the GUI will create more log entries:

    1. On a save, when one of the following differs from the most recent log entry:

      1. The username of the saving user

      2. The status of the case

      3. The IsReconderation field

      4. The current day

    2. On import of company data from UC, SIE or Excel file (This log entry does not represent a "Save" action)

    3. On some other decision such as a Reconsideration of a case (This log entry does not represent a "Save" action)

  7. Call FetchCalculation, and the case will contain the GUI's new log entries

  8. Now if you want to update the case again by API, you should add yet another log entry, so basically repeat from step 2.