Clarity PPM1

Expand all | Collapse all

TIP : How To Put Any Dynamically Generated Value On A Clarity Object

navzjoshi0011-22-2012 08:04 AM

Christopher Hackett11-26-2012 11:23 AM

ashmi_ashma10-21-2015 08:25 AM

  • 1.  TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-22-2012 05:05 AM
      |   view attached
    Hi,

    A number of times on the forums I have suggested or tried to explain a technique where we can put a "dynamically generated" value (be it a score, a piece of text, a URL, etc) on a object page.

    Yesterday I found myself needing to do this again, so I tried to document the technique as I went along. (I went a little way past documenting the technique though and this has resulted in the attached "HowTo" guide).

    Dave.


    --

    Summary (see document for full details)

    What this ‘technique’ does

    Allows us to display “any” sort of calculated value on a Clarity object edit-page.

    Where “any sort of calculated value” could be;


    A derived value based on the current object (similar to a calculated attribute but with much more control over the calculation

    A “looked up” value from another related object

    A dynamically generated hyperlink to another Clarity page (such as a portlet-page with a URL parameter)

    A dynamically generated hyperlink to an external system

    The result from a call to an external system (performance may be an issue here)

    Just about ANYTHING else “data-like”* that you can think of
    (* - I have not tried to get it working with images)

    How It Works

    We create a parameterized-NSQL based lookup.

    The lookup ALWAYS returns a known value (e.g. “1”) as its ‘hidden key’ and a calculated value as its “display Attribute” – the calculated value is where we derive the dynamically generated value based on the parameter.

    We then create a new attribute on the object, and use the lookup against the attribute. We need to set the attribute default to our “known value”.

    Place the attribute on the object edit page and set its values to read-only.

    .

    Attachment(s)



  • 2.  RE: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-22-2012 08:04 AM
    Thanks for sharing this Dave !!!

    NJ


  • 3.  RE: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-26-2012 11:23 AM

    Thanks for sharing this Dave!



  • 4.  RE: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-27-2012 08:05 AM
    Hi, Dave.

    Nice hack, but I'm not convinced. The way I understand this, is that all your logic is in the display part of the lookup -- meaning that the database column for the attribute in the background will always hold a "1".
    This might be OK for displaying stuff in Clarity, but it means the actual value is not available for reporting, etc. Also, as you note, you'll run into some hassle in list portlets.

    Why not just make an attribute of the desired type, make that read-only, use a process and an sql:update to correctly set the value for the attribute?

    Daniel


  • 5.  RE: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-27-2012 08:23 AM

    dtietze wrote:

    The way I understand this, is that all your logic is in the display part of the lookup -- meaning that the database column for the attribute in the background will always hold a "1".
    Yes - exactly right!

    dtietze wrote:

    This might be OK for displaying stuff in Clarity
    Yes - and that is all I'm doing; just displaying "other stuff" related to my object, which may or may not be contained in Clarity.

    dtietze wrote:

    , but it means the actual value is not available for reporting, etc. Also, as you note, you'll run into some hassle in list portlets.
    For "reporting" you would just have to derive the "calculated value" in the reporting solution (NSQL portlet/report/etc) [ if you encapsulate the calculation logic in a database package then you could use the exact same "code" for reporting as in the hack/lookup ]

    dtietze wrote:

    Why not just make an attribute of the desired type, make that read-only, use a process and an sql:update to correctly set the value for the attribute?
    OK that would work but 3 reasons why you might choose to use this technique instead though;

    (1) <sql:update> is unsupported* on Clarity objects. You might describe my "hack" as a "hack" but there is no customisation involved in it.
    *Granted, we could update via XOG instead of <sql:update> but...

    (2) I don't want to wait until the process-engine has processed for me to redisplay my calculated value; in my "hack", the calculated value is visible immediately on screen refresh.

    (3) a change in my "calculated value" may not actually be triggered from my object (or even from Clarity itself) - for example if the lookup is reading external data from another system.

    --

    In fairness, if the use-case works with an asynchronous process-based update, then by all means do that and not this "hack" :grin:


  • 6.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 08-08-2014 03:57 AM

    A build on this technique from Gene with regard to displaying icons instead of just text in a dynamically built hyperlink;

     

    gcubed wrote:

     

    Dave,

     

    I was thinking about the icon url.

     

    If you loaded a set of icons in the knowledge store:

     

    ScreenHunter_31 Aug. 07 23.05.png

    You would be able to access them via there URL link.  For example the devil_smile.gif is located at this URL:

     

    https://cppm.ondemand.ca.com/niku/app?action=dms.viewFile&RhXm0r7tSeUqEr=true&fileId=5272209&fileName=devil_smile.gif

     

    So in your “How To Put Any Dynamically Generated Value On A Clarity Object” taking the following NSQL for dynamic links:

     

    SELECT

    @SELECT:1:DUMMY@

    ,@SELECT:X.details:template_details@

    FROM

    (

    SELECT

    '<a href="'||T.template_link||'" target="_blank">Link to TEMPLATE</a>'

    END

    AS details

    FROM

    odf_ca_****** T

    JOIN odf_ca_YYYYYY R ON R.item = T.ID

    WHERE R.ID = @WHERE:PARAM:USER_DEF:INTEGER:object_id@

    UNION

    SELECT 'DUMMY' FROM DUAL

    WHERE @WHERE:PARAM:USER_DEF:INTEGER:object_id@ IS NULL

    ) X

    WHERE @FILTER@

     

    By modifying the following line from:

    '<a href="'||T.template_link||'" target="_blank">Link to TEMPLATE</a>'

     

    To

    '<a href="'||T.template_link||'" target="_blank"><img src="https://cppm.ondemand.ca.com/niku/app?action=dms.viewFile&RhXm0r7tSeUqEr=true&fileId=5272209&fileName=devil_smile.gif" />

    </a>'

     

    I would expect the devil_smile.gif icon to appear rather than the “Link to TEMPLATE” text link.

     

    V/r,

    Gene

     

    Cool!



  • 7.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 09-20-2014 02:10 AM

    Hi! I've tried this solution and for some reason i got some anomalies :(. Meaning that the relevant field in database contains NULL (not 1) after saving page in clarity (where I use this dynamic lookup). And therefore - after saving > the lookup does not show any values.... And I could not figure out, why this is happening

     

    Lookup SQL is as following:

    SELECT
      @SELECT:1:DUMMY@,
      @SELECT:Q.JIRANOTICE:JIRANOTICE@
    FROM (
      SELECT CASE WHEN COUNT(i.ID) > 1 THEN 'Existing' ELSE 'Not Existing' END AS JIRANOTICE
      FROM INV_INVESTMENTS i INNER JOIN ODF_CA_INV ci ON i.ID = ci.ID
      WHERE ci.jira_id = @WHERE:PARAM:USER_DEF:STRING:JIRA_ID@
      UNION
      SELECT 'Not Existing' JIRANOTICE
      FROM DUAL
      WHERE @WHERE:PARAM:USER_DEF:STRING:JIRA_ID@ IS NULL
    ) Q
    WHERE @FILTER@
    


  • 8.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 09-22-2014 05:32 AM

    The value on the database always has to be '1' ; so check your settings for "default value" on the attribute and make sure that all values on the database are '1' - then check what happens when you re-save that page, it sounds like perhaps the lookup is not returning a '1' for you but I'm not sure how that would happen.



  • 9.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 09-22-2014 07:02 AM

    Hi! That's what's suprising me also, that i have default value = 1 set in investment level (because the attribute is in investment level)...and also idea level...when i'll do in investment level - Populate Null Values with the Default - i see in the DB, that the value is 1 in database. But when saving data in relevant idea, it saves NULL to DB. Don't understand why...



  • 10.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 09-22-2014 07:08 AM

    ^  bit confused; IDEA and INVESTMENT are separate objects - you have the dummy field on on the INVESTMENT so what do you mean by "saving data in relevant idea"? Are you talking about converting an IDEA to an INVESTMENT (in which case the problem might be what the dummy value gets set to upon the conversion process)???



  • 11.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 04-01-2015 02:41 PM

    Hi Dave,

     

    I have tried the above trick to display the Parent value of the Investment Type lookup. I am using the below SQL to display the value.

     

    The issue is that it is not populating the value for some of the project. Any idea ?

     

    SELECT

    @SELECT:1:DUMMY_ID@

    ,@SELECT:RESULT.PLKUP_VAL:PLKUP_VALUE@

    FROM

    (

    SELECT PARENT_LKUP.NAME PLKUP_VAL

    FROM CMN_LOOKUPS_V CHILD_LKUP

    INNER JOIN CMN_LOOKUPS_V PARENT_LKUP ON CHILD_LKUP.PARENT_LOOKUP_CODE = PARENT_LKUP.LOOKUP_CODE

    INNER JOIN INV_INVESTMENTS INV ON CHILD_LKUP.LOOKUP_CODE = INV.STAGE_CODE

    WHERE INV.ID = @WHERE:PARAM:USER_DEF:INTEGER:inv_id@

    AND PARENT_LKUP.LOOKUP_TYPE = 'INV_PROCESS_TYPE'

    AND CHILD_LKUP.LANGUAGE_CODE = 'en'

    AND PARENT_LKUP.LANGUAGE_CODE = 'en'

    AND CHILD_LKUP.IS_ACTIVE = 1

    AND PARENT_LKUP.IS_ACTIVE = 1

    UNION

    SELECT to_char(null) from DUAL

    WHERE @WHERE:PARAM:USER_DEF:INTEGER:inv_id@ is NULL

    )RESULT

    WHERE @FILTER@

     

    Thanks

    HT



  • 12.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 04-02-2015 04:23 AM

    The SQL looks fine to me.

     

    What do you mean by "not populating the value for some of the project" - what are the differences between the project that it does populate for and those that it doesn't?



  • 13.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 04-14-2015 02:52 PM

    The difference between the 2 projects is that one is having inactive lookup value, so what i did that re-activate the lookup value, check the checkbox "populate null values with the default" in the attributes and then again de-activate the lookup value.

     

    Now it is showing the parent value if we select the child.

     

    Thanks

    HT



  • 14.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 04-15-2015 03:44 AM

    Ok - I'll assume you are OK now!

     

    The thing about the "dummy lookup" in this technique though is that is always returns the same value (1), it is just the "display value" of the lookup which is "dynamic" and derived from the object-context.



  • 15.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 06-23-2015 08:08 AM

    It is me again and I've copied this from the shortening long URL thread

    Now I've manage to make a couple of implementations of those rather smoothly and are banging the limitations hard.

     

    Is it correct that color mapping is not possible if the data is numeric, because there is  lookup and it is dynamic and not static?

     

    Secondly the values displayed in the properties view are not stored in the database (like in the CMN_CAPTIONS_NLS) but always calculated on the fly?

    So I I want the values in a portlet I would need the include the same query as in the lookup to the query of the portlet?



  • 16.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 06-23-2015 08:19 AM

    Is it correct that color mapping is not possible if the data is numeric, because there is  lookup and it is dynamic and not static?

     

     

    yeah - the "actual value" is always going to be "1" so the "normal Clarity-way" that you would map to a colour (or an icon) will not help us ; BUT Gene posted a build on "my" technique (which I reposted earlier in this thread) in order to display icons - essentially doing the mapping as part of the (dynamically constructed) html in the lookup ; so you should be able to do what it sounds like you are thinking about using that.


    Secondly the values displayed in the properties view are not stored in the database (like in the CMN_CAPTIONS_NLS) but always calculated on the fly?

    So I I want the values in a portlet I would need the include the same query as in the lookup to the query of the portlet?

    Yes, just include the logic in the portlet's query - earlier in this thread I said "For "reporting" you would just have to derive the "calculated value" in the reporting solution (NSQL portlet/report/etc) [ if you encapsulate the calculation logic in a database package then you could use the exact same "code" for reporting as in the hack/lookup ]" that is was I was referring to there.

     

     



  • 17.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 06-23-2015 09:08 AM

    Thank you for your patience and sharing your wisdom.



  • 18.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 07-02-2015 04:24 PM

    Now the calculated attribute and the portlet are a little more than a week old and suddenly no more calculation are made. All the values are blank. The query based portlet still displays values as before.

     

    If the calculated attribute worked properly for a while and and nobody fiddled it should be OK and if not I can create another just to be sure, would that be a system issue underlying?

    Because nothing happens there are of course no errors.



  • 19.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 07-03-2015 03:19 AM

    Well clearly "something" has gone wrong - this trick doesn't expire over time (I have many attributes many years old using it! )

     

    What I would look at it this happened to me would firstly be the underlying data ; is the attribute value still "1" on *ALL* records on the underlying table? (if not ; check the attribute "default value" in the object/attribute set up - remember that that lookup always needs to return "1", even when on that object/attribute page)

     

    If thats all OK, I'd double check the NSQL logic in the lookup.

     

    After that I'd be a bit at a loss....



  • 20.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 07-03-2015 03:38 AM

    Just to be sure I created it again with a new lookup and it worked fine.

    So I replaced the original and relabeled the new with the old name and the users don't see the difference only that now it is working.

    Thanks for your response.



  • 21.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 10-21-2015 07:37 AM

    Hi Dave,

     

    great tip, but I have a question. When tried to implement this on CA Sandbox v. 14.2, it worked well according to your guide.

     

    However when tried to implement on our customer Clarity v.13.3 it not shown me "Object_ID" in Lookup Param Mapping in my Dummy attribute.

    Would you know what could cause it? Might it be the version? Query in Lookup is of course the same. I've just used 'project' object, but it also not worked with 'risk' object. Thanks

     

    In Clarity 13.3:

    Object_ID missing.jpg

     

    In Clarity Sandbox 14.2:

    Object_ID shown.jpg

     

    Matej



  • 22.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 10-21-2015 07:52 AM

    ^ Ok that looks very weird - but nothing to do with "my trick" I think - just a general "parametrised lookup" issue.

     

    I've never seen that sort of thing, maybe a but in 13.3 with parametrised lookups, but not one I'm aware of, sorry.



  • 23.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 10-21-2015 07:56 AM

    Hmm, OK. Dave, when you don't know to help, then nobody so we have to accept this situation. Thanks again for checking.

     

    Note: Just one more question I've just had in my mind: Does the CA Sandbox exist also for ver. 13.3 yet, or not? To be able to try on fresh installation...

     

    Matej



  • 24.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 10-21-2015 08:03 AM

    I've never used the sandbox so I wouldn't know!

     

    But CA support might know if there are any known issues with parameterised-lookups in 13.3?



  • 25.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 10-21-2015 08:18 AM

    OK I'll ask for this, thanks.

     

    Matej



  • 26.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 03-07-2016 10:58 AM

    Hi,

     

    I have the same issue. I am trying to build a Dynamic lookup for Booking manager  in the Team object. I could not get the PRID in the Object list and so I took the PRUID as the parameter to pass. I am getting the value on the Resource workload Portlet if I hard code the PRUID. But then I pass the variable and in the Team Lookup when I connect the variable to the PRUID, I do not get any value on the resource workload portet. Any help is appreciated. My code looks like this:

    SELECT

    @SELECT:1:DUMMY_ID@

    ,@SELECT:X.BOOK_MNG:BOOK_MNG@

    FROM

    (

    SELECT (SELECT SRM.FULL_NAME FROM SRM_RESOURCES SRM WHERE SRM.USER_ID = REQ.BOOK_MANAGER_ID) AS BOOK_MNG

      FROM PRTEAM TEM

      LEFT OUTER JOIN RSM_REQ_REQUISITIONS REQ

      ON REQUIREMENT_ID=TEM.PRID

      AND REQ.OBJECT_ID=TEM.PRPROJECTID

      AND REQ.OBJECT_TYPE = 'SRM_PROJECTS'

      AND REQ.STATUS_CODE NOT IN ('BOOKED','CLOSED')

    WHERE 'prteam'+CAST(REQ.REQUIREMENT_ID AS VARCHAR(7)) = @WHERE:PARAM:USER_DEF:STRING:pruid@

    UNION

    SELECT ISNULL(NULL,'NA') from DUAL

    WHERE @WHERE:PARAM:USER_DEF:STRING:pruid@ is NULL

    ) X

    WHERE @FILTER@



  • 27.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 03-07-2016 12:00 PM

    You should be able to use PRTEAM.PRID in your query and link that to the "[--Object ID--]" in the lookup mapping I would have thought?

     

    [ Don't think I've ever seen any "good code" ever trying to join data on those PRUID columns, they have always seemed to me to be some sort of throwback to old-technology ]



  • 28.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 03-07-2016 02:10 PM

    Thanks for the tip. I tried this. But I still do not get any results. Again, if I hard code the PRID, I do get the results

    My code looked as given below:

     

    SELECT

    @SELECT:1:DUMMY_ID@

    ,@SELECT:X.BOOK_MNG:BOOK_MNG@

    FROM

    (

    SELECT (SELECT SRM.FULL_NAME FROM SRM_RESOURCES SRM WHERE SRM.USER_ID = REQ.BOOK_MANAGER_ID) AS BOOK_MNG

      FROM RSM_REQ_REQUISITIONS REQ

      INNER JOIN PRTEAM TEM

      ON REQ.REQUIREMENT_ID=TEM.PRID

    WHERE REQ.OBJECT_TYPE = 'SRM_PROJECTS'

      AND REQ.OBJECT_TYPE = 'SRM_PROJECTS'

      AND  TEM.PRID=@WHERE:PARAM:USER_DEF:INTEGER:object_id@

      UNION

    SELECT ISNULL(NULL,'NA') from DUAL

    WHERE @WHERE:PARAM:USER_DEF:INTEGER:object_id@ is NULL

    ) X

    WHERE @FILTER@



  • 29.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 03-08-2016 03:53 AM

    Mohan.K I can only suggest that you "double-check" all the different things that need to be done to get this technique to work ; your NSQL does not look wrong but there are a number of important other steps that need to be done correctly to get this to work. Refer to the advice I have given to one of the (many) other people who make some random "doesn't work" comment without fully checking all the steps! (In your case I would perhaps first check that the database value is "1" for all records, missing that step would certainly give the symptoms that you describe (but the "problem" could also be elsewhere)).

     

    Worse case : go back to my original document, do everything in that document exactly as I have done - see the technique working, only then modify it for your local requirement.



  • 30.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 07-07-2016 10:53 AM

    Actually we are on 14.3 and are seeing the same thing above. It works, but on new records that are create din CA PPM it does not work. To resolve the situation we have to go back into the attribute and select "Populate Null Values with the Default" and press the "Save" button again. Then the new records work. Unfortunately, we cannot do this every-time a new record is created. 

     

    Interesting behavior.



  • 31.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 07-07-2016 11:09 AM

    ^ sounds like a problem with the defaulting of the attribute then (rather than the "trick" specifically) ; do other 'normal' attributes (with a default) get populated OK on record creation?



  • 32.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 07-07-2016 12:31 PM

    Other normal attributes are fine with the defaults on creation. Just this one. I created a test in another environment and the results were the same. I may give it a go in 14.4 sandbox tonight.

     

    Thanks!



  • 33.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 07-07-2016 12:57 PM

    Thats really weird, as far as the object is concerned its 'just' an attribute with a default value - might have to get CA Support onto the case



  • 34.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 07-07-2016 02:20 PM

    Since a lot of my work was moved to a new org, i have to have them open the ticket with CA support.



  • 35.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 10-21-2015 08:25 AM

    Thanks for sharing Dave! will try it soon!



  • 36.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-10-2015 12:40 PM

    Hi Dave,

     

    Can you please help/guide me to add dynamic url in Project edit object.On click of this dynamic url, it should open Project Alignment Rating page.

    This might be similar to Originating Idea field.

     

    Thanks in Advanced.



  • 37.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-10-2015 01:58 PM

    shital wrote:

     

    Hi Dave,

     

    Can you please help/guide me to add dynamic url in Project edit object.On click of this dynamic url, it should open Project Alignment Rating page.

    This might be similar to Originating Idea field.

     

    Thanks in Advanced.

    Well, the lookup that you need to write just needs to provide the URL that you want to link to as its "display value" - follow the (fairly explicit) instructions in that document I posted originally and you should get it all working.



  • 38.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-10-2015 04:15 PM

    There is a little discussion on getting URL's with this technique in this thread

    https://communities.ca.com/thread/54954980



  • 39.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-11-2015 01:24 AM

    I try to access the post (TIP : How To Put Any Dynamically Generated Value On A Clarity Object ), and I get the below message:

     

     

     

    NJ



  • 40.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-11-2015 01:24 AM

    Although, I can access the post from the inbox

     

    NJ



  • 41.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-11-2015 03:51 AM

    [OFFTOPIC] so you post in thread https://communities.ca.com/thread/99705433 that you can't access thread https://communities.ca.com/thread/99705433 and then you post again saying that you can?

    Was any of that really worthwhile, or appropriate to this thread? (and I include my post now in that comment)

     

     



  • 42.  Re: TIP : How To Put Any Dynamically Generated Value On A Clarity Object

    Posted 11-11-2015 12:14 PM

    Hi Dave,

    I referred your doc and created dummy lookup but noting is appearing in front of field (no value to click).

    My requirement is - I need to create new field 'Update Project Alignment Rating' on project with type virtual string and fields value should be URL of project's sub-page.

    Do you know how this originating idea implemented. I need the same for my case.

    It would be great if you could provide me some details on originating idea, i will refer that.

     

    Thanks for your help and time.