marketplace development guide
PDF

Demo version requirements

Glossary Item Box

Introduction

The purpose of demo versions is enabling a user to see how the solution operates.

A demo version is a set of demo data bound to a separate package that depends only on the solution package.

The recommended procedure of creating a demo version:

  1. Deploy a clean Creatio build.
  2. Install the solution package (e.g., LabReports).
  3. Create a package titled as follows: Package name + _Demo (e.g., LabReports_Demo). Select the package of the installed solution in the dependencies.
  4. Populate the sections and lookups with demo data, bind them to the demo package, sort the records to display the data correctly (follow the instructions below).
  5. Export the package.

After you export the package, install it to a separate clean build and test the correctness and completion of its demo data. After you successfully complete the testing of the package with demo data, forward it to the Marketplace team.

For example, for the Advanced excel reports for Creatio solution:

  1. Populate the records in the [Report constructor] section. When adding records, make different combinations of populating the primary fields for the object (e.g., [Report title], [Report view format], [Start with line], [Create column titles]).
  2. Populate all details for several records (e.g., [Custom filters], [Report columns], [Section reports], [Report history]).
  3. Add a template file for one of the populated records.
  4. Populate records in the [Notifications] block, import the report.

Glossary:

  • Softkey data – examples of populating the system objects. The softkey data is added to the solution primary package. The records should be in English and contain a “(sample)” text in their names.
  • Demo data – examples of populating the system objects that are created in a separate package and depend on the primary package of the solution.
  • Showcase records – section records populated with demo data. The showcase records are the first three records in a section.

Additional information on binding data to packages:

Record author:

  • All data are created on behalf of the same demo user bound by the user Id;
  • Demo user (John Best) Id is 76929f8c-7e15-4c64-bdb0-adc62d383727.

Sorting and saving:

  1. Set up sorting of lists to display showcase records on top. If the showcase records are not selected/populated, you can first select the sorting and afterwards populate the showcase records.
  2. After you set the needed sorting, click [View] -> [Select fields to display]. Click the arrow on the [Save] button and select [Save for all users] option.
  3. You can search for the needed record by the Key value that will match the sorting schema. You can view it in the URL. For example, sorting for the [Contracts] section will be saved in the record with Key=ContractSectionV2GridSettingsGridDataView. After saving for all users it will contain ContactId=NULL.

Specific/custom sorting must be saved in accordance with the above procedure. Sorting of the demo data cancels the softkey data sorting contained in schemas.

Populating sections:

  • The number of records in sections should be sufficient to display on the screen and provide enough data for realistic analytics (about 20 records in average).
  • Make sure that the number of table records does not exceed 1000.
  • The first three records in a section (showcase records) must be the most complete.

Lookups

  • Before you start populating sections, check and update the lookups.
  • The lookups can contain softkey (bound to the primary package of the solution) or demo data.
  • Do not duplicate records in lookups.

Record contents

  • Record information must be consistent.
  • Section records should be of different types. The record variety can be visible in folders and dashboards.
  • The records must be logically bound to other records (we recommend populating the records in “chains” and not per section).
  • Populate record information in sections, feed, notifications, email messages, comments, likes, etc.
  • All demo data should have positive connotations. Even case incidents of the “complaint” category should not be clearly negative.

Record data

  • Multiple system records contain a date field.
  • To ensure that the record info is always up to date, use the script for shifting dates. It changes the dates based on the date of updating the demo records, specified in the “English Demo Data Actual Date” (ActualizedDemoDate_en) system setting.
  • When you populate the demo data, change the dates in accordance with the system setting date.
  • For example, if the update date is 01.11.2019, the script will change the 01.11.2019 date with the current date in the demo data. Likewise, the 01.10.2019 date will change to yesterday’s date, etc. A demo record whose date is 05.11.2019 will be recorded as a future date after the date shift, i.e., 4 months later than the current date of running the script.
  • Dates can be added automatically when saving records. The build should not contain illogical dates.

The script for updating the dates:

