SMS history between 2 dates - Twilio - c#

I'm developing an SMS communication test app in WPF C# with Twilio. Almost everything works like a charm but I cannot retrieve the SMS history between 2 given dates.
The strange thing is that I can retrieve the total SMS costs between 2 dates which is almost the same...
Now here is my code to retrieve the costs for 2 given dates (which works) :
public void SmsBilling()
{
var records = RecordResource.Read(
category: RecordResource.CategoryEnum.SmsOutbound,
startDate: DateTime.Parse(bills.StartDate),
endDate: DateTime.Parse(bills.EndDate));
foreach (var record in records)
{
bills.NbSms = record.Count;
bills.SmsCost = record.Price;
}
}
This is the code to retrieve the history between 2 dates
(which crashes with the following exception : System.ArgumentNullException: 'The string reference is not set to an instance of a string.
Parameter name: s')
private void GetSms()
{
smsList.Sms = new List<Sms>();
var messages = MessageResource.Read(
limit: 20,
dateSentAfter: DateTime.Parse(bills.StartDate),
dateSentBefore: DateTime.Parse(bills.EndDate));
foreach (var record in messages)
{
smsList.Sms.Add(new Sms { DateHour = record.DateSent, Recipient = record.To, Source = record.From.ToString() });
}
smslist.ItemsSource = smsList.Sms;
}
What am I missing?

You can't pass a null reference to DateTime.Parse.
You may want to replace null values with DateTime.MinValue and DateTime.MaxValue:
dateSentAfter: DateTime.Parse(bills.StartDate ?? DateTime.MinValue),
dateSentBefore: DateTime.Parse(bills.EndDate ?? DateTime.MaxValue));

Related

how can I use "distinct" with all my property

