<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Add a date timestamp on primary attachment when downloaded. in Windchill Customization</title>
    <link>https://www.ptcusercommunity.com/t5/Windchill-Customization/Add-a-date-timestamp-on-primary-attachment-when-downloaded/m-p/988298#M9147</link>
    <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://www.ptcusercommunity.com/t5/user/viewprofilepage/user-id/608591"&gt;@DKWc&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The information is stored as a Security Audit log&amp;nbsp;&lt;/P&gt;
&lt;P&gt;if it is not activated you can activate the logging of the download event.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://www.ptc.com/en/support/article/cs269060" target="_self"&gt;cs269060 - WCAudit tablespace (e.g. table DOWNLOADEVENTINFO, AUDITRECORD)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;wt.content.ContentServiceEvent/READ_CONTENT&amp;nbsp;&lt;/STRONG&gt;is the audit log type&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then you can create a DataUtility for an attribute that retrieve last audit log record with download event.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;There is one issue with Visualization. Visualization worker also download the primary content.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Hi&amp;nbsp;&lt;A href="https://community.ptc.com/t5/user/viewprofilepage/user-id/608591" target="_blank" rel="noopener"&gt;@DKWc&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;here is an example - I used attribute AV_CODE but it does not mater&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="HelesicPetr_5-1733910172299.png" style="width: 429px;"&gt;&lt;img src="https://www.ptcusercommunity.com/t5/image/serverpage/image-id/115523i8AD9B22E1A2A9517/image-dimensions/429x297?v=v2" width="429" height="297" role="button" title="HelesicPetr_5-1733910172299.png" alt="HelesicPetr_5-1733910172299.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;here is a configuration and a place where you set the datautility&amp;nbsp;&lt;/P&gt;
&lt;P&gt;service.properties&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="HelesicPetr_4-1733910107894.png" style="width: 1150px;"&gt;&lt;img src="https://www.ptcusercommunity.com/t5/image/serverpage/image-id/115522iF0F5A73C4E9A58C1/image-dimensions/1150x715?v=v2" width="1150" height="715" role="button" title="HelesicPetr_4-1733910107894.png" alt="HelesicPetr_4-1733910107894.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;and finally here s a code for DataUtility&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE class="lia-code-sample  language-java"&gt;&lt;CODE&gt;package cz.aveng.HELTest1;

import com.ptc.core.components.descriptor.ModelContext;
import com.ptc.core.components.factory.dataUtilities.DefaultDataUtility;
import com.ptc.core.components.rendering.guicomponents.Label;
import wt.audit.AuditRecord;
import wt.doc.WTDocument;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.pds.StatementSpec;
import wt.query.*;
import wt.util.WTException;

/**
 * Datautilita for timestamp display from AuditRecord of Download event
 * &amp;lt;Service context="default" name="com.ptc.core.components.descriptor.DataUtility"
 * targetFile="codebase/service.properties"&amp;gt;
 * &amp;lt;Option cardinality="duplicate" order="1" overridable="true"
 * requestor="java.lang.Object"
 * selector="downloadAuditEventTimeStamp"
 * serviceClass="cz.aveng.HELTest1.AVCustomTestDataUtility"/&amp;gt;
 * &amp;lt;/Service&amp;gt;
 */
public class AVCustomTestDataUtility extends DefaultDataUtility
{
	public AVCustomTestDataUtility()
	{
	}

