Dynamics CRM Script Help - Date Field Comparison to Current Date + Number Field - dynamics-crm-2011

Order form has two fields, Ship Date (datefield) and Lead Time (number field in days).
When a ship date is entered, it should be greater than the current date + the lead time. alert user if not, and do not allow save of record.
There is one exception to the rule though: If the approved for rush field and approved by field is filled out the alert is not necessary and record can be saved.
++ It would be a plus if this could actually not account for weekend days. But not mandatory
function checkLeadTime
{
var shipDate = Xrm.Page.getAttribute("requestdeliveryby").getValue();
var leadTime = Xrm.Page.getAttribute("orbus_leadtime").getValue();
var leadTimeDate = Xrm.Page.getAttribute("orbus_leadtimedate").getValue():
if(leadTime != NULL)
{
var approvedRushProduction = xrm.getAttribute("orbus_projectapprovedrush").getValue();
var approvedBy = Xrm.Page.getAttribute("orbus_approvedbyid").getValue();
var currentTime = new Date();
var newDate = currentTime.setDays(currentTime.getDays + leadTime);
leadTimeDate.setValue(newDate);
if(approvedRushProduction == 0 && approvedBy == NULL)
{
if ( newDate < shipDate)
{
alert("Sorry, Ship Date is less than lead time!");
}
else
{
alert("Current Time = " + newDate);
}
}
}
}

You can attach your function to the form onSave event.
if ( newDate < shipDate ) {
alert("Sorry, Ship Date is less than lead time!");
Xrm.Page.context.getEventArgs().preventDefault();
} else {
alert("Current Time = " + newDate);
}
Use Xrm.Page.context.getEventArgs().preventDefault() to stop the save event.

To stop saving and show error message you can use:
Xrm.Page.getControl(fieldName).setNotification(message);
http://garethtuckercrm.com/2013/10/17/crm-2013-new-features-javascript-notifications/

Related

Returning wrong DateTime in search results by using KeywordQuery

I have a big problem. I am using KeywordQuery in server side code to return items from several lists with same contenttypeid. I have in those list some datetime columns. When i return the value from the keywordwquery search i get
3/2/2017 11:00:00 PM
But i saved 3/3/2017 as date in the list item! What is wrong here? Why am i receiving always the date - 1 hour from the search database and how can i correct this in my server side code?
This is my code:
SearchServiceApplicationProxy proxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.GetProxy(SPServiceContext.GetContext(querySite));
using (KeywordQuery keywordQuery = new KeywordQuery(proxy))
{
try
{
keywordQuery.ResultsProvider = SearchProvider.Default;
keywordQuery.StartRow = 0;
keywordQuery.RowLimit = 9999;
keywordQuery.EnableStemming = false;
keywordQuery.TrimDuplicates = false;
keywordQuery.AuthenticationType = QueryAuthenticationType.PluggableAuthenticatedQuery;
keywordQuery.KeywordInclusion = KeywordInclusion.AllKeywords;
keywordQuery.QueryText = "contentclass:\"STS_ListItem_Task\" NOT ContentTypeId:\"0x010800C140B62AF5566C4CBFC76C53B8D4DA94\"";
keywordQuery.SelectProperties.Add("Author");
keywordQuery.SelectProperties.Add("AssignedTo");
keywordQuery.SelectProperties.Add("DueDate");
keywordQuery.SelectProperties.Add("StartDate");
keywordQuery.SelectProperties.Add("path");
keywordQuery.SelectProperties.Add("title");
SearchExecutor executor = new SearchExecutor();
ResultTableCollection resultTableCollection = executor.ExecuteQuery(keywordQuery);
var resultTables = resultTableCollection.Filter("TableType", KnownTableTypes.RelevantResults);
ResultTable resultTable = resultTableCollection.FirstOrDefault();
if (resultTable.Table.Rows.Count > 0)
{
...
}
}
catch (Exception ex)
{
}
}
I believe it's the time zone shift that comes into play here. Check which time is local and which is UTC.

Auto populate item amount in custom field

