I have problems getting a fetchxml date filter on a dataverse virtual table to work.
The table has a property cra42_modifieddate which is optional DateTime.
{% fetchxml productQuery %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="cra42_saleslt_product">
<filter>
<condition value="2008-03-11" attribute="cra42_modifieddate" operator="on-or-after" />
</filter>
</entity>
</fetch>
{% endfetchxml %}
The filter works fine if I query string columns (e.g. Name), and it works if I filter dates against a standard table. Could it be that this type of filter is not supported for virtual tables?
Related
I'm trying to display the selected values of a MultiSelect Option Set in a custom page in Web Portal with Liquid Template.
I wrote the FetchXml query anf if i test it the query in XrmToolBox, it's return the field with values.
But when Liquid Template executes the query in the Web Template, the field is null or empty :
{% fetchxml areas %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="ioc_role">
<attribute name="ioc_roleid" />
<attribute name="ioc_functionalarea" />
<order attribute="ioc_personid" descending="false" />
<filter type="and">
<condition attribute="ioc_roleid" operator="eq" value="{{myGuid}}" />
</filter>
</entity>
</fetch>
{% endfetchxml %}
{% for item in areas.results.entities %}
<span>{{item.ioc_functionalarea}}</span>
{% endfor %}
The result by XrmToolBox :
<resultset>
<result>
<ioc_roleid>
{74D55E06-175F-E911-A966-000D3A441525}
</ioc_roleid>
<ioc_functionalarea name="[-1,182090000,182090001,182090003,-1]" >
[-1,182090000,182090001,182090003,-1]
</ioc_functionalarea>
</result>
</resultset>
Do you have any idea about this behavior?
item.ioc_functionalarea is an array,
You probably have to try like
item.ioc_functionalarea[0]
This will give 1st multi select value.
Also just to check could you show roleid,
I mean just to be sure you do get roleid in your liquid template.
I get the good item when I display the roleid.
I tried :
item.ioc_functionalarea.size => nothing
item.ioc_functionalarea | size => 0
item.ioc_functionalarea | join: ',' => nothing
Say we have a entity called Timesheet. For simplicity, let's assume the Timesheet entity has three properties (TimesheetID, Status and Hours).
We currently allows the owners of Timesheet objects to submit their Timesheets via this end point -
POST: /Users/{UserID}/Timesheets/{TimesheetID}
With {UserID} currently is the owner of the Timesheet object. With {TimesheetID} I can also trace back the owner of the Timesheet in the database.
OK, now here is the question -
Now we'd like to have their managers to be able to update the Timesheet objects of the employees to that report to them (such as approve/reject Timesheets by changing the Status, or override Hours).
However, there are different levels of Manager Permissions. Some managers are only allow to update Status and some of them are allowed to update both Status and Hours.
Should I reuse the existing end point for both regular user submissions and managers update (I prefer)? Or should I create a different end point for each of the "Manager Level"?
If I hope to reuse the existing end point for all user submissions and manager updates, how do I handle the errors such as if a manager is configured to only update the Status, but the TimeSheet object posted to the REST service has both Status and Hours changed. Should I respond with a 403 with a detailed error description to tell the Manager that you can't change the Hours property or update the Status and ignore Hours?
If you're following the HATEOAS constraint, then a GET on the Timesheet resource will provide the hypermedia controls (links and forms) that can currently be used to interact with it. While this can be done a number of ways, the one that provides the lowest form of coupling, will include in the form they valid parameters.
For your example, I would include two manager forms with the same endpoint /Users/{UserID}/Timesheets/{TimesheetID}. The first one would have a status as a required field, the second one would have status (status could be optional) and hours (hours would be required).
You could then either have the second form respond with 403 Forbidden if the submitter is not permitted to submit hours. Or alternatively, you could filter the forms included in the GET, so that only the forms the user is permitted to submit are shown.
Update
For example and GET on /Users/1234/Timesheets/24 might currently produce
<Timesheet>
<TimesheetID>24</TimesheetID>
<Status>Submitted</Status>
<Hours>40</Hours>
</Timesheet>
To apply the HATEOAS constraint, we need to add the hypermedia controls. We'll ignore the URLs for the moment, because they are implementation details. This might give us something like
<Timesheet>
<TimesheetID>24</TimesheetID>
<Status>Submitted</Status>
<Hours>40</Hours>
<link rel="self" href="{{selfUrl}}"/>
<form id="approve" action="{{approveUrl}}" method="PUT">
<Status cardinality="required">
<option value="Approve"/>
</Status>
</form>
<form id="reject" action="{{rejectUrl}}" method="PUT">
<Status cardinality="required">
<option value="Reject"/>
</Status>
</form>
<form id="update" action="{{updateUrl}}" method="PUT">
<Status cardinality="required">
<option value="Approve"/>
<option value="Reject"/>
</Status>
<Hours type="decimal" cardinality="required"/>
</form>
... there might be other forms too, like ...
<form id="cancel" action="{{cancelUrl}}" method="DELETE"/>
</Timesheet>
What the forms do (and how to recognise a form) are what get's documented in the media type. For instance:
The cancel form on a Timesheet resource will cancel the timesheet, updating it's status to "Cancelled". Once a Timesheet has been cancelled, it will no longer be possible to update approve or reject the timesheet.
Also in the media type you would document the properties of the resources. e.g.,
The Timesheet resource has a the following properties:
TimesheetID A unique identifier for the timesheet
Status The current status of the timesheet. Status may include
Submitted The timesheet has been submitted, but not approved
Approved The timesheet has been approved
Rejected The timesheet has been rejected
Cancelled The timesheet has been cancelled
Hours The number of hours (decimal) recorded for the timesheet
While this could be specified by a schema, this should be avoided as doing so can may it very difficult to extent the resources later on. For instance, you might decide to add a "WeekEnding" date property. Existing callers should not care about the new property, which is fine if they are just plucking out the data they are interested in. However, if you've specified the schema without thoughts of extension, then adding properties can cause validation errors in the callers when you add properties.
Now, in terms of who can do what we have a couple of options. One option is to just include all the controls and respond with 403 for any requests made that the caller is not authorised to invoke. Another option is to filter the controls, so they can only see the ones they can invoke. e.g. for the manager that can approve/reject, they might get the following response
<Timesheet>
<TimesheetID>24</TimesheetID>
<Status>Submitted</Status>
<Hours>40</Hours>
<link rel="self" href="{{selfUrl}}"/>
<form id="approve" action="{{approveUrl}}" method="PUT">
<Status cardinality="required">
<option value="Approve"/>
</Status>
</form>
<form id="reject" action="{{rejectUrl}}" method="PUT">
<Status cardinality="required">
<option value="Reject"/>
</Status>
</form>
</Timesheet>
Whereas a manager that can update the hours might get
<Timesheet>
<TimesheetID>24</TimesheetID>
<Status>Submitted</Status>
<Hours>40</Hours>
<link rel="self" href="{{selfUrl}}"/>
<form id="approve" action="{{approveUrl}}" method="PUT">
<Status cardinality="required">
<option value="Approve"/>
</Status>
</form>
<form id="reject" action="{{rejectUrl}}" method="PUT">
<Status cardinality="required">
<option value="Reject"/>
</Status>
</form>
<form id="update" action="{{updateUrl}}" method="PUT">
<Status cardinality="required">
<option value="Approve"/>
<option value="Reject"/>
</Status>
<Hours type="decimal" cardinality="required"/>
</form>
</Timesheet>
Alternatively, you can include all the forms for all the users, but add an indicator that they are not authorised to invoke it. e.g. for the manager that can't update hours:
<Timesheet>
<TimesheetID>24</TimesheetID>
<Status>Submitted</Status>
<Hours>40</Hours>
<link rel="self" href="{{selfUrl}}"/>
<form id="approve" action="{{approveUrl}}" method="PUT">
<Status cardinality="required">
<option value="Approve"/>
</Status>
</form>
<form id="reject" action="{{rejectUrl}}" method="PUT">
<Status cardinality="required">
<option value="Reject"/>
</Status>
</form>
<form id="update" action="{{updateUrl}}" method="PUT" authorised="false">
<Status cardinality="required">
<option value="Approve"/>
<option value="Reject"/>
</Status>
<Hours type="decimal" cardinality="required"/>
</form>
</Timesheet>
I prefer this later approach as you don't end up with support calls for your API, with developers complaining that a particular form doesn't exist. Either way (included or filtered), if the caller invokes a form they are not permitted to, you would still respond with 403.
A bit off topic, but for completeness, HATEOAS really comes to the fore because it communicates the valid set of hypermedia controls based on the current state of the resource. e.g., when a Timesheet has been cancelled, it's not longer valid to approve/reject or update it, so a GET on a cancelled Timesheet might return
<Timesheet>
<TimesheetID>24</TimesheetID>
<Status>Cancelled</Status>
<Hours>40</Hours>
<link rel="self" href="{{selfUrl}}"/>
</Timesheet>
This clearly communicates to the caller that no further actions are permitted on this particular Timesheet.
The other thing you'll have noticed is that we haven't actually specified any or the URLs yet. They might all be all the same (e.g. /Users/{UserID}/Timesheets/{TimesheetID}) or they might be different (e.g. selfUrl=/Users/{UserID}/Timesheets/{TimesheetID}, updateURL=/Users/{UserID}/Timesheets/{TimesheetID}/update, etc).
Ultimately the caller should not care as it will use whatever is in the form/link. This provides you with great flexibility as you can change these to suit your implementation needs. For instance, if you are using Command Query Responsibility Segregation (CQRS), it might make sense to send GET requests to //readonly.myserver.com/Users/{UserID}/Timesheets/{TimesheetID} and POST, PUT and DELETE requests to //readwrite.myserver.com/Users/{UserID}/Timesheets/{TimesheetID}.
Yes, go with 403 Forbidden. I matches the scenario you describe. RFC 7231 says:
The 403 (Forbidden) status code indicates that the server understood
the request but refuses to authorize it. A server that wishes to
make public why the request has been forbidden can describe that
reason in the response payload (if any).
As an alternative, the server could perform those actions the current user is allowed to and ignore everything else. If this is a good idea depends on your scenarion. I woul prefer to deny the whole request and return 403 Forbidden.
1) You use POST to create, so you can use PUT on the same endpoint to update the data (providing the new data in the content of the request). To limit/log who updates the data you can pass their user/manager ID as a query parameter, or inside the body
2) 403 Forbidden sound better so that it's more clear for the user(manager) what has happened instead of letting him think the data was updated correctly but it was only partially updated actually
I'm creating a custom (1.6) component wherein users can book a camp site. Users will be required to log in if they want to use funds/credits that they already have stored. Only certain groups can use these funds/credits.
I have created an access.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<access component="com_propbooker">
<section name="booking">
<action name="booking.create" title="Book Site" description="Allows users of this group to book sites." />
</section>
</access>
and my config.xml file:
<config>
<fieldset name="API Configuration" label="API Configuration">
<field name="google_api_key" label="Google API Key" type="text" size="50" default="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
</fieldset>
<fieldset name="Booking Permissions" label="Booking Permissions" description="Set Groups that can book sites">
<field name="booking_permission" label="Booking Permission" type="rules" class="inputbox" validate="rules" filter="rules" component="com_propbooker" section="booking" />
</fieldset>
</config>
It all shows up fine when I click the options button, but no changes are ever saved. It always flips back to "Inherited" when i click the "Save" button.
Thanks in advance for any insight.
Try using permissions as the fieldset name and rules as the fieldname in your config.xml.
Like this:
<fieldset name="permissions"
label="JCONFIG_PERMISSIONS_LABEL"
description="JCONFIG_PERMISSIONS_DESC" >
<field name="rules"
type="rules"
label="JCONFIG_PERMISSIONS_LABEL"
class="inputbox"
validate="rules"
filter="rules"
component="com_propbooker"
section="booking"
/>
</fieldset>
I would also consider using the section name component as it is the default naming. But your needs may be different.
I need to filter my list based on selected dropdown value. I've created a DVWP for that and converted it into a dropdown. Now I'm following this post to fire events when dropdown value is selected but I just do not know where to change the code. I'm filtering the list based on years. I have an year list which stores year values and filters it accordingly when the dropdown is selected. I've modified it like this:
<xsl:otherwise>
<select name="ID" size="1" onchange="document.location.href='pageName.aspx?year=' + this.options[selectedIndex.value])">
<option selected="true" value="0">Choose One...</option>
<xsl:call-template name="dvt_1.body">
<xsl:with-param name="Rows" select="$Rows" />
</xsl:call-template>
</select>
I've no idea of xslt and this isn't firing any event when i change the dropdown value. Please help me with this.
Update: The HTML I get:
<td valign="top">
<div WebPartID="9e0da2fd-21ea-417f-863d-6551d16e72a1" HasPers="false" id="WebPartWPQ3" width="100%" class="noindex" allowDelete="false" style="" >
<select name="ID" size="1" onchange="document.location.href='http://pageName.aspx?year=' + this.options[selectedIndex].value" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
<option selected="" value="0">Choose One...</option>
<option>2009</option>
<option>2010</option>
<option>2011</option>
<option>2012</option>
<option>2013</option>
</select>
</div>
</td>
I'm somewhat doubtful that this is an XSLT issue. The script for the onchange handler in that tutorial seems to boil down to:
document.location.href='pageName.aspx?year=' + this.options[selectedIndex].value
Note that .value is outside the []. Could you give that a try? Is your browser reporting any JavaScript errors when you change the dropdown selection?
Now, according to this tutorial, you can filter a list by specifying query parameters named FilterField1, FilterValue1, etc, so could you try something like this:
document.location.href='pageName.aspx?FilterField1=ColumnName&FilterValue1='
+ this.options[selectedIndex].value + '&year=' + this.options[selectedIndex].value
Here you would replace "ColumnName" with the actual name of the column, as indicated in that tutorial. Could you try something like that?
I've defined a content type 'related links' and set Inherits="False" and added line to remove out-of-the-box 'title' field as I don't want it showing in the view or new/edit/display forms, see (OPTION 1) in CAML below.
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<!-- ===== Fields ===== -->
<!-- Link Category -->
<Field DisplayName="Link Category"
Name="LinkCategory"
ID="{654EAC00-342B-4176-9D91-613AD724F684}"
Group="Custom"
Overwrite="True"
Type="Lookup"
ShowField="Title"
List="Lists/LinkCategoryList"
WebId="~sitecollection" />
<!-- ===== Content Type ===== -->
<!--
Related Links
- Parent ContentType: Item (0x01)
-->
<ContentType Name="Related Links"
ID="0x0100c11a1db14e564574bc49a2aa9bf325d3"
Group="Custom"
Description=""
Inherits="False"
Version="0">
<FieldRefs>
<!-- Title (OPTION 1) -->
<RemoveFieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" />
<!-- (OPTION 2)
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
Hidden="TRUE" Required="FALSE" DisplayName="_hidden" />
-->
<!-- Link Category -->
<FieldRef DisplayName="Link Category"
Name="LinkCategory"
ID="{654EAC00-342B-4176-9D91-613AD724F684}"
Required="True" />
</FieldRefs>
</ContentType>
</Elements>
This does remove the 'title' field from the content type but when I try to associate the content type with a list it does not display the 'LinkCategory' field in the view or new/edit/display forms. Why is it so?
<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint"
Title="Related Links"
FolderCreation="FALSE"
Direction="$Resources:Direction;"
Url="Lists/RelatedLinksListDefinition"
BaseType="0"
EnableContentTypes="True"
xmlns="http://schemas.microsoft.com/sharepoint/">
<MetaData>
<ContentTypes>
<!-- Related Links -->
<ContentTypeRef ID="0x0100c11a1db14e564574bc49a2aa9bf325d3" />
</ContentTypes>
<Fields>
</Fields>
<Views>
<View ...etc...>
<ViewFields>
<FieldRef Name="LinkCategory"></FieldRef>
</ViewFields>
<Query>
<OrderBy>
<FieldRef Name="ID"></FieldRef>
</OrderBy>
</Query>
</View>
</Views>
<Forms>
<Form Type="DisplayForm" Url="DispForm.aspx"
SetupPath="pages\form.aspx" WebPartZoneID="Main" />
<Form Type="EditForm" Url="EditForm.aspx"
SetupPath="pages\form.aspx" WebPartZoneID="Main" />
<Form Type="NewForm" Url="NewForm.aspx"
SetupPath="pages\form.aspx" WebPartZoneID="Main" />
</Forms>
</MetaData>
</List>
As a work around I've set Inherits="True" on the content type and used (OPTION 2) in content type CAML and that hides the 'title' field, but would really like to understand what's going on here and what's the best approach to take. Thanks in advance!
PS: This post has similar question: SharePoint 2010: RemoveFieldRef and Inherits="TRUE"
PSS: When I browse via SP Manager 2010 after deploying using OPTION 1, I get the following:
'Link Category' Field created correctly
'Related Links' Content Type created correctly with 'Link Category' field
'Related Links' list created with 'Related Links' Content Type associated
However 'Related Links' list has no reference to 'Link Category' Field.
Ok so was on my way up the garden path...
The issue why 'Link Category' Field was not being created on the 'Related Links' list wasn't related to setting Inherits="False", it was because I had not defined it in the list schema even though I'd defined it in the content type. As mentioned here:
http://msdn.microsoft.com/en-us/library/aa543576.aspx
When SharePoint Foundation creates a list instance, it includes only
those columns that are declared in the base type schema of the list or
in the list schema. If you reference a site content type in the list
schema, and that content type references site columns that are not
included in the base type schema of the list or in the list schema,
those columns are not included. You must declare those columns in the
list schema for SharePoint Foundation to include them on the list.
And here:
http://stefan-stanev-sharepoint-blog.blogspot.com/2010/03/contenttypebinding-vs-contenttyperef.html
One ugly thing about it is that you specify a site content type to be
attached to the list based on that list definition but the framework
doesn’t provision the fields in the content type if they are missing
in the list – so you need to add manually all content type’s fields in
the Fields element of the list schema file. This is actually what I
called the fields’ redefinition issue...
So duplicated Field element below from the content type definition to list schema:
<Fields>
<Field DisplayName="Link Category"
Name="LinkCategory"
ID="{654EAC00-342B-4176-9D91-613AD724F684}"
Group="Custom"
Overwrite="True"
Type="Lookup"
ShowField="Title"
List="Lists/LinkCategoryList"
WedId="~sitecollection" />
</Fields>
I can confirm that using Inherits="False" & <RemoveFieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" /> does remove the title field.
Here's another good link about Inherits="False" for those who stumble upon this post.
https://sharepoint.stackexchange.com/questions/2995/mysteries-of-the-contenttype-inherits-attribute