Difference between revisions of "VN3056REP - Same business logic as View Report for View Cross function from Questionnaire list"

From Catglobe Wiki
Jump to: navigation, search
(Design decisions)
 
(17 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
<accesscontrol>Main:MyGroup</accesscontrol>
 +
[[Category:Miscellaneous]]
 +
 
== Introduction ==
 
== Introduction ==
 
[[Image:ViewCrossFunction.PNG]]
 
[[Image:ViewCrossFunction.PNG]]
Line 20: Line 23:
 
* If option 1 is selected, data cache will be re-setup, rebuild, and then show the cross viewer page.
 
* If option 1 is selected, data cache will be re-setup, rebuild, and then show the cross viewer page.
 
* If option 2 is selected, just show the cross viewer page with the old data cache.
 
* If option 2 is selected, just show the cross viewer page with the old data cache.
 
== New CGScript functions  ==
 
 
New CGScript are introduced in to Report library (the one in CatGlobe.Report project - ''CatGlobe.Framework.Report.Script.CGScript_System_Report'').
 
 
*Tabulation_setTableLayout(TableChartLayoutType)
 
 
The only argument is a value of enumeration ''CatGlobe.Framework.Report.Elements.TableChartLayoutType''. The result should be store in ''TabulationConfig'' object. But due to some constraint transferring data between old and new code, only store the value as '''string'''.
 
 
*countAnswer()
 
 
The normal ''count()'' function is for counting the number of respondents to a question and this function is for counting the number of question that were answered. For example, we have a multi-question "What do you prefer?" which have 3 answer options A, B, C. And we have 2 respondents R1 and R2, R1's answer is A, B while R2's answer is 1, 3. Then:
 
 
:*count() =&gt; returns 2 (there are 2 respondents to the question)
 
:*countAnswer() =&gt; returns 4 (R1 chose 2 options and R2 chose 2 options)
 
 
'''NOTE''': for Data team, please note that there is 2 ''CGScript_System_Report.cs'' files, one in the ''CatGlobe'' project and the other is in ''CatGlobe.Report'' project. If you have to modify this file, please modify the one in ''CatGlobe.Report'' project because the new report engine is working with this file only.
 
  
 
== Design detail ==
 
== Design detail ==
[[Image: TableChartBuilder.png]]
+
* Re-make a new "Regenerate instant cross" dialog as above.
 +
* There are two main processes for this dialog:
 +
:* The Page_Load event:
  
There are currently 3 types of layout that are encoded inside enum ''TableChartLayoutType''. There is also a factory method for getting the right builder base on its layout type.
+
[[Image:3056_FLPageLoadMethod.PNG]]
  
''TableChartBuilder'' provide all necessary methods for building a table. There are a couple of abstract methods that must be implemented in the concrete implementation. The next important one is the ''ClassicTableChartLayoutType'' which build the class layout of cross diagram as image below.
+
: Create default data cache
 +
<source lang=csharp>
 +
// QuestionnaireObject is a selected Questionnaire
 +
QuestionnaireCacheSpecification qcsObject = DiagramUtilities.CreateNewDCSByQuestionnaire(QuestionnaireObject);
 +
</source>
  
[[Image:CrossDiagram-Classic.png]]
+
:* The Button Ok clicked event:
  
The 2 child classes of ''ClassicTableChartLayoutType'' provide 2 different layout (left title and ifka) as below images
+
[[Image:3056_FLButtonOkClicked.png]]
  
* Left title
+
: Re-setup data cache:
[[Image:CrossDiagram-LeftTitleClassic.png]]
+
<source lang=csharp>
 +
// _dcsId is a questionnaire cache specification ID
 +
// _pqId is a project questionnaire ID
 +
var pq = ProjectQuestionnaire.GetByPrimaryKey(_pqId);
 +
var qcs = QuestionnaireCacheSpecification.GetBy(_dcsId);
 +
var pqs = new List<ProjectQuestionnaire> { pq };
 +
qcs.QuickSetup(pqs, true);
 +
qcs.AxisSet = qcs.CreateDefaultAxisSet();
 +
qcs.Save();
 +
</source>
 +
: Rebuild data cache:
 +
<source lang=csharp>
 +
// qcsObject is a questionnaire cache specification object
 +
DataCacheManager.Instance.BuildDCSIfNeeded(qcsObject, true, false);
 +
</source>
 +
: Re-setup and rebuild data cache in another thread
 +
<source lang=csharp>
 +
[ServerMethod]
 +
      public bool ResetupAndRebuildDcs(int pqId, int qcsId, string key)
 +
      {
 +
        var identity = WindowsIdentity.GetCurrent();
 +
        var generator = new ResetupDcsForCrossDiagramGenerator(pqId, qcsId, key, identity);
 +
        var thread = new Thread(generator.ResetupDcs)
 +
        {
 +
            CurrentCulture = Thread.CurrentThread.CurrentCulture,
 +
            CurrentUICulture = Thread.CurrentThread.CurrentUICulture
 +
        };
 +
        thread.Start();
 +
        return true;
 +
      }
 +
</source>
 +
: Class diagram of ResetupDcsForCrossDiagramGenerator class
 +
[[Image: ResetupDcsForCrossDiagramGenerator.png]]
 +
: ResetupDcs() method:
 +
<source lang=csharp>
 +
public void ResetupDcs()
 +
      {
 +
        if (IsInProc())
 +
        {
 +
            ResetupDcsReal();
 +
            return;
 +
        }
 +
        _identity.Impersonate();
 +
        IoC.Resolve<IAccessFactoryFactory>().CreateFactory();
  
* IFKA
+
        try
[[Image:CrossDiagram-Ifka.png]]
+
        {
 
+
            ResetupDcsReal();
There is another request that require a lot more effort which is [[Synchronize tables' size]].
+
            AppDomain.CurrentDomain.SetData(_threadkey, string.Format("Success.{0}", _dcsId));
 +
        }
 +
        catch (Exception e)
 +
        {
 +
            Abort(e);
 +
        }
 +
        finally
 +
        {
 +
            Commit();
 +
        }
 +
      }
 +
</source>
 +
: ResetupDcsReal() method: note that ''AccessFactory.CurrentInstance().ConnectionFactory.Commit();'' has to be called before building Dcs to get latest data.
 +
<source lang=csharp>
 +
private void ResetupDcsReal()
 +
      {
 +
        var pq = ProjectQuestionnaire.GetByPrimaryKey(_pqId);
 +
        var qcs = QuestionnaireCacheSpecification.GetBy(_dcsId);
 +
        var pqs = new List<ProjectQuestionnaire> { pq };
 +
        qcs.QuickSetup(pqs, true);
 +
        qcs.AxisSet = qcs.CreateDefaultAxisSet();
 +
        qcs.Save();
 +
        AccessFactory.CurrentInstance().ConnectionFactory.Commit();
 +
        DataCacheManager.Instance.BuildDCSIfNeeded(qcs, true, true);
 +
      }
 +
</source>
  
 
== Document revisions ==
 
== Document revisions ==
Line 67: Line 127:
 
|-
 
|-
 
| 0.1  
 
| 0.1  
| 05.02.2010
+
| 23.03.2010
| [[Nguyễn Trung Chính]]
+
| [[Trần Nguyễn Thanh Tùng]]
| Add description for cgscript
+
| Technical design
 
| NA
 
| NA
 
|-
 
|-
| 0.2
+
| 0.2  
| 11.02.2010
+
| 01.04.2010
| [[Nguyễn Trung Chính]]
+
| [[Trần Nguyễn Thanh Tùng]]
| Finish
+
| Update to bug fixed - Finish
| 60300
+
| NA
 
|}
 
|}

Latest revision as of 04:22, 18 October 2013

<accesscontrol>Main:MyGroup</accesscontrol>

Introduction

ViewCrossFunction.PNG

The current process of "View cross" function in Questionnaire list:

  • Create / Rebuild the default data cache of selected questionnaire.
  • Check if the data cache has any axises, if yes redirect to a "nearly" cross viewer page, if no, just render an error message.

Disadvantage:

  • The data cache is always rebuilt if there is a change in data of questionnaire.
  • If the questionnaire template of questionnaire is changed, it is too difficult to re-setup the data cache.

Design decisions

When "View Cross" function of Questionnaire list is clicked:

  • If this is the first time that this function is used for selected questionnaire, create a data cache and redirect to cross viewer page.
  • If not, use the same business logic as "View Report" function, show the below dialog

ViewCrossDialog.PNG

  • If option 1 is selected, data cache will be re-setup, rebuild, and then show the cross viewer page.
  • If option 2 is selected, just show the cross viewer page with the old data cache.

Design detail

  • Re-make a new "Regenerate instant cross" dialog as above.
  • There are two main processes for this dialog:
  • The Page_Load event:

3056 FLPageLoadMethod.PNG

Create default data cache
// QuestionnaireObject is a selected Questionnaire
QuestionnaireCacheSpecification qcsObject = DiagramUtilities.CreateNewDCSByQuestionnaire(QuestionnaireObject);
  • The Button Ok clicked event:

3056 FLButtonOkClicked.png

Re-setup data cache:
// _dcsId is a questionnaire cache specification ID
// _pqId is a project questionnaire ID
var pq = ProjectQuestionnaire.GetByPrimaryKey(_pqId);
var qcs = QuestionnaireCacheSpecification.GetBy(_dcsId);
var pqs = new List<ProjectQuestionnaire> { pq };
qcs.QuickSetup(pqs, true);
qcs.AxisSet = qcs.CreateDefaultAxisSet();
qcs.Save();
Rebuild data cache:
// qcsObject is a questionnaire cache specification object
DataCacheManager.Instance.BuildDCSIfNeeded(qcsObject, true, false);
Re-setup and rebuild data cache in another thread
 [ServerMethod]
      public bool ResetupAndRebuildDcs(int pqId, int qcsId, string key)
      {
         var identity = WindowsIdentity.GetCurrent();
         var generator = new ResetupDcsForCrossDiagramGenerator(pqId, qcsId, key, identity);
         var thread = new Thread(generator.ResetupDcs)
         {
            CurrentCulture = Thread.CurrentThread.CurrentCulture,
            CurrentUICulture = Thread.CurrentThread.CurrentUICulture
         };
         thread.Start();
         return true;
      }
Class diagram of ResetupDcsForCrossDiagramGenerator class

ResetupDcsForCrossDiagramGenerator.png

ResetupDcs() method:
 public void ResetupDcs()
      {
         if (IsInProc())
         {
            ResetupDcsReal();
            return;
         }
         _identity.Impersonate();
         IoC.Resolve<IAccessFactoryFactory>().CreateFactory();

         try
         {
            ResetupDcsReal();
            AppDomain.CurrentDomain.SetData(_threadkey, string.Format("Success.{0}", _dcsId));
         }
         catch (Exception e)
         {
            Abort(e);
         }
         finally
         {
            Commit();
         }
      }
ResetupDcsReal() method: note that AccessFactory.CurrentInstance().ConnectionFactory.Commit(); has to be called before building Dcs to get latest data.
private void ResetupDcsReal()
      {
         var pq = ProjectQuestionnaire.GetByPrimaryKey(_pqId);
         var qcs = QuestionnaireCacheSpecification.GetBy(_dcsId);
         var pqs = new List<ProjectQuestionnaire> { pq };
         qcs.QuickSetup(pqs, true);
         qcs.AxisSet = qcs.CreateDefaultAxisSet();
         qcs.Save();
         AccessFactory.CurrentInstance().ConnectionFactory.Commit();
         DataCacheManager.Instance.BuildDCSIfNeeded(qcs, true, true);
      }

Document revisions

Version No. Date Changed By Description Svn revision
0.1 23.03.2010 Trần Nguyễn Thanh Tùng Technical design NA
0.2 01.04.2010 Trần Nguyễn Thanh Tùng Update to bug fixed - Finish NA