	public Object getDataValue(String var1, Object peristable, ModelContext var3) throws WTException
	{
		Object retValue = super.getDataValue(var1, peristable, var3);
		Label label = new Label(var1);
		if (peristable instanceof WTDocument)
		{
			WTDocument doc = (WTDocument) peristable;
			try
			{
				String searchCondition = "*/wt.content.ContentServiceEvent/READ_CONTENT";
				QuerySpec queryspec = new QuerySpec();
				int idLinkObject = queryspec.appendClassList(AuditRecord.class, true);
				CompositeWhereExpression andCondition = new CompositeWhereExpression(LogicalOperator.AND);
				andCondition.append(new SearchCondition(AuditRecord.class, AuditRecord.EVENT_KEY, SearchCondition.LIKE, searchCondition, false), new int[]{idLinkObject});
				andCondition.append(new SearchCondition(AuditRecord.class, AuditRecord.TARGET_NUMBER, SearchCondition.LIKE, doc.getNumber(), false), new int[]{idLinkObject});
				queryspec.appendWhere(andCondition, new int[]{idLinkObject, idLinkObject});

				queryspec.appendOrderBy(new OrderBy(new ClassAttribute(AuditRecord.class, AuditRecord.CREATE_TIMESTAMP), true), new int[]{0});

				QueryResult queryResult = PersistenceHelper.manager.find((StatementSpec) queryspec);

				while (queryResult.hasMoreElements())
				{
					Object resultObj = queryResult.nextElement();
					if (resultObj instanceof Persistable[])
					{
						Object resultAuditObj = ((Persistable[])resultObj)[0];
						if (resultAuditObj instanceof AuditRecord)
						{
							retValue = ((AuditRecord) resultAuditObj).getCreateTimestamp();
							break;
						}
					}
				}

			} catch (WTException e)
			{
				e.printStackTrace();
			}
		}
		return retValue;
	}
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT color="#FF0000"&gt;&lt;STRONG&gt;last thing,&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/FONT&gt;I would recommend to create database indexes on two columns for the AuditRecord table.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;targetNumber&lt;/P&gt;
&lt;P&gt;it will increase performance&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="HelesicPetr_0-1733911720759.png" style="width: 681px;"&gt;&lt;img src="https://www.ptcusercommunity.com/t5/image/serverpage/image-id/115526i779FBCEA7A72E9BA/image-dimensions/681x278?v=v2" width="681" height="278" role="button" title="HelesicPetr_0-1733911720759.png" alt="HelesicPetr_0-1733911720759.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;PetrH&lt;/P&gt;</description>
    <pubDate>Wed, 11 Dec 2024 10:09:03 GMT</pubDate>
    <dc:creator>HelesicPetr</dc:creator>
    <dc:date>2024-12-11T10:09:03Z</dc:date>
    <item>
      <title>Add a date timestamp on primary attachment when downloaded.</title>
      <link>https://www.ptcusercommunity.com/t5/Windchill-Customization/Add-a-date-timestamp-on-primary-attachment-when-downloaded/m-p/988280#M9145</link>
      <description>&lt;P&gt;Hi All,&lt;/P&gt;&lt;P&gt;Can we add a timestamp on the primary attachment been downloaded.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;How can we achieve it?&lt;/P&gt;&lt;P&gt;Any references would be appreciated&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 11 Dec 2024 07:32:33 GMT</pubDate>
      <guid>https://www.ptcusercommunity.com/t5/Windchill-Customization/Add-a-date-timestamp-on-primary-attachment-when-downloaded/m-p/988280#M9145</guid>
      <dc:creator>DKWc</dc:creator>
      <dc:date>2024-12-11T07:32:33Z</dc:date>
    </item>
    <item>
      <title>Re: Add a date timestamp on primary attachment when downloaded.</title>
      <link>https://www.ptcusercommunity.com/t5/Windchill-Customization/Add-a-date-timestamp-on-primary-attachment-when-downloaded/m-p/988298#M9147</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://www.ptcusercommunity.com/t5/user/viewprofilepage/user-id/608591"&gt;@DKWc&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The information is stored as a Security Audit log&amp;nbsp;&lt;/P&gt;
&lt;P&gt;if it is not activated you can activate the logging of the download event.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://www.ptc.com/en/support/article/cs269060" target="_self"&gt;cs269060 - WCAudit tablespace (e.g. table DOWNLOADEVENTINFO, AUDITRECORD)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;wt.content.ContentServiceEvent/READ_CONTENT&amp;nbsp;&lt;/STRONG&gt;is the audit log type&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then you can create a DataUtility for an attribute that retrieve last audit log record with download event.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;There is one issue with Visualization. Visualization worker also download the primary content.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Hi&amp;nbsp;&lt;A href="https://community.ptc.com/t5/user/viewprofilepage/user-id/608591" target="_blank" rel="noopener"&gt;@DKWc&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;here is an example - I used attribute AV_CODE but it does not mater&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="HelesicPetr_5-1733910172299.png" style="width: 429px;"&gt;&lt;img src="https://www.ptcusercommunity.com/t5/image/serverpage/image-id/115523i8AD9B22E1A2A9517/image-dimensions/429x297?v=v2" width="429" height="297" role="button" title="HelesicPetr_5-1733910172299.png" alt="HelesicPetr_5-1733910172299.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;here is a configuration and a place where you set the datautility&amp;nbsp;&lt;/P&gt;
&lt;P&gt;service.properties&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="HelesicPetr_4-1733910107894.png" style="width: 1150px;"&gt;&lt;img src="https://www.ptcusercommunity.com/t5/image/serverpage/image-id/115522iF0F5A73C4E9A58C1/image-dimensions/1150x715?v=v2" width="1150" height="715" role="button" title="HelesicPetr_4-1733910107894.png" alt="HelesicPetr_4-1733910107894.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;and finally here s a code for DataUtility&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE class="lia-code-sample  language-java"&gt;&lt;CODE&gt;package cz.aveng.HELTest1;

import com.ptc.core.components.descriptor.ModelContext;
import com.ptc.core.components.factory.dataUtilities.DefaultDataUtility;
import com.ptc.core.components.rendering.guicomponents.Label;
import wt.audit.AuditRecord;
import wt.doc.WTDocument;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.pds.StatementSpec;
import wt.query.*;
import wt.util.WTException;

/**
 * Datautilita for timestamp display from AuditRecord of Download event
 * &amp;lt;Service context="default" name="com.ptc.core.components.descriptor.DataUtility"
 * targetFile="codebase/service.properties"&amp;gt;
 * &amp;lt;Option cardinality="duplicate" order="1" overridable="true"
 * requestor="java.lang.Object"
 * selector="downloadAuditEventTimeStamp"
 * serviceClass="cz.aveng.HELTest1.AVCustomTestDataUtility"/&amp;gt;
 * &amp;lt;/Service&amp;gt;
 */
public class AVCustomTestDataUtility extends DefaultDataUtility
{
	public AVCustomTestDataUtility()
	{
	}

