Is there a REST endpoint to get a list of a project's task assignments in Project Server? - rest

I've tried sending a request to
"/_api/ProjectServer/Projects('projectid')/Assignments", but all it does is return duplicates of the last assignment which is weird because the number of objects it returns is always equal to the number of assignments there are in the project.
Basically if I assign a resource to each of a hundred different tasks, the call returns 100 duplicates of the last task's assignment in the list.
I suspect it might be a bug, I'd appreciate it if someone could confirm or deny my assumption and/or let me know if there's any other way to retrieve the list of assignments in a project.

I didn't exactly know how to work with rest but I would like to provide you with litle lines of code using CSOM that, if I understood properly the question, it might help you:
private static void ListPublishedProjects()
{
// Get the list of projects on the server.
projContext.Load(projContext.Projects);
projContext.ExecuteQuery();
var proj = projContext.Projects.First(p => p.Name == "<project name>");
projContext.ExecuteQuery();
//You must ckeck out the project and load it's tasks
var draftProj = proj.CheckOut();
projContext.Load(draftProj.Tasks);
projContext.ExecuteQuery();
//Loop between all tasks
foreach (DraftTask task in draftProj.Tasks)
{
// Load all assignments in that task
projContext.Load(task.Assignments);
projContext.ExecuteQuery();
//Loop between al assignments
foreach (var assignment in task.Assignments)
{
projContext.Load(assignment.Owner, temp => temp.LoginName, temp => temp.Email);
projContext.Load(assignment.Resource);
projContext.ExecuteQuery();
Console.WriteLine("\n\t RESOURCE NAME:" + assignment.Resource.Name + " => " + assignment.ActualWork);
}
}
//Remember to publish and checkin the project when you finish your TODOs
draftProj.Publish(true);
draftProj.CheckIn(true);
QueueJob qJob = projContext.Projects.Update();
JobState jobState = projContext.WaitForQueue(qJob, 200);
}
}
Hope it helps,

Related

How I can get list all scenario from specflow dll?

