Set entity record to Active - dynamics-crm-2011

there are plenty of examples out there of how to set a record to Inactive, but how do you set it to Active?
I'm guessing you just use different values for the State and Status option sets, but what are they?
Thanks!

Example for activating Account entity:
Account account = new Account();
// ...
SetStateRequest req = new SetStateRequest();
req.EntityMoniker = new EntityReference(Account.EntityLogicalName, account.Id);
req.State = new OptionSetValue(0);
req.Status = new OptionSetValue(1);
service.Execute(req);
For status and state codes check Account Entity OptionSet Attribute Metadata on MSDN.

I found the answer.
Just replace the state and status values with the correct values from here:
http://msdn.microsoft.com/en-us/library/bb890228.aspx
This code uses a new thread for the process which isn't always necessary, but you get the idea.
ThreadPool.QueueUserWorkItem(new WaitCallback(SetState), (object)new SetStateThreadRequest()
{
proxy = proxy,
Request = new SetStateRequest()
{
EntityMoniker = new EntityReference(Entity, entity.Id),
State = new OptionSetValue(0), // <== 0 = Active, 1 = Inactive
Status = new OptionSetValue(1) // <== 1 = Active, 2 = Inactive (some use -1)
}
});

Related

Field not automatically included in poline

I want to create a purchase order, the fields are not calculated : line.SiteID ; line.LineType ; line.ExpenseAcctID ; line.POAccrualAcctID
while in manual entry everything works correctly
order.OrderType = "RO";
order.Status="H";
order.BranchID=une_commandevente.BranchID;
order = poOrder.CurrentDocument.Insert(order);
order.VendorID = cmdfrs.Usrfournisseur;
order.OrderDate = DateTime.Today;
order.OrderDesc = "XXX";
order.VendorRefNbr="XXX";
poOrder.CurrentDocument.Update(order);
foreach (SOLine une_lignevente in PXSelectReadonly<SOLine,Where<SOLine.orderNbr, Equal<Required<SOLine.orderNbr>>,And<SOLine.orderType,Equal<Required<SOLine.orderType>>>>>.Select(this.Base,une_commandevente.OrderNbr,une_commandevente.OrderType))
{
var une_ligneventeext = une_lignevente.GetExtension<SOLineExt>();
if (une_ligneventeext.Usrfournisseur==cmdfrs.Usrfournisseur)
{
var line = poOrder.Transactions.Insert();
line.OrderType = "RO";
line.InventoryID = une_lignevente.InventoryID;
line.SiteID=3;
line.LineType = "NS";
line.ExpenseAcctID=39367;
line.POAccrualAcctID=39367;
line.OrderQty= une_lignevente.Qty;
line.UOM=une_lignevente.UOM;
poOrder.CurrentDocument.Update(order);
poOrder.Transactions.Update(line);
}
}
poOrder.CurrentDocument.Update(order);
poOrder.Actions.PressSave();
Thanks
Xav
There are a few adjustments needed in your logic:
For the header's cache, use the main view (Document) instead of CurrentDocument
For the header DAC, assign the Key values, then insert the row in the cache and then assign the rest of the values
For the iteration, there is no need to update the header's cache
For the grid DAC, there is no need to explicitly indicate the key values as those are defaulted from the header based on [PXDBDefault] attribute
I'd also recommend to update the cache after there is a known field that triggers events. For instance, entering the Vendor, defaults the vendor location.
Try this modified (and simplified) version:
order.OrderType = "RO";
order = poOrder.Document.Insert(order);
order.OrderDate = DateTime.Today;
order.VendorID = cmdfrs.Usrfournisseur;
poOrder.Document.Update(order);
order.BranchID=une_commandevente.BranchID;
order.OrderDesc = "XXX";
order.VendorRefNbr="XXX";
poOrder.Document.Update(order);
foreach (SOLine une_lignevente in PXSelectReadonly<SOLine,Where<SOLine.orderNbr, Equal<Required<SOLine.orderNbr>>,And<SOLine.orderType,Equal<Required<SOLine.orderType>>>>>.Select(this.Base,une_commandevente.OrderNbr,une_commandevente.OrderType))
{
var une_ligneventeext = une_lignevente.GetExtension<SOLineExt>();
if (une_ligneventeext.Usrfournisseur==cmdfrs.Usrfournisseur)
{
POLine line = new POLine();
line = poOrder.Transactions.Insert(line);
line.InventoryID = une_lignevente.InventoryID;
poOrder.Transactions.Update(line);
line.SiteID=3;
poOrder.Transactions.Update(line);
line.ExpenseAcctID=39367;
line.POAccrualAcctID=39367;
poOrder.Transactions.Update(line);
line.OrderQty= une_lignevente.Qty;
line.UOM=une_lignevente.UOM;
poOrder.Transactions.Update(line);
}
}
poOrder.Actions.PressSave();
Also, I'd recommend testing this in a fresh environment w/o customizations. Create a test button that instantiates the graph and creates a PO with a couple of lines.