How to auto-populate item amount in custom field on cash sales.
I am new to client script and here is the snippet which i have tried but it doesn't function as expected.Please suggest.
function custItemAmount(type)
{
if(type == 'edit')
{
var record = nlapiLoadRecord(nlapiGetRecordType(), nlapiGetRecordId());
var itemCount = record.getLineItemCount('item');
for(i=1; i<=itemCount; i++)
{
//fetch amount of each item
var item_amount=record.getLineItemValue('item', 'amount', i);
if (item_amount != null && item_amount != '') {
record.setLineItemValue('item', 'custbody_itemamount', i, item_amount);
//set total amount to custom item amount field
}
}
var id = nlapiSubmitRecord(record, true);
}
}
It looks like you're trying to set the wrong field for the line item. Is custbody_itemamount really the field you want? Seems like a body field to me, not a line item field. I'd expect it be called custcol_lineitemamount
Try the following instead, though check to make sure the field names are correct, since I've made some assumptions.
{
if(type == 'edit')
{
var record = nlapiLoadRecord(nlapiGetRecordType(), nlapiGetRecordId());
var itemCount = record.getLineItemCount('item');
for(i=1;i<=itemCount;i++)
{
//fetch amount of each item
var item_amount=record.getLineItemValue('item', 'amount', i);
if (item_amount != null && item_amount != '') {
record.setLineItemValue('item', 'custcol_itemamount', i, item_amount);
//set total amount to custom item amount field
}
}
var id = nlapiSubmitRecord(record, true);
}
When do you want to see the custom column populated? Is it after the User has added the line? If yes, then you script is incorrect. The script you shared looks to be a User Event script. These types of script only execute when you either load or save a record.
Resolved with below simple script..Thanks for your help.
==
function custItemAmount(type)
{
if(type == 'item'){
var item_amount=parseFloat(nlapiGetLineItemValue('item','amount'));
//nlapiSetFieldValue('custcol_item_amount',item_amount);
nlapiSetCurrentLineItemValue('item','custcol_item_amount',nlapiFormatCurrency(item_amount));
}
return true;
}

Sub Grid Total In Crm

I have a primary Entity (Self-Insurance) and a secondary entity (Compensation). They have a 1:N relationship. So in my main form of Self Insurance I have a sub-grid with the name 'Worker_Compensation' where i am adding up some payroll values.
I have 2 questions. . .
1: The thing I want is that when I add some values in the sub-grid. I need to show a sum of all payrolls in the text below of my main form named as 'TOTAL'.
2: Where should i call this java script(On which event) Onload or Onsave of form ? or else where because I can seems to locate the events on Subgrid.
I am using a java script for this purpose.
enter code here
function setupGridRefresh() {
var targetgrid = document.getElementById("Worker_Compensation");
// If already loaded
if (targetgrid.readyState == 'complete') {
targetgrid.attachEvent("onrefresh", subGridOnload);
}
else {
targetgrid.onreadystatechange = function applyRefreshEvent() {
var targetgrid = document.getElementById("Worker_Compensation");
if (targetgrid.readyState == 'complete') {
targetgrid.attachEvent("onrefresh", subGridOnload);
}
}
}
subGridOnload();
}
function subGridOnload() {
//debugger;
var grid = Xrm.Page.ui.controls.get('Worker_Compensation')._control;
var sum = 0.00;
if (grid.get_innerControl() == null) {
setTimeout(subGridOnload, 1000);
return;
}
else if (grid.get_innerControl()._element.innerText.search("Loading") != -1) {
setTimeout(subGridOnload, 1000);
return;
}
var ids = grid.get_innerControl().get_allRecordIds();
var cellValue;
for (i = 0; i < ids.length; i++) {
if (grid.get_innerControl().getCellValue('new_estannualpayroll', ids[i]) != "") {
cellValue = grid.get_innerControl().getCellValue('new_estannualpayroll', ids[i]);
cellValue = cellValue.substring(2);
cellValue = parseFloat(cellValue);
sum = sum + cellValue;
}
}
var currentSum = Xrm.Page.getAttribute('new_payrolltotal').getValue();
if (sum > 0 || (currentSum != sum && currentSum != null)) {
Xrm.Page.getAttribute('new_payrolltotal').setValue(sum);
}
}
This piece of code is not working. after i add values in the grid my textbox remains empty!
Thanks in advance
If you are upgrading to Microsoft CRM 2015 soon or are already on Microsoft CRM 2015, you can do this without any JavaScript by simply creating a new calculated rollup field and placing that underneath the sub grid, or wherever you wish to place it on the form. Note that this field is calculated ever 12 hours, but if you wish to, it could be calculated on form load via JavaScript. You can see details about that at https://msdn.microsoft.com/en-us/library/dn817863.aspx -"Calculated and Rollup Attributes". The TechNet document, "Define rollup fields" at https://technet.microsoft.com/library/dn832162.aspx has some good examples, scenarios, and discussion about the limitations of the rollup fields.
You can do it with subgrid's onRefresh. This is also unsupportted way but it works. You must add this functions to your javascript
function AddEventToGridRefresh(gridName, functionToCall) {
// retrieve the subgrid
var grid = document.getElementById(gridName);
// if the subgrid still not available we try again after 1 second
if (grid == null) {
setTimeout(function () {AddEventToGridRefresh(gridName, functionToCall);}, 1000);
return;
}
// add the function to the onRefresh event
grid.control.add_onRefresh(functionToCall);
}
// function used in this example
function AdviseUser() {
alert("Sub-Grid refreshed");
}
For more information, here is the link

How to validate & compare hours part of sharepoint datetime control?

I have two sharepoint datetime controls where timeOnly=true. I need to validate as required field & validate as one controls Hours value must be Greater than & Equal to other one. I want to do it in Client side.
Note: Using timeOnly="true" means need to validate Hours & minutes Only.
you will find several good solutions by searching Google for the phrase - sharepoint datetimecontrol validation - without using quotes
Created an asp.net custom validator to compare hours & minutes part of two datetime controls.
And called javascript function from ClientValidationFunction property of asp.net custom validator.
Function is here:
function ValidateHour&Minute(sender, args){
var startDateHour = document.getElementById("<%=DateTimeControlStartDate.Controls[1].ClientID %>").value;// gets value from hours dropdown list for 1st datetime control
var startDateMinute = document.getElementById("<%=DateTimeControlStartDate.Controls[2].ClientID %>").value;// gets value from minutes dropdown list for 1st datetime control
var timeStart = new Date();
var timeEnd = new Date();
var strStartHour;
var hourType;
hourType = startDateHour.split(' ');
if (hourType[1] == "AM") {
startDateHour=startDateHour.split(' ');
strStartHour = startDateHour[0];
}
else {
startDateHour=startDateHour.split(' ');
strStartHour = startDateHour[0];
strStartHour = parseInt(strStartHour) + 12;
}
timeStart.setHours(strStartHour, startDateMinute, 0, 0);
var strEndHour;
var endDateHour = document.getElementById("<%=DateTimeControlEndDate.Controls[1].ClientID %>").value;// gets value from hours dropdown list for 2nd datetime control
var endDateMinute = document.getElementById("<%=DateTimeControlEndDate.Controls[2].ClientID %>").value;// gets value from minutes dropdown list for 2nd datetime control
hourType = endDateHour.split(' ');
if (hourType[1] == "AM") {
endDateHour=endDateHour.split(' ');
strEndHour = endDateHour[0];
}
else {
endDateHour= endDateHour.split(' ');
strEndHour = endDateHour[0];
strEndHour = parseInt(strEndHour) + 12;
}
timeEnd.setHours(strEndHour, endDateMinute, 0, 0);
if (timeStart < timeEnd) {
args.IsValid = true;
}
else {
args.IsValid = false;
}
}

Domain object string list - Adding on the fly

Maybe this is an issue with persistance and the domain object. So I have a list of manual notes that can be added to a person. My person class looks similar to this (I've wrapped the object in transients to ignore persistence):
class Person {
...
List<String> notes = new ArrayList<String>()
...
}
When I update a person with a note (textfield on view will allow note to be added), I want to do something simple like adding the new note to the array list tied to the person:
class PersonController {
...
def update() {
def contactInstance = Contact.get(params.id)
if (!contactInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'contact.label', default: 'Contact'), params.id])
redirect(action: "list")
return
}
if (params.version) {
def version = params.version.toLong()
if (contactInstance.version > version) {
contactInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
[message(code: 'contact.label', default: 'Contact')] as Object[],
"Another user has updated this Contact while you were editing")
render(view: "edit", model: [contactInstance: contactInstance])
return
}
}
contactInstance.properties = params
/**
* Check for inactive - Then flag with user and date tag
*/
if(params.isActive == null) {
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm");
Date date = new Date();
contactInstance.properties.isActiveNote = "Made inactive by " + session.user + " on " + dateFormat.format(date) + "."
}
/**
* Date stamp of the note itself
*/
if(params.notes.equals("")) {}
else {
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm");
Date date = new Date();
//contactInstance.properties.notes = contactInstance.properties.notes + " " + params.notes + " - (" + dateFormat.format(date) + " " + session.user + ");"
contactInstance.allThese.add(contactInstance.properties.notes)
println(contactInstance.allThese)
}
if (!contactInstance.save(flush: true)) {
render(view: "edit", model: [contactInstance: contactInstance])
return
}
flash.message = message(code: 'default.updated.message', args: [message(code: 'contact.label', default: 'Contact'), contactInstance.id])
redirect(action: "show", id: contactInstance.id)
}
...
}
The call to update from my gsp:
<g:actionSubmit class="save" action="update" value="${message(code:'default.button.update.label', default: 'Update')}" />
But it just seems to store the array with a single note. Is there a persistance issue with Grails domain objects and collections? It could very well be a simple issue on my end!
Thanks for all the help.
If your view includes multiple <input> fields or <textarea>s with the same name ("notes", to match the field name in your Domain class), Grails will automatically bind the values to your notes array.
You might also look into the new params.list() method that would allow you to iterate through request parameters and then add them individually to your array.

Resources