I saw this link and I notice we have the same problem, and his question still didn't answer yet.
Here is the question.
public class ServiceSel
{
public void GetCheqe()
{
bool sessionBegun = false;
bool connectionOpen = false;
QBSessionManager rp = null;
try
{
rp = new QBSessionManager();
IMsgSetRequest requestMsgSet = rp.CreateMsgSetRequest("US", 8, 0);
requestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;
rp.OpenConnection("Database Path File QuickBooks", "QuickBooks Integration Demo");
connectionOpen = true;
rp.BeginSession("", ENOpenMode.omDontCare);
sessionBegun = true;
ICheckQuery checkQuery = requestMsgSet.AppendCheckQueryRq();
IMsgSetResponse msgSetRs = rp.DoRequests(requestMsgSet);
IResponse response = msgSetRs.ResponseList.GetAt(0);
ICheckRetList checkRetList = (ICheckRetList)response.Detail;
if (checkRetList != null)
{
for (int i = 0; i < checkRetList.Count; i++)
{
ICheckRet checkRet = checkRetList.GetAt(i);
//Bank Account On top
string TxnID = checkRet.TxnID.GetValue().ToString(); //Data correct
string TxnNumber = checkRet.TxnNumber.GetValue().ToString(); //Data correct
string Account = checkRet.AccountRef.FullName.GetValue(); //Data correct
string Amount = checkRet.Amount.GetValue().ToString(); //Data correct
if (checkRet.ExpenseLineRetList != null)
{
Error checkRet.Expense Show null Data But in quickbooks have many data expense in calendar
}
}
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message, "Error");
}
finally
{
if (sessionBegun)
{
rp.EndSession();
}
if (connectionOpen)
{
rp.CloseConnection();
}
}
}
Why ExpenseLineRetList is null?
A check request will not include the detail lines of the check unless you include it in your query. By adding the IncludeLineItems setting, you'll get access to the Expense or Item lists of the check (a check could have Expense lines, Item lines, or both). You'll want to change to include the following:
ICheckQuery checkQuery = requestMsgSet.AppendCheckQueryRq();
checkQuery.IncludeLineItems.SetValue(true);
IMsgSetResponse msgSetRs = rp.DoRequests(requestMsgSet);
I would also suggest that you check the response code before trying to get the response detail so you can better handle errors:
IResponse response = msgSetRs.ResponseList.GetAt(0);
if(response.StatusCode != 0)
{
// There was an error. response.StatusCode has the error number
// response.StatusMessage has the error description.
}
else
{
ICheckRetList checkRetList = (ICheckRetList)response.Detail;
.
.
.
}
Related
Is it possible to program a startup hold into an Xbox game package that waits for the user's cloud saves to sync before continuing? I have an HTML5 game package for which I require save data to be loaded from Xbox Live which is then read from local storage (in JSON format) to populate the load screen at startup, and I also have to account for any error messages for which the user may have to respond. The game itself is started up once sync is done (but obviously not until after the legal stuff has been taken care of, so logo splash, engine branding, seizure advisory and possibly also the FBI and ESRB notices also have to be taken into account). If it also helps to investigate, data is being saved properly while there's an active session and I can successfully copy it to local app storage. The Xbox Live copy, on the other hand, seems to be at issue right now.
I'm not holding that much data in the game files, either - just five save slots not including global config and user settings. Basically I'm trying to keep the per-user storage well under the 64MB cap on creator's projects (not to mention that my initial request for ID#Xbox didn't work out) and I'm hoping to have this implemented before I even dare to resubmit. This is provided that it's even possible of course, considering all of the conflicting information I've been receiving through my Bing and Google requests.
The closest I have come is with the following code, which is based largely on Microsoft Docs samples. This first block is what's supposed to load the Xbox data and copy it to disk, and for which I require the delay in the first place:
public void doStartup()
{
getData(-1);
for (int i = 0; i <= 5; i++)
{
getData(i);
}
}
public async void getData(int savefileId)
{
var users = await Windows.System.User.FindAllAsync();
string c_saveBlobName = "Advent";
//string c_saveContainerDisplayName = "GameSave";
string c_saveContainerName = "file" + savefileId;
if (savefileId <= 0) c_saveContainerName = "config";
if (savefileId == 0) c_saveContainerName = "global";
GameSaveProvider gameSaveProvider;
GameSaveProviderGetResult gameSaveTask = await GameSaveProvider.GetForUserAsync(users[0], "00000000-0000-0000-0000-00006d0be05f");
//Parameters
//Windows.System.User user
//string SCID
if (gameSaveTask.Status == GameSaveErrorStatus.Ok)
{
gameSaveProvider = gameSaveTask.Value;
}
else
{
return;
//throw new Exception("Game Save Provider Initialization failed");;
}
//Now you have a GameSaveProvider
//Next you need to call CreateContainer to get a GameSaveContainer
GameSaveContainer gameSaveContainer = gameSaveProvider.CreateContainer(c_saveContainerName);
//Parameter
//string name (name of the GameSaveContainer Created)
//form an array of strings containing the blob names you would like to read.
string[] blobsToRead = new string[] { c_saveBlobName };
// GetAsync allocates a new Dictionary to hold the retrieved data. You can also use ReadAsync
// to provide your own preallocated Dictionary.
GameSaveBlobGetResult result = await gameSaveContainer.GetAsync(blobsToRead);
string loadedData = "";
//Check status to make sure data was read from the container
if (result.Status == GameSaveErrorStatus.Ok)
{
//prepare a buffer to receive blob
IBuffer loadedBuffer;
//retrieve the named blob from the GetAsync result, place it in loaded buffer.
result.Value.TryGetValue(c_saveBlobName, out loadedBuffer);
if (loadedBuffer == null)
{
//throw new Exception(String.Format("Didn't find expected blob \"{0}\" in the loaded data.", c_saveBlobName));
}
DataReader reader = DataReader.FromBuffer(loadedBuffer);
loadedData = reader.ReadString(loadedBuffer.Length);
if (savefileId <= 0)
{
try
{
System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\config.json", loadedData);
}
catch { }
}
else if (savefileId == 0)
{
try
{
System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\global.json", loadedData);
}
catch { }
}
else
{
try
{
System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\file"+savefileId+".json", loadedData);
}
catch { }
}
}
}
And this is what's supposed to read the data when called by the HTML5 portion:
public string getSaveFile(int savefileId)
{
string data;
if (savefileId == 0)
{
try
{
data = System.IO.File.ReadAllText(ApplicationData.Current.LocalFolder.Path + "\\global.json");
if (data == null) data = "";
Debug.WriteLine(data);
}
catch { data = ""; }
return data;
} else
{
try
{
data = System.IO.File.ReadAllText(ApplicationData.Current.LocalFolder.Path + "\\file" + savefileId + ".json");
if (data == null) data = "";
Debug.WriteLine(data);
}
catch { data = ""; }
return data;
}
}
public string getConfig()
{
string data;
try
{
data = System.IO.File.ReadAllText(ApplicationData.Current.LocalFolder.Path + "\\config.json");
if (data == null) data = "";
Debug.WriteLine(data);
}
catch { data = ""; }
return data;
}
And this is the save code on the WinRT side:
public async void doSave(int key, string data)
{
//Get The User
var users = await Windows.System.User.FindAllAsync();
string c_saveBlobName = "Advent";
string c_saveContainerDisplayName = "GameSave";
string c_saveContainerName = "file"+key;
if (key == -1) c_saveContainerName = "config";
if (key == 0) c_saveContainerName = "global";
GameSaveProvider gameSaveProvider;
GameSaveProviderGetResult gameSaveTask = await GameSaveProvider.GetForUserAsync(users[0], "00000000-0000-0000-0000-00006d0be05f");
//Parameters
//Windows.System.User user
//string SCID
if (gameSaveTask.Status == GameSaveErrorStatus.Ok)
{
gameSaveProvider = gameSaveTask.Value;
}
else
{
return;
//throw new Exception("Game Save Provider Initialization failed");
}
//Now you have a GameSaveProvider (formerly ConnectedStorageSpace)
//Next you need to call CreateContainer to get a GameSaveContainer (formerly ConnectedStorageContainer)
GameSaveContainer gameSaveContainer = gameSaveProvider.CreateContainer(c_saveContainerName); // this will create a new named game save container with the name = to the input name
//Parameter
//string name
// To store a value in the container, it needs to be written into a buffer, then stored with
// a blob name in a Dictionary.
DataWriter writer = new DataWriter();
writer.WriteString(data); //some number you want to save, in this case 23.
IBuffer dataBuffer = writer.DetachBuffer();
var blobsToWrite = new Dictionary<string, IBuffer>();
blobsToWrite.Add(c_saveBlobName, dataBuffer);
GameSaveOperationResult gameSaveOperationResult = await gameSaveContainer.SubmitUpdatesAsync(blobsToWrite, null, c_saveContainerDisplayName);
int i;
for (i = 1; i <= 90000; i++) {}
Debug.WriteLine("SaveProcessed");
//IReadOnlyDictionary<String, IBuffer> blobsToWrite
//IEnumerable<string> blobsToDelete
//string displayName
}
And I have just recently added the user detection code to the main project.
public static async void InitializeXboxGamer(TextBlock gamerTagTextBlock)
{
try
{
XboxLiveUser user = new XboxLiveUser();
SignInResult result = await user.SignInSilentlyAsync(Window.Current.Dispatcher);
if (result.Status == SignInStatus.UserInteractionRequired)
{
result = await user.SignInAsync(Window.Current.Dispatcher);
}
System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\curUser.txt", user.Gamertag);
}
catch (Exception ex)
{
// TODO: log an error here
}
}
Big dumb... I figured out the problem with my code. When loading the global config, getData is passed a negative one; however for some reason it was writing the app data file instead so after I changed the verification to be a little more specific it started to work as expected.
public void doStartup()
{
getData(-1);
for (int i = 0; i <= 5; i++)
{
getData(i);
}
}
public async void getData(int savefileId)
{
var users = await Windows.System.User.FindAllAsync();
string c_saveBlobName = "Advent";
//string c_saveContainerDisplayName = "GameSave";
string c_saveContainerName = "file" + savefileId;
if (savefileId <= 0) c_saveContainerName = "config";
if (savefileId == 0) c_saveContainerName = "global";
GameSaveProvider gameSaveProvider;
GameSaveProviderGetResult gameSaveTask = await GameSaveProvider.GetForUserAsync(users[0], "00000000-0000-0000-0000-00006d0be05f");
//Parameters
//Windows.System.User user
//string SCID
if (gameSaveTask.Status == GameSaveErrorStatus.Ok)
{
gameSaveProvider = gameSaveTask.Value;
}
else
{
return;
//throw new Exception("Game Save Provider Initialization failed");;
}
//Now you have a GameSaveProvider
//Next you need to call CreateContainer to get a GameSaveContainer
GameSaveContainer gameSaveContainer = gameSaveProvider.CreateContainer(c_saveContainerName);
//Parameter
//string name (name of the GameSaveContainer Created)
//form an array of strings containing the blob names you would like to read.
string[] blobsToRead = new string[] { c_saveBlobName };
// GetAsync allocates a new Dictionary to hold the retrieved data. You can also use ReadAsync
// to provide your own preallocated Dictionary.
GameSaveBlobGetResult result = await gameSaveContainer.GetAsync(blobsToRead);
string loadedData = "";
//Check status to make sure data was read from the container
if (result.Status == GameSaveErrorStatus.Ok)
{
//prepare a buffer to receive blob
IBuffer loadedBuffer;
//retrieve the named blob from the GetAsync result, place it in loaded buffer.
result.Value.TryGetValue(c_saveBlobName, out loadedBuffer);
if (loadedBuffer == null)
{
//throw new Exception(String.Format("Didn't find expected blob \"{0}\" in the loaded data.", c_saveBlobName));
}
DataReader reader = DataReader.FromBuffer(loadedBuffer);
loadedData = reader.ReadString(loadedBuffer.Length);
if (savefileId <= 0)
{
try
{
System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\config.json", loadedData);
}
catch { }
}
else if (savefileId == 0)
{
try
{
System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\global.json", loadedData);
}
catch { }
}
else
{
try
{
System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\file"+savefileId+".json", loadedData);
}
catch { }
}
}
}
I still need the execution delay though, but that's for an entirely different reason that I discuss over here.
I am trying to PAUSE the Ads with the AdId and AdGroupID. I have successfully paused an AdGroup but i want to pause Ads individually. Is this possible on Adwords API. I tried the code below but It seems it only works on AdGroup level. Also checked the AdService but seems that there is no option to edit the Status.
I am using Ads.AdWords.v201809
Thanks in advance
public void googleEnableDisableAds(AdWordsUser user, long adGroupId, long AdID, AdGroupAdStatus AdStatus)
{
using (AdGroupAdService adGroupAdService =
(AdGroupAdService)user.GetService(AdWordsService.v201809.AdGroupAdService))
{
List<AdGroupAdOperation> operations = new List<AdGroupAdOperation>();
// Create the expanded text ad.
ExpandedTextAd expandedTextAd = new ExpandedTextAd
{
//CR[i].
id = AdID
};
AdGroupAd expandedTextAdGroupAd = new AdGroupAd
{
adGroupId = adGroupId,
ad = expandedTextAd,
// Optional: Set the status.
status = AdStatus
};
// Create the operation.
AdGroupAdOperation operation = new AdGroupAdOperation
{
#operator = Operator.SET,
operand = expandedTextAdGroupAd
};
operations.Add(operation);
AdGroupAdReturnValue retVal = null;
try
{
if (operations.Count > 0)
{
// Create the ads.
retVal = adGroupAdService.mutate(operations.ToArray());
// Display the results.
if (retVal != null && retVal.value != null)
{
foreach (AdGroupAd adGroupAd in retVal.value)
{
ExpandedTextAd newAd = adGroupAd.ad as ExpandedTextAd;
Console.WriteLine(
"Expanded text ad with ID '{0}' and headline '{1} - {2}' " +
"was added.", newAd.id, newAd.headlinePart1, newAd.headlinePart2);
//adGroupId
}
}
else
{
Console.WriteLine("No expanded text ads were created.");
}
}
adGroupAdService.Close();
}
catch (Exception e)
{
throw new System.ApplicationException("Failed to create expanded text ad.", e);
}
}
}
Here is an example from API docs https://developers.google.com/adwords/api/docs/samples/csharp/basic-operations#pause-an-ad
The key idea is to set status property to PAUSED
AdGroupAdStatus status = AdGroupAdStatus.PAUSED
I got stuck when trying to implement the "apply credit" functionality of Quickbooks to existing invoices if credit is available for that customer. I am able to do it via Quickbooks Desktop UI but not getting the way to implement it via a .Net integrated app, written in C#. Can any one please guide on this.
Code which I am using to implement "apply credit" to Quickbooks via C# code.
I am getting the error: "QuickBooks found an error when parsing the provided XML text stream." with below code.
public void ApplyCreditsOnPrePayInvoices()
{
// open connection and begin session before data fetch - intentionally skipped this code
IMsgSetRequest msgset = null;
ICreditMemoQuery creditMemoQuery = null;
string sCustomerName = string.Empty;
if (this.GetConnectedToQB()) //this is the method call to login to quickbooks desktop
{
try
{
// during data fetch
msgset = m_sessionManager.CreateMsgSetRequest("US", 8, 0);
creditMemoQuery = msgset.AppendCreditMemoQueryRq();
creditMemoQuery.ORTxnQuery.TxnFilter.ORDateRangeFilter.ModifiedDateRangeFilter.FromModifiedDate.SetValue(new DateTime(2012, 3, 31), false);
IMsgSetResponse msgRes = m_sessionManager.DoRequests(msgset);
IResponseList responseList = msgRes.ResponseList;
if (responseList.Count > 0)
{
IResponse response = responseList.GetAt(0);
ICreditMemoRetList creditMemoList = response.Detail as ICreditMemoRetList;
if (creditMemoList == null)
{
return;
}
for (int i = 0; i <= creditMemoList.Count - 1; i++)
{
ICreditMemoRet qbCreditMemo = creditMemoList.GetAt(i);
if (this.GetQBCustomerListId(qbCreditMemo.CustomerRef.FullName.GetValue()) != string.Empty)
{
m_requestMsgSet.ClearRequests();
m_requestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;
IInvoiceAdd invoiceAddRq = m_requestMsgSet.AppendInvoiceAddRq();
invoiceAddRq.CustomerRef.FullName.SetValue(qbCreditMemo.CustomerRef.FullName.GetValue());
ISetCredit SetCredit1 = invoiceAddRq.SetCreditList.Append();
SetCredit1.CreditTxnID.SetValue(qbCreditMemo.TxnID.GetValue());
SetCredit1.AppliedAmount.SetValue(qbCreditMemo.TotalAmount.GetValue());
IMsgSetResponse responseSetInvoice = m_sessionManager.DoRequests(m_requestMsgSet);
DataSet dsInvoice = this.GetExtractResponseFromQB(responseSetInvoice);
string sQueryResponse = Stringcl.GetValue(dsInvoice.Tables["InvoiceAddRs"].Rows[0]["statusMessage"]);
if (sQueryResponse == "Status OK")
{
Console.WriteLine("Credit no.:" + qbCreditMemo.TxnID.GetValue() + " Customer:" + qbCreditMemo.CustomerRef.FullName.GetValue() + " Total:" + qbCreditMemo.TotalAmount.GetValue());
}
}
}
}
}
catch (Exception ex)
{
string ss = ex.Message;
//handle exception here
}
finally
{
if (msgset != null)
{
Marshal.FinalReleaseComObject(msgset);
}
if (creditMemoQuery != null)
{
Marshal.FinalReleaseComObject(creditMemoQuery);
}
}
}
// end session and close connection after data fetch - intentionally skipped this code
}
Thanks in advance!!
I got solution by using below function:-
public void ApplyCreditsOnPrePayInvoices(string sMonth, string sYear)
{
IMsgSetRequest IMsgSetRequestToQB = null;
ICreditMemoQuery ICreditMemoQueryToQB = null;
string sInvoiceTxnId = string.Empty;
string sInvoiceNumber = string.Empty;
if (this.GetConnectedToQB())
{
try
{
IMsgSetRequestToQB = m_sessionManager.CreateMsgSetRequest("US", 8, 0);
ICreditMemoQueryToQB = IMsgSetRequestToQB.AppendCreditMemoQueryRq();
ICreditMemoQueryToQB.ORTxnQuery.TxnFilter.ORDateRangeFilter.ModifiedDateRangeFilter.FromModifiedDate.SetValue(DateTimecl.GetValue("1." + sMonth + sYear), true);
IMsgSetResponse IMsgSetResponseFromQB = m_sessionManager.DoRequests(IMsgSetRequestToQB);
IResponseList ICreditListMemoAvailable = IMsgSetResponseFromQB.ResponseList;
if (ICreditListMemoAvailable.Count > 0)
{
string sCustomerListIdQB = string.Empty;
string sCustomerAccountNumber = string.Empty;
string sQBImportPrepayAccounts = Path.Combine(Environment.CurrentDirectory, sMonth + sYear, "Step11_QBImport_PrepayAccounts.csv");
DataTable dtQBImportPrepayAccounts = Utilcl.GetDataTableFromCSVFile(sQBImportPrepayAccounts);
IResponse ICreditMemoAvailable = ICreditListMemoAvailable.GetAt(0);
ICreditMemoRetList iCreditMemoList = ICreditMemoAvailable.Detail as ICreditMemoRetList;
if (iCreditMemoList != null)
{
for (int iCtr = 0; iCtr <= iCreditMemoList.Count - 1; iCtr++)
{
ICreditMemoRet ICreditMemo = iCreditMemoList.GetAt(iCtr);
DataRow[] drInvoiceNos = dtQBImportPrepayAccounts.Select("RefNumber = '" + ICreditMemo.RefNumber.GetValue() + "'");
if (drInvoiceNos.Length > 0)
{
sInvoiceNumber = Stringcl.GetValue(drInvoiceNos[0]["RefNumber"]);
m_requestMsgSet.ClearRequests();
m_requestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;
IReceivePaymentAdd IReceivePayment = m_requestMsgSet.AppendReceivePaymentAddRq();
sInvoiceTxnId = this.GetQBInvoiceTxnIDList(ICreditMemo.CustomerRef.FullName.GetValue()); //To get the Transaction ID of Invoice
IReceivePayment.CustomerRef.FullName.SetValue(Stringcl.GetValue(ICreditMemo.CustomerRef.FullName.GetValue()));
IAppliedToTxnAdd IAppliedToTxnAddress = IReceivePayment.ORApplyPayment.AppliedToTxnAddList.Append();
IAppliedToTxnAddress.TxnID.SetValue(sInvoiceTxnId);
ISetCredit ISetCreditToInvoice = IAppliedToTxnAddress.SetCreditList.Append();
ISetCreditToInvoice.CreditTxnID.SetValue(ICreditMemo.TxnID.GetValue());
ISetCreditToInvoice.AppliedAmount.SetValue(ICreditMemo.TotalAmount.GetValue());
IMsgSetResponse responseApplyCredit = m_sessionManager.DoRequests(m_requestMsgSet);
DataSet dsInvoice = this.GetExtractResponseFromQB(responseApplyCredit);
string sQueryResponse = Stringcl.GetValue(dsInvoice.Tables["ReceivePaymentAddRs"].Rows[0]["statusMessage"]);
if (sQueryResponse != "Status OK")
{
Utilcl.LogMessage("QB Credit Memo Query Response: " + sQueryResponse);
}
}
}
}
}
}
catch (Exception ex)
{
Utilcl.LogMessage(ex);
}
finally
{
if (IMsgSetRequestToQB != null)
{
Marshal.FinalReleaseComObject(IMsgSetRequestToQB);
}
if (ICreditMemoQueryToQB != null)
{
Marshal.FinalReleaseComObject(ICreditMemoQueryToQB);
}
}
}
}
I use Evernote C# API. I understand how filters working.
ENNoteStoreClient store = ENSessionAdvanced.SharedSession.PrimaryNoteStore;
SyncState currentState = store.GetSyncState();
int currentUpdateCount = currentState.UpdateCount;
if (currentUpdateCount > latestUpdateCount)
{
latestUpdateCount = currentUpdateCount;
// Here synchronization code
}
I have latestUpdateCount and how I can get notes with sequence number >= this number?
You'll want to use GetFilteredSyncChunk using code something like the following:
List<SyncChunk> syncBlocks = new List<SyncChunk>();
int maxEntries = 250;
// These are sample filter settings; you should use what's appropriate for you based on
// what data you want returned in your note objects.
SyncChunkFilter filter = new SyncChunkFilter();
filter.IncludeNotes = true;
filter.IncludeNoteAttributes = true;
filter.IncludeNotebooks = true;
filter.IncludeTags = false;
filter.IncludeSearches = false;
filter.IncludeResources = false;
filter.IncludeLinkedNotebooks = false;
filter.IncludeExpunged = false;
filter.IncludeNoteApplicationDataFullMap = false;
filter.IncludeResourceApplicationDataFullMap = false;
filter.IncludeNoteResourceApplicationDataFullMap = false;
do
{
SyncChunk chunk = store.getFilteredSyncChunk(currentUpdateCount, maxEntries, filter);
if (chunk == null)
{
return null; // This can happen if there is a "503 - Service unavailable" error accessing this person's Evernote info
}
syncBlocks.Add(chunk);
currentUpdateCount = chunk.ChunkHighUSN;
} while (currentUpdateCount < serverSyncState.UpdateCount);
foreach (SyncChunk chunk in syncBlocks)
{
if (chunk != null && chunk.Notes != null)
{
foreach (Note chunkNote in chunk.Notes)
{
// do something with the retrieved chunkNote object
}
}
}
I have the following code which creates a Task in Salesforce and then tracks a user's browsing history and stores it in SalesForce. Currently, it displays each and every page the user has browsed as an individual entry. I want to group all those entries together in the Browsing_History__c object instead of task being created every time a user visits a page.
Any help would be appreciated..I am not familiar with SF very much. :)
private void CreateTaskInSF(string id, string type, string details, string description)
{
// if there's a similar Event in the past 2 hours, don't add it
QueryResult qr = null;
try // get events from past 2 hours
{
qr = Binding.query("Select Details__c from Task WHERE WhoId='" + id + "' and Type__c='" + type + "' and CreatedDate > " + DateTime.UtcNow.AddHours(-2).ToString("s") + "Z");
}
catch (Exception e)
{
return;
}
bool logged = false;
if (qr != null) // if there are Tasks in past 2 hours
{
sforce.sObject[] browsing = qr.records;
if (browsing != null)
{
// iterate through events to make sure the new Task isn't logged
for (int i = 0; i < browsing.Length; i++)
{
Task currTask = (Task)browsing[i];
if (currTask.Details__c == details)
{
if (description != "") // is there a description to check for?
{
string oldTaskDescription = "";
if (currTask.Description != null)
oldTaskDescription = currTask.Description;
if (oldTaskDescription == description) // if there is a description match
logged = true;
}
else
logged = true; // there's no description, so check only on details field
}
}
}
}
if (logged == true)
{
return; // if Activity is already logged, don't log it again
}
else if (type == "Browsing")
{
QueryResult browsingQuery = null;
try // get events from past 2 hours
{
browsingQuery = Binding.query("Select Web_Browsing__c from Task WHERE WhoId='" + id + "' and Subject='" + type + "' and Details__c='" + details + "' and CreatedDate > " + DateTime.UtcNow.AddHours(-2).ToString("s") + "Z");
}
catch
{
}
Boolean createNewBrowsing = false;
if (browsingQuery != null) // if there are Tasks in past 2 hours
{
sforce.sObject[] webBrowsing = browsingQuery.records;
if (webBrowsing != null)
{
//find correct object and update Browsing_History__c
//Binding.update
}
else
{
createNewBrowsing = true;
}
}
else
{
createNewBrowsing = true;
}
if (createNewBrowsing)
{
Web_Browsing__c newTask = new Web_Browsing__c();
newTask.Lead__c = id;
newTask.Browsing_History_255__c = details;
newTask.Type__c = type;
newTask.Browsing_History__c = details;
newTask.CreatedDate = DateTime.Now;
//if(type == "Browsing") newTask. = details;
//SaveResult[] createResult = Binding.create(new sObject[] { newTask });
try
{
SaveResult[] createResult = Binding.create(new sObject[] { newTask });
}
catch (Exception e)
{
return;
}
}
}
else
{
// if this new Activity isn't logged, then create a new Activity Task
sforce.Task newTask = new sforce.Task();
newTask.WhoId = id;
newTask.Subject = type;
newTask.Details__c = details;
if (description != "") newTask.Description = description;
newTask.Status = "Completed";
newTask.Priority = "Normal";
newTask.ActivityDate = DateTime.Now;
newTask.ActivityDateSpecified = true;
// insert it
try
{
SaveResult[] createResult = Binding.create(new sforce.sObject[] { newTask });
}
catch (Exception e)
{
return;
}
}
}
You'll need to update your query to ask for the browsing history object and update the code to create a browsing history object instead of a task.
If you haven't already, review the Web Services API docs, it has examples for querying and creating in java/c#.