EWS - How to search for items [message] between dates? - c#

I am trying to search for message items between two dates from the inbox folder.
I use the following restrictionType but it throws this error:
firmt.RootFolder = null
What am I doing wrong?
There is some messages between the mentionned dates ;-)
Thanks for your suggestions.
using (ExchangeServiceBinding esb = new ExchangeServiceBinding())
{
esb.Url = ConfigurationManager.AppSettings["ExchangeWebServicesURL"].ToString();
esb.RequestServerVersionValue = new RequestServerVersion();
esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;
esb.PreAuthenticate = true;
esb.Credentials = new NetworkCredential(email, password);
FindItemType findItemRequest = new FindItemType();
// paging
IndexedPageViewType ipvt = new IndexedPageViewType();
ipvt.BasePoint = IndexBasePointType.Beginning;
ipvt.MaxEntriesReturned = nombreMessage;
ipvt.MaxEntriesReturnedSpecified = true;
ipvt.Offset = offset;
findItemRequest.Item = ipvt;
// filter by dates
AndType andType = new AndType();
List<SearchExpressionType> searchExps = new List<SearchExpressionType>();
RestrictionType restriction = new RestrictionType();
PathToUnindexedFieldType pteft = new PathToUnindexedFieldType
{
FieldURI = UnindexedFieldURIType.itemDateTimeSent
};
IsGreaterThanOrEqualToType IsGreaterThanOrEqualTo = new IsGreaterThanOrEqualToType
{
Item = pteft,
FieldURIOrConstant = new FieldURIOrConstantType
{
Item = new ConstantValueType
{
Value = DateTime.Today.AddDays(-6d).ToString()
}
}
};
searchExps.Add(IsGreaterThanOrEqualTo);
IsLessThanOrEqualToType IsLessThanOrEqualTo = new IsLessThanOrEqualToType
{
Item = pteft,
FieldURIOrConstant = new FieldURIOrConstantType
{
Item = new ConstantValueType
{
Value = DateTime.Today.AddDays(1d).ToString()
}
}
};
searchExps.Add(IsLessThanOrEqualTo);
andType.Items = searchExps.ToArray();
restriction.Item = andType;
findItemRequest.Restriction = restriction;
//// Define the sort order of items.
FieldOrderType[] fieldsOrder = new FieldOrderType[1];
fieldsOrder[0] = new FieldOrderType();
PathToUnindexedFieldType dateOrder = new PathToUnindexedFieldType
{
FieldURI = UnindexedFieldURIType.itemDateTimeReceived
};
fieldsOrder[0].Item = dateOrder;
fieldsOrder[0].Order = SortDirectionType.Descending;
findItemRequest.SortOrder = fieldsOrder;
findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
// define which item properties are returned in the response
findItemRequest.ItemShape = new ItemResponseShapeType
{
BaseShape = DefaultShapeNamesType.IdOnly
};
// identify which folder to search
DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
folderIDArray[0] = new DistinguishedFolderIdType { Id = DistinguishedFolderIdNameType.inbox };
// add folders to request
findItemRequest.ParentFolderIds = folderIDArray;
// find the messages
FindItemResponseType findItemResponse = esb.FindItem(findItemRequest);
//-------------
ArrayOfResponseMessagesType responseMessages = findItemResponse.ResponseMessages;
ResponseMessageType responseMessage = responseMessages.Items[0];
if (responseMessage is FindItemResponseMessageType)
{
FindItemResponseMessageType firmt = (responseMessage as FindItemResponseMessageType);
*******FindItemParentType fipt = firmt.RootFolder;********
object obj = fipt.Item;
// FindItem contains an array of items.
ArrayOfRealItemsType realitems = (obj as ArrayOfRealItemsType);
ItemType[] items = realitems.Items;
// if no messages were found, then return null -- we're done
if (items == null || items.Count() <= 0)
return null;
// FindItem never gets "all" the properties, so now that we've found them all, we need to get them all.
BaseItemIdType[] itemIds = new BaseItemIdType[items.Count()];
for (int i = 0; i < items.Count(); i++)
itemIds[i] = items[i].ItemId;
GetItemType getItemType = new GetItemType
{
ItemIds = itemIds,
ItemShape = new ItemResponseShapeType
{
BaseShape = DefaultShapeNamesType.AllProperties,
BodyType = BodyTypeResponseType.Text,
BodyTypeSpecified = true,
AdditionalProperties = new BasePathToElementType[] {
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.itemDateTimeSent },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageFrom },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageIsRead },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageSender },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageToRecipients },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageCcRecipients },
new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageBccRecipients }
}
}
};
GetItemResponseType getItemResponse = esb.GetItem(getItemType);
messages = ReadItems(getItemResponse, items.Count());
}