Netsuite Userevent Script

I have a userevent script to change the Field in Contract record from PO record. The Script is running fine. But whenever I edit a contract record and try to submit it : It throws the error "Another user has updated this record since you began editing it. Please close the record and open it again to make your changes".
May I know the reason behind this ?
/*---------------------------------------------------------------------------------------------------------------
Description : Whenever the PO vendor is changed(due to Split vendor) that should replace the same in Contract page record automatically.
Script type : User Event Script
Script id : customscript452
Version : 1.0
Applied to : Contract
----------------------------------------------------------------------------------------------------------------*/
function srchfield()
{
var stRecordid = nlapiGetRecordId(); //returns the contract id
if(stRecordid== undefined || stRecordid== null || stRecordid==' ')
{
}
else
{
var stRecordtype = nlapiGetRecordType(); //returns the contract record type = jobs
var stRecord = nlapiLoadRecord(nlapiGetRecordType(), stRecordid);
nlapiLogExecution('debug','Load Object',stRecord);
var stContractID = stRecord.getFieldValue('entityid'); //returns the value of the field contractid whose fieldid is = entityid
nlapiLogExecution('debug','stContractID',stContractID);
var stCompanyName = stRecord.getFieldValue('companyname'); //returns the value of the field company name whose fieldid is = companyname
nlapiLogExecution('debug','stCompanyName',stCompanyName);
var stConcatenate = stContractID+" : "+stCompanyName; //Concatenate the two Fields to get the result which needs to be found in PO
var arrFilters = new Array(); // This is Array Filters all the Purchase Order Record Search
arrFilters.push(new nlobjSearchFilter('type', null, 'anyof',
[
'PurchOrd'
]));
arrFilters.push(new nlobjSearchFilter('mainline', null, 'is', 'T')); //This is to exclude line level results
arrFilters.push(new nlobjSearchFilter('custbodycontract', null, 'is', stRecordid)); //This is Filters in Contracts Search
var arrColumns = new Array();
arrColumns.push(new nlobjSearchColumn('entity')); //This is Search Column Field in Records
var arrSearchresults = nlapiSearchRecord('purchaseorder', null, arrFilters, arrColumns); //This is Filters in Search Result Purchase Order
if(arrSearchresults== undefined || arrSearchresults== null || arrSearchresults==' ')
{
}
else
{
var length = arrSearchresults.length;
}
if(length== undefined || length== null || length==' ')
{
}
else
{
for (var i = 0; arrSearchresults != null && i < arrSearchresults.length; i++)
{
var objResult = arrSearchresults[i];
var stRecId = objResult.getId();
var stRecType = objResult.getRecordType();
var stCntrctName = objResult.getValue('entity'); //This is Value are Get Purchase Order Records and Field for Vendor = entity
}
}
//var record = nlapiLoadRecord(nlapiGetRecordType(), stRecordid, stCntrctName);
if (stCntrctName =='custentityranking_vendor_name')
{
}
else
{
var stChangeName = stRecord.setFieldValue('custentityranking_vendor_name', stCntrctName); //This is Value are the Set in Main Vendor Field = custentityranking_vendor_name
nlapiSubmitRecord(stRecord, null, null); // Submit the Field Value in Record Type
}
}
}
The User Event script executes as the Contract record is being saved to the database. At the same time, you are loading a second copy of the record from the database and trying to submit the copy as well. This is causing the error you're seeing.
You fix this by just using nlapiSetFieldValue to set the appropriate field on the Contract.
I might also recommend getting more familiar with JavaScript by going through the JavaScript Guide over at MDN. In particular, take a look at the Boolean description so that you know how JavaScript evaluates Boolean expressions. This will help you greatly reduce the amount of code you've written here, as many of your conditionals are unnecessary.
What userevent do you have? It is happening depending on what type of user event and API you are using. Looking at your code, you are trying to load contract record that is already updated at the database. So you might consider below to address your issue. Hope, it helps.
If it is a before submit, you don't need to load the record where the script is deployed.
Just use nlapiGet* and nlapiSet* to get and set values. You also don't need to use nlapiSubmitRecord to reflect the change. With before submit, it executes before the record is being saved to the database. So your changes will still be reflected.
Then if it is after submit, it will be executed after the record has been saved to the database, Thus you might use the following API depending on your needs. Actually, this is the best practice to make sure the solution .
nlapiGetNewRecord - only use this if the script only needs to retrieve info from header and sublists. And nothing to set.
nlapiLookupField - use this if the script only needs to get value/s at the header and nothing from the line.
nlapiSubmitField - the script don't need to load and submit record if the changes only on header. Just use this API.
nlapiLoadRecord and nlapiSubmitRecord- use the former if the script will have changes at the line and then use the latter api to commit it on the database.
Being a user event script code, The code you showed is very not good considering performance.
Here is the sample you can merge
var stRecordid = nlapiGetRecordId(); //returns the contract id
// Every record has an internal id associated with it. No need to add condition explicitly to check if its null
var stRecordtype = nlapiGetRecordType();
var fields = ['entityid','companyname'];
var columns = nlapiLookupField(stRecordtype, stRecordid, fields);
var stContractID = columns.entityid;
var stCompanyName = columns.companyname;
nlapiLogExecution('debug','stContractID/stCompanyName',stContractID+'/'+stCompanyName);
var stConcatenate = stContractID+" : "+stCompanyName; //Concatenate the two Fields to get the result which needs to be found in PO
//
//your code of search
//you can improve that code also by using nlapilook up
nlapiSubmitField(stRecordtype, stRecordid, 'custentityranking_vendor_name', 'name to be updated');