/*
** Project: Creatio
** DBMS   : MSSQL 2008
** Type   : Script
** Name   : Actualize Date For Demo
*/
IF EXISTS (
    SELECT NULL
    FROM sys.objects
    WHERE [type] = 'TR' AND [name] = 'TR_BulkEmail_ProcessStatisticAfterUpdate'
)
DISABLE TRIGGER [dbo].[TR_BulkEmail_ProcessStatisticAfterUpdate] ON [dbo].[BulkEmail]
GO
IF EXISTS (
    SELECT NULL
    FROM sys.objects
    WHERE [type] = 'TR' AND [name] = 'TRCallAI'
)
DISABLE TRIGGER [dbo].[TRCallAI] ON [dbo].[Call]
GO


set nocount on
declare @NL char(1)
set @NL = char(13)

declare @ActualizedDemoDate datetime2
set @ActualizedDemoDate = (
    select top 1 sv.DateTimeValue 
    from SysSettings ss, SysSettingsValue sv
    where ss.Id = sv.SysSettingsId 
    and ss.Code like 'ActualizedDemoDate%'
    order by sv.ModifiedOn desc
)

if (@ActualizedDemoDate is null) 
begin
    print 'DemoDate is null.'
    return
end

print 'DemoDate is ' + cast(@ActualizedDemoDate as varchar)
declare @DaysDiff int
set @DaysDiff = datediff(DAY, @ActualizedDemoDate, getdate())
declare @DaysDiffStr varchar(6)
set @DaysDiffStr = cast(@DaysDiff as varchar(6))

declare @Table sysname
declare @Column sysname    

declare [c] cursor for
select table_name, column_name
from INFORMATION_SCHEMA.COLUMNS
where 
    (upper(data_type) = 'DATETIME' or upper(data_type) = 'DATETIME2' or upper(data_type) = 'DATE')
    and (column_name not in ('ModifiedOn') or 
            table_name in ('Opportunity', 'OpportunityInStage', 'SocialMessage', 'Lead', 'Contact', 'Account', 'KnowledgeBase', 'Product',
            'ApplicationApproval', 'Campaign', 'BulkEmail', 'CaseMessageHistory', 'Case', 'Activity', 'Invoice'))
    and (column_name not in ('CreatedOn') or 
            table_name in ('Opportunity', 'OpportunityInStage', 'SocialMessage', 'Lead', 'Contact', 'Account', 'KnowledgeBase', 'Product',
            'ApplicationApproval', 'Campaign', 'BulkEmail', 'CaseMessageHistory', 'Case', 'Activity', 'Invoice'))
    and not table_name in ('SysLic', 'RemindInterval', 'SysRecentEntity', 'PlanYear', 'PlanMonth', 'PlanQuarter', 'Period', 'FinIndicator', 'CampaignPlanner', 'MktgActivity', 'CurrencyRate')
    and not (table_name in ('ContactAnniversary', 'AccountAnniversary') and column_name = 'Date')
    and not (table_name in ('Contact') and column_name = 'BirthDate')
    and not (table_name in ('SysAdminUnit') and column_name = 'PasswordExpireDate')
    and not (table_name in ('SysImage') and column_name = 'UploadedOn')
    and objectproperty(object_id(table_name), 'IsTable') = 1
    order by table_name, column_name

open [c]