I found the answer on my own after a long search about date format.
The restrictions has to be defined as this:
// greater or equal to
string dateStart = DateTime.Today.add(-6d);
string dateEnd = DateTime.Today.Add(1d);
PathToUnindexedFieldType dateSentPath = new PathToUnindexedFieldType();
dateSentPath.FieldURI = UnindexedFieldURIType.itemDateTimeSent;
IsGreaterThanOrEqualToType IsGreaterThanOrEqual = new IsGreaterThanOrEqualToType();
IsGreaterThanOrEqual.Item = dateSentPath;
FieldURIOrConstantType dateConstant = new FieldURIOrConstantType();
ConstantValueType dateConstantValue = new ConstantValueType();
dateConstantValue.Value = string.Format("{0}-{1}-{2}T00:00:00Z", dateStart.Year.ToString(), dateStart.Month.ToString(), dateStart.Day.ToString());
dateConstant.Item = dateConstantValue;
IsGreaterThanOrEqual.FieldURIOrConstant = dateConstant;
// less than or equal to
PathToUnindexedFieldType dateSentPath1 = new PathToUnindexedFieldType();
dateSentPath1.FieldURI = UnindexedFieldURIType.itemDateTimeSent;
IsLessThanOrEqualToType lessThanOrEqualTo = new IsLessThanOrEqualToType();
lessThanOrEqualTo.Item = dateSentPath1;
FieldURIOrConstantType dateConstant1 = new FieldURIOrConstantType();
ConstantValueType dateConstantValue1 = new ConstantValueType();
dateConstantValue1.Value = string.Format("{0}-{1}-{2}T00:00:00Z", dateEnd.Year.ToString(), dateEnd.Month.ToString(), dateEnd.Day.ToString());
dateConstant1.Item = dateConstantValue1;
lessThanOrEqualTo.FieldURIOrConstant = dateConstant1;
RestrictionType restriction = new RestrictionType();
AndType andType = new AndType();
andType.Items = new SearchExpressionType[] { lessThanOrEqualTo, IsGreaterThanOrEqual };
restriction.Item = andType;
findItemRequest.Restriction = restriction;
Hope this help someone some day ;-)

In case anyone stumbles upon this in the future, EWS has gotten even more strict about date formatting. The accepted answer formatting works for 2 digit months, but it does not for single digit months.
The formatting that works in all cases is:
DateTime.Today.AddDays(15).ToString("yyyy-MM-ddThh:mm:ssZ")

The restriction also works using the "Sortable date/time pattern".
Datetime.Now.ToString("s")

Related

Google Sheets API .NET v4 Creating Drop-down list for a grid cell

