I was developing one application where I want to retrieve the available rooms from the "All Rooms" of the outlook address book. I am able to retrieve all the room entries from "All Rooms" Address Entry List. And then able to search for individual room's availability by calling AddressEntry.GetFreeBusy().
But the problem I am facing is the time performance of the code. If the number of rooms is high(let's say 500) then the time take to search availability of the room(worst case scenario where available room locates near to last of the list) is very high.
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application()
var allRooms = app.Session.AddressLists["All Rooms"].Cast<Microsoft.Office.Interop.Outlook.AddressEntry>().ToLis();
DateTime today = DateTime.Today;
foreach(var room in allRooms)
{
//the below function will return the room status in a string of 1&0 for an interval of 1 min
string status = room.GetFreeBusy(today, 1, true); //sequentially calling this method is costly. What improvement can I do here?
//process the status and make some if free for certain time period add to list of available list
}
The GetFreeBusy method accepts three parameters and the default value for the MinPerChar parameter is 30 minutes. But your code only checks the first minute of the appointment. You need to go over the whole duration of your meeting (at least 30 minutes). Take a look at the similar forum thread.
If you are a .Net Developer then use Microsoft Graph APIs for this purpose. I used
POST /me/calendar/getSchedule
POST /users/{id|userPrincipalName}/calendar/getSchedule
from to achieve this. You can login as your userid and use ME option or you can use application mode login to login and use {id|userPrincipalName} to get calendar details for a room.
This link provides the basics on how to login and have good examples for Graph in general.
https://developer.microsoft.com/en-us/graph/graph-explorer
Ref:
https://learn.microsoft.com/en-us/graph/api/calendar-getschedule?view=graph-rest-1.0&tabs=http
Related
I developing a sale system using asp.net mvc. My search system allows users to save their search criteria and will notify them by email when a new product is posted is met their criteria. I tried the following:
The first way: Create a function to send bulk mail through gmail and I put this function in the post function. You can see the code described below to understand what I said:
public ActionResult PostProduct()
{
....
var list = Check(); // get a list of user email when their search criteria are met with the posted product
Send(list); // send email to the list
// I don't know how long does it take to complete this function?
}
However, this method requires a lot of resources from the server and takes a lot of time to respond (if the number of emails up to 1000, it would be a bad thing), but I can customize the parameters into email content (such as links, images, ...)
The second way: I used a mail service (MailChimp) and I called its API successfully, sending mail seems easy but I can not adjust the input parameters. That means I can not customize the content of my email.
I would like to ask people if there is a better and wiser way of doing things than I used to. Thank for reading
I am using the eBay Trading API with C# .NET SDK
I created a ReturnPolicyType
ReturnPolicyType policy=new ReturnPolicyType();
I set the policy properties and everything seems to work except the restocking fee
policy.RestockingFeeValue = "Percent_15";
And:
policy.RestockingFeeValueOption = "Percent_15";
I've also tried "15%" instead of "Percent_15"
but neither of them show the restocking fee on the listing
I've also asked the question on eBay's developer forums but they are pretty vacant of activity.
My full return policy code is below
ReturnPolicyType policy=new ReturnPolicyType();
policy.Refund="MoneyBack";
policy.ReturnsWithinOption="Days_30";
policy.ShippingCostPaidBy = "Buyer";
policy.RestockingFeeValue = "15%";
policy.RestockingFeeValueOption = "Percent_15";
policy.Description = "Returns are welcome on all items other than those sold on an 'AS - IS' basis. Buyers returning items shipped outside of the US will be responsible for all customs fees as well. Please read and fully understand the terms of our policy in advance if you wish to request a return.";
policy.ReturnsAcceptedOption="ReturnsAccepted";
policy.ShippingCostPaidByOption="Buyer";
The rest of the return policy displays as expected on the listing
To obtain the list of currently supported values, call GeteBayDetails with DetailName set to ReturnPolicyDetails. Then, look for the list of restocking fee percentage values in the ReturnPolicyDetails.RestockingFeeValue containers in the response.
https://developer.ebay.com/devzone/xml/docs/reference/ebay/types/ReturnPolicyType.html
I fetched an item listed using our old listing method and looked through the API call log to see the XML format of the existing listing.
I noticed a tag SellerReturnProfile inside of a tag SellerProfiles
I was able to populate the tags in the additem call like so
item.SellerProfiles = new SellerProfilesType();
var returnpolicy = new SellerReturnProfileType();
returnpolicy.ReturnProfileID = 63410125011;
returnpolicy.ReturnProfileName = "Returns Accepted,Buyer,30 Days,Money Default";
item.SellerProfiles.SellerReturnProfile = returnpolicy;
I had to list shipping profiles and payment profiles in the same way. It seems like if you list one seller profile the other 2 become required. In this case, the return profile was already defined in eBay as our default return profile.
They can be found in Account Settings -> Business Policies, but the id number has to be found with a getitem call on an existing item with the profile set.
It seems like the other call method ReturnPolicyType() might be depreciated as per these two sources
Business Policies Opt-In out soon to be enforced
Mapping Business Policies Management API Fields to Trading API Fields
Any seller who is opted into Business Policies will not be able to use the legacy fields at all, for Payment, Returns or Shipping in any new listing. If legacy fields are passed into the request, they will be ignored and dropped and the seller may get a warning message to that effect.
and
If you pass in Business Policies profile IDs and the legacy fields, the legacy fields will be ignored and dropped.
We are doing Exchange web server synchronization with our application. To identify EWS changes we use; service.SyncFolderItems() method, like explain on MSDN. But, while doing initial sync it takes all the events in calendar, very older ones too. To avoid getting older events we need to use time period or Sync Start From time while requesting changes from SyncFolderItems() method.
1) Can SyncFolderItems() method accept user given time period when getting events from EWS ? & How ?
2) If not, Any workaround ?
There is a way to avoid older events in calendar using service.SyncFolderItems() method.
<SyncFolderItems>
<ItemShape/>
<SyncFolderId/>
<SyncState/>
<Ignore/>
<MaxChangesReturned/> <SyncScope/>
</SyncFolderItems>
That Ignore parameter will accept List of event Ids. and ignore them while syncing. To do that , First we need to retrieve older event IDs, Exchange will only accept two years old event
DateTime startDate = DateTime.Now.AddYears(-2); //start from two years earlier
DateTime endDate = DateTime.Now.AddMonths(-1); // End One Month before,
//you can use Convert.ToDateTime("01/01/2013"); what ever date you wanted.
Create Item id List;
List<ItemId> itmid = new List<ItemId>();
Create Calendar View object;
CalendarView cView = new CalendarView(startDate, endDate);
Retrieve Appointments;
// Retrieve a collection of appointments by using the calendar view.
FindItemsResults<Item> appointments = service.FindItems(WellKnownFolderName.Calendar, cView);
Or you can use this, But previous code have some optimization. (Google)
FindItemsResults<Appointment> appointments = service.FindAppointments(WellKnownFolderName.Calendar, cView);
Add retrieve event ids into list,
foreach (var item in appointments)
{
itmid.Add(item.Id);
}
Finally, in your SyncFolderItems method will looks like this;
service.SyncFolderItems(new FolderId(WellKnownFolderName.Calendar), PropertySet.IdOnly, itmid, 10, SyncFolderItemsScope.NormalItems, sSyncState);
Hope this will help any of you.
Currently, SyncFolderItems only supports synchronizing the entire mailbox. It doesn't support synchronizing starting from a specific time period. This type of request has been shared with the product planners. Hopefully we'll see this type of functionality.
In terms of workarounds, you could:
1) Sync all of the events with only the ItemId. Throw away items don't need.
2) Perform a FindItems with your intended time period, use GetItem (Bind) to get the events, and then use notifications to learn when a new item arrives, or when an item is updated. What you won't get with this is what has changed. For new items, this isn't an issue. But for updated items, you'll have to perform a GetItem (Load) and then diff the updated and old items to see what has changed.
Over the last few weeks I was tasked with developing a ticketing system specific to my companies needs. Alright, not a huge deal.. Now I am onto a little trickier subject that I just can't wrap my head around completely.
Notification System based on a tickets last update time.
Alright so as we all know in a ticketing system we have tickets, lots of them.. Each of our tickets have a ticket "state" such as "Waiting on Client", "Pending Shipment" etc. These states have different thresholds I.E: 60 minutes, 120 minutes..
Basically I have a server application that runs every two hours. It loops through all the open tickets in the system, checks their ticket state and threshold and if the LastUpdate time is outside of my threshold of 60 minutes then the system fires off a notification saying that this ticket hasn't been taken care of and someone needs to get on top of it. Alright great, so that means every two hours the system runs it will check the time, if the ticket does not comply with its threshold then a level 2 notification gets sent out. The same process applies for notification 3.
The problem with this scenario is that what happens when Friday rolls around? There may only be 3 tickets that have notifications that need to be sent by the close of business Friday. However when Monday rolls around and this system runs again, it is going to find every ticket out of compliance which means we will more than likely have over 100 tickets in peoples mailbox. This seems like such a common problem among any notification system that operates off a datetime.
Any suggestions?
EDIT: Now that I know it's a C# app..
When your application is deciding whether or not to send a notification.. first, check if it is the weekend:
if (DateTime.Now.DayOfWeek != DayOfWeek.Saturday && DateTime.Now.DayOfWeek != DayOfWeek.Sunday)
// start sending notifications.
Or, you could do this:
if (TimeSpanElapsedToSendNotificationFor(thisItem)) {
if (isWeekend()) {
thisItem.LastUpdate.AddDays(2);
persist(thisItem); // update the DB
return;
}
// send notification here..
}
So, first check to see if the desired notification time has passed. If it has.. double check if it's the weekend.. if it is.. add 2 days to the LastUpdate property on this item then exit the function. If its a weekday, it will continue processing. Using this second method, your very first check will be false on the second run-through for all jobs unless they are added on the weekend.
PS: Why don't you just use a scheduled task and only run it during work hours?
We are currently working on creating a sync service between our product and Exchange using Exchange Web Services Managed API. Specifically we want to sync (on a time schedule) specific Appointments back and forth on a users calender. As part of the sync, we don't necessarily want to sync ALL appointments, but have built up some complex SearchFilters to return only the appointments we want. Our problem is that in order to use the SearchFilters, we need to use the ExchangeService.FindItems method, but this method only returns the Master Recurrence of recurring events. Our other option is to use ExchangeService.FindAppointment, this will do the Recurrence Expansion for us, but has the new problem that we can only limit the result appointments using a start and end date. Looking at how the ExchangeService.FindAppointment is implemented, we can see that it is implemented using the FindItems method, which leads me to believe that I should be able to tell the ExchangeService.FindItems method to do a recurrence expansion.
How can I get a list of expanded appointments from exchange using a complex SearchFilter?
Just found this on MSDN:
http://msdn.microsoft.com/en-us/library/hh148195(v=exchg.140).aspx
Considerations for searching calendar appointments
Calendar appointments are a special case for searches. Some calendar appointments, such as recurring appointments, can have exceptions and deleted occurrences. To ensure that the Exchange server expands recurring appointments when searching a calendar folder, you need to use calendar paging. When you use calendar paging, however, you can’t use any other search restrictions. This means that if, for example, you want to display all of the calendar appointments this month for a particular organizer, you can't create a search filter that is based on the organizer. Instead, you can use the CalendarView class to query for all appointments in the month and then filter the appointments on the client side based on the organizer. The following example shows how to use a calendar view to search for appointments in a calendar.
For anyone that finds guxiyou's solution with FindAppointments/CalendarView impractical, my solution below. CalendarView is especially not convenient in a situation of automatic synchronization where you'd preferably use a "last modified" filter instead of retrieving everything and filtering client-side, which is not very performant.
I used the regular FindItems way which does support filters, and while iterating the appointments checked AppointmentType, which in case of a RecurrenceMaster type would find the linked occurrences and add these to the to-be-synced list.
Below the method to subsequently get the occurrences of these appointments. Recurrent patterns with no end date are ignored as these would make your loop infinite. These recurrences would have to be handled differently to be synchronized anyway, unless you limit the synchronization window.
private IEnumerable<Appointment> GetRecurrentAppointments(Appointment masterAppointment)
{
Recurrence recurrence = masterAppointment.Recurrence;
if (recurrence == null || !recurrence.HasEnd)
yield break;
for (int i = 1; i <= recurrence.NumberOfOccurrences; i++)
{
Appointment occurrence = Appointment.BindToOccurrence(ExchangeServiceProxy, masterAppointment.Id, i);
yield return occurrence;
}
}