I am using Netsuite API (version v2016_2) to search data. With below code, it seems that Netsuite taking much time to give response for the query. I am searching GL transaction of periticular period that has 149 MainLine record and 3941 LineItem (Journal Entries) record and Netsuite takes almost 22 minutes to give this data in response. Below is code snippet that I am using to search transaction.
public void GetTransactionData()
{
DataTable dtData = new DataTable();
string errorMsg = "";
LoginToService(ref errorMsg);
TransactionSearch objTransSearch = new TransactionSearch();
TransactionSearchBasic objTransSearchBasic = new TransactionSearchBasic();
SearchEnumMultiSelectField semsf = new SearchEnumMultiSelectField();
semsf.#operator = SearchEnumMultiSelectFieldOperator.anyOf;
semsf.operatorSpecified = true;
semsf.searchValue = new string[] { "Journal" };
objTransSearchBasic.type = semsf;
objTransSearchBasic.postingPeriod = new RecordRef() { internalId = "43" };
objTransSearch.basic = objTransSearchBasic;
//Set Search Preferences
SearchPreferences _searchPreferences = new SearchPreferences();
Preferences _prefs = new Preferences();
_serviceInstance.preferences = _prefs;
_serviceInstance.searchPreferences = _searchPreferences;
_searchPreferences.pageSize = 1000;
_searchPreferences.pageSizeSpecified = true;
_searchPreferences.bodyFieldsOnly = false;
//Set Search Preferences
try
{
SearchResult result = _serviceInstance.search(objTransSearch);
/*
Above line taking almost 22 minutes for below record count
result.recordList.Length = 149
Total JournalEntryLine = 3941
*/
List<JournalEntry> lstJEntry = new List<JournalEntry>();
List<JournalEntryLine> lstLineItems = new List<JournalEntryLine>();
if (result.status.isSuccess)
{
for (int i = 0; i <= result.recordList.Length - 1; i += 1)
{
JournalEntry JEntry = (JournalEntry)result.recordList[i];
lstJEntry.Add((JournalEntry)result.recordList[i]);
if (JEntry.lineList != null)
{
foreach (JournalEntryLine line in JEntry.lineList.line)
{
lstLineItems.Add(line);
}
}
}
}
try
{
_serviceInstance.logout();
}
catch (Exception ex)
{
}
}
catch (Exception ex)
{
throw ex;
}
}
I am unable to know that If I am missing something in my code or this is something about the data. Please suggest me some sort of solution for this.
Thanks.
You should set _searchPreferences.bodyFieldsOnly = true. It will improve the performance with searching because it doesn't return the related or sublist data
I think you are doing this search from the outside of the Netsuite to get journal entries data or lines. Instead of doing a direct search outside, do maintain RESTLET in NETSUITE and call that RESTLET. In the RESTLET DO that search you wanted and return results. Within the NETSUITE, search performance gives fast results.
Related
I'm running the Microsoft sample for Bing Entity Search using the SDK and (NOT the REST API.) I can.t figure out how to enter the location key/value pair, based on this documentation:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.cognitiveservices.search.entitysearch.entitiesoperationsextensions.search?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DEN-US%26k%3Dk(Microsoft.Azure.CognitiveServices.Search.EntitySearch.EntitiesOperationsExtensions.Search);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.7.2);k(DevLang-csharp)%26rd%3Dtrue&view=azure-dotnet
I would like to continue to use named parameters so I can still do this:
var restaurants = client.Entities.Search(query: currentQuery, location: lat:? long:?);
The method with the query and location from the Microsoft sample will look like this:
public static void MultipleCurrentQueryLookup(string subscriptionKey)
{
var client = new EntitySearchClient(new ApiKeyServiceClientCredentials subscriptionKey));
try
{
string currentQuery = Settings1.Default.CurrentQuery;
var restaurants = client.Entities.Search(query: currentQuery,
location: "lat:47.623, long:-122.361, re:380m");
if (restaurants?.Places?.Value?.Count > 0)
{
// get all the list items that relate to this query
var listItems = restaurants.Places.Value.Where(thing => thing.EntityPresentationInfo.EntityScenario == EntityScenario.ListItem).ToList();
if (listItems?.Count > 0)
{
var sb = new StringBuilder();
foreach (var item in listItems)
{
var place = item as Place;
if (place == null)
{
Console.WriteLine("Unexpectedly found something that isn't a place named \"{0}\"", item.Name);
continue;
}
sb.AppendFormat(",{0} ({1}) {2}", place.Name, place.Telephone, place.Url);
}
Console.WriteLine("Ok, we found these places: ");
Console.WriteLine(sb.ToString().Substring(1));
}
else
{
Console.WriteLine("Couldn't find any relevant results for \"The Current Query\"");
}
}
else
{
Console.WriteLine("Didn't see any data..");
}
}
catch (ErrorResponseException ex)
{
Console.WriteLine("Encountered exception. " + ex.Message);
}
}
I had wrote some code for creating po via code, but it faild with error message: "CS Error: Cannot generate the next number for the sequence."
How can I fix this? Anything I missed? Thx for helping!
protected void createPO() {
POOrder order = new POOrder();
POOrderEntry graph = PXGraph.CreateInstance < POOrderEntry > ();
order.OrderType = "Normal";
order.OrderDesc = "some text";
order.EmployeeID = 215;
order.Hold = false;
var branch = (Branch)PXSelect<Branch, Where<Branch.branchCD, Equal<Required<Branch.branchCD>>>>.Select(Base, "WEST");
graph.FieldDefaulting.AddHandler<POOrder.branchID>((s, e) =>
{
e.NewValue = branch.BranchID;
e.Cancel = true;
});
order.VendorID = 79;
order = graph.CurrentDocument.Insert(order);
graph.CurrentDocument.Update(order);
graph.Actions.PressSave();
throw new PXRedirectRequiredException(graph, null);
}
Try to simply it first to see if something like this works...
protected void createPO()
{
var graph = PXGraph.CreateInstance<POOrderEntry>();
var order = graph.Document.Insert(new POOrder());
order.OrderType = POOrderType.RegularOrder; // This is the default so not necessary
order.OrderDesc = "some text";
order.EmployeeID = 215;
order.Hold = false;
order.VendorID = 79;
graph.Document.Update(order);
graph.Actions.PressSave();
throw new PXRedirectRequiredException(graph, null);
}
Using the Document view in place of the CurrentDocument view which is based on the current record of Document. Document is the primary view and the primary view should be used.
Also for the purchase order type the attribute related to the list values should be used for the stored value of the database (vs what you had was the displayed list value). For example order.OrderType = POOrderType.RegularOrder. Also this is the default value for a PO so it is not necessary to set this value unless you want a different constant found in the POOrderType class.
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.
I customized the ARPaymentEntry in which it creates a Journal Voucher Entry with created Credit Memo, it retrieves the Credit Memo applies the open invoice that is also applied in the current payment. when I create the instance to call the Credit Memo and add the Invoice in ARAdjust table, an error occurs when trying to insert it, giving a Reference Nbr cannot be found in the system, although when I'm trying to manually applying it I could see the open invoice.
public void ReleaseCreditMemo(string refNbr)
{
try
{
ARPaymentEntry docGraph = PXGraph.CreateInstance<ARPaymentEntry>();
List<ARRegister> list = new List<ARRegister>();
ARPayment payment;
ARRegister invoice = PXSelect<ARRegister, Where<ARRegister.docType, Equal<Required<ARRegister.docType>>, And<ARRegister.refNbr, Equal<Required<ARRegister.refNbr>>>>>.Select(docGraph, ARInvoiceType.CreditMemo, refNbr);
docGraph.Document.Current = PXSelect<ARPayment, Where<ARPayment.docType, Equal<Required<ARPayment.docType>>, And<ARPayment.refNbr, Equal<Required<ARPayment.refNbr>>>>>.Select(docGraph, ARInvoiceType.CreditMemo, refNbr);
payment = docGraph.Document.Current;
list.Add(payment);
foreach (ISARWhTax item in ARWhLine.Select())
{
decimal? _CuryAdjgAmt = payment.CuryOrigDocAmt > invoice.CuryDocBal ? invoice.CuryDocBal : payment.CuryOrigDocAmt;
decimal? _CuryAdjgDiscAmt = payment.CuryOrigDocAmt > invoice.CuryDocBal ? 0m : invoice.CuryDiscBal;
ARAdjust adj = new ARAdjust();
adj.AdjdBranchID = item.AdjdBranchID;
adj.AdjdDocType = ARInvoiceType.Invoice;
adj.AdjdRefNbr = item.AdjdRefNbr;
adj.AdjdCustomerID = item.CustomerID;
adj.AdjdDocDate = invoice.DocDate;
adj.CuryAdjgAmt = _CuryAdjgAmt;
adj.CuryAdjdDiscAmt = _CuryAdjgDiscAmt;
if (docGraph.Document.Current.CuryUnappliedBal == 0m && docGraph.Document.Current.CuryOrigDocAmt > 0m)
{
throw new PXLoadInvoiceException();
}
//This line code below OCCURS THE ERROR
docGraph.Adjustments.Insert(adj);
}
docGraph.Save.Press();
PXLongOperation.StartOperation(docGraph, delegate() { ARDocumentRelease.ReleaseDoc(list, false); });
}
catch (Exception ex)
{
throw new PXException(ex.Message);
}
}
I would look at the selector of the field causing the error ("Reference Nbr.") as having a selector on a field will validate the entered value to the selector's select statement (unless validatevalue=false for the selector). Maybe the selector will give you some pointers as to what is missing or causing the validation to fail.
I figured it out it that after the code below executes it does not immediately updates the View. So what I did is to execute my code at ARPayment_RowSelected event with a conditional statement if the document is released.
PXLongOperation.StartOperation(this.Base, delegate() { ARDocumentRelease.ReleaseDoc(list, false); });
I had some confusion which I want to clear it - I am inserting values into database using ADO.NET. Let say I want to insert 10 item if I encounter error while inserting data of 5th item it should roll back whatever I had inserted into the database.
I just read the concept of Transaction and Rollback method and also tried to implement it in the program but still it insert 4 item and give me error message of 5th item. It doesn't roll back insert query.
Does transaction and roll back method solved my issue or I need to used other alternative.
here is my code,
for (int i = 0; i < itemLength - 1; i++)
{
//--- Start local transaction ---
myTrans = Class1.conn.BeginTransaction();
//--- Assign transaction object and connection to command object for a pending local transaction ---
_insertQry = Class1.conn.CreateCommand();
_insertQry.Connection = Class1.conn;
_insertQry.Transaction = myTrans;
_insertQry.CommandText = "INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (#ItemNo, #PropertyNo, #ValueNo)";
//_insertQry = new SqlCommand("INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (#ItemNo, #PropertyNo, #ValueNo)", Class1.conn);
_insertQry.Parameters.AddWithValue("#ItemNo", _itemNo[i]);
_insertQry.Parameters.AddWithValue("#PropertyNo", _propNo);
_insertQry.Parameters.AddWithValue("#ValueNo", _propValue);
_insertQry.ExecuteNonQuery();
myTrans.Commit();
}
Can anyone help me?
It sounds like you are trying to achieve an atomic commit. It either inserts completely or doesn't insert at all.
Try something like the following
SqlTransaction objTrans = null;
using (SqlConnection objConn = new SqlConnection(strConnString))
{
objConn.Open();
objTrans = objConn.BeginTransaction();
SqlCommand objCmd1 = new SqlCommand("insert into tbExample values(1)", objConn);
SqlCommand objCmd2 = new SqlCommand("insert into tbExample values(2)", objConn);
try
{
objCmd1.ExecuteNonQuery();
objCmd2.ExecuteNonQuery();
objTrans.Commit();
}
catch (Exception)
{
objTrans.Rollback();
}
finally
{
objConn.Close();
}
Also take a look at
http://www.codeproject.com/Articles/10223/Using-Transactions-in-ADO-NET
I did 2 modification to your code
1) Move the BeginTransaction() outside the for loop, So that all your 10 INSERt statements are in a single transaction, that is what you want if you want them to be atomic
2) added a TRY/CATCH block, so that you can roll back in case of errors.
//--- Start local transaction ---
myTrans = Class1.conn.BeginTransaction();
bool success = true;
try
{
for (int i = 0; i < itemLength - 1; i++)
{
//--- Assign transaction object and connection to command object for a pending local transaction ---
_insertQry = Class1.conn.CreateCommand();
_insertQry.Connection = Class1.conn;
_insertQry.Transaction = myTrans;
_insertQry.CommandText = "INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (#ItemNo, #PropertyNo, #ValueNo)";
//_insertQry = new SqlCommand("INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (#ItemNo, #PropertyNo, #ValueNo)", Class1.conn);
_insertQry.Parameters.AddWithValue("#ItemNo", _itemNo[i]);
_insertQry.Parameters.AddWithValue("#PropertyNo", _propNo);
_insertQry.Parameters.AddWithValue("#ValueNo", _propValue);
_insertQry.ExecuteNonQuery();
}
}
catch (Exception ex)
{
success = false;
myTrans.Rollback();
}
if (success)
{
myTrans.Commit();
}
let me know if this doesn't works.
You are on the right path, ADO.NET supports transactions so you will be able to rollback on errors.
Posting your your code here would get you more specific guidance; However since your question is very generic, I will encourage you to follow the template provided by MSDN
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// Start a local transaction.
SqlTransaction sqlTran = connection.BeginTransaction();
// Enlist a command in the current transaction.
SqlCommand command = connection.CreateCommand();
command.Transaction = sqlTran;
try
{
// Execute two separate commands.
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
command.ExecuteNonQuery();
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
command.ExecuteNonQuery();
// Commit the transaction.
sqlTran.Commit();
Console.WriteLine("Both records were written to database.");
}
catch (Exception ex)
{
// Handle the exception if the transaction fails to commit.
Console.WriteLine(ex.Message);
try
{
// Attempt to roll back the transaction.
sqlTran.Rollback();
}
catch (Exception exRollback)
{
// Throws an InvalidOperationException if the connection
// is closed or the transaction has already been rolled
// back on the server.
Console.WriteLine(exRollback.Message);
}
}
}