I'm trying to create a drop-down list on a grid. I was following the advice on this page. However, I'm not able to enter any string values for UserEnteredValue. The underlined error I'm getting:
Cannot implicitly convert type 'Google.Apis.Sheets.v4.Data.ConditionValue' to 'System.Collections.Generic.IList'.An explicit conversion exists(are you missing a cast?)
public Request createDataValidationRequest(int sheetID, int startRow, int endRow, int startColumn, int endColumn)
{
var updateCellsRequest = new Request() {
SetDataValidation = new SetDataValidationRequest()
{
Range = new GridRange()
{
SheetId = sheetID,
StartRowIndex = startRow,
StartColumnIndex = startColumn,
EndRowIndex = endRow,
EndColumnIndex = endColumn
},
Rule = new DataValidationRule()
{
Condition = new BooleanCondition()
{
Type = "ONE_OF_LIST",
Values = new ConditionValue()
{
UserEnteredValue = "awer"
}
},
InputMessage = "Select an Option",
ShowCustomUi = true,
Strict = true
}
}
};
return updateCellsRequest;
}
I was able to get the following, for my situation to work.
SpreadsheetsResource.GetRequest request = _sheetsService.Spreadsheets.Get(newTimeSheet.Id);
Spreadsheet spreadsheet = request.Execute();
SheetProperties timeSheetProperties = new SheetProperties();
for (int z = 0; z < spreadsheet.Sheets.Count; z++)
{
SheetProperties sheetProperties = spreadsheet.Sheets[z].Properties;
if (sheetProperties.Title == "3c TIME")
{
timeSheetProperties = sheetProperties;
break;
}
}
var updateCellsRequest = new Request()
{
SetDataValidation = new SetDataValidationRequest()
{
Range = new GridRange()
{
SheetId = timeSheetProperties.SheetId,
StartRowIndex = 2,
StartColumnIndex = 0,
EndColumnIndex = 1
},
Rule = new DataValidationRule()
{
Condition = new BooleanCondition()
{
//Type = "ONE_OF_RANGE",
Type = "ONE_OF_LIST",
Values = new List<ConditionValue>()
{
new ConditionValue()
{
UserEnteredValue = "YES",
},
new ConditionValue()
{
UserEnteredValue = "NO",
},
new ConditionValue()
{
UserEnteredValue = "MAYBE",
}
}
},
InputMessage = "Select an Option",
ShowCustomUi = true,
Strict = true
}
}
};
var requestBody = new Google.Apis.Sheets.v4.Data.BatchUpdateSpreadsheetRequest();
var requests = new List<Request>();
requests.Add(updateCellsRequest);
requestBody.Requests = requests;
var batchRequest = _sheetsService.Spreadsheets.BatchUpdate(requestBody, newTimeSheet.Id);
batchRequest.Execute();

Displaying data labels on open xml charts in c#

We are using open xml for displaying bar graph in exl export but it is not showing labels on data like values above each bar.
Here is the code i am using
BarChart barChart = plotArea.AppendChild<BarChart>(new BarChart(new BarDirection() { Val = new EnumValue<BarDirectionValues>(BarDirectionValues.Column) },
new BarGrouping() { Val = new EnumValue<BarGroupingValues>(BarGroupingValues.Clustered) }));
BarChartSeries barChartSeries = barChart.AppendChild<BarChartSeries>(new BarChartSeries(new Index()
{
Val =
new UInt32Value(i)
},
new Order() { Val = new UInt32Value(i) },
new SeriesText(new NumericValue() { Text = key })));
where key is data value for bar. But still it is not displaying. Can anyone tell where exactly have to put data label so that value labels should be visible on top of each bar in bar graph
You just need to create a DataLabels class, modify how you want them to look and append it to your series. Hope this helps
C.DataLabels dataLabels2 = new C.DataLabels();
C.TextProperties textProperties2 = new C.TextProperties();
A.BodyProperties bodyProperties2 = new A.BodyProperties();
A.ListStyle listStyle2 = new A.ListStyle();
A.Paragraph paragraph2 = new A.Paragraph();
A.ParagraphProperties paragraphProperties2 = new A.ParagraphProperties();
A.DefaultRunProperties defaultRunProperties2 = new A.DefaultRunProperties() { FontSize = 700 };
A.SolidFill solidFill2 = new A.SolidFill();
A.SchemeColor schemeColor2 = new A.SchemeColor() { Val = A.SchemeColorValues.Background1 };
solidFill2.Append(schemeColor2);
defaultRunProperties2.Append(solidFill2);
paragraphProperties2.Append(defaultRunProperties2);
A.EndParagraphRunProperties endParagraphRunProperties2 = new A.EndParagraphRunProperties() { Language = "en-US" };
paragraph2.Append(paragraphProperties2);
paragraph2.Append(endParagraphRunProperties2);
textProperties2.Append(bodyProperties2);
textProperties2.Append(listStyle2);
textProperties2.Append(paragraph2);
C.ShowLegendKey showLegendKey2 = new C.ShowLegendKey() { Val = false };
C.ShowValue showValue2 = new C.ShowValue() { Val = true };
C.ShowCategoryName showCategoryName2 = new C.ShowCategoryName() { Val = false };
C.ShowSeriesName showSeriesName2 = new C.ShowSeriesName() { Val = false };
C.ShowPercent showPercent2 = new C.ShowPercent() { Val = false };
C.ShowBubbleSize showBubbleSize2 = new C.ShowBubbleSize() { Val = false };
C.ShowLeaderLines showLeaderLines2 = new C.ShowLeaderLines() { Val = false };
dataLabels2.Append(textProperties2);
dataLabels2.Append(showLegendKey2);
dataLabels2.Append(showValue2);
dataLabels2.Append(showCategoryName2);
dataLabels2.Append(showSeriesName2);
dataLabels2.Append(showPercent2);
dataLabels2.Append(showBubbleSize2);
dataLabels2.Append(showLeaderLines2);
barChartSeries2.Append(dataLabels2);