Netsuite Past Due Reminder using SuiteScript

The script is complete! Thanks for all those who replied :)
/*
* Author: Laura Micek
* Date: 5-13-15
* Purpose: This script creates a saved search in order to pull the information needed to send out an email to alert customers that
* their account is past due. The saved searched makes sure that the customer is 11 days or more past due, checks to see if they are
* exempt from past due reminders, and that their account balance is greater than 1. Once the saved search runs, it will loop thru the
* customers that meet these requirements and it will use the days past due to determine if an email needs to be sent. An email will
* only be sent if the days past due are equal to 11 or if the days past due minus 11, modded by 8 equals 0 which means that it has
* been 8 days since the last notification.
*/
function email_late_customers(type) {
//variables
var send_from = 22730; // Internal ID of NS User
//setup filters and result columns for a customer saved search
var filters = new Array();
filters[0] = new nlobjSearchFilter('daysoverdue',null,'greaterthanorequalto',11);
filters[1] = new nlobjSearchFilter('custentitypastdueremind',null,'is', 'F');
filters[2] = new nlobjSearchFilter('balance',null,'greaterthan', 1);
var columns = new Array();
columns[0] = new nlobjSearchColumn('internalid');
columns[1] = new nlobjSearchColumn('email');
columns[2] = new nlobjSearchColumn('daysoverdue');
//run saved search and loop thru results
var customers = nlapiSearchRecord('customer',null,filters,columns);
for (var i = 0; customers != null && i < customers.length; i++) {
//grab all the customer data
var this_customer = customers[i];
var cust_id = this_customer.getValue('internalid');
var send_to = this_customer.getValue('email');
var getpastduedays = this_customer.getValue('daysoverdue');
//this is the check to see if the amount of days is over 11 to see if another email needs to be sent.
if(getpastduedays > 11) {
var checkPastDue = (getpastduedays - 11) % 8;
}
/*
if the above checkPastDues evaluates to zero then it has been 8 days since the last notification, this is the other condition to send an email. The first being that the customer is 11 days past due.
*/
if(getpastduedays == 11 || checkPastDue == 0) {
//email subject
var subject = 'Your Account is Past Due';
// create body text
var body = 'Hello, \r\r';
body += ' This is a reminder that your account is currently past due. Attached is a current detailed aging of your account for your reference.\r\r ';
body += ' Can you please review and let me know the status of payment?\r\r';
body += ' Your prompt attention to this matter would be greatly appreciated. If you have any questions reguarding this account, please ';
body += ' contact us as soon as possible. Any questions or invoice copy requests can be email to ar#doubleradius.com.\r\r';
body += ' If payment has been recently been made, please accept our thanks and ignore this reminder.\r\r';
body += 'Thank You!\r\r';
//setup filters and result columns for a transaction saved search
var filters = new Array();
filters[0] = new nlobjSearchFilter('status',null,'is', 'CustInvc:A');
filters[1] = new nlobjSearchFilter('type',null,'is', 'CustInvc');
filters[2] = new nlobjSearchFilter('email',null,'is', send_to);
filters[3] = new nlobjSearchFilter('mainline',null,'is', 'T');
var columns = new Array();
columns[0] = new nlobjSearchColumn('internalid');
//run saved search and loop thru results
var transactions = nlapiSearchRecord('transaction',null,filters,columns);
var invoices = [];
for (var i = 0; transactions != null && i < transactions.length; i++) {
//grab all the transaction data
var this_transaction = transactions[i];
invoices[i] = this_transaction.getValue('internalid');
}
//print the statement to a PDF file object
var attachment = [];
for (var i = 0; invoices != null && i < invoices.length; i++) {
attachment[i] = nlapiPrintRecord('TRANSACTION',invoices[i],'DEFAULT',null);
}
//send the PDF as an attachment
nlapiSendEmail(send_from,/*send_to*/ 'lauram#doubleradius.com', subject, body, null, null, null, attachment);
}
}
}
You don't need scripting to achieve this simple requirement. All you need is a saved search and a workflow. The key thing here is you need to come up with the right criteria on your saved search. Once you have the right saved search you set your workflow's Initiation to run on Scheduled and choose the frequency. Use the Send Email action to send the email to the customers and you are good to go.
Also, from the saved search you can join the customer record to the Messages Field so you will have the ability to check when was the last email sent.
You might also need a Email Template.
If you're going to use a Scheduled Script you will need to collect the records you want to inspect. If these are Customer records then be sure to setup searchFilters and searchColumns to come back and then collect the results.
// set Customer record filters and columns to return
var filters = new Array();
filters.push( new nlobjSearchFilter('isActive', null, 'is', 'F') );
filters.push( new nlobjSearchFilter('someotherfield', null, 'isempty') );
var cust_cols = new Array();
cust_cols.push( new nlobjSearchColumn('companyname') );
cust_cols.push( new nlobjSearchColumn('someotherfield') );
// now get the records that fit your filters and return the cols specified
overdue_customers = nlapiSearchRecord('customer', null, searchfilter, columns);
I generally like to move my content/body creating code into separate functions but it's really not that important depending on how complicated your script is. For instance I have a couple of scripts that do a lot of processing that have to send some information on a record by record basis but also sends "digest" type emails to others. Think customers and account managers. While it was a pain to set up everything up to handle both cases having a email content generating function was much saner and easier to read.
Though there are many approaches you could use for this, I think your scheduled script approach will work just fine. You can make the logic for identifying which emails to send by offloading the 8-day calculation to your search filters, instead of manually trying to compute. I would have a filter in my search of something like:
new nlobjSearchFilter('custentity_dayssincelastemailed', null, 'before', 'previousOneWeek');
See the Help article titled Search Date Filters for more details on what you can do with Dates in filters.
After that, I believe you should be able to create an Email Template and utilize that in your code to set the title and the boilerplate of the email body.
Where I'm a little less certain, and what may be more difficult for you, is your A/R Aging attachment. Not sure I've worked with attaching statements.

