Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NGPVAN -- update_person_json function doesn't update person record #673

Open
harnoorSingh-wtpmi opened this issue Apr 27, 2022 · 9 comments
Labels
bug Impact - something is currently broken in Parsons and needs to be fixed high priority Priority - addressing this is an urgent need for a broad swath of Parsons users

Comments

@harnoorSingh-wtpmi
Copy link

The update_person_json() function does not seem to function as the documentation indicates. When I use the function to attempt to update a contact (in the demo EA site using a sandbox the EA team setup for me) in the following way:

van = VAN(db='MyCampaign') van.update_person_json(id=101991312, match_json={'codes':None})

I get a strange JSON output that is completely different from the actual person's record (it is shown below)

{'vanId': 101991312,
 'firstName': 'joe',
 'lastName': 'jack',
 'middleName': None,
 'suffix': None,
 'title': None,
 'sourceFileTitle': None,
 'sourceFileFirstName': None,
 'sourceFileMiddleName': None,
 'sourceFileLastName': None,
 'sourceFileSuffix': None,
 'contactMode': None,
 'organizationContactCommonName': None,
 'organizationContactOfficialName': None,
 'salutation': 'joe',
 'formalSalutation': 'joe jack',
 'additionalSalutation': None,
 'preferredPronoun': None,
 'pronouns': None,
 'envelopeName': 'joe jack',
 'formalEnvelopeName': 'joe jack',
 'additionalEnvelopeName': None,
 'contactMethodPreferenceCode': None,
 'nickname': None,
 'website': None,
 'professionalSuffix': None,
 'party': None,
 'employer': None,
 'occupation': None,
 'jobTitle': None,
 'sex': None,
 'dateOfBirth': None,
 'selfReportedRace': None,
 'selfReportedEthnicity': None,
 'selfReportedRaces': None,
 'selfReportedEthnicities': None,
 'selfReportedGenders': None,
 'selfReportedSexualOrientations': None,
 'selfReportedLanguagePreference': None,
 'emails': None,
 'phones': None,
 'addresses': None,
 'recordedAddresses': None,
 'identifiers': None,
 'codes': None,
 'customFields': None,
 'primaryCustomField': None,
 'contributionSummary': None,
 'suppressions': None,
 'caseworkCases': None,
 'caseworkIssues': None,
 'caseworkStories': None,
 'notes': None,
 'scores': None,
 'customProperties': None,
 'electionRecords': None,
 'membershipStatus': None,
 'organizationRoles': None,
 'districts': None,
 'surveyQuestionResponses': None,
 'finderNumber': None,
 'biographyImageUrl': None,
 'primaryContact': None}

But if I run

van.get_person(id=101991312)

I get the following which proves that the above JSON is not reflecting the updated record of the person

people INFO Getting person with  of 101991312 at url people/101991312

{'vanId': 101991312,
 'firstName': 'joe',
 'lastName': 'jack',
 'middleName': None,
 'suffix': None,
 'title': None,
 'sourceFileTitle': None,
 'sourceFileFirstName': None,
 'sourceFileMiddleName': None,
 'sourceFileLastName': None,
 'sourceFileSuffix': None,
 'contactMode': None,
 'organizationContactCommonName': None,
 'organizationContactOfficialName': None,
 'salutation': 'joe',
 'formalSalutation': 'joe jack',
 'additionalSalutation': None,
 'preferredPronoun': None,
 'pronouns': None,
 'envelopeName': 'joe jack',
 'formalEnvelopeName': 'joe jack',
 'additionalEnvelopeName': None,
 'contactMethodPreferenceCode': None,
 'nickname': None,
 'website': None,
 'professionalSuffix': None,
 'party': None,
 'employer': None,
 'occupation': None,
 'jobTitle': None,
 'sex': None,
 'dateOfBirth': None,
 'selfReportedRace': None,
 'selfReportedEthnicity': None,
 'selfReportedRaces': None,
 'selfReportedEthnicities': None,
 'selfReportedGenders': None,
 'selfReportedSexualOrientations': None,
 'selfReportedLanguagePreference': None,
 'emails': [{'type': 'P',
   'email': '[email protected]',
   'dateCreated': '2022-04-11T10:39:00Z',
   'isPreferred': True,
   'isSubscribed': True,
   'subscriptionStatus': 'S'}],
 'phones': [],
 'addresses': [],
 'recordedAddresses': [],
 'identifiers': [],
 'codes': [{'codeId': 1002611,
   'parentCodeId': None,
   'name': 'test source code',
   'codeType': 'SourceCode'}],
 'customFields': [],
 'primaryCustomField': None,
 'contributionSummary': None,
 'suppressions': [],
 'caseworkCases': [],
 'caseworkIssues': [],
 'caseworkStories': [],
 'notes': [],
 'scores': None,
 'customProperties': [],
 'electionRecords': [],
 'membershipStatus': None,
 'organizationRoles': [],
 'districts': [{'districtFieldId': 0,
   'name': 'State',
   'parentFieldId': None,
   'isCustomDistrict': False,
   'districtFieldValues': [{'id': 'FL',
     'name': 'Florida',
     'parentId': None}]}],
 'surveyQuestionResponses': None,
 'finderNumber': None,
 'biographyImageUrl': None,
 'primaryContact': None}