Travelport uAPI SoapClient response issue

i am new to travelport universal api. i receive response from api. I perform LOW FARE SEARCH and in response the fare information and the flight information return in two different list.the problem is that i don't find any relationship in these LIST's. and also WHAT IS THE BEST WAY TO DECODE THE WSDL RESPONSE. i am using WSDL below is my code
string TargetBranch = "P7004961";
string OriginApplication = "uAPI";
string Origin="DXB";
string Destination="LHR";
string Departuredate = "2014-03-25T00:00:00";
string FlightStatus = "One-way";
string url = "https://americas-uapi.copy-webservices.travelport.com/B2BGateway/connect/uAPI/AirService";
string ReturnDate = "2014-04-05T00:00:00";
string UserName = "Universal API/uAPI6035036525-8ff7f8fc", Password = "DSXSEDn3fme9d6m2DfKP5rEaW";
LowFareSearchReq req = new LowFareSearchReq();
req.TargetBranch = TargetBranch;
BillingPointOfSaleInfo biPOS = new BillingPointOfSaleInfo();
biPOS.OriginApplication = OriginApplication;
req.BillingPointOfSaleInfo = biPOS;
/////////// Origin to Destination////////////////
SearchAirLeg airLeg = new SearchAirLeg();
Airport fromAirPort = new Airport() { Code = Origin };
typeSearchLocation fromTypLoc = new typeSearchLocation() { Item = fromAirPort };
airLeg.SearchOrigin = new typeSearchLocation[1] { fromTypLoc };
Airport toAirPort = new Airport() { Code = Destination };
typeSearchLocation toTypLoc = new typeSearchLocation() { Item = toAirPort };
airLeg.SearchDestination = new typeSearchLocation[1] { toTypLoc };
typeTimeSpec origDep = new typeTimeSpec() { PreferredTime = Departuredate };
airLeg.Items = new typeTimeSpec[1] { origDep };
/////////////////// Destination to Origin ////////////////////
SearchAirLeg returnLeg = new SearchAirLeg();
Airport RetfromAirport = new Airport() { Code = Destination };
typeSearchLocation fromLocation = new typeSearchLocation() { Item = RetfromAirport };
returnLeg.SearchOrigin = new typeSearchLocation[1] { fromLocation };
Airport retToAirpot = new Airport() { Code = Origin };
typeSearchLocation tolocation = new typeSearchLocation() { Item = retToAirpot };
returnLeg.SearchDestination = new typeSearchLocation[1] { tolocation };
typeTimeSpec retdate = new typeTimeSpec() { PreferredTime = ReturnDate };
returnLeg.Items = new typeTimeSpec[1] { retdate };
///////// checking for one way or return//////////////////////////
if (FlightStatus == "One-way")
{
req.Items = new object[] { airLeg };
}
else
{
req.Items = new object[] { airLeg, returnLeg };
}
AirSearchModifiers AirsearchModifier = new AirSearchModifiers()
{
DistanceType = typeDistance.KM,
IncludeFlightDetails = true,
PreferNonStop = true,
MaxSolutions = "300",
PreferredProviders= new Provider[1]{ new Provider(){ Code="1G"}}
};
req.AirSearchModifiers = AirsearchModifier;
SearchPassenger pass1 = new SearchPassenger() { Code = "ADT" };
req.SearchPassenger = new SearchPassenger[] { pass1 };
string Currency = "PKR";
AirPricingModifiers AirPriceMode = new AirPricingModifiers() { CurrencyType = Currency, };
req.AirPricingModifiers = AirPriceMode;
LowFareSearchRsp response = new LowFareSearchRsp();
AirLowFareSearchBinding binding = new AirLowFareSearchBinding();
binding.Url = url;
binding.Credentials = new NetworkCredential(UserName, Password);
response = binding.service(req);
Thanks to all.Finally i found result which is below quit easy in fact In the LowFareSearch response you get back among other info a list of AirSegments and a list of AirPricingSolutions. Each AirPricingSolution contains AirPricingInfo with the applicable SegmentRef keys and BookingCode info. Each SegmentRef key corresponds to a flight in the AirSegment list. This is how you know which flights (AirSegments) correspond to a specific price (AirPricingSolution).

