HTML Editor and Log File/Field changes

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
gstenstrom
Posts: 17
Joined: Thu Feb 16, 2017 8:35 am

HTML Editor and Log File/Field changes

Post by gstenstrom » Thu Mar 16, 2017 7:10 am

Hi, I'm new to Lansa and need help on several fronts. I have been through eLearning and looked around in the IDE and Forums and I'm not seeing some of the things we need for our new VLFOne project.
First, I need a HTML Editor like the one you have here in the forum. Is this part of VLFOne? Need it to send emails, show email history along using it for comments sections.

Second, we need to log file field changes into one file. I looked at triggers but not finding anything helpful.
This is an example of the information to be saved:
File / Field Changes
File Field Prev Value New Value Date Time User
OCS Opp Credit Initial Recv Chk 0 2016-11-02 11:06 AM CSTURTEV
OCS Opp Credit Prior Ship Recv Chk 0 2016-11-02 11:06 AM CSTURTEV
OCS Opp Credit D1 RECV CHK 0 2016-11-02 11:06 AM CSTURTEV
OCS Opp Credit D2 RECV CHK 0 2016-11-02 11:06 AM CSTURTEV
OCS Opp Header Opp Description New Center 11/01/2016 New Center test 11/01/2016 2016-11-01 04:33 PM CSTURTEV
OCS Opp Contract Contract Number 123456 2016-11-01 04:33 PM CSTURTEV
OCS Opp Contract Customer Number null 000502 043 2016-11-01 04:33 PM CSTURTEV
OCS Opp Contract Order Number 654988 2016-11-01 04:33 PM CSTURTEV
OCS Opp Contract PO Number 12 2016-11-01 04:33 PM CSTURTEV
OCS Opp Contract Contract Mgmt Owner null CSTURTEV 2016-11-01 04:33 PM CSTURTEV
OCS Opp Contract Freight Terms null 02 2016-11-01 04:33 PM CSTURTEV
OCS Opp Contract DistributorAgent null 3115 2016-11-01 04:33 PM CSTURTEV
OCS Opp Contract Hungary Check Box 1 2016-11-01 04:33 PM CSTURTEV
OCS Opp Sales Payment src desc null The man with the money 2016-11-01 04:32 PM CSTURTEV
File Name - OCP06B Field Name - ADD_Prod Line - 1 - Anvilane 2016-11-01 04:32 PM CSTURTEV

jyoung
Posts: 653
Joined: Thu Jan 21, 2016 6:43 am
Location: Oklahoma City, OK USA

Re: HTML Editor and Log File/Field changes

Post by jyoung » Thu Mar 16, 2017 7:38 am

Regarding the HTML Editor, I have not seen one built into LANSA, but you should be able to create one using a widget. A widget is just a interface between LANSA and some JavaScript which you can use to hook up a JavaScript based HTML editor. You would use the widget to handle the HTML editor, and it would provide a property to expose it to LANSA. Once you have the property you can access it via RDMLX and save it or do whatever you need to. Use Integrator to send emails.

Regarding the log files, one way I have done this was to have a near exact copy of the file (same fields + extra audit fields). Then after an insert or an update, its a simple additional insert into your log table.

It could look something like this

Code: Select all