CRM 2013 to update statecode of Incident Resolution Entity

I am quite new to this part of CRM. I want to set the StateCode field of Incident Resolution Entity.
I am trying the following way -
IncidentResolution res = new IncidentResolution();
res.IncidentId = new EntityReference();
res.IncidentId.LogicalName =Incident.EntityLogicalName;
res.IncidentId.Id = new Guid(row["id"].ToString());
res.StateCode = new OptionSetValue((int)IncidentResolutionState.Completed)); //This Following gives the error as System.Nullable<IncidentResolution.StateCode> cannot be assigned to--It is readonly.
CloseIncidentRequest req = new CloseIncidentRequest();
req.IncidentResolution = res;
req.Status = new OptionSetValue();
req.Status.Value = 5; // Problem Solved
service.execute(req);
The problem i am facing is to set the StateCode property for Incident Resolution Entity.
Any help would be appreciated.
Thanks in Advance
you don't need to set the StateCode of the IncidentResolution, only the Status of CloseIncidentRequest:
IncidentResolution res = new IncidentResolution
{
Subject = "Resolved Sample Incident",
IncidentId = new EntityReference(Incident.EntityLogicalName, new Guid(row["id"].ToString()))
};
// Close the incident with the resolution.
CloseIncidentRequest req = new CloseIncidentRequest
{
IncidentResolution = res,
Status = new OptionSetValue(5)
};
service.execute(req);