How to insert multiple items in Quickbook Invoice

I need to insert a new invoice for a particular customer , I can able to insert , but i don't have any idea about how to insert multiple items in invoice. How to use the property Items and ItemsElementName to insert multiple items.
If my question is unclear please let me know. I have attached the snapshot and code for reference.
Code:
protected void btnsendInvoiceDetails_Click(object sender, EventArgs e)
{
string accessToken = "lvprdRM1HLr6o11Bnip2fGizlXWbFfADnS1Btvm2L4VPOTRI";
string appToken = "297db54bb5526b494adb86fb2a41063192cd";
string accessTokenSecret = "JfSTrprW83JTXrSVHD3uf7th23gP0SOzBQcn4Nrt";
string consumerKey = "qyprdKLN5YHpCPSlWQZTiKVc28dywR";
string consumerSecret = "JPMNB37YnCPGU9m9vuXkF2M71lbDb7blhcLB7HeF";
string companyID = "813162085";
OAuthRequestValidator oauthValidator = new OAuthRequestValidator(accessToken, accessTokenSecret, consumerKey, consumerSecret);
ServiceContext context = new ServiceContext(oauthValidator,appToken,companyID, IntuitServicesType.QBO);
DataServices service = new DataServices(context);
InvoiceHeader a = new InvoiceHeader();
a.CustomerName = "Antivirus Norton Security";
a.CustomerId = new IdType { idDomain = idDomainEnum.QBO, Value = "6" };
a.TotalAmt = 157.00m;
a.SubTotalAmt = 37.00m;
a.ShipMethodName = "Gmail";
a.ShipMethodId = new IdType { idDomain = idDomainEnum.QBO, Value = "41" };
a.DocNumber = "1040";
a.DueDateSpecified = true;
// a.Item = 10.00m;
//a.ItemElementName = ItemChoiceType2.DiscountAmt;
DateTime dt = Convert.ToDateTime("08/07/2013");
a.DueDate = dt;
InvoiceLine mnm = new InvoiceLine();
mnm.Desc = "Antivirus Norton Security The Best Security ";
mnm.Id = new IdType { idDomain = idDomainEnum.QBO, Value = "25" };
mnm.Amount = 65.00m;
mnm.AmountSpecified = true;
// mnm.Items = "Europe";
//mnm.ItemsElementName = "Zebronic";
InvoiceLine[] invline = new InvoiceLine[] { mnm };
var invoices = new Intuit.Ipp.Data.Qbo.Invoice();
invoices.Header = a;
invoices.Line = invline;
var addedInvoice = service.Add(invoices);
var qboInvoices = service.FindAll(invoices, 1,10);
foreach (var qboinv in qboInvoices)
{
string id = Convert.ToString(qboinv.Id.Value);
}
GridView1.DataSource = invoices;
GridView1.DataBind();
}
Image:
Try this:
InvoiceLine i = new InvoiceLine();
i.ItemsElementName = new ItemsChoiceType2[1];
i.ItemsElementName[0] = ItemsChoiceType2.ItemId;
i.Items = new Intuit.Ipp.Data.Qbd.IdType[1];
i.Items[0] = new Intuit.Ipp.Data.Qbd.IdType() { idDomain = Intuit.Ipp.Data.Qbd.idDomainEnum.QBO, Value = "6" };