	public Object getDataValue(String var1, Object peristable, ModelContext var3) throws WTException
	{
		Object retValue = super.getDataValue(var1, peristable, var3);
		Label label = new Label(var1);
		if (peristable instanceof WTDocument)
		{
			WTDocument doc = (WTDocument) peristable;
			try
			{
				String searchCondition = "*/wt.content.ContentServiceEvent/READ_CONTENT";
				QuerySpec queryspec = new QuerySpec();
				int idLinkObject = queryspec.appendClassList(AuditRecord.class, true);
				CompositeWhereExpression andCondition = new CompositeWhereExpression(LogicalOperator.AND);
				andCondition.append(new SearchCondition(AuditRecord.class, AuditRecord.EVENT_KEY, SearchCondition.LIKE, searchCondition, false), new int[]{idLinkObject});
				andCondition.append(new SearchCondition(AuditRecord.class, AuditRecord.TARGET_NUMBER, SearchCondition.LIKE, doc.getNumber(), false), new int[]{idLinkObject});
				queryspec.appendWhere(andCondition, new int[]{idLinkObject, idLinkObject});

				queryspec.appendOrderBy(new OrderBy(new ClassAttribute(AuditRecord.class, AuditRecord.CREATE_TIMESTAMP), true), new int[]{0});

				QueryResult queryResult = PersistenceHelper.manager.find((StatementSpec) queryspec);

				while (queryResult.hasMoreElements())
				{
					Object resultObj = queryResult.nextElement();
					if (resultObj instanceof Persistable[])
					{
						Object resultAuditObj = ((Persistable[])resultObj)[0];
						if (resultAuditObj instanceof AuditRecord)
						{
							retValue = ((AuditRecord) resultAuditObj).getCreateTimestamp();
							break;
						}
					}
				}

			} catch (WTException e)
			{
				e.printStackTrace();
			}
		}
		return retValue;
	}
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT color="#FF0000"&gt;&lt;STRONG&gt;last thing,&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/FONT&gt;I would recommend to create database indexes on two columns for the AuditRecord table.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;targetNumber&lt;/P&gt;
&lt;P&gt;it will increase performance&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="HelesicPetr_0-1733911720759.png" style="width: 681px;"&gt;&lt;img src="https://www.ptcusercommunity.com/t5/image/serverpage/image-id/115526i779FBCEA7A72E9BA/image-dimensions/681x278?v=v2" width="681" height="278" role="button" title="HelesicPetr_0-1733911720759.png" alt="HelesicPetr_0-1733911720759.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;PetrH&lt;/P&gt;</description>
      <pubDate>Wed, 11 Dec 2024 10:09:03 GMT</pubDate>
      <guid>https://www.ptcusercommunity.com/t5/Windchill-Customization/Add-a-date-timestamp-on-primary-attachment-when-downloaded/m-p/988298#M9147</guid>
      <dc:creator>HelesicPetr</dc:creator>
      <dc:date>2024-12-11T10:09:03Z</dc:date>
    </item>
  </channel>
</rss>