while (1 = 1)
begin
    fetch next from [c] into @Table, @Column

    if @@fetch_status = -1 break
    if @@fetch_status = -2 continue

    declare @tempExecStr nvarchar(max)
    set @tempExecStr = (
        ' update [' + @Table + '] ' + @NL +
        ' set [' + @Column + '] = dateadd(DAY, ' + @DaysDiffStr + ', [' + @Column + '])' + @NL + 
        ' where not [' + @Column + '] is null ' + @NL + 
        ' and datediff(DAY, [' + @Column + '], ''99991231'') > ' + @DaysDiffStr)
        
    exec (@tempExecStr)
    
    set @tempExecStr = (
    'DECLARE @currentDate DATETIME2 = getutcdate();' +
    ' update [' + @Table + '] ' + @NL +
    ' set [' + @Column + '] = @currentDate' + @NL + 
    ' where [' + @Column + '] > @currentDate' + @NL +
    ' and ''' + @Column + ''' in (''CreatedOn'', ''ModifiedOn'')')

    exec (@tempExecStr)
    
    print @Table + ' Column ->' +@Column + ' Diff->' + @DaysDiffStr + '(days) is updated.'
end
close [c]
deallocate [c]
GO
/* Actualize Date For Demo Forecasts */

IF (OBJECT_ID(N'ForecastSheet') IS NOT NULL)
BEGIN
    /*Actualize opportunity DueDate for demo Forecast*/
    --DECLARE @minOpportunityDueDate DATETIME2 = (SELECT MIN(o.DueDate) FROM Opportunity o);
    --DECLARE @newMinOpportunityDueDate DATETIME2 = DATEADD(MONTH, ((DATEPART(YEAR, GETUTCDATE()) - 2000) * 12) + DATEPART(MONTH, GETUTCDATE()) - 2, CONVERT(DATETIME, '2000.01.13', 102));
    --DECLARE @opportunityDueDateDiff INT = DATEDIFF(DAY,@minOpportunityDueDate, @newMinOpportunityDueDate);
    --IF @opportunityDueDateDiff <> 0 BEGIN
    -- PRINT 'Will add ' + CAST(@opportunityDueDateDiff AS VARCHAR(10)) + ' days to Opportunity DueDate';
    -- UPDATE Opportunity
    -- SET DueDate = DATEADD(DAY, @opportunityDueDateDiff, DueDate)                                    
    --END
    

    DECLARE @entityForecastMap TABLE(
        ForecastEntityName NVARCHAR(50)
    );  

    INSERT INTO @entityForecastMap 
    VALUES 
        ('AccountForecast'),
        ('ContactForecast'),
        ('LeadTypeForecast'),
        ('OppDepartmentForecast')

    DECLARE @sql NVARCHAR(max);
    DECLARE @tableName NVARCHAR(100);

    DECLARE c CURSOR FOR
        SELECT ForecastEntityName FROM @entityForecastMap
    OPEN c

    WHILE 1 = 1
    BEGIN
        FETCH NEXT FROM c INTO @tableName
        IF @@FETCH_STATUS = -1 BREAK
        IF @@FETCH_STATUS = -2 CONTINUE

        IF (OBJECT_ID(@tableName) IS NOT NULL)
        BEGIN
            SET @sql = '
                UPDATE f
                SET PeriodId = (
                    SELECT 
                        inp.Id 
                    FROM Period inp
                    WHERE inp.PeriodTypeId = p.PeriodTypeId
                    AND inp.StartDate = DATEADD(year, DATEDIFF(year, p.StartDate, GETDATE()), p.StartDate)
                    AND inp.DueDate = DATEADD(year, DATEDIFF(year, p.DueDate, GETDATE()), p.DueDate)
                    )
                FROM '+ @tableName +' f
                JOIN Period p ON p.Id = f.PeriodId
            ';
            EXEC sp_executesql @sql;
        END;
    END;
    CLOSE c
    DEALLOCATE c
END;

GO

IF EXISTS (
    SELECT NULL
    FROM sys.objects
    WHERE [type] = 'TR' AND [name] = 'TR_BulkEmail_ProcessStatisticAfterUpdate'
)
ENABLE TRIGGER [dbo].[TR_BulkEmail_ProcessStatisticAfterUpdate] ON [dbo].[BulkEmail]
GO
IF EXISTS (
    SELECT NULL
    FROM sys.objects
    WHERE [type] = 'TR' AND [name] = 'TRCallAI'
)
ENABLE TRIGGER [dbo].[TRCallAI] ON [dbo].[Call]
GO

Comprehensive record views

  • If activities are created during adding data, check the records in the activity schedule.
  • If you need to display analytics in the Dashboards when populating the demo data, check the charts in each sections taking into account the update date.
  • Some sections have pre-configured filters by Owner and time period ([Activities], [Invoices], etc.). When you populate the data, make sure that the grid list contains records meeting the filter conditions.
© Creatio 2002-2020.

Did you find this information useful?

How can we improve it?