This action might not be possible to undo. Are you sure you want to continue?
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
GV’s Workflows Variable Naming Constants Business Services Business Components Applets Views Tables Links Repository Report
• The high degree of global variables in our application is troubling. It seems GV's are the 'first plan' to fulfill a requirement but we should be looking for alternatives. The GV's are not named property and are updated throughout the application: RTE's, bus comp script, bus serv script, WF's, etc. Every new GV should go through a governance process and be approved prior to being created. (our goal will be to identify and document all existing GV’s) • Logic should be as central as possible. If the logic has already begin with runtime events & workflows, the continue with such. If the logic is eScript, the continue with eScript. Centralized code is far easier to maintain that code spread across multiple objects & technologies.
• If multiple connecting arrows originate from, or lead into a given step, try to make the workflow more readable by having the connectors map to different sides of an object • Workflows start step and end step should carry unique distinct names. This makes it easier to debugging with WF Instance Monitor & FDR files. The start step and end step could carry the abbreviation of the WF name (ie Start-CE for Create Engagement). Same for tasks • Make use of the comments at all levels: WF, WF steps and WF Properties for self-documentation • All steps in workflow should have Error Exception Handling
• Consistent use of variable naming is important for readability and selfdocumentation • The first letter of each variable name should be a lower case letter: i:integer, n:number, s:string, o:Object, ps: PropSet • If the variable is modular, indicate in the name of the variable by preceding it with an m • The remainder of the variable name should be upper & lower case • The variable name should be descriptive and unique enough so that comments would not be required. • Following the point above, now add some comments. • GV’s & Profile Attr’s should start with letters: gv
• Make use of constants in the declaration section for readability and selfdocumentation. • The goal of self-documentation is to minimize maintenance and bugs. The best way to do this is to make the code clear, and understandable. • Consider the two example on the next slide. The code for both is exactly the same. Which is easier to read?
• Business services are powerful but should consider alternative approaches. Use business services only after the following has been exhausted: • Can an out of-the-box approach or OOB bus service work? • Can an existing Deloitte Business Service work? We have many generic business services (Deloitte accelerators) • Any new business services should not be created without approval from the governance team • Business service methods should be well documented with comments throughout the code. • Logic should not be contained within the preInvoke method. The logic should only be written in a function. Minimum code (only a select case and call to the functions should be in the preInvoke)
• Any script related comments will also apply here • Considerations: ‒ Any calculated fields which reference MVG’s will degrade performance. Ensure the proper testing / tuning is done to minimize performance degradation ‒ Force Active and Link Specification on fields should also be considered although the performance risks are much lower (consult docs for proper use of these properties) ‒ It is not best practice to ‘hard code’ view names, responsibilities etc within calc fields or user props so consider any and all alternatives ‒ Changes to an object should have comments inserted at the beginning of the property: Initials_Date_Defect or CR# [Breif Description] with the existing comments following… (ie most recent comment at top / front). If limit reached, delete the last comment. ‒ Cloning BC’s should be a (very) last approach and approval from the governance committee is required before continuing
Business Components - CONT
• Picklists should never be implemented on Id fields • Remember than any logic written for a given BC event will also be triggered through integration (this is important to remember if App.Raise error is used) (or consider async use as SADMIN (RCR etc)) • Try/Catch/Finally should always be used • Performance should be considered on field changes (ie PreSetField & SetField) so careful of too much validation here... • Consider the number of queries used to validate. Could some queries be consolidated? Must another query be added to fulfill the new requirement? • Minimize the use of triggering the event of another BC: For example, in this Current BC, avoid code such as: • This.Parent.WriteRecord(). [Any script like this must be approved by governance committee]
• Previous slides pertaining to comments, scripts etc will also apply here • Since preCanInvoke runs often, ensure logic (and queries!) is kept to a minimum • Careful when querying on current objects as it will affect record focus • Close attention to aesthetic detail and usability is key ‒ Form Applets:
• Placement and [Tab] ordering of fields
• • • •
Be careful about Applet Web Template Items Don’t use the expression Clean up template items Ensure that no two web template items do not share the same identifier
• Suggest that the top applet default to ‘slim’ showing only the minimum number of fields: hoping to remove the vertical scroll bar. User may choose to ‘show more’. (This is more for Bus Analysts…) • If the views shows parent and grandchild BC’s, then it should also show the child BC to maintain context. • Consistency across the application is important. For any questions, consider what has been implemented on other views. (This is more for Bus Analysts…)
• Any new column added which uses LOV, developer should run the MLOV utility to ensure they have not broken any rules • New columns in base tables is preferred to columns in extension tables • Consider indexes • Pay careful attention the following properties for LOV bounded: • Translation Table (S_LST_OF_VAL) • Bounded • Length = 30 • Translate • LOV Type • A foreign key column should always have a value for foreign key table
• Should never be based on calc fields • Pay attention to: • Cascade delete [ask governance committee]
• Always include destination field and source field.
Daily Dev Change Reporting
• Report can be run to show changes to repository. Copy / paste into SQL tool
------------------------------------------------------------------------------ Who has made what changes in repository ----------------------------------------------------------------------------DECLARE @Date1 AS varchar(80); SET @Date1 = DATEADD(day,DATEDIFF(day,-1,GETDATE()),-1115); -- one day higher: for example: if 4 then query will show it'll be 3 days ago DECLARE @Date2 AS varchar(80); SET @Date2 = DATEADD(day,DATEDIFF(day,1,GETDATE()),2) -- 2 represents tommrow
select distinct 'Report', r.NAME "Parent", '', '', '', r.LAST_UPD, u.LOGIN, r.COMMENTS from S_REPORT r, S_USER u where r.LAST_UPD_BY = u.ROW_ID and r.LAST_UPD >= @Date1 AND r.LAST_UPD < @Date2 union all
select distinct 'Int Obj', io.NAME "Parent", 'Int Comp', ic.NAME, f.NAME, ic.LAST_UPD, u.LOGIN, io.COMMENTS + '-' + ic.COMMENTS + '-' + f.COMMENTS from S_INT_OBJ io, S_USER u, S_INT_COMP ic, S_INT_FIELD f where f.INT_COMP_ID = ic.ROW_ID and ic.INT_OBJ_ID = io.ROW_ID and ic.LAST_UPD_BY = u.ROW_ID and ic.LAST_UPD >= @Date1 AND ic.LAST_UPD < @Date2 union all select 'Picklist', p.NAME "Parent", '', '' , p.SRCHSPEC, p.LAST_UPD, u.LOGIN, p.COMMENTS from S_PICKLIST p, S_USER u where p.LAST_UPD_BY = u.ROW_ID and p.LAST_UPD >= @Date1 AND p.LAST_UPD < @Date2 union all
select 'Screen', s.NAME "Parent", 'View', sv.NAME , sv.COMMENTS, sv.LAST_UPD, u.LOGIN, s.COMMENTS from S_SCREEN s, S_USER u, S_SCREEN_VIEW sv where sv.SCREEN_ID = s.ROW_ID and sv.LAST_UPD_BY = u.ROW_ID and sv.LAST_UPD >= @Date1 AND sv.LAST_UPD < @Date2 union all
select 'View', v.NAME "Parent", 'Applet', vi.APPLET_NAME, vi.COMMENTS, vi.LAST_UPD, u.LOGIN, v.COMMENTS from S_VIEW v, S_USER u, S_VIEW_WEB_TMPL vt, S_VIEW_WTMPL_IT vi where vi.VIEW_WEB_TMPL_ID = vt.ROW_ID and vt.VIEW_ID = v.ROW_ID and vi.LAST_UPD_BY = u.ROW_ID and vi.LAST_UPD >= @Date1 AND vi.LAST_UPD < @Date2
union all select 'Table', t.NAME "Parent", 'Column', c.NAME, c.DESC_TEXT, c.LAST_UPD, u.LOGIN, t.DESC_TEXT from S_TABLE t, S_USER u, S_COLUMN c where c.TBL_ID = t.ROW_ID and c.LAST_UPD_BY = u.ROW_ID and c.LAST_UPD >= @Date1 AND c.LAST_UPD < @Date2
union all select 'Task', t.NAME "Parent", '', '', '', t.LAST_UPD, u.LOGIN, t.COMMENTS from S_TU_TASK t, S_USER u where t.LAST_UPD_BY = u.ROW_ID and t.LAST_UPD_BY = u.ROW_ID and t.STATUS_CD = 'COMPLETED'and t.LAST_UPD_BY = u.ROW_ID and t.LAST_UPD >= @Date1 AND t.LAST_UPD < @Date2
select 'WF', w.PROC_NAME "Parent", '', '', '', w.LAST_UPD, u.LOGIN, w.COMMENTS from S_WFR_PROC w, S_USER u where w.LAST_UPD_BY = u.ROW_ID and w.STATUS_CD = 'COMPLETED'and w.LAST_UPD_BY = u.ROW_ID and w.LAST_UPD >= @Date1 AND w.LAST_UPD < @Date2 union all select 'Bus Serv', bs.NAME "Parent", 'User Prop', up.NAME, up.VALUE, up.LAST_UPD, u.LOGIN, up.COMMENTS from S_SERVICE bs, S_USER u, S_SERVICE_UPROP up where up.SERVICE_ID = bs.ROW_ID and up.LAST_UPD_BY = u.ROW_ID and up.LAST_UPD >= @Date1 AND up.LAST_UPD < @Date2
union all select 'Bus Serv', bs.NAME "Parent", 'Browser Script', s.NAME, s.SCRIPT, s.LAST_UPD, u.LOGIN, s.COMMENTS from S_SERVICE bs, S_USER u, S_SVC_BRS_SCRPT s where s.SERVICE_ID = bs.ROW_ID and bs.LAST_UPD_BY = u.ROW_ID and s.LAST_UPD >= @Date1 AND s.LAST_UPD < @Date2 union all select 'Bus Serv', bs.NAME "Parent", 'Server Script', ss.NAME, ss.SCRIPT, ss.LAST_UPD, u.LOGIN, ss.COMMENTS from S_SERVICE bs, S_USER u, S_SERVICE_SCRPT ss where ss.SERVICE_ID = bs.ROW_ID and bs.LAST_UPD_BY = u.ROW_ID and ss.LAST_UPD >= @Date1 AND ss.LAST_UPD < @Date2 union all select 'Applet', a.NAME "Parent", 'Browser Script', bs.NAME, bs.SCRIPT, a.LAST_UPD, u.LOGIN, bs.COMMENTS from S_APPLET a, S_USER u, S_APLT_BRSSCRPT bs where bs.APPLET_ID = a.ROW_ID and bs.LAST_UPD_BY = u.ROW_ID and bs.LAST_UPD >= @Date1 AND bs.LAST_UPD < @Date2 union all select 'Applet', a.NAME "Parent", 'Server Script', ss.NAME, ss.SCRIPT, a.LAST_UPD, u.LOGIN, ss.COMMENTS from S_APPLET a, S_USER u, S_APPL_WEBSCRPT ss where ss.APPLET_ID = a.ROW_ID and ss.LAST_UPD_BY = u.ROW_ID and ss.LAST_UPD >= @Date1 AND ss.LAST_UPD < @Date2 union all
select 'Applet', a.NAME "Parent", 'User Prop', up.NAME, up.VALUE, a.LAST_UPD, u.LOGIN, up.COMMENTS from S_APPLET a, S_USER u, S_APPLET_UPROP up where up.APPLET_ID = a.ROW_ID and up.LAST_UPD_BY = u.ROW_ID and up.LAST_UPD >= @Date1 AND up.LAST_UPD < @Date2 union all select 'Applet', a.NAME "Parent", '', '', '', a.LAST_UPD, u.LOGIN, a.COMMENTS from S_APPLET a, S_USER u where a.LAST_UPD_BY = u.ROW_ID and a.LAST_UPD >= @Date1 AND a.LAST_UPD < @Date2 union all select 'BC', bc.NAME "Parent", '', '', '', bc.LAST_UPD, u.LOGIN,bc.COMMENTS from S_BUSCOMP bc, S_USER u where bc.LAST_UPD_BY = u.ROW_ID and bc.LAST_UPD >= @Date1 AND bc.LAST_UPD < @Date2 union all select 'BC', bc.NAME "Parent", 'Field' "Child", f.NAME, bc.COMMENTS, f.LAST_UPD, u.LOGIN, f.COMMENTS from S_FIELD f, S_USER u, S_BUSCOMP bc where f.BUSCOMP_ID = bc.ROW_ID and f.LAST_UPD_BY = u.ROW_ID and f.LAST_UPD >= @Date1 AND f.LAST_UPD < @Date2 union all select 'BC', bc.NAME "Parent", 'User Prop', up.NAME, bc.COMMENTS, up.LAST_UPD, u.LOGIN, up.COMMENTS from S_BUSCOMP_UPROP up, S_USER u, S_BUSCOMP bc where up.BUSCOMP_ID = bc.ROW_ID and up.LAST_UPD_BY = u.ROW_ID and up.LAST_UPD >= @Date1 AND up.LAST_UPD < @Date2 union all select 'BC', bc.NAME "Parent", 'Server Script', bcs.NAME, bc.COMMENTS, bcs.LAST_UPD, u.LOGIN, bcs.COMMENTS from S_BUSCOMP_SCRIPT bcs, S_USER u, S_BUSCOMP bc where bcs.BUSCOMP_ID = bc.ROW_ID and bcs.LAST_UPD_BY = u.ROW_ID and bcs.LAST_UPD >= @Date1 AND bcs.LAST_UPD < @Date2 union all select 'BO', bo.NAME "Parent", bo.PR_BUSCOMP_NAME, boc.NAME, '', bo.LAST_UPD, u.LOGIN, bo.COMMENTS from S_BUSOBJ bo, S_BOCOMP boc, S_USER u where boc.BUSOBJ_ID = bo.ROW_ID and boc.LAST_UPD_BY = u.ROW_ID and boc.LAST_UPD >= @Date1 AND boc.LAST_UPD < @Date2 union all select 'Link', link.NAME "Parent", '', '', '', link.LAST_UPD, u.LOGIN, link.COMMENTS from S_LINK link, S_USER u where link.LAST_UPD_BY = u.ROW_ID and link.LAST_UPD >= @Date1 AND link.LAST_UPD < @Date2
• If you create objects / fields / scripts, be diligent to inactivate them if you have changed design • Include ROW_ID in any errors message
This action might not be possible to undo. Are you sure you want to continue?