group_by name(#MyFields) fields(#MyField1 #MyField2)
group_by name(#MyLogFields) fields(#MyLogKey #MyKey #MyField1 #MyField2 #UpdatedBy #UpdatedOn)

#UpdatedBy := "Username"
#UpdatedOn := #STD_DATEX.Now
#MyLogKey := *AUTONUMLOGKEY 

update fields(#MyFields) in_file(MyFile) with_key(#MyKey)
insert fields(#MyLogFields) to_file(MyLogFile)

User avatar
Stewart Marshall
Posts: 417
Joined: Thu Nov 05, 2015 5:25 pm

Re: HTML Editor and Log File/Field changes

Post by Stewart Marshall » Thu Mar 16, 2017 8:38 am

LANSA has no native built rich text capabilities. The reason for this is that it's a surprisingly complicated subject matter and there are many expert providers.

Have a look at QuillJS.com. This is a free open source editor and you should be able to interface to this via a simple Widget.

With regards to updating a log file, you can attach a Trigger to a table definition (http://docs.lansa.com/14/en/lansa013/co ... 4_0465.htm) that fires after an insert or an update.
Stewart Marshall

Independent IT Consultant
www.marshallfloyd.com.au

MarkD
Posts: 627
Joined: Wed Dec 02, 2015 9:56 am

Re: HTML Editor and Log File/Field changes

Post by MarkD » Thu Mar 16, 2017 2:42 pm

Following is an example of a trigger that reports on changes to last name, given name or salary in the shipped XEmployee table.
When hooked up to fire after updates it produces files into folder c:\temp that look like this:
Capture2.PNG
Capture2.PNG (9.78 KiB) Viewed 5257 times
Ina real application you'd use a data base table I guess.
The important code in the trigger is here:
Capture1.PNG
Capture1.PNG (32.57 KiB) Viewed 5257 times

Code: Select all

Function Options(*DIRECT *HEAVYUSAGE *MLOPTIMISE) Rcv_List(#TRIG_LIST) Trigger(*FILE XEMPLOYEE)

* The data base row data
Def_List Name(#TRIG_LIST) Type(*WORKING) Entrys(2)

* Original values
Define Field(#Previous_xEmployeeSurname) Reffld(#xEmployeeSurname)
Define Field(#Previous_xEmployeeGivenNames) Reffld(#xEmployeeGivenNames)
Define Field(#Previous_xEmployeeSalary) Reffld(#xEmployeeSalary)

* Temporary reportList
Define Field(#ReportText) Type(*NVARCHAR) Length(1024)
Define Field(#ReportLines) Reffld(#Std_int)
Def_List Name(#ReportList) Fields(#ReportText) Counter(#ReportLines) Type(*WORKING) Entrys(*MAX)
Define_Com Class(#vf_elretc) Name(#ReturnCode)
Define_Com Class(#PRIM_ALPH) Name(#ReportFileName)

* Default return code
#TRIG_RETC := OK

Case Of_Field(#TRIG_OPER)


* Fire on after update operations on this table
When Value_Is(= AFTUPD)

* Get the previous (before update) values and save them for comparison
Get_Entry Number(2) From_List(#TRIG_LIST)
#Previous_xEmployeeSurname := #xEmployeeSurname
#Previous_xEmployeeGivenNames := #xEmployeeGivenNames
#Previous_xEmployeeSalary := #xEmployeeSalary

* Now get the new updated employee values
Get_Entry Number(1) From_List(#TRIG_LIST)

* Now compare the original value and new values and report on any changes
#COM_OWNER.CompareStrings( #Previous_xEmployeeSurname #xEmployeeSurname "Surname" )
#COM_OWNER.CompareStrings( #Previous_xEmployeeGivenNames #xEmployeeGivenNames "Given Names" )
#COM_OWNER.CompareNumbers( #Previous_xEmployeeSalary #xEmployeeSalary "Salary" )



* If anything was reported then save to a temporary file in C:\temp
* In a real version this indformation woudl more likly go into a data base table
If (#ReportLines > 0)
#ReportFileName := "c:\temp\ReportChanges_" + *Datec + *Timec + ".txt"
Use Builtin(TRANSFORM_List) With_Args(#ReportList #ReportFileName TU) To_Get(#ReturnCode)
Clr_List Named(#ReportList)
If (#ReturnCode <> OK)
Abort Msgtxt("Error writing to file " + #ReportFileName)
Endif
Endif


Endcase

* Return control to the invoker
Return
* ----------------------------------------------------------------------------
Mthroutine Name(CompareStrings)
Define_Map For(*INPUT) Class(#Prim_dc.UnicodeString) Name(#OldValue)
Define_Map For(*input) Class(#Prim_dc.UnicodeString) Name(#NewValue)
Define_Map For(*input) Class(#Prim_dc.UnicodeString) Name(#Description)

If (#OldValue <> #NewValue)
Execute Subroutine(Report) With_Parms((#Description + " was changed from '" + #OldValue + "' to '" + #NewValue + "'"))
Endif

Endroutine

* ----------------------------------------------------------------------------
Mthroutine Name(CompareNumbers)
Define_Map For(*INPUT) Class(#vf_elnuml) Name(#OldValue)
Define_Map For(*input) Class(#vf_elnuml) Name(#NewValue)
Define_Map For(*input) Class(#Prim_alph) Name(#Description)

If (#OldValue <> #NewValue)
Execute Subroutine(Report) With_Parms((#Description + " was changed from " + #OldValue.AsString + " to " + #NewValue.AsString))
Endif

Endroutine

* ----------------------------------------------------------------------------
Subroutine Name(Report) Parms((#ReportText *RECEIVED))

#DATETIMEX := #DATETIMEX.Now
#ReportText := #DATETIMEX.AsDisplayString + ":" + *User + "- XEMPLOYEE - Employee " + #xEmployeeIdentification + " " + #ReportText
Add_Entry To_List(#ReportList)

Endroutine

MarkD
Posts: 627
Joined: Wed Dec 02, 2015 9:56 am

Re: HTML Editor and Log File/Field changes

Post by MarkD » Thu Mar 16, 2017 3:31 pm

Regarding HTML editing - we are in the process of incorporating Quill into the VLF-ONE shipped demo.
Hopefully that can be posted to the forum as a generic notes command handler in the next week or so.
You could then use it as is, or pull it apart to use in other VL-Web situations.
Here is an image of it being used showing a note attached to an employee that includes an image and a variety of text formats.
Capture5.PNG
Capture5.PNG (99.89 KiB) Viewed 5253 times

gstenstrom
Posts: 17
Joined: Thu Feb 16, 2017 8:35 am

Re: HTML Editor and Log File/Field changes

Post by gstenstrom » Sat Mar 18, 2017 7:50 am

Hi MarkD,

I went ahead and setup your example on the XEmployee Trigger. I created a Process and Function but being new to Lansa I don't know enough about them and how they are run or executed. I went ahead and tried to Executed the Process via the IDE which started the process. I then ran the XEmployee Web Demo and changed an employee. Nothing showed up in the process and the file c:\temp\ReportChanges.. didn't appear. What am I missing?

MarkD
Posts: 627
Joined: Wed Dec 02, 2015 9:56 am

Re: HTML Editor and Log File/Field changes

Post by MarkD » Sat Mar 18, 2017 11:05 am

Assuming that your trigger function is compiled the steps to hook it up to the xEmployee table/file go like this:

Locate and open the definition of the xEmployee table/file.
Switch to the Rules & Triggers tab.
Right mouse on any field/column and use the option to add a trigger:
Capture1.PNG
Capture1.PNG (54.39 KiB) Viewed 5216 times
In the trigger attachment panel that appears specify your function, and choose that it executes only after updates:
Capture2.PNG
Capture2.PNG (7.13 KiB) Viewed 5216 times
Save those changes to the xEmployee table/file definition, then locate xEmployee in the repositry browser and right click and choose the Compile option. Use the option to compile to OAM only:
Capture3.PNG
Capture3.PNG (39.7 KiB) Viewed 5216 times


Assuming that all completes okay, then execute anything that updates the xEmployee table.
There are some Vl-Web examples and the VLF-ONE examples Business Objects 101, 102 and 103 all do as well.
When you execute any of them and update the surname, given name or salary you should get a new file created in the c:\temp folder.

gstenstrom
Posts: 17
Joined: Thu Feb 16, 2017 8:35 am

Re: HTML Editor and Log File/Field changes

Post by gstenstrom » Tue Mar 21, 2017 12:33 am

Thanks, that worked. I didn't realize you could attach a file Trigger to any of the fields.

gstenstrom
Posts: 17
Joined: Thu Feb 16, 2017 8:35 am

Re: HTML Editor and Log File/Field changes

Post by gstenstrom » Thu Mar 23, 2017 1:48 am

I got my trigger function to work but I have a few questions. First I need to track the user that changed the data. We will be using VLF One against our iSeries server. I tried *USER, #USER and it gave me DCXPGMLIB. I tried the other *USER... and *WEBUSER and those are blank. Is there something we need to set when we sign into VLF-ONE which validates our iSeries Id in order for this to work?

Next, is there away to programmatically loop on the fields for the #TRIG_LST to dynamically Define the #Previous... fields, Save the #Previous values and run the #COM_OWNER.Compare... We have several files with quite a lot of fields so I'm looking a some short-cut in creating the functions.

Lastly, I'm using the .FieldAttributeAsString function to get some information on the field. I don't see an attribute or property for the Identifier. Is this available within my trigger function?

MarkD
Posts: 627
Joined: Wed Dec 02, 2015 9:56 am

Re: HTML Editor and Log File/Field changes

Post by MarkD » Thu Mar 23, 2017 8:24 am

Regarding the user profile, I guess there are several ways to do that.

One way, which I have not personally tried, might be to have a look at http://docs.lansa.com/14/en/lansa048/in ... 8_6710.htm
and http://vlforum.lansa.com.au/viewtopic.php?f=4&t=69 if you have not already.

Then create your own server side “System Manager” or “Common Services” reusable part, named, say, MyManager.
Any code that wants to use it just defines it like this:

Define_com #MyManager Name(#MyManager) Scope(*Application)

Noting that using Scope(*Application) is essential for this to work.

Plug it into all your server modules at start up and close as suggested in the previous links.
Define a property in it named LoggedOnUser.
Change your version of InitializeServiceRoutine to accept a parameter that gets mapped into property LoggedOnUser.

Then at the start of every server module pass the parameter with the logged on user’s name.

The user could come into the server routine as a parameter passed in from the client and sourced from #avFrameworkManager.avLoggedOnUser.

Alternatively, it could come from #Persistent_ApplicationString1 (say) if your logon program, your version of UF_OLOGON, decided to use that persistent string to persistently store the user name on the server.

Either way, after your version of InitializeServiceRoutine runs at the start of your server routine the property LoggedOnUser is set and available to all other programs.

In your trigger you would then declare #MyManager scope(*Application) and access #MyManager.LoggedOnUser. You could provide other details, like the name of the active server module to the trigger this way as well.

MarkD
Posts: 627
Joined: Wed Dec 02, 2015 9:56 am

Re: HTML Editor and Log File/Field changes

Post by MarkD » Thu Mar 23, 2017 8:25 am

RE: is there away to programmatically loop on the fields for the #TRIG_LST? Not that I know of.

MarkD
Posts: 627
Joined: Wed Dec 02, 2015 9:56 am

Re: HTML Editor and Log File/Field changes

Post by MarkD » Thu Mar 23, 2017 8:28 am

Re: FieldAttributeAsString - sorry I don;t know anything about using that.

User avatar
Stewart Marshall
Posts: 417
Joined: Thu Nov 05, 2015 5:25 pm

Re: HTML Editor and Log File/Field changes

Post by Stewart Marshall » Thu Mar 23, 2017 9:12 am

gstenstrom wrote: Next, is there away to programmatically loop on the fields for the #TRIG_LST to dynamically Define the #Previous... fields, Save the #Previous values and run the #COM_OWNER.Compare... We have several files with quite a lot of fields so I'm looking a some short-cut in creating the functions.
There's no way to loop through fields, but you can save yourself a fair bit of code by creating 2 very big variables and comparing those.

Code: Select all

Get_entry 1 #Trig_list
#Previous := #Field1 + #Field2 + #Number.Asstring....etc
Get_entry 2 #Trig_list
#Current := #Field1 + #Field2 + #Number.Asstring....etc

if (#Previous <> #Current)
*etc
Endif
Stewart Marshall

Independent IT Consultant
www.marshallfloyd.com.au

User avatar
Stewart Marshall
Posts: 417
Joined: Thu Nov 05, 2015 5:25 pm

Re: HTML Editor and Log File/Field changes

Post by Stewart Marshall » Thu Mar 23, 2017 9:18 am

gstenstrom wrote:I'm using the .FieldAttributeAsString function to get some information on the field. I don't see an attribute or property for the Identifier. Is this available within my trigger function?
FieldAttributeAsString is limited to returning field definition data such as the Description or the column headings.

I'm curious as to why you would want programmatic access to the identifier of a field though.

Regards
Stewart Marshall

Independent IT Consultant
www.marshallfloyd.com.au

KevinW
Posts: 28
Joined: Thu May 26, 2016 11:18 am

Re: HTML Editor and Log File/Field changes

Post by KevinW » Thu Mar 23, 2017 11:56 am

RE: is there away to programmatically loop on the fields for the #TRIG_LST?

Write an old school building block template.
Unfortunately only good for up to 99 fields :(
Following is untested:
@@GET_FILS TO(1) PROMPT('Enter file for the trigger')
@@CLR_LST NUMBER(01)
@@RTV_FLDS FROM_FILE(01) INTO_LST(01)
@@SET_IDX IDX_NAME(FL) TO(1)
AGN: @@LABEL
DEFINE FIELD(#PRV@@LEL01FL) LIKE(#@@LEL01FL)
@@INC_IDX IDX_NAME(FL)
@@CMP_IDX IDX_NAME(FL) IDX_VALUE(@@LNE01) IF_LT(AGN) IF_EQ(AGN)
@@CLR_LST NUMBER(01)

gstenstrom
Posts: 17
Joined: Thu Feb 16, 2017 8:35 am

Re: HTML Editor and Log File/Field changes

Post by gstenstrom » Fri Mar 24, 2017 12:38 am

Stewart Marshall wrote:
gstenstrom wrote:I'm using the .FieldAttributeAsString function to get some information on the field. I don't see an attribute or property for the Identifier. Is this available within my trigger function?
FieldAttributeAsString is limited to returning field definition data such as the Description or the column headings.

I'm curious as to why you would want programmatic access to the identifier of a field though.

Regards
We are storing all File/Field changes into one file for audits. I'm saving the Field Label for later display but would like to tie it the actual field id on our iSeries.
Currently we have to manually look it up rather than coding for it

Code: Select all

* Now get the new updated employee values
Get_Entry Number(1) From_List(#TRIG_LIST)

* Now compare the original value and new values and report on any changes
#COM_OWNER.CompareStrings( #Previous_OC12_Status #OC12_Status "#OC12_Status" #oc12_Status.FieldAttributeAsString( Label ) )
#COM_OWNER.CompareStrings( #Previous_OC12_UserType #OC12_UserType "OC12_OCUTYP12" #oc12_UserType.FieldAttributeAsString( Label ) )
#COM_OWNER.CompareStrings( #Previous_OC12_Manager #OC12_Manager "OC12_MANA" #OC12_Manager.FieldAttributeAsString( Label ) )
#COM_OWNER.CompareStrings( #Previous_OC12_LocnMaintenance #OC12_LocnMaintenance "OC12_LOCN" #OC12_LocnMaintenance.FieldAttributeAsString( Label ) )
#COM_OWNER.CompareStrings( #Previous_OC12_OppCreation #OC12_OppCreation "OC12_OPPC" #OC12_OppCreation.FieldAttributeAsString( Label ) )
#COM_OWNER.CompareStrings( #Previous_OC12_PriceModelMaint #OC12_PriceModelMaint "OC12_PRIC" #OC12_PriceModelMaint.FieldAttributeAsString( Label ) )
#COM_OWNER.CompareStrings( #Previous_OC12_OppCreditApproval #OC12_OppCreditApproval "OC12_OP_1" #OC12_OppCreditApproval.FieldAttributeAsString( Label ) )
#COM_OWNER.CompareStrings( #Previous_OC12_OppContractMgt #OC12_OppContractMgt "OC12_OP_2" #OC12_OppContractMgt.FieldAttributeAsString( Label ) )
#COM_OWNER.CompareStrings( #Previous_OC12_OppLogisticInfo #OC12_OppLogisticInfo "OC12_OPPL" #OC12_OppLogisticInfo.FieldAttributeAsString( Label ) )

Mthroutine Name(CompareStrings)
Define_Map For(*INPUT) Class(#Prim_dc.UnicodeString) Name(#OldValue)
Define_Map For(*input) Class(#Prim_dc.UnicodeString) Name(#NewValue)
Define_Map For(*input) Class(#Prim_alph) Name(#Field)
Define_Map For(*input) Class(#Prim_alph) Name(#Description)

If (#OldValue <> #NewValue)
#OC14_File := 'OCP12B'
#OC14_FileGroup := 'X'
#OC14_RecordKey := #OC12_Company + #OC12_User
#OC14_Field := #Field
#OC14_FieldDescription := #Description
#OC14_PreviousValue := #OldValue.GetValue
#OC14_NewValue := #NewValue.GetValue
#OC14_ChangedTimeStamp := #DATETIMEX.Now
#OC14_User := #USER
#OC14_AuditReason #OC14_RecordType := ''
#COM_OWNER.WriteAuditRecord
Endif

Endroutine

atostaine
Posts: 416
Joined: Wed Jan 20, 2016 7:38 am

Re: HTML Editor and Log File/Field changes

Post by atostaine » Wed Apr 05, 2017 6:52 am

We include that sort of "audit" trigger to nearly every file we create. The trigger checks a code file to determine if we should be logging the changes for each individual field.

Users absolutely love seeing "Becky changed the ship date from 04/04/2017 to 07/07/2017, on 04/04/2017 @ 11:59:00" Developers love seeing which job and object made the changes.
Art Tostaine

Post Reply