I have a method that allows me to create an agent list.
This list of agents contains "Nom", "Prenom", "Matricule", "Mail".
I use.distinct() to sort them, but this only takes into account "Nom", "Prenom", "Matricule". This does not check if the emails are different. How do I proceed?
The creation of my agent list:
private ObservableCollection<AgentMailModel> _Agents;
public ObservableCollection<AgentMailModel> Agents
{
get
{
return _Agents;
}
set
{
if (value != _Agents)
{
_Agents = value;
RaisePropertyChanged("Agents");
}
}
}
foreach (Destinataire dst in (await _dataService.GetDestinatairesAsync()))
_TmpAgents.Add(new AgentMailModel() { Matricule = dst.Matricule, Nom = dst.Nom, Prenom = dst.Prenom, Mail = dst.Mail });
foreach (AgentModel ag in (await _dataService.GetAgentsContratsAsync()))
_TmpAgents.Add(new AgentMailModel() { Matricule = ag.Matricule, Nom = ag.Nom, Prenom = ag.Prenom, Mail = ag.Mail });
Agents = new ObservableCollection<AgentMailModel(_TmpAgents.Distinct());
My list in WPF :
My database :
As you can see :
It displays "carré" (cause "Nom" is different, It also works with a different "Prenom" or "Matricule) and only one "carre" (without "é").
Distinct() doesn't work with my Mails. Any tips ?
You have two possibilities.
First one is to create a class of IEqualityComparer and implement a full comparison.
you can find an example here.
The second one is to convert the objects to JSON, and made of comparison of strings instead of objects.

Making a list of objects filled with SOAP API data results in "Index out of range" exception

I use an e-commerce SOAP API, forgive me if it's too confusing to answer. I just want to know if I'm just making a stupid mistake before I write a ticket to API maintainers.
public void WriteXML()
{
var results = GetProductsFromApi().results.ToList();
using (var file = File.Create(#"products.xml"))
{
var list = new List<Product>();
var writer = new XmlSerializer(typeof(List<Product>));
foreach (var result in results)
{
var newProduct = new Product
{
Id = result.productId,
Index = result.productDisplayedCode,
Stock = result.productStocksData.productStocksQuantities[0].productSizesData[0].productSizeQuantity,
IsIgnored = false,
IsInDelivery = false
};
list.Add(newProduct);
}
writer.Serialize(file, list);
}
}
I made a request to the API and I want to store it in a list, so each result gets serialized into an XML later. The code above works if I set Stock to something like Stock = 1, - however if left as it is, the program quits with Unhandled exception: System.IndexOutOfRangeException.
What's weird though is that if I do something similar to the following before building the Product object:
Console.WriteLine(result.productStocksData.productStocksQuantities[0].productSizesData[0].productSizeQuantity);
...I am met with a correct API response.
I have no clue what's going on. I tried checking if the result is null before constructing Product, but it didn't help. The whole exception is so confusing to me I don't really know where to start looking.
Edit: Using Fildor's proposed code, I wrote this:
float? lol = result.productStocksData.productStocksQuantities.FirstOrDefault().productSizesData.FirstOrDefault()?.productSizeQuantity ?? null; //doesn't actually change anything if it's null or 0
if (lol.GetValueOrDefault() == 0) {
lol = 1;
};
var newProduct = new Product
{
Id = result.productId,
Index = result.productDisplayedCode,
Stock = (float)lol,
IsIgnored = false,
IsInDelivery = false
};
Console.WriteLine("Processed product has a stock of " + lol);
list.Add(newProduct);
It now results in System.NullReferenceException. It responds with actual stock size, and said error appears after.

Redis Optimization with .NET, and a concrete example of How to Store and get an element from Hash

I have more than 15000 POCO elements stored in a Redis List. I'm using ServiceStack in order to save and get them. However, I'm not pleased about the response times that I have when I get them into a grid. As I read , it would be better to store these object in hash - but unfortunately I could not find any good example for my case :(
This is the method I use, in order to get them into my grid
public IEnumerable<BookingRequestGridViewModel> GetAll()
{
try
{
var redisManager = new RedisManagerPool(Global.RedisConnector);
using (var redis = redisManager.GetClient())
{
var redisEntities = redis.As<BookingRequestModel>();
var result =redisEntities.Lists["BookingRequests"].GetAll().Select(z=> new BookingRequestGridViewModel
{
CreatedDate =z.CreatedDate,
DropOffBranchName =z.DropOffBranch !=null ? z.DropOffBranch.Name : string.Empty,
DropOffDate =z.DropOffDate,
DropOffLocationName = z.DropOffLocation != null ? z.DropOffLocation.Name : string.Empty,
Id =z.Id.Value,
Number =z.Number,
PickupBranchName =z.PickUpBranch !=null ? z.PickUpBranch.Name :string.Empty,
PickUpDate =z.PickUpDate,
PickupLocationName = z.PickUpLocation != null ? z.PickUpLocation.Name : string.Empty
}).OrderBy(z=>z.Id);
return result;
}
}
catch (Exception ex)
{
return null;
}
}
Note that I use redisEntities.Lists["BookingRequests"].GetAll() which is causing performance issues (I would like to use just redisEntities.Lists["BookingRequests"] but I lose last updates from grid - after editing)
I would like to know if saving them into list is a good approach as for me it's very important to have a fast grid (I have now 1 second at paging which is huge).
Please, advice!
Firstly you should not create a new Redis Client Manager like RedisManagerPool instance each time, there should only be a singleton instance of RedisManagerPool in your App which all clients are resolved from.
But otherwise I would rethink your data access strategy, downloading 15K items in a batch is not an ideal strategy. You can create indexes by storing ids in Sets or you could store items in a sorted set with a value that you can page against like an incrementing id, e.g:
var redisEntities = redis.As<BookingRequestModel>();
var bookings = redisEntities.SortedSets["bookings"];
foreach (var item in new BookingRequestModel[0])
{
redisEntities.AddItemToSortedSet(bookings, item, item.Id);
}
That way you will be able to fetch them in batches, e.g:
var batch = bookings.GetRangeByLowestScore(fromId, toId, skip, take);

Get field data outside of reporting database using Encompass360 SDK

I'm trying to build a standalone application that creates a custom report for Encompass360 without needing to put certain fields into the reporting database.
So far I have only found one way to do it, but it is extremely slow. (Much slower than a normal report within encompass when retrieving data outside of the reporting database.) It takes almost 2 minutes to pull the data for 5 loans doing this:
int count = 5;
StringList fields = new StringList();
fields.Add("Fields.317");
fields.Add("Fields.3238");
fields.Add("Fields.313");
fields.Add("Fields.319");
fields.Add("Fields.2");
// lstLoans.Items contains the string location of the loans(i.e. "My Pipeline\Dave#6")
foreach (LoanIdentity loanID in lstLoans.Items)
{
string[] loanIdentifier = loanID.ToString().Split('\\');
Loan loan = Globals.Session.Loans.Folders[loanIdentifier[0]].OpenLoan(loanIdentifier[1]);
bool fundingPlus = true; // if milestone == funding || shipping || suspended || completion;
if (!fundingPlus)
continue;
bool oneIsChecked = false;
LogMilestoneEvents msEvents = loan.Log.MilestoneEvents;
DateTime date;
MilestoneEvent ms = null; // better way to do this probably
if (checkBox4.Checked)
{
ms = msEvents.GetEventForMilestone("Completion");
if (ms.Completed)
{
oneIsChecked = true;
}
}
else if (checkBox3.Checked)
{
ms = msEvents.GetEventForMilestone("Suspended");
if (ms.Completed)
{
oneIsChecked = true;
}
}
else if (checkBox2.Checked)
{
ms = msEvents.GetEventForMilestone("Shipping");
if (ms.Completed)
{
oneIsChecked = true;
}
}
else if (checkBox1.Checked)
{
ms = msEvents.GetEventForMilestone("Funding");
if (ms.Completed)
{
oneIsChecked = true;
}
}
if (!oneIsChecked)
continue;
string LO = loan.Fields["317"].FormattedValue;
string LOid = loan.Fields["3238"].FormattedValue;
string city = loan.Fields["313"].FormattedValue;
string address = loan.Fields["319"].FormattedValue;
string loanAmount = loan.Fields["2"].FormattedValue;
if (loanAmount == "")
{
Console.WriteLine(LO);
continue;
}
int numLoans = 1;
addLoanFieldToListView(LO, numLoans, city, address, loanAmount);
if (--count == 0)
break;
}
}
I haven't been able to figure out how to use any of the pipeline methods to retrieve data outside the reporting database, but when all of the fields I am looking for are in the reporting database, it hardly takes a couple seconds to retrieve the contents of hundreds of loans using these tools:
session.Reports.SelectReportingFieldsForLoans(loanGUIDs, fields);
session.Loans.QueryPipeline(selectedDate, PipelineSortOrder.None);
session.Loans.OpenPipeline(PipelineSortOrder.None);
What would really help me is if somebody provided a simple example for retrieving data outside of the reporting database by using the encompass sdk that doesn't take longer than it ought to for retrieving the data.
Note: I am aware I can add the fields to the reporting database that aren't in it currently, so this is not the answer I am looking for.
Note #2: Encompass360 doesn't have it's own tag, if somebody knows of better tags that can be added for the subject at hand, please add them.
I use the SelectFields method on Loans to retrieve loan field data that is not in the reporting database in Encompass. It is very performant compared to opening loans up one by one but the results are returned as strings so it requires some parsing to get the values in their native types. Below is the example from the documentation for using this method.
using System;
using System.IO;
using EllieMae.Encompass.Client;
using EllieMae.Encompass.BusinessObjects;
using EllieMae.Encompass.Query;
using EllieMae.Encompass.Collections;
using EllieMae.Encompass.BusinessObjects.Loans;
class LoanReader
{
public static void Main()
{
// Open the session to the remote server
Session session = new Session();
session.Start("myserver", "mary", "maryspwd");
// Build the query criterion for all loans that were opened this year
DateFieldCriterion dateCri = new DateFieldCriterion();
dateCri.FieldName = "Loan.DateFileOpened";
dateCri.Value = DateTime.Now;
dateCri.Precision = DateFieldMatchPrecision.Year;
// Perform the query to get the IDs of the loans
LoanIdentityList ids = session.Loans.Query(dateCri);
// Create a list of the specific fields we want to print from each loan.
// In this case, we'll select the Loan Amount and Interest Rate.
StringList fieldIds = new StringList();
fieldIds.Add("2"); // Loan Amount
fieldIds.Add("3"); // Rate
// For each loan, select the desired fields
foreach (LoanIdentity id in ids)
{
// Select the field values for the current loan
StringList fieldValues = session.Loans.SelectFields(id.Guid, fieldIds);
// Print out the returned values
Console.WriteLine("Fields for loan " + id.ToString());
Console.WriteLine("Amount: " + fieldValues[0]);
Console.WriteLine("Rate: " + fieldValues[1]);
}
// End the session to gracefully disconnect from the server
session.End();
}
}
You will highly benefit from adding these fields to the reporting DB and using RDB query instead. Internally, Encompass has to open / parse files when you read fields without RDB, which is a slow process. Yet it just does a SELECT query on fields in RDB which is a very fast process. This tool will allow you quickly checking / finding which fields are in RDB so that you can create a plan for your query as well as a plan to update RDB: https://www.encompdev.com/Products/FieldExplorer
You query RDB via Session.Loans.QueryPipeline() very similarly to your use of Loan Query. Here's a good example of source code (in VB): https://www.encompdev.com/Products/AlertCounterFieldPlugin

Get all seller transactions using eBay api

How to get all items and transactions made by the seller on eBay for all time. I can successfully receive all transaction details for the past 10 days using the following code:
// Getting sold items
var durationSpecifiedeBaySellingCall = new GetMyeBaySellingCall(apiContext)
{
SoldList = new ItemListCustomizationType
{
DurationInDays = 10,
DurationInDaysSpecified = true,
Include = true
},
DetailLevelList = new DetailLevelCodeTypeCollection
{
DetailLevelCodeType.ReturnAll
}
};
durationSpecifiedeBaySellingCall.Execute();
but I'm not able to receive all transactions for the past 10 years, for example, when replace the value of DurationInDays with 3650 instead of 10. durationSpecifiedeBaySellingCall.SoldListReturn is null. How can I properly get the list of all user transactions?
It looks like you are using the GetMyeBaySelling API call, the documentation states that you can only pull a Max of 60 Days.
eBay Documentation GetMyeBaySelling

Categories

Resources