Article: AN0002447Updated: 14.11.2020
ObjectGears allows to keep track of record changes by means of an audit-trail, that can be switched on in the class set-up. After that buttons will appear in the record detail and enable to display previous versions of the record by means of list of records or by means of a detailed archive showing which value in which column was changed to which new value, by whom, when and how.
Display of the Detailed archive contains all the changes and looks in the following way.
In certain cases we will want to record in a clear and transparent way history of just some items. Those which are critical for assessment of the case development. We will show this in an example of Incident at which we care about changes in columns Status, Solver and Solution team. We can see a record of an Incident in the below screen with these fields highlighted.
We want to see changes in these critical fields in a clear way as the following screen suggests - tab Time marks in the Incident record.
We want add new records, that will be displayed in this tab, after any change in the above stated fields. We can achieve this in three easy steps.
- We will create class Time marks for storing changes in the critical fields.
- We will create Master-detail relation in the class Incident.
- We will create rule for adding records into class Time marks.
Class Time marks storing changes in the key fields
We will create a new class with following columns. We can notice:
- The class does not contain reference just to the class Incident, but also to other classes (Problem, Task, Catalogue request, User call). All these classes can share one class for recording time marks.
- Date - shows when the change occured.
- Description - localized text describing which type of change occured (Change of solver, Change of status, Change of solution team). Users with various language settings will see this text in their respective languages.
- Original value, New value - columns showing which value was changed to which value. Users can see this again in their language version.
- Original Id and New Id - columns showing Id values of referenced records before the change and after the change. These values do not have to be displayed to users but we will utilize them in calculations how long certain record was in a certain status or how long it was assigned to somebody.
- Type - type of change given by the column type in which the change occured. This value corresponds to the Description above but it is again intended for processing data stored in the class Time marks.
Master-detail relationship
We will create the master-detail relation in the usual way and select columns from the linked class Time marks which shall be displayed.
Rule adding records to the class Time marks
We will create a rule After saving existing record of type Script in the class Incident. This rule will create a new record in the class Time marks for each change in one of the fields Status, Solver and Solution group. Because this record will be linked to the record from the class Incident which was changed, we will see it also in the Master-detail relation in the given Incident.
var clTS = null;
var date = OG.DateTime.Now;
if (OGActualDataRow.IsChange('solver'))
{
clTS = OGDataParent.Model.ClassDefs['time_mark'];
var dr = OG.DataRow.CreateNew(clTS.Id);
dr['incident'] = OGActualDataRow.Id;
dr['date'] = date;
dr['type'] = 'solver';
dr['previous_value'] = GetPerson(OGOldDataRow['solver']);
dr['new_value'] = GetPerson(OGActualDataRow['solver']);
dr['previous_id'] = GetPersonId(OGOldDataRow['solver']);
dr['new_id'] = GetPersonId(OGActualDataRow['solver']);
dr['description'] = 'cs-CZ::Změna řešitele~de-DE::Löser-Änderung~en-US::Solver change';
OG.DataRow.SaveData(dr);
}
if (OGActualDataRow.IsChange('solution_team'))
{
if ( clTS == null)
{
clTS = OGDataParent.Model.ClassDefs['time_mark'];
}
var colSolutionTeam = OGDataParent.Columns['solution_team'];
var dr = OG.DataRow.CreateNew(clTS.Id);
dr['incident'] = OGActualDataRow.Id;
dr['date'] = date;
dr['type'] = 'solution_team';
dr['previous_value'] = OGOldDataRow.GetClassLinkAsString(colSolutionTeam.Id);
dr['new_value'] = GetShortDescription(OGActualDataRow.GetDR('solution_team'));
dr['previous_id'] = OGOldDataRow.GetClassLink(colSolutionTeam.Id);
dr['new_id'] = OGActualDataRow.GetClassLink(colSolutionTeam.Id);
dr['description'] = 'cs-CZ::Změna řešitelského týmu~de-DE::Änderung von Lösungteam~en-US::Change of solution team';
OG.DataRow.SaveData(dr);
}
if (OGActualDataRow.IsChange('status'))
{
if ( clTS == null)
{
clTS = OGDataParent.Model.ClassDefs['time_mark'];
}
var colStatus = OGDataParent.Columns['status'];
var dr = OG.DataRow.CreateNew(clTS.Id);
dr['incident'] = OGActualDataRow.Id;
dr['date'] = date;
dr['type'] = 'status';
dr['previous_value'] = OGOldDataRow.GetClassLinkAsString(colStatus.Id);
dr['new_value'] = GetShortDescription(OGActualDataRow.GetDR('status'));
dr['previous_id'] = OGOldDataRow.GetClassLink(colStatus.Id);
dr['new_id'] = OGActualDataRow.GetClassLink(colStatus.Id);
dr['description'] = 'cs-CZ::Změna stavu~de-DE::Änderung von Status~en-US::Change of status';
OG.DataRow.SaveData(dr);
}
function GetPerson(person)
{
return (person == null ? null : person.DisplayName);
}
function GetPersonId(person)
{
return (person == null ? null : person.Id);
}
function GetShortDescription(dr)
{
return (dr == null ? null : dr.ShortDescriptionOrFullId);
}
function GetId(dr)
{
return (dr == null ? null : dr.Id);
}