Or from other place..
What I want: get all scenario names on start test, but without start all tests.
What I tried: by assembly reflection I scanned content, but one contain only feature names and method names. Not scenario names. (from this: Get list of tests in nunit library programmatically without having to run tests)
Also exist ScenarioContext, but it contain only current names. Not all existing in testsuite.
What i am using:
Specflow for describe.
NUnit for run. VS2019.
TestRail for result collect. TestSuite contains testName equal test describe in Specflow.
I hope it possible.
Thanks to all!
Ok, I`m finded it!
List<string> scenLst = new List<string>();
try
{
var assembly = System.Reflection.Assembly.LoadFrom(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "project.dll"));
var types = assembly.GetTypes();
foreach (Type t in types){
foreach (var method in t.GetMethods()){
foreach (var attributes in tm.GetCustomAttributes())
{
if (attributes is DescriptionAttribute){
var d = propertyList.Properties["Description"][0].ToString();
if(d != null){
scenLst.Add();
}
}
}
}
}
catch (Exception ex){...}
return scenLst;
}
To get tags use CategoryAttribute (from NUnit).

Iterate until matching text is found

I am writing a test which should iterate until a partial matching text is found . Once found , it should do some thing. Here is my code.
let getName = await $$('.button').getText();
if (getName === 'New name') {
// do something here
}
My test doesn't iterate even though there exists a matching name. It should also consider partials tests, for instance New name 1.
Appreciate your suggestions.
My answer is a shot in a dark due to lack of details in your question, but I'll try to guess your problem.
$$().getText() returns array of strings, thus your code must be
let names = await $$('.button').getText();
for (let i=0; i<names.length; i++) {
if (names[i].includes('New name')) {
// do something here
}
}
But when you await $$().getText(), and there are more than ~10 elements, be ready to face this error Random occurrences of Failed: ECONNREFUSED connect ECONNREFUSED 127.0.0.1 when running protractor tests
Actually, I must include another guess here based on an assumption you'll need to interact with the first element that matches condition
let $newNameElement = await $$('.button').filter( $elem =>
(await $elem.getText()).toLowerCase().includes('new name');
).get(0);
// do whatever you want with your $newNameElement

CQ Workflow- Comment not transferring between participant with a process step in between

When there is a process step between two participant steps, the comments is not passing between participants. My Workflow is like this-
ParticipantA ---> Process step X (ecma script) ----> Process step Y (ecma script) -----> ParticipantB
When I add some comment at ParticipantA step it does not carry forward to ParticipantB. Seems OOB functionality has limitations on this.
As a workaround, I am trying to get it at "Process step X" and passing on to Process step Y. I am able to get it but not able to set it for next step.
Below is my code-
log.info("Noop process called for: " + workItem.getWorkflowData().getPayload());
var comment = workItem.getMetaDataMap().get("comment");
log.info("Comment in approval process-----------" + comment);
var workflowData = workItem.getWorkflowData();
if (workflowData.getPayloadType() == "JCR_PATH") {
log.info("setting comment in meta data----------------");
workflowData.getMetaDataMap().put("comment", comment);
}
Can you help on how to set comment for next step?
Thanks in advance.
Regards,
Vivek
You would need to actually store your comment within a workflow Metadata Map. This
should help.
Once you have successfully stored your comment, you can access it later.
Hope this helps
I guess it is a session change within the workflow. The WorkflowData instance will be newly set. You can easily check it in the debugger of your ide. You have to iterate over the HistoryItems as illustrated here:
final List<HistoryItem> history = workflowSession.getHistory(workItem.getWorkflow());
final List<String> comments = new ArrayList<>();
if (history.size() > 0) {
HistoryItem current = history.get(history.size() - 1);
do {
comments.add(current.getComment());
current = current.getPreviousHistoryItem();
} while (current != null);
}
Comments are empty strings, if not set - if i'm not mistaken.

What is the better way to do the below program(c#3.0)

Consider the below program
private static bool CheckFactorPresent(List<FactorReturn> factorReturnCol)
{
bool IsPresent = true;
StringBuilder sb = new StringBuilder();
//Get the exposure names from Exposure list.
//Since this will remain same , so it has been done outside the loop
List<string> lstExposureName = (from item in Exposures
select item.ExposureName).ToList<string>();
foreach (FactorReturn fr in factorReturnCol)
{
//Build the factor names from the ReturnCollection dictionary
List<string> lstFactorNames = fr.ReturnCollection.Keys.ToList<string>();
//Check if all the Factor Names are present in ExposureName list
List<string> result = lstFactorNames.Except(lstExposureName).ToList();
if (result.Count() > 0)
{
result.ForEach(i =>
{
IsPresent = false;
sb.AppendLine("Factor" + i + "is not present for week no: " + fr.WeekNo.ToString());
});
}
}
return IsPresent;
}
Basically I am checking if all the FactorNames[lstFactorNames] are present in
ExposureNames[lstExposureName] list by using lstFactorNames.Except(lstExposureName).
And then by using the Count() function(if count() > 0), I am writing the error
messages to the String Builder(sb)
I am sure that someone can definitely write a better implementation than the one presented.
And I am looking forward for the same to learn something new from that program.
I am using c#3.0 and dotnet framework 3.5
Thanks
Save for some naming convention issues, I'd say that looks fine (for what I can figure out without seeing the rest of the code, or the purpose in the effort. The naming conventions though, need some work. A sporadic mix of ntnHungarian, PascalCase, camelCase, and abbrv is a little disorienting. Try just naming your local variables camelCase exclusively and things will look a lot better. Best of luck to you - things are looking good so far!
- EDIT -
Also, you can clean up the iteration at the end by just running a simple foreach:
...
foreach (var except in result)
{
isPresent = false;
builder.AppendFormat("Factor{0} is not present for week no: {1}\r\n", except, fr.WeekNo);
}
...

Simplest way to process a list of items in a multi-threaded manner

I've got a piece of code that opens a data reader and for each record (which contains a url) downloads & processes that page.
What's the simplest way to make it multi-threaded so that, let's say, there are 10 slots which can be used to download and process pages in simultaneousy, and as slots become available next rows are being read etc.
I can't use WebClient.DownloadDataAsync
Here's what i have tried to do, but it hasn't worked (i.e. the "worker" is never ran):
using (IDataReader dr = q.ExecuteReader())
{
ThreadPool.SetMaxThreads(10, 10);
int workerThreads = 0;
int completionPortThreads = 0;
while (dr.Read())
{
do
{
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
if (workerThreads == 0)
{
Thread.Sleep(100);
}
} while (workerThreads == 0);
Database.Log l = new Database.Log();
l.Load(dr);
ThreadPool.QueueUserWorkItem(delegate(object threadContext)
{
Database.Log log = threadContext as Database.Log;
Scraper scraper = new Scraper();
dc.Product p = scraper.GetProduct(log, log.Url, true);
ManualResetEvent done = new ManualResetEvent(false);
done.Set();
}, l);
}
}
You do not normally need to play with the Max threads (I believe it defaults to something like 25 per proc for worker, 1000 for IO). You might consider setting the Min threads to ensure you have a nice number always available.
You don't need to call GetAvailableThreads either. You can just start calling QueueUserWorkItem and let it do all the work. Can you repro your problem by simply calling QueueUserWorkItem?
You could also look into the Parallel Task Library, which has helper methods to make this kind of stuff more manageable and easier.