When I walked through this issue with Shauna from the Parsons team she pointed out that this command doesn't appear to hit an endpoint for the API that would delete or update a contact's record according to Parson's documentation for the update_person_json() method. It appears that the documentation is incorrect or this function is not working exactly as it should.

Just for reference, this is the API's page of documentation that provides code which successfully (I have tested it and it works) deletes codes off of contacts' records, and this is the [page of the documentation]( for the API that is linked for the update_person_json() parson method.

@thebbennett
Copy link
Collaborator

Hey! I'm also working on a script that uses this function. Can you tell me what the expected output is? I've used this function in previous scripts at Sunrise with success

@harnoorSingh-wtpmi
Copy link
Author

harnoorSingh-wtpmi commented Apr 27, 2022

So from my understanding of the documentation, I would think that the function should edit the person's record with whatever has been provided to match_json that differs from the current record. As for the output I'm a little less sure, but again, from the documentation I would guess that it should be the new JSON record of the person after it has been updated according to the match_json field. In my case this would be a JSON field like this

{'vanId': 101991312,
 'firstName': 'joe',
 'lastName': 'jack',
 'middleName': None,
 'suffix': None,
 'title': None,
 'sourceFileTitle': None,
 'sourceFileFirstName': None,
 'sourceFileMiddleName': None,
 'sourceFileLastName': None,
 'sourceFileSuffix': None,
 'contactMode': None,
 'organizationContactCommonName': None,
 'organizationContactOfficialName': None,
 'salutation': 'joe',
 'formalSalutation': 'joe jack',
 'additionalSalutation': None,
 'preferredPronoun': None,
 'pronouns': None,
 'envelopeName': 'joe jack',
 'formalEnvelopeName': 'joe jack',
 'additionalEnvelopeName': None,
 'contactMethodPreferenceCode': None,
 'nickname': None,
 'website': None,
 'professionalSuffix': None,
 'party': None,
 'employer': None,
 'occupation': None,
 'jobTitle': None,
 'sex': None,
 'dateOfBirth': None,
 'selfReportedRace': None,
 'selfReportedEthnicity': None,
 'selfReportedRaces': None,
 'selfReportedEthnicities': None,
 'selfReportedGenders': None,
 'selfReportedSexualOrientations': None,
 'selfReportedLanguagePreference': None,
 'emails': [{'type': 'P',
   'email': '[email protected]',
   'dateCreated': '2022-04-11T10:39:00Z',
   'isPreferred': True,
   'isSubscribed': True,
   'subscriptionStatus': 'S'}],
 'phones': [],
 'addresses': [],
 'recordedAddresses': [],
 'identifiers': [],
 'codes': [{'codeId': 1002611,
   'parentCodeId': None,
   'name': 'test source code',
   'codeType': 'SourceCode'}],
 'customFields': [],
 'primaryCustomField': None,
 'contributionSummary': None,
 'suppressions': [],
 'caseworkCases': [],
 'caseworkIssues': [],
 'caseworkStories': [],
 'notes': [],
 'scores': None,
 'customProperties': [],
 'electionRecords': [],
 'membershipStatus': None,
 'organizationRoles': [],
 'districts': [{'districtFieldId': 0,
   'name': 'State',
   'parentFieldId': None,
   'isCustomDistrict': False,
   'districtFieldValues': [{'id': 'FL',
     'name': 'Florida',
     'parentId': None}]}],
 'surveyQuestionResponses': None,
 'finderNumber': None,
 'biographyImageUrl': None,
 'primaryContact': None}

(the codes field now is blank and all codes have been wiped). Let me know if any of my understanding around this function is off.

I'm also a little confused because it seems that the update_person_json function is hitting this endpoint with the POST method, but this doesn't seem to allow for any updating or deleting of information. I hope all of that helps!

@thebbennett
Copy link
Collaborator

This is what my code looks like

json = {"phones": [{"phoneNumber": phone, "phoneOptInStatus": "I"}]}  # I for Opted In
r = ea.update_person_json(id=vanid, match_json=json)

I'm going to play around and see if I can verify that I'm updating the record

@harnoorSingh-wtpmi
Copy link
Author

Alright, thank you, please let me know!

@thebbennett
Copy link
Collaborator

I attempted to opt myself in and out of our SMS list and when I checked my record, my PhoneOptInStatus was still "Unknown". This is odd because I worked with TMC to build this script a year or so ago and was under the impression that it worked.

@harnoorSingh-wtpmi
Copy link
Author

harnoorSingh-wtpmi commented Apr 27, 2022

Yes, this is essentially the problem I'm having. It's very odd because the endpoint should allow you to update a record if you provide an existing VANID, but that doesn't appear to be working for any field based on your example. So now I'm not sure if it's an issue with Parsons or the endpoint itself.

@shaunagm shaunagm added bug Impact - something is currently broken in Parsons and needs to be fixed high priority Priority - addressing this is an urgent need for a broad swath of Parsons users labels Apr 28, 2022
@ydamit
Copy link
Contributor

ydamit commented Apr 29, 2022

Hi folks,

TL;DR: I think there might not actually be a bug here.

I wanted to report that I was able to update a phone's opt in using @thebbennett's exact code. I even tested it with a stringified phone number, and even with dashes, suggesting that EA strips way non-digits in the API call to the people/{vanid} endpoint. I think the response JSON from EA must be set up to automatically not expand any of the array items (see the GET people/{vanid} endpoint endpoint's $expand param for my reference point here). But I saw the changes in the UI pretty much instantly.

So with that in mind, along with other recent API changes, I can confirm that I was also unable to add or remove Codes using the upsert_person_json() method, nor, crucially, with POSTing to the person/{vanid} endpoint at all. I was, however, able to both add and remove Codes by POSTing to the person/{vanid}/codes endpoint and DELETEing at the person/{vanid}/codes/{codeid} endpoint, respectively. Considering that Codes is also absent from the Common Model example, I suspect that EA was allowing changes using the old, catch-all endpoint for a while, but have since deprecated that as an option.

I think, then, the problem may just be that we have no ability to ask for expanded arrays in responses from the people/{vanid} endpoints, and that the people/{vanid}/codes endpoints don't respond with anything! As a result, I was only able to confirm successes in the UI, or by making a GET people/{vanid} request (which was the only way for Source Codes, since they don't show up in the UI), and not in the response.

@shaunagm
Copy link
Collaborator

shaunagm commented Jun 8, 2022

I haven't had a chance to look into this too deeply, but the get_person method, which update_person and update_person_json call via the intermediary of _people_search, has a bug in it which messes up the expand_fields parameters and was causing 404s for me. Might be related?

@sduveen-pivot
Copy link

I think this issue is just that the relationships are not updateable from the update_person endpoint. We have two paths we could go depending on how general-case we want to do:

  1. error out if someone tries to change relation fields (like codes) so people know they can't update those with this call
  2. upon seeing 'codes' in match_json, we instead call the codes endpoint as mentioned above and do that part for someone.

I think adding/deleting array/list objects might be frought -- e.g. if you think you're 'adding a code' by doing a for-loop on a bunch of IDs and codes=[{'codeId': 1002611....}] then you might not realize that you're actually removing all other codes from those users -- so I suggest we error out instead and provide separate api to remove_person_code()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Impact - something is currently broken in Parsons and needs to be fixed high priority Priority - addressing this is an urgent need for a broad swath of Parsons users
Projects
None yet
Development

No branches or pull requests

5 participants