Convert DateTime field token to local time zone in email rule - orchardcms

Within Orchard I have a custom content type that includes a DateTime field. I've created a rule to send an email when a new content item is submitted. I'm able to include the value of the DateTime field in the email using the following token:
{Content.Fields.MyContentType.MyDateTimeField}
The problem I'm running into is that the date/time value that replaces the token is in UTC and I need it to be in the timezone configured for my Orchard instance.
I see there's a token for the current date/time that looks like this:
{Date.Local}
But .Local does not seem to be valid on the DateTime field token.
It looks like it wouldn't be too hard to create a custom token provider to solve for this but before I did that I wanted to make sure I wasn't missing an easier, existing solution.

The date token does indeed have a Local subtoken but the problem here is that {Content.Fields.MyContentType.MyDateTimeField} is not a date token, it's still just the field. You need to get its actual value. If you look at FieldTokens.cs, you'll see that the date field token has a DateTime token. So {Content.Fields.MyContentType.MyDateTimeField.DateTime.Local} should do the trick I think.

Related

Using Graph API to query SharePoint list items and expand user field

I'm trying to query for some SP list items, all is working fine except I can't seem to expand a custom column of type Person.
I can see the createdBy and lastModifiedBy expanded and even includes the AAD user id, which is great and also leads me to think what I want is possible!
But mine is a custom column.
I'm running this and can only seem to get the SP user list id and the user's display name...neither of which are much use.
/items?expand=fields(select=UserLookupId,User)
Ideally I'd like to get the AAD user id as per createdBy and modifiedBy field, but the email would suffice.
Otherwise the only way I can see is to query the User Information List (using the UserLookupId) to get the email?
Thanks
This appears to be correct assumption:
Otherwise the only way I can see is to query the User Information List
(using the UserLookupId) to get the email?
for non-system user fields, it is indeed a way to go, but there are some distinctions whether user field is multi-valued or single-valued.
If Approvers is a multi-valued user field, then the following query:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items?$expand=fields($select=Approvers)
returns email and id properties along with displayName property for user field value.
While for single-valued user field only id (available via {userfield}LookupId property) and displayName properties could be requested via items endpoint, for example:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items?$expand=fields($select=Approver,ApproverLookupId)
So, indeed User Information List needs to be utilized to request additional user properties, for example:
https://graph.microsoft.com/v1.0/sites/root/lists('User Information List')/items/{item-id}/?$expand=fields($select=Email)
where item-id corresponds to user field lookup id
This was my experience modifying the
Build Angular single-page apps with Microsoft Graph. In the examples below, I changed my id's out with the default text.
Here is
The Finished Project on thier github
In Graph Explorer, this worked. You can verify it at the Microsoft Graph Explorer.
https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items?expand=fields($select=id,Title)
In the app/graph.service.ts in the app, this did not work. Even though you would expect it to based on the graph explorer.
.api('/sites/{site-id}/lists/{list-id}/items?fields($select=id,Title)')
Changing the app/graph.service.ts api call worked.
.api('/sites/{site-id}/lists/{list-id}/items?')
.expand('fields($select=id,Title)')
The result looked like this:
fields: {
#odata.etag: ""d6f5b6ea-9f90-452d-98ba-e838f58d3359,1"",
Title: "IT SPECIALIST (MID)",
id: "20"
}
Here's an example site id:
some.sharepoint.com,9dk062b-2e54-4e4f-b71a-cdb74f42cc44,c6cf6b0a-cc7c-41fd-a76a-ef8f97e8a22f
Here's an example list id.
8eg8c29a-5555-4cfc-bfa4-0e907488f781
The end url won't have any {} in it.

Getting content vales in a Orchard workflow

What I'm trying to do is send an email when a particular content type is created in Orchard.
What I did was create a workflow that detects when a "Practice" type is created and send an email.
Initially I hard coded everything (email address, subject and body). I am getting an email every time a "Practice" type is created.
I then tried using tokens to get real values. Initially I tried..
{Content.ContentType} and
{Content.Id}
Those seem to be working. The ContentType is "Practice" and the Id is the correct value.
The Practice type has a field called "ContactEmail", but I can't seem to get that value to show up. Here are the different variations I've tried...
{Content.Fields.Practice.ContactEmail}
{Content.ContactEmail}
{Content.Practice.ContactEmail}
but it's always blank (testing by putting these fields in the email body).
Any suggestions on how to the the "ContactEmail" value from a Practice?
Thanks!
Additional info...
The Practice part is created from a module (i.e. migration, model, etc.). What I think I may have to do is create a token provider for the Practice part. Does that sound right?

How to access nested Part properties in Email Workflow?

I have a Registration ContentType, which contains a ContentPicker field for a Building Item, which contains a Geolocation Part with some properties like Latitude and Longitude.
When a new Registration is Published, it triggers a custom Workflow that sends out an email. In the body of the email I can get to the fields of the Building using tokens like this: {Content.Fields.Registration.Building.Content.Fields.Building.Address}
How can I get to the property values of the Geolocation Part contained within the Building? Can I do something like this? {Content.Fields.Registration.Building.Content.Parts.Geolocation.Latitude}
I'm new to Orchard and I can't figure out how it's structured. Can this be done out of the box or will I have to write a custom token?
If you know which content item to take from the content picker field (for example if it always is only one), then the following might work:
{Content.Fields.Registration.Building.Content.Fields.Building.ContentItems[0].Geolocation.Latitude}
This is assuming your Building field is configured to pick content types with a Geolocation part

\d1\ Alternative to print a date on documents rather than have the user enter manually?

I am sending \s1\ perfectly fine to Docusign however \d1\ requests the signer to enter a date manually. This is obviously open to abuse on legal contracts.
Is there another tag i can use that prints the date of signing so the signer does not have to enter a date?
THank you
Are you using the Anchor Tagging feature since I see you referencing strings like \s1\ and \d1\? Or are you are using the DfS (DocuSign for Salesforce) integration and setting those strings through there?
The bottom line is that yes, it is definitely possible (and easy) to add a date tag that automatically populates based on the date your recipients are signing the document, so that they can not set whatever date they want. You just need to make sure you are using the Date Signed DocuSign tab instead of a regular date tab.
This is what it looks like in the DocuSign tagger:
If you do not have access to the tagging screen then you'll need to ask your DocuSign Admin.

What is GenerateEmailConfirmationToken() doing exactly?

I have two questions concerning ASP.Identity 2.0 "GenerateEmailConfirmationToken/GenerateEmailConfirmationTokenAsync" methods.
// Generate token
var token = Url.Encode(await UserManager.GenerateEmailConfirmationTokenAsync(user.Id));
Is this token stored in the database? I guess it should. But in which field? I just find "PasswordHash" and "SecurityStamp" on the User table. Both don't seem to match.
I was under the impression that once I generate an email token, the EmailConfirmed field of the User table would be set to false. But it stays true. So, what is the purpose of creating a token if the corresponding user account stays confirmed? Or in other words: What do I need to do in order to generate a new token AND also set the account to NOT confirmed?
To summarise the discussion in comments: tokens are not stored anywhere - they are crypto-generated (not exactly sure about exact process of generation) from SecruityStamp and when they are coming back, they can be de-crypted and compared.
As for EmailConfirmed field - this is for you to maintain and look after. You'll manually need to deny login for users with no confirmed email. And you'll need to set the flag when email confirmation does come through.

Resources