NpqsqlParameter - Multiple Values

Code:
string sqlCommand = #"UPDATE table SET active = 0 WHERE id IN (#CommaSeparatedId)";
string sqlParamName = "CommaSeparatedId";
string sqlParamValue = "111, 222";
try
{
using (NpgsqlConnection connection = new NpgsqlConnection())
{
// Get connection string from Web.config
connection.ConnectionString = _connectionString;
connection.Open();
Int32 rowsAffected;
using (NpgsqlCommand command = new NpgsqlCommand(sqlCommand, connection))
{
NpgsqlParameter sqlParam = new NpgsqlParameter(sqlParamName, NpgsqlTypes.NpgsqlDbType.Varchar);
// Code below no exception occur, and active not updated to 0
// sqlParam.Value = sqlParamValue;
// This code works for only one value
sqlParam.Value = "111";
command.Parameters.Add(sqlParam);
rowsAffected = command.ExecuteNonQuery();
}
}
}
catch (NpgsqlException pgEx)
{
throw pgEx;
}
The problem is:
If I'm using the 111, 222 as the sqlParam.Value'rowsAffected = 0, but if I'm using only111or222rowsAffected = 1`. That means it success to updated when only 1 value but will failed if trying to update more than 1 value.
Expected Query:
UPDATE table
SET active = 0
WHERE id IN ('111', '222');
What I'm missing in code above?
The problem you are facing is due to the fact that the parameter value "111,222" will be seen by the database engine not like two distinct values, but as one.
The database search for a record with ID = "111,222" and find nothing matching the request.
You should try to use a stored procedure and execute a Dynamic SQL according to the syntax required by PostgreSQL

Resources