Χρήση API χρονοδιαγράμματος έργου για την εκτέλεση λειτουργιών με οντότητες προγραμματισμού
Ισχύει για: Project Operations για σενάρια βασισμένα σε πόρους/μη εφοδιασμένα, ελαφριά ανάπτυξη - συμφωνία για προτιμολόγηση.
Οντότητες προγραμματισμού
Τα API χρονοδιαγράμματος έργου παρέχουν τη δυνατότητα εκτέλεσης λειτουργιών δημιουργίας, ενημέρωσης και διαγραφής με Οντότητες προγραμματισμού. Η διαχείριση αυτών των οντοτήτων γίνεται μέσω της μηχανής προγραμματισμού στο Έργο για το web. Οι λειτουργίες δημιουργίας, ενημέρωσης και διαγραφής με Οντότητες προγραμματισμού περιορίστηκαν σε προηγούμενες εκδόσεις του Dynamics 365 Project Operations.
Ο παρακάτω πίνακας παρέχει μια πλήρη λίστα των οντοτήτων χρονοδιαγράμματος έργου.
Όνομα οντότητας | Λογικό όνομα οντότητας |
---|---|
Project | msdyn_project |
Εργασία έργου | msdyn_projecttask |
Εξάρτηση εργασίας έργου | msdyn_projecttaskdependency |
Ανάθεση πόρου | msdyn_resourceassignment |
Κάδος έργου | msdyn_projectbucket |
Μέλος ομάδας έργου | msdyn_projectteam |
Λίστες ελέγχου έργου | msdyn_projectchecklist |
Ετικέτα έργου | msdyn_projectlabel |
Εργασία έργου για την ετικέτα | msdyn_projecttasktolabel |
Κύκλος επανάληψης έργου | msdyn_projectsprint |
OperationSet
Το OperationSet είναι ένα μοτίβο μονάδας εργασίας που μπορεί να χρησιμοποιηθεί όταν διάφορα αιτήματα που επηρεάζουν το χρονοδιάγραμμα πρέπει να υποβληθούν σε επεξεργασία εντός μιας συναλλαγής.
API χρονοδιαγράμματος έργου
Ακολουθεί μια λίστα με τα τρέχοντα API χρονοδιαγράμματος έργου.
API | Description |
---|---|
msdyn_CreateProjectV1 | Αυτό το API χρησιμοποιείται για τη δημιουργία ενός έργου. Το έργο και ο προεπιλεγμένος κάδος έργου δημιουργούνται αμέσως. Η δημιουργία έργου μπορεί επίσης να γίνει με την προσθήκη μιας γραμμής στον πίνακα έργου με τη χρήση τυπικών Dataverse API. Αυτή η διαδικασία δεν δημιουργεί προεπιλογή για το έργο, αλλά ενδέχεται να έχει καλύτερη απόδοση. |
msdyn_CreateTeamMemberV1 | Αυτό το API χρησιμοποιείται για τη δημιουργία ενός μέλους ομάδας έργου. Η καρτέλα μέλους ομάδας δημιουργείται αμέσως. Η δημιουργία μέλους ομάδας μπορεί επίσης να γίνει με την προσθήκη μιας γραμμής στον πίνακα Μέλη ομάδας έργου χρησιμοποιώντας τα τυπικά API του Dataverse. |
msdyn_CreateOperationSetV1 | Αυτό το API μπορεί να χρησιμοποιηθεί για τον προγραμματισμό διαφόρων αιτήσεων που πρέπει να εκτελεστούν εντός μιας συναλλαγής. |
msdyn_PssCreateV1 | Αυτό το API χρησιμοποιείται για τη δημιουργία μιας οντότητας. Η οντότητα μπορεί να είναι οποιαδήποτε από τις οντότητες προγραμματισμού έργου που υποστηρίζουν τη λειτουργία δημιουργίας. |
msdyn_PssCreateV2 | Αυτό το API χρησιμοποιείται για τη δημιουργία μιας οντότητας. Λειτουργεί όπως msdyn_PssCreateV1, αλλά πολλές οντότητες μπορούν να δημιουργηθούν σε μία ενέργεια. |
msdyn_PssUpdateV1 | Αυτό το API χρησιμοποιείται για την ενημέρωση μιας οντότητας. Η οντότητα μπορεί να είναι οποιαδήποτε από τις οντότητες προγραμματισμού έργου που υποστηρίζουν τη λειτουργία ενημέρωσης. |
msdyn_PssUpdateV2 | Αυτό το API χρησιμοποιείται σε ενημερωμένες οντότητες. Λειτουργεί όπως msdyn_PssUpdateV1, αλλά πολλές οντότητες μπορούν να ενημερωθούν σε μία ενέργεια. |
msdyn_PssDeleteV1 | Αυτό το API χρησιμοποιείται για τη διαγραφή μιας οντότητας. Η οντότητα μπορεί να είναι οποιαδήποτε από τις οντότητες προγραμματισμού έργου που υποστηρίζουν τη λειτουργία διαγραφής. |
msdyn_PssDeleteV2 | Αυτό το API χρησιμοποιείται για τη διαγραφή οντοτήτων. Λειτουργεί όπως msdyn_PssDeleteV1, αλλά πολλές οντότητες μπορούν να διαγραφούν σε μία ενέργεια. |
msdyn_ExecuteOperationSetV1 | Αυτό το API χρησιμοποιείται για την εκτέλεση όλων των λειτουργιών εντός του δεδομένου συνόλου λειτουργιών. |
msdyn_PssUpdateResourceAssignmentV1 | Αυτό το API χρησιμοποιείται για την ενημέρωση μιας προγραμματισμένης εργασίας ανάθεσης πόρων. |
Χρήση API χρονοδιαγράμματος έργου με το OperationSet
Επειδή οι καρτέλες δημιουργούνται αμέσως τόσο για το CreateProjectV1 όσο και για το CreateTeamMemberV1, αυτά τα API δεν μπορούν να χρησιμοποιηθούν άμεσα στο OperationSet. Ωστόσο, μπορείτε να τα χρησιμοποιήσετε για να δημιουργήσετε τις απαραίτητες καρτέλες, να δημιουργήσετε ένα OperationSet και, στη συνέχεια, να χρησιμοποιήσετε αυτές τις προ-δημιουργημένες καρτέλες στο OperationSet.
Υποστηριζόμενες λειτουργίες
Οντότητα προγραμματισμού | Δημιουργία | Update | Delete | Σημαντικές επισημάνσεις |
---|---|---|---|---|
Εργασία έργου | Ναι | Ναι | Ναι | Μπορείτε να επεξεργαστείτε τα πεδία Πρόοδος, EffortCompleted και EffortRemaining στο Project for the Web, αλλά δεν είναι δυνατή η επεξεργασία τους στο Project Operations. |
Εξάρτηση εργασίας έργου | Όχι | όχι | Όχι | Οι καρτέλες εξάρτησης εργασιών έργου δεν ενημερώνονται. Αντίθετα, είναι δυνατό να διαγραφεί μια παλιά καρτέλα και να δημιουργηθεί μια νέα καρτέλα. |
Ανάθεση πόρου | Όχι | Ναι* | Όχι | Οι λειτουργίες με τα ακόλουθα πεδία δεν υποστηρίζονται: BookableResourceID, Effort, EffortCompleted, EffortRemaining και PlannedWork. |
Κάδος έργου | Όχι | Όχι | Όχι | Ο προεπιλεγμένος κάδος δημιουργείται με τη χρήση του API CreateProjectV1. Η υποστήριξη για τη δημιουργία και διαγραφή κάδων έργων προστέθηκε στην έκδοση ενημέρωσης 16. |
Μέλος ομάδας έργου | Ναι | Ναι | Ναι | Για τη λειτουργία δημιουργίας, χρησιμοποιήστε το API CreateTeamMemberV1. |
Project | Όχι | Όχι | όχι | Οι λειτουργίες με τα ακόλουθα πεδία δεν υποστηρίζονται: StateCode, BulkGenerationStatus, GlobalRevisionToken, CalendarID, Effort, EffortCompleted, EffortRemaining, Progress, Finish, TaskEarliestStart και Duration. |
Λίστες ελέγχου έργου | Όχι | Όχι | Όχι | |
Ετικέτα έργου | όχι | Όχι | όχι | Τα ονόματα ετικετών μπορούν να αλλάξουν. Αυτή η δυνατότητα είναι διαθέσιμη μόνο στο Project for the Web. Δημιουργούνται ετικέτες με την πρώτη φορά που ανοίγετε ένα έργο. |
Εργασία έργου για την ετικέτα | Όχι | όχι | Όχι | Αυτή η δυνατότητα είναι διαθέσιμη μόνο στο Project for the Web. |
Κύκλος επανάληψης έργου | Όχι | Όχι | Όχι | Το πεδίο Έναρξη πρέπει να έχει μια ημερομηνία προγενέστερη από το πεδίο Τέλος. Οι κύκλοι επανάληψης για το ίδιο έργο δεν μπορούν να επικαλύπτονται μεταξύ τους. Αυτή η δυνατότητα είναι διαθέσιμη μόνο στο Project for the Web. |
Στόχος έργου | Όχι | Όχι | Όχι | Δεν υποστηρίζονται οι λειτουργίες με τα ακόλουθα πεδία: DescriptionPlainText, TaskDisplayOrder |
Εργασία έργου για τον στόχο | Όχι | Όχι | Όχι | Δεν υποστηρίζονται οι λειτουργίες με τα ακόλουθα πεδία: TaskDisplayOrder |
* Οι καρτέλες ανάθεσης πόρων δεν ενημερώνονται. Αντίθετα, είναι δυνατό να διαγραφεί η παλιά καρτέλα και να δημιουργηθεί μια νέα καρτέλα. Παρέχεται ξεχωριστό API για την ενημέρωση των περιγραμμάτων ανάθεσης πόρων.
Η ιδιότητα αναγνωριστικού είναι μόνο για ανάγνωση. Εάν παρέχεται η ιδιότητα αναγνωριστικού, το σύστημα προσπαθεί να τη χρησιμοποιήσει και πετάει μια εξαίρεση εάν δεν μπορεί να χρησιμοποιηθεί. Εάν δεν παρέχεται, το σύστημα το δημιουργεί.
Περιορισμοί και γνωστά προβλήματα
Ο ακόλουθος κατάλογος παρουσιάζει τους περιορισμούς και τα γνωστά προβλήματα:
Τα API χρονοδιαγράμματος έργου μπορούν να χρησιμοποιηθούν μόνο από Χρήστες με Άδεια χρήσης του Microsoft Project. Δεν είναι δυνατό να χρησιμοποιηθούν από:
- Χρήστες εφαρμογής
- Χρήστες συστήματος
- Χρήστες ενοποίησης
- Άλλοι χρήστες που δεν διαθέτουν την απαιτούμενη άδεια χρήσης
Κάθε OperationSet μπορεί να έχει μέγιστο αριθμό 200 λειτουργιών.
Κάθε χρήστης μπορεί να έχει μόνο μέγιστο αριθμό 10 ανοιχτών OperationSets.
Κάθε λειτουργία ενημέρωσης ενημέρωσης καμπύλης εκχώρησης πόρων μετράει ως μία λειτουργία.
Κάθε λίστα ενημερωμένων καμπυλών μπορεί να περιέχει το πολύ έως 100 τμήματα χρόνου.
Η κατάσταση αποτυχίας και τα αρχεία καταγραφής αποτυχίας του OperationSet δεν είναι αυτή τη στιγμή διαθέσιμα.
Υπάρχει μέγιστο όριο 400 κύκλοι επανάληψης ανά έργο.
Χειρισμός σφαλμάτων
- Για να εξετάσετε τα σφάλματα που δημιουργούνται από τα σύνολα λειτουργιών, μεταβείτε στην επιλογή Ρυθμίσεις>Προγραμματισμός ενοποίησης>Σύνολα λειτουργιών.
- Για να εξετάσετε τα σφάλματα που δημιουργούνται από την υπηρεσία χρονοδιαγράμματος έργου, μεταβείτε στις Ρυθμίσεις>Προγραμματισμός ενοποίησης>Αρχεία καταγραφής σφαλμάτων PSS.
Επεξεργασία καμπύλων εκχώρησης πόρων
Σε αντίθεση με όλα τα άλλα API προγραμματισμού έργου που ενημερώνουν μια οντότητα, το API καμπύλης ανάθεσης πόρων είναι αποκλειστικά υπεύθυνο για τις ενημερώσεις σε ένα μόνο πεδίο, msdyn_plannedwork, σε μία μόνο οντότητα msydn_resourceassignment.
Η δεδομένη λειτουργία χρονοδιαγράμματος είναι:
- σταθερές μονάδες.
- Το ημερολόγιο έργου είναι από τις 9:00 έως τις 5:00 μμ (Ώρα Ειρηνικού) Δευτέρα, Τρίτη, Πέμπτη και Παρασκευή. (Δεν υπάρχει εργασία τις Τετάρτες.)
- Το ημερολόγιο πόρων είναι από τις 9:00 π.μ. έως τις 1:00 μμ (Ώρα Ειρηνικού) Δευτέρα έως Παρασκευή.
Αυτή η ανάθεση είναι για μία εβδομάδα, τέσσερις ώρες την ημέρα, επειδή το ημερολόγιο πόρων είναι από τις 9:00 π.μ. έως τη 1:00 μ.μ. (ώρα Ειρηνικού) ή τέσσερις ώρες την ημέρα.
Εργασία | Ημερομηνία έναρξης | Ημερομηνία λήξης | Ποσότητα | 6/13/2022 | 6/14/2022 | 6/15/2022 | 6/16/2022 | 6/17/2022 | |
---|---|---|---|---|---|---|---|---|---|
9-1 υπάλληλος | T1 | 6/13/2022 | 6/17/2022 | 20 | 4 | 4 | 4 | 4 | 4 |
Για παράδειγμα, εάν θέλετε ο εργαζόμενος να εργάζεται μόνο τρεις ώρες κάθε ημέρα αυτήν την εβδομάδα και να έχει μια ώρα για άλλες εργασίες.
Δείγμα ωφέλιμου φορτίου UpdatedContours
[{
"minutes":900.0,
"start":"2022-06-13T00:00:00-07:00",
"end":"2022-06-18T00:00:00-07:00"
}]
Αυτή είναι η εκχώρηση μετά την εκτέλεση του API χρονοδιαγράμματος ενημέρωσης καμπύλης.
Κλείσιμο εργασίας | Ημερομηνία έναρξης | Ημερομηνία λήξης | Ποσότητα | 6/13/2022 | 6/14/2022 | 6/15/2022 | 6/16/2022 | 6/17/2022 | |
---|---|---|---|---|---|---|---|---|---|
9-1 υπάλληλος | T1 | 6/13/2022 | 6/17/2022 | 15 | 3 | 3 | 3 | 3 | 3 |
Δείγμα σεναρίου
Σε αυτό το σενάριο, δημιουργείτε ένα έργο, ένα μέλος ομάδας, τέσσερις εργασίες και δύο αναθέσεις πόρων. Στη συνέχεια, ενημερώνετε μία εργασία, θα ενημερώσετε το έργο, θα ενημερώσετε μια καμπύλη ανάθεσης πόρου, θα διαγράψετε μια εργασία, θα διαγράψετε μία ανάθεση πόρου και θα δημιουργήσετε μια εξάρτηση εργασίας.
Entity project = CreateProject();
project.Id = CallCreateProjectAction(project);
var projectReference = project.ToEntityReference();
var teamMember = new Entity("msdyn_projectteam", Guid.NewGuid());
teamMember["msdyn_name"] = $"TM {DateTime.Now.ToShortTimeString()}";
teamMember["msdyn_project"] = projectReference;
var createTeamMemberResponse = CallCreateTeamMemberAction(teamMember);
var description = $"My demo {DateTime.Now.ToShortTimeString()}";
var operationSetId = CallCreateOperationSetAction(project.Id, description);
var task1 = GetTask("1WW", projectReference);
var task2 = GetTask("2XX", projectReference, task1.ToEntityReference());
var task3 = GetTask("3YY", projectReference);
var task4 = GetTask("4ZZ", projectReference);
var assignment1 = GetResourceAssignment("R1", teamMember, task2, project);
var assignment2 = GetResourceAssignment("R2", teamMember, task3, project);
var task1Response = CallPssCreateAction(task1, operationSetId);
var task2Response = CallPssCreateAction(task2, operationSetId);
var task3Response = CallPssCreateAction(task3, operationSetId);
var task4Response = CallPssCreateAction(task4, operationSetId);
var assignment1Response = CallPssCreateAction(assignment1, operationSetId);
var assignment2Response = CallPssCreateAction(assignment2, operationSetId);
task2["msdyn_subject"] = "Updated Task";
var task2UpdateResponse = CallPssUpdateAction(task2, operationSetId);
project["msdyn_subject"] = $"Proj update {DateTime.Now.ToShortTimeString()}";
var projectUpdateResponse = CallPssUpdateAction(project, operationSetId);
List<UpdatedContour> updatedContours = new List<UpdatedContour>();
UpdatedContour updatedContour = new UpdatedContour();
updatedContour.Start = DateTime.UtcNow.Date;
updatedContour.End = DateTime.UtcNow.Date.AddDays(1);
updatedContour.Minutes = 120;
updatedContours.Add(updatedContour);
String serializedUpdate = JsonConvert.SerializeObject(updatedContours);
var updateContoursResponse = CallPssUpdateContourAction(assignment1.Id, serializedUpdate, operationSetId);
var task4DeleteResponse = CallPssDeleteAction(task4.Id.ToString(), task4.LogicalName, operationSetId);
var assignment2DeleteResponse = CallPssDeleteAction(assignment2.Id.ToString(), assignment2.LogicalName, operationSetId);
var dependency1 = GetTaskDependency(project, task2, task3);
var dependency1Response = CallPssCreateAction(dependency1, operationSetId);
CallExecuteOperationSetAction(operationSetId);
Console.WriteLine("Done....");
Πρόσθετα δείγματα
#region Call actions --- Sample code ----
/// <summary>
/// Calls the action to create an operationSet
/// </summary>
/// <param name="projectId">project id for the operations to be included in this operationSet</param>
/// <param name="description">description of this operationSet</param>
/// <returns>operationSet id</returns>
private string CallCreateOperationSetAction(Guid projectId, string description)
{
OrganizationRequest operationSetRequest = new OrganizationRequest("msdyn_CreateOperationSetV1");
operationSetRequest["ProjectId"] = projectId.ToString();
operationSetRequest["Description"] = description;
OrganizationResponse response = organizationService.Execute(operationSetRequest);
return response["OperationSetId"].ToString();
}
/// <summary>
/// Calls the action to create an entity
/// </summary>
/// <param name="entity">Scheduling entity</param>
/// <param name="operationSetId">operationSet id</param>
/// <returns>OperationSetResponse</returns>
private OperationSetResponse CallPssCreateAction(Entity entity, string operationSetId)
{
OrganizationRequest operationSetRequest = new OrganizationRequest("msdyn_PssCreateV1");
operationSetRequest["Entity"] = entity;
operationSetRequest["OperationSetId"] = operationSetId;
return GetOperationSetResponseFromOrgResponse(organizationService.Execute(operationSetRequest));
}
/// <summary>
/// Calls the action to update an entity
/// </summary>
/// <param name="entity">Scheduling entity</param>
/// <param name="operationSetId">operationSet Id</param>
/// <returns>OperationSetResponse</returns>
private OperationSetResponse CallPssUpdateAction(Entity entity, string operationSetId)
{
OrganizationRequest operationSetRequest = new OrganizationRequest("msdyn_PssUpdateV1");
operationSetRequest["Entity"] = entity;
operationSetRequest["OperationSetId"] = operationSetId;
return GetOperationSetResponseFromOrgResponse(organizationService.Execute(operationSetRequest));
}
/// <summary>
/// Calls the action to update an entity
/// </summary>
/// <param name="recordId">Id of the record to be deleted</param>
/// <param name="entityLogicalName">Entity logical name of the record</param>
/// <param name="operationSetId">OperationSet Id</param>
/// <returns>OperationSetResponse</returns>
private OperationSetResponse CallPssDeleteAction(string recordId, string entityLogicalName, string operationSetId)
{
OrganizationRequest operationSetRequest = new OrganizationRequest("msdyn_PssDeleteV1");
operationSetRequest["RecordId"] = recordId;
operationSetRequest["EntityLogicalName"] = entityLogicalName;
operationSetRequest["OperationSetId"] = operationSetId;
return GetOperationSetResponseFromOrgResponse(organizationService.Execute(operationSetRequest));
}
/// <summary>
/// Calls the action to update a Resource Assignment contour
/// </summary>
/// <param name="resourceAssignmentId">Id of the resource assignment to be updated</param>
/// <param name="serializedUpdates">JSON formatted contour updates</param>
/// <param name="operationSetId">operationSet id</param>
/// <returns>OperationSetResponse</returns>
private OperationSetResponse CallPssUpdateContourAction(string resourceAssignmentId, string serializedUpdates string operationSetId)
{
OrganizationRequest operationSetRequest = new OrganizationRequest("msdyn_PssUpdateResourceAssignmentContourV1");
operationSetRequest["ResourceAssignmentId"] = resourceAssignmentId;
operationSetRequest["UpdatedContours"] = serializedUpdates;
operationSetRequest["OperationSetId"] = operationSetId;
return GetOperationSetResponseFromOrgResponse(OrganizationService.Execute(operationSetRequest));
}
/// <summary>
/// Calls the action to execute requests in an operationSet
/// </summary>
/// <param name="operationSetId">operationSet id</param>
/// <returns>OperationSetResponse</returns>
private OperationSetResponse CallExecuteOperationSetAction(string operationSetId)
{
OrganizationRequest operationSetRequest = new OrganizationRequest("msdyn_ExecuteOperationSetV1");
operationSetRequest["OperationSetId"] = operationSetId;
return GetOperationSetResponseFromOrgResponse(organizationService.Execute(operationSetRequest));
}
/// <summary>
/// This can be used to abandon an operationSet that is no longer needed
/// </summary>
/// <param name="operationSetId">operationSet id</param>
/// <returns>OperationSetResponse</returns>
protected OperationSetResponse CallAbandonOperationSetAction(Guid operationSetId)
{
OrganizationRequest operationSetRequest = new OrganizationRequest("msdyn_AbandonOperationSetV1");
operationSetRequest["OperationSetId"] = operationSetId.ToString();
return GetOperationSetResponseFromOrgResponse(organizationService.Execute(operationSetRequest));
}
/// <summary>
/// Calls the action to create a new project
/// </summary>
/// <param name="project">Project</param>
/// <returns>project Id</returns>
private Guid CallCreateProjectAction(Entity project)
{
OrganizationRequest createProjectRequest = new OrganizationRequest("msdyn_CreateProjectV1");
createProjectRequest["Project"] = project;
OrganizationResponse response = organizationService.Execute(createProjectRequest);
var projectId = Guid.Parse((string)response["ProjectId"]);
return projectId;
}
/// <summary>
/// Calls the action to create a new project team member
/// </summary>
/// <param name="teamMember">Project team member</param>
/// <returns>project team member Id</returns>
private string CallCreateTeamMemberAction(Entity teamMember)
{
OrganizationRequest request = new OrganizationRequest("msdyn_CreateTeamMemberV1");
request["TeamMember"] = teamMember;
OrganizationResponse response = organizationService.Execute(request);
return (string)response["TeamMemberId"];
}
private OperationSetResponse GetOperationSetResponseFromOrgResponse(OrganizationResponse orgResponse)
{
return JsonConvert.DeserializeObject<OperationSetResponse>((string)orgResponse.Results["OperationSetResponse"]);
}
private EntityCollection GetDefaultBucket(EntityReference projectReference)
{
var columnsToFetch = new ColumnSet("msdyn_project", "msdyn_name");
var getDefaultBucket = new QueryExpression("msdyn_projectbucket")
{
ColumnSet = columnsToFetch,
Criteria =
{
Conditions =
{
new ConditionExpression("msdyn_project", ConditionOperator.Equal, projectReference.Id),
new ConditionExpression("msdyn_name", ConditionOperator.Equal, "Bucket 1")
}
}
};
return organizationService.RetrieveMultiple(getDefaultBucket);
}
private Entity GetBucket(EntityReference projectReference)
{
var bucketCollection = GetDefaultBucket(projectReference);
if (bucketCollection.Entities.Count > 0)
{
return bucketCollection[0].ToEntity<Entity>();
}
throw new Exception($"Please open project with id {projectReference.Id} in the Dynamics UI and navigate to the Tasks tab");
}
private Entity CreateProject()
{
var project = new Entity("msdyn_project", Guid.NewGuid());
project["msdyn_subject"] = $"Proj {DateTime.Now.ToShortTimeString()}";
return project;
}
private Entity GetTask(string name, EntityReference projectReference, EntityReference parentReference = null)
{
var task = new Entity("msdyn_projecttask", Guid.NewGuid());
task["msdyn_project"] = projectReference;
task["msdyn_subject"] = name;
task["msdyn_effort"] = 4d;
task["msdyn_scheduledstart"] = DateTime.Today;
task["msdyn_scheduledend"] = DateTime.Today.AddDays(5);
task["msdyn_start"] = DateTime.Now.AddDays(1);
task["msdyn_projectbucket"] = GetBucket(projectReference).ToEntityReference();
task["msdyn_LinkStatus"] = new OptionSetValue(192350000);
//Custom field handling
/*
task["new_custom1"] = "Just my test";
task["new_age"] = 98;
task["new_amount"] = 591.34m;
task["new_isready"] = new OptionSetValue(100000000);
*/
if (parentReference == null)
{
task["msdyn_outlinelevel"] = 1;
}
else
{
task["msdyn_parenttask"] = parentReference;
}
return task;
}
private Entity GetResourceAssignment(string name, Entity teamMember, Entity task, Entity project)
{
var assignment = new Entity("msdyn_resourceassignment", Guid.NewGuid());
assignment["msdyn_projectteamid"] = teamMember.ToEntityReference();
assignment["msdyn_taskid"] = task.ToEntityReference();
assignment["msdyn_projectid"] = project.ToEntityReference();
assignment["msdyn_name"] = name;
return assignment;
}
protected Entity GetTaskDependency(Entity project, Entity predecessor, Entity successor)
{
var taskDependency = new Entity("msdyn_projecttaskdependency", Guid.NewGuid());
taskDependency["msdyn_project"] = project.ToEntityReference();
taskDependency["msdyn_predecessortask"] = predecessor.ToEntityReference();
taskDependency["msdyn_successortask"] = successor.ToEntityReference();
taskDependency["msdyn_linktype"] = new OptionSetValue(192350000);
return taskDependency;
}
#endregion
#region OperationSetResponse DataContract --- Sample code ----
[DataContract]
public class OperationSetResponse
{
[DataMember(Name = "operationSetId")]
public Guid OperationSetId { get; set; }
[DataMember(Name = "operationSetDetailId")]
public Guid OperationSetDetailId { get; set; }
[DataMember(Name = "operationType")]
public string OperationType { get; set; }
[DataMember(Name = "recordId")]
public string RecordId { get; set; }
[DataMember(Name = "correlationId")]
public string CorrelationId { get; set; }
}
#endregion
#region UpdatedContour DataContract --- Sample code ----
[DataContract]
public class UpdatedContour
{
[DataMember(Name = "start")]
public DateTime Start { get; set; }
[DataMember(Name = "end")]
public DateTime End { get; set; }
[DataMember(Name = "minutes")]
public decimal Minutes { get; set; }
}
#endregion