Create workforce assignments based on selection from feature layer

568
5
Jump to solution
12-15-2023 02:05 PM
AriLukas
Occasional Contributor

I have been attempting to create workforce assignments based on values of an existing feature layer on AGOL.

I followed the workflow described in this blog: https://community.esri.com/t5/arcgis-workforce-blog/automate-workforce-with-arcgis-api-for-python/ba...

The section of code where assignments are supposed to be created is: 

assignments = []
for feature in pr:
assignments.append(
workforce.Assignment(
project,
geometry=feature.geometry,
location=feature.attributes["locdesc"],
description=feature.attributes["details"],
assignment_type="Inspect Trees",
status="unassigned"
)
)
project.assignments.batch_add(assignments)

 In the code from shown above I changed assignment_type="Inspect Trees"] to assignment_type=feature.attributes["AssignType"] in hopes I could take values from my existing feature layer that are stored in the AssignType field and create assignments based on those. I made sure the assignment types matched exactly to what are stored in my feature layer (example 1=Abandoned Car in both the workforce layer and my feature layer).

However, when I try to run the block of code I get the following error: 

ValidationError                           Traceback (most recent call last)
/tmp/ipykernel_28/1267473057.py in <cell line: 2>()
      2 for feature in pr:
      3     assignments.append(
----> 4         workforce.Assignment(      5             project,
      6             geometry=feature.geometry,

/opt/conda/lib/python3.9/site-packages/arcgis/apps/workforce/assignment.py in __init__(self, project, feature, geometry, assignment_type, assigned_date, assignment_read, completed_date, declined_comment, declined_date, description, dispatcher, due_date, in_progress_date, location, notes, paused_date, priority, status, work_order_id, worker)
    188             self.status = status
    189             self.work_order_id = work_order_id
--> 190             self.assignment_type = assignment_type
    191             self.dispatcher = dispatcher
    192             self.worker = worker

/opt/conda/lib/python3.9/site-packages/arcgis/apps/workforce/assignment.py in assignment_type(self, value)
    380                 self._assignment_type = self.project._cached_assignment_types[value]
    381             else:
--> 382                 raise ValidationError("Invalid Assignment Type", self)
    383         elif isinstance(value, str):
    384             for at in self.project._cached_assignment_types.values():

ValidationError: Invalid Assignment Type

 When I hard code it assignments are created without any issue but instead of creating assignments based on what value is stored in my feature classes, I get assignments that are all the same. 

Any insight would be greatly appreciated. 

 

 

0 Kudos
1 Solution

Accepted Solutions
RobertAnderson3
MVP Regular Contributor

I have a script set up to create assignments, it decides if an assignment is being created based on an attribute, but not the assignment type, but in using this you could perhaps set it up so you have this section multiple times and just set the assignment type in each loop? (maybe not the most efficient, but I made it work so I'm happy with it haha)

assignments = []
weekdays_dic ={0:'GR1', 1:'GR2',2:'GR3',3:'GR4',4:'GR5',5:'GR6', 6:'GR0'}
weekday_today = weekdays_dic[datetime.today().weekday()]
hort_garbage = project.workers.get(user_id="horticulture.garbage@moncton.ca_moncton")
robert = project.workers.get(user_id="robert.anderson@moncton.ca_moncton")
end_of_day = datetime.combine(datetime.now(), time.max)

for feature in garbage_cans:
    subarea=str(feature.attributes["SUBAREA"]).replace(" ","").split(",")
    unittype=str(feature.attributes["UNITTYPE"])
    if weekday_today in subarea and (unittype=='DOGPOLE' or unittype=='GARCAN' or unittype=='NEEDLE BOX'):
        assignments.append(
            workforce.Assignment(
                project,
                geometry=feature.geometry,
                location=feature.attributes["UNITID"],
                description=feature.attributes["ADDRQUAL"],
                priority="Medium",
                due_date=end_of_day,
                assignment_type="Empty Garbage",
                status="assigned",
                worker=hort_garbage
            )
        )
project.assignments.batch_add(assignments)

 

My other thought is you either need to make sure the assignment type in the layer is EXACTLY the same domain label as in your project, or you'll need to store it as the GlobalID that the assignment table stores. Or you could use the dictionary for your assignments between the two layers like I have for my days of the week?

View solution in original post

0 Kudos
5 Replies
RobertAnderson3
MVP Regular Contributor

I have a script set up to create assignments, it decides if an assignment is being created based on an attribute, but not the assignment type, but in using this you could perhaps set it up so you have this section multiple times and just set the assignment type in each loop? (maybe not the most efficient, but I made it work so I'm happy with it haha)

assignments = []
weekdays_dic ={0:'GR1', 1:'GR2',2:'GR3',3:'GR4',4:'GR5',5:'GR6', 6:'GR0'}
weekday_today = weekdays_dic[datetime.today().weekday()]
hort_garbage = project.workers.get(user_id="horticulture.garbage@moncton.ca_moncton")
robert = project.workers.get(user_id="robert.anderson@moncton.ca_moncton")
end_of_day = datetime.combine(datetime.now(), time.max)

for feature in garbage_cans:
    subarea=str(feature.attributes["SUBAREA"]).replace(" ","").split(",")
    unittype=str(feature.attributes["UNITTYPE"])
    if weekday_today in subarea and (unittype=='DOGPOLE' or unittype=='GARCAN' or unittype=='NEEDLE BOX'):
        assignments.append(
            workforce.Assignment(
                project,
                geometry=feature.geometry,
                location=feature.attributes["UNITID"],
                description=feature.attributes["ADDRQUAL"],
                priority="Medium",
                due_date=end_of_day,
                assignment_type="Empty Garbage",
                status="assigned",
                worker=hort_garbage
            )
        )
project.assignments.batch_add(assignments)

 

My other thought is you either need to make sure the assignment type in the layer is EXACTLY the same domain label as in your project, or you'll need to store it as the GlobalID that the assignment table stores. Or you could use the dictionary for your assignments between the two layers like I have for my days of the week?

0 Kudos
AriLukas
Occasional Contributor

I created a field in my hosted feature service that matches exactly to assignment type in workforce but had no luck. Since there are only about 10 items i would need to have assignments created for so I don't think it would be a huge lift to copy and paste this section of code 10 times. 

I was looking over your code and was wondering where and at what point do you define garbage_cans

thank you again for your help!

0 Kudos
RobertAnderson3
MVP Regular Contributor

No problem! And hmm interesting, using the globalID style or the name? Because in my loop I have it set by the name of the assignment type, they seem to work interchangeably, whether that's best practice or not I'm not sure though haha.

I define garbage_cans in an earlier cell, it's the layer I'm working with. With itemID actually being the ID of the item in ArcGIS Online.

layer = gis.content.get("itemID").layers[1]
garbage_cans = layer.query('1=1', out_sr=3857).features

 

0 Kudos
AriLukas
Occasional Contributor

ahh i forgot to run that cell first! Your workflow worked like a charm. Thank you!

0 Kudos
RobertAnderson3
MVP Regular Contributor

I'm glad to hear it worked, no problem at all!

0 Kudos