API Questions on Kentico API.
Version 6.x > API > DocumentType API View modes: 
User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 6/12/2012 2:29:15 PM
   
DocumentType API
I'm trying to add a new document type using the API although I've only found instructions to clone one. I want to check first it exists, if so, check the fields and add/remove if necessary, then add new documents based on that document type. I've got a list of locations that I will import on a daily basis and I know that once the actual document type object is created it won't have to be created again but wanted to know how to do it for my own knowledge.

When I import these records each day, is there a way to schedule or create a process within Kentico to go out and get these records from the other datasource? Or do they have to be pushed to Kentico?

User avatar
Member
Member
kentico_michal - 6/14/2012 3:14:19 AM
   
RE:DocumentType API
Hi,

The code that demonstrates how you can create a new document type using API can be found here: ~\CMSModules\AdminControls\Controls\Class\NewClassWizard.ascx.cs

You just need to create a new DataClassInfo object, set all properties and insert the new class into DB:

DataClassInfoProvider.SetDataClass(DataClassInfo dci);

Also, the following knowledge base article shows how to create a new document type field using API: How to add a new field to a document type using API.

Moreover, you can create a custom scheduler to perform the task automatically at a specific time Scheduling a custom code.

Best regards,
Michal Legen

User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 6/14/2012 7:22:16 AM
   
RE:DocumentType API
Thanks Michal! That is exactly what I was looking for. I did find the Scheduler documentation yesterday and was able to use it and my custom code to run the process.

One last question I have is when I run through the process of creating the new documents, it takes some time to do this. First the module looks to see if there are any existing documents, if so, it deletes them then it create between 400 and 450 new records each day. Just in my testing yesterday it took about 15-20 minutes to run. Is there a way to speed this up? I have what I believe to be some pretty simple code:


public string Execute(TaskInfo ti)
{
switch (ti.TaskName)
{
case "Import_Stores":
GetStores();
break;
}
string details = "Executed from: '/App_Code/KT/Classes/KTTasks.cs'. Class: " + ti.TaskAssemblyName + "." + ti.TaskClass + ". Task data: " + ti.TaskData;
EventLogProvider.LogInformation("KT.KTTasks", "Execute", details);
return null;
}

protected void GetStores()
{
TreeProvider tree = new TreeProvider(CMSContext.CurrentUser);
CMS.TreeEngine.TreeNode parentNode = tree.SelectSingleNode(CMSContext.CurrentSiteName, "/Locations", "en-us");

if (parentNode != null)
{
KT.RetailStructure.RetailStructureService rss = new KT.RetailStructure.RetailStructureService();
DataTable dt = new DataTable();
KT.RetailStructure.ServiceCallResult scr = rss.GetStoreData("Kentico");

// delete all the current documents first
foreach (CMS.TreeEngine.TreeNode childNode in parentNode.Children)
{
DocumentHelper.DeleteDocument(childNode, tree, true, true, true);
}

if (!scr.HasErrors)
{
if (scr.DataSetResults.Tables[0].Rows.Count > 0)
{
dt = scr.DataSetResults.Tables[0];
DataRow[] rows = dt.Select("Division=1 AND ZoneNumber < 9000 AND DistrictNumber < 9000");
foreach (DataRow dr in rows)
{
CMS.TreeEngine.TreeNode newNode = CMS.TreeEngine.TreeNode.New("KT.Store", tree);
newNode.DocumentName = Convert.ToString(dr["StoreNumber"]);
newNode.DocumentCulture = "en-us";
newNode.SetValue("Address1", dr["Address1"]);
newNode.SetValue("Address2", dr["Address2"]);
newNode.SetValue("City", dr["City"]);
newNode.SetValue("St", dr["St"]);
newNode.SetValue("Longitude", dr["Longitude"]);
newNode.SetValue("Latitude", dr["Latitude"]);
......

//save the new document
newNode.Insert(parentNode);

// workflow
WorkflowManager workflowManager = new WorkflowManager(tree);
WorkflowInfo workflow = workflowManager.GetNodeWorkflow(newNode);

// check to see if using workflow
if (workflow != null)
{
if (!workflow.WorkflowAutoPublishChanges)
{
if (workflowManager.CanUserApprove(newNode))
{
// publish the document
WorkflowStepInfo step = WorkflowStepInfoProvider.GetWorkflowStepInfo("Published", workflow.WorkflowID);
workflowManager.MoveToSpecificStep(newNode, step, "Published by Import");
}
else
{
EventLogProvider ev = new EventLogProvider();
ev.LogEvent(EventLogProvider.EVENT_TYPE_INFORMATION, DateTime.Now, "KTTasks.GetStores()", "Execute", null, "The user is not authorized to approve this document.");
}
}
else
{
EventLogProvider ev = new EventLogProvider();
ev.LogEvent(EventLogProvider.EVENT_TYPE_INFORMATION, DateTime.Now, "KTTasks.GetStores()", "Execute", null, "The document uses versioning without workflow, changes are published automatically.");
}
}
else
{
// not using workflow
}
}
}
}
else
{
SystemException e = new SystemException(scr.ErrorMessage);
EventLogProvider.LogException("KTTasks.GetStores", "", e);
}
}
}

User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 6/14/2012 8:01:54 AM
   
RE:DocumentType API
One other item, the Scheduler runs under the asp.net process or Public user. When I run my process I need to approve the documents through workflow, which I have setup although when I get to workfloManager.CanUserApprove(newNode), it states the Public user not able to authorize this. Aside from removing the node from workflow is there a different way to run the Scheduled Task under a different user? It would be nice to have an option similar to what Windows Task Scheduler has by selecting a user account (sounds like a new feature).

User avatar
Member
Member
kentico_michal - 6/25/2012 3:47:03 AM
   
RE:DocumentType API
Hi,

Well, it is not so uncommon for a scheduled task to run a couple of minutes especially when document management is involved. In terms of the second question, you can usually supply the UserInfo object under which you want the code to run, for example, the CanUserApprove method has an overloaded version that accepts the UserInfo object (TreeNode node, UserInfo userInfo).

Best regards,
Michal Legen