Using eBay SDK API: internationalShippingOptions.ShipToLocation.Add("Worldwide"); causes:"Object reference not set to an instance of an object"

My goal here so to make the listing say "Free International Shipping". Trying to set up international options and it said I need to set ShipToLocation I tried the line below:
internationalShippingOptions.ShipToLocation.Add("Worldwide");
But when the program hits it I get this error:
"Object reference not set to an instance of an object"
If you would like to see the full method it is:
static ShippingDetailsType BuildShippingDetails()
{
ShippingDetailsType sd = new ShippingDetailsType();
sd.ApplyShippingDiscount = false;
sd.ShippingType = ShippingTypeCodeType.Flat;
AmountType amount = new AmountType();
amount.Value = 0;
amount.currencyID = CurrencyCodeType.USD;
ShippingServiceOptionsTypeCollection shippingOptions = new ShippingServiceOptionsTypeCollection();
ShippingServiceOptionsType domesticShippingOptions = new ShippingServiceOptionsType();
domesticShippingOptions.ShippingService = ShippingServiceCodeType.EconomyShippingFromOutsideUS.ToString();
domesticShippingOptions.FreeShipping = true;
domesticShippingOptions.ShippingServiceCost = amount;
domesticShippingOptions.ShippingServicePriority = 1;
shippingOptions.Add(domesticShippingOptions);
ShippingServiceOptionsType internationalShippingOptions = new ShippingServiceOptionsType();
InternationalShippingServiceOptionsType internationalShippingOptions = new InternationalShippingServiceOptionsType();
internationalShippingOptions.ShippingService = ShippingServiceCodeType.StandardInternational.ToString();
internationalShippingOptions.ShipToLocation.Add("Worldwide");
internationalShippingOptions.FreeShipping = true;
sd.InternationalShippingServiceOption = new InternationalShippingServiceOptionsTypeCollection(new InternationalShippingServiceOptionsType[] { internationalShippingOptions });
sd.ShippingServiceOptions = shippingOptions;
return sd;
}
Here is the code to make it say "Free Standard Intl Shipping". At first in the sandbox it says "Free Standard Shipping" but if you change the shipping destination in the sandbox it will say "Free Standard Intl Shipping".
static ShippingDetailsType BuildShippingDetails()
{
// Shipping details
ShippingDetailsType sd = new ShippingDetailsType();
sd.ApplyShippingDiscount = true;
sd.PaymentInstructions = "eBay .Net SDK test instruction.";
sd.ShippingRateType = ShippingRateTypeCodeType.StandardList;
// Shipping type and shipping service options
//adding international shipping
InternationalShippingServiceOptionsType internationalShipping1 = new InternationalShippingServiceOptionsType();
internationalShipping1.ShippingService = ShippingServiceCodeType.StandardInternational.ToString();
internationalShipping1.ShippingServiceCost = new AmountType { Value = 0, currencyID = CurrencyCodeType.USD };
internationalShipping1.ShippingServicePriority = 1;
internationalShipping1.ShipToLocation = new StringCollection(new[] { "Worldwide" });
sd.ShippingServiceUsed = ShippingServiceCodeType.StandardInternational.ToString();
sd.InternationalShippingServiceOption = new InternationalShippingServiceOptionsTypeCollection(new[] { internationalShipping1 });
//adding domestic shipping
ShippingServiceOptionsType domesticShipping1 = new ShippingServiceOptionsType();
domesticShipping1.ShippingService = ShippingServiceCodeType.ShippingMethodStandard.ToString();
domesticShipping1.ShippingServiceCost = new AmountType { Value = 0, currencyID = CurrencyCodeType.USD };
domesticShipping1.ShippingInsuranceCost = new AmountType { Value = 0, currencyID = CurrencyCodeType.USD };
domesticShipping1.ShippingServicePriority = 4;
domesticShipping1.LocalPickup = true;
domesticShipping1.FreeShipping = true;
sd.ShippingServiceOptions = new ShippingServiceOptionsTypeCollection(new[] { domesticShipping1 });
sd.ShippingType = ShippingTypeCodeType.Flat;
return sd;
To call the method:
item.ShippingDetails = BuildShippingDetails();

Categories

Resources