Requisition API is returning bad request error


#1

Dear Justin,

Requisition API is returning bad request error when I try to upload requisitions to the back-end system. Request-Response log is as shown below.


Request - 1

--> POST http://10.42.0.1:8080/openboxes-qf/api/generic/requisition http/1.1
    Content-Type: application/json; charset=UTF-8
    Content-Length: 703
    Accept: */*
    Connection: keep-alive
    Cookie: JSESSIONID=0F3ED21172107AC21AE60595C92D2BAF

{"id":"1","locationGroup":{"id":"ff8081816605e69901660671db73000e","name":"Regional"},"locationType":{"description":"Depot","id":"2","locationTypeCode":"DEPOT","name":"Depot|fr:D"},"name":"Bahirdar PFSA-Hub","sortOrder":0,"hasBinLocationSupport":false},"name":"Request from DMarkos Health Center","origin":{"id":"3","locationType":{"description":"Depot","id":"2","locationTypeCode":"DEPOT","name":"Depot|fr:D"},"name":"DMarkos Health Center","sortOrder":0,"hasBinLocationSupport":false},"requestedBy":{"email":"jmiranda@pih.org","firstName":"Justin","id":"3","lastName":"Miranda","name":"Justin Miranda","username":"jmiranda"},"isTemplate":false}
<-- 400 Bad Request http://10.42.0.1:8080/openboxes-qf/api/generic/requisition (180ms)
    Server: Apache-Coyote/1.1
    Content-Type: application/json;charset=UTF-8
    Transfer-Encoding: chunked
    Date: Sat, 02 Feb 2019 23:50:27 GMT

{"errorCode":400,"errorMessage":"Validation errors","data":[{"arguments":["Destination","Requisition"],"bindingFailure":false,"class":"org.springframework.validation.FieldError","code":"nullable","codes":["org.pih.warehouse.requisition.Requisition.destination.nullable.error.org.pih.warehouse.requisition.Requisition.destination","org.pih.warehouse.requisition.Requisition.destination.nullable.error.destination","org.pih.warehouse.requisition.Requisition.destination.nullable.error.org.pih.warehouse.core.Location","org.pih.warehouse.requisition.Requisition.destination.nullable.error","requisition.destination.nullable.error.org.pih.warehouse.requisition.Requisition.destination","requisition.destination.nullable.error.destination","requisition.destination.nullable.error.org.pih.warehouse.core.Location","requisition.destination.nullable.error","org.pih.warehouse.requisition.Requisition.destination.nullable.org.pih.warehouse.requisition.Requisition.destination","org.pih.warehouse.requisition.Requisition.destination.nullable.destination","org.pih.warehouse.requisition.Requisition.destination.nullable.org.pih.warehouse.core.Location","org.pih.warehouse.requisition.Requisition.destination.nullable","requisition.destination.nullable.org.pih.warehouse.requisition.Requisition.destination","requisition.destination.nullable.destination","requisition.destination.nullable.org.pih.warehouse.core.Location","requisition.destination.nullable","nullable.org.pih.warehouse.requisition.Requisition.destination","nullable.destination","nullable.org.pih.warehouse.core.Location","nullable"],"defaultMessage":"Property [{0}] of class [{1}] cannot be null","field":"destination","objectName":"org.pih.warehouse.requisition.Requisition","rejectedValue":null},{"arguments":["Origin","Requisition"],"bindingFailure":false,"class":"org.springframework.validation.FieldError","code":"nullable","codes":["org.pih.warehouse.requisition.Requisition.origin.nullable.error.org.pih.warehouse.requisition.Requisition.origin","org.pih.warehouse.requisition.Requisition.origin.nullable.error.origin","org.pih.warehouse.requisition.Requisition.origin.nullable.error.org.pih.warehouse.core.Location","org.pih.warehouse.requisition.Requisition.origin.nullable.error","requisition.origin.nullable.error.org.pih.warehouse.requisition.Requisition.origin","requisition.origin.nullable.error.origin","requisition.origin.nullable.error.org.pih.warehouse.core.Location","requisition.origin.nullable.error","org.pih.warehouse.requisition.Requisition.origin.nullable.org.pih.warehouse.requisition.Requisition.origin","org.pih.warehouse.requisition.Requisition.origin.nullable.origin","org.pih.warehouse.requisition.Requisition.origin.nullable.org.pih.warehouse.core.Location","org.pih.warehouse.requisition.Requisition.origin.nullable","requisition.origin.nullable.org.pih.warehouse.requisition.Requisition.origin","requisition.origin.nullable.origin","requisition.origin.nullable.org.pih.warehouse.core.Location","requisition.origin.nullable","nullable.org.pih.warehouse.requisition.Requisition.origin","nullable.origin","nullable.org.pih.warehouse.core.Location","nullable"],"defaultMessage":"Property [{0}] of class [{1}] cannot be null","field":"origin","objectName":"org.pih.warehouse.requisition.Requisition","rejectedValue":null},{"arguments":["Requested by","Requisition"],"bindingFailure":false,"class":"org.springframework.validation.FieldError","code":"nullable","codes":["org.pih.warehouse.requisition.Requisition.requestedBy.nullable.error.org.pih.warehouse.requisition.Requisition.requestedBy","org.pih.warehouse.requisition.Requisition.requestedBy.nullable.error.requestedBy","org.pih.warehouse.requisition.Requisition.requestedBy.nullable.error.org.pih.warehouse.core.Person","org.pih.warehouse.requisition.Requisition.requestedBy.nullable.error","requisition.requestedBy.nullable.error.org.pih.warehouse.requisition.Requisition.requestedBy","requisition.requestedBy.nullable.error.requestedBy","requisition.requestedBy.nullable.error.org.pih.warehouse.core.Person","requisition.requestedBy.nullable.error","org.pih.warehouse.requisition.Requisition.requestedBy.nullable.org.pih.warehouse.requisition.Requisition.requestedBy","org.pih.warehouse.requisition.Requisition.requestedBy.nullable.requestedBy","org.pih.warehouse.requisition.Requisition.requestedBy.nullable.org.pih.warehouse.core.Person","org.pih.warehouse.requisition.Requisition.requestedBy.nullable","requisition.requestedBy.nullable.org.pih.warehouse.requisition.Requisition.requestedBy","requisition.requestedBy.nullable.requestedBy","requisition.requestedBy.nullable.org.pih.warehouse.core.Person","requisition.requestedBy.nullable","nullable.org.pih.warehouse.requisition.Requisition.requestedBy","nullable.requestedBy","nullable.org.pih.warehouse.core.Person","nullable"],"defaultMessage":"Property [{0}] of class [{1}] cannot be null","field":"requestedBy","objectName":"org.pih.warehouse.requisition.Requisition","rejectedValue":null}]}

Regards,

Andualem W.


#2

The issue you keep running into is that the data you’re passing in your POST request (create/update) include too many unnecessary attributes/objects.

  • Remove id attribute as that’ll be assigned by the API
  • Remove locationGroup as it is not involved in requisition creation
  • Remove locationType as it is not involved in requisition creation
  • The requestedBy attribute is required and just needs an ID
  • The name attribute is required and should be a user-friendly description of the requisition (i.e. My first requisition). We sometimes just autopopulate it with the origin.name, destination.name, dateRequested, and requestedBy.name
  • The dateRequested field is required and looked good in your second example
  • The origin and destination are required and just need the ID.

In general, instead of sending full JSON objects

POST [http://10.42.0.1:8080/openboxes-qf/api/generic/requisition](http://10.42.0.1:8080/openboxes-qf/api/generic/requisition) http/1.1
Content-Type: application/json; charset=UTF-8
Content-Length: 703
Accept: */*
Connection: keep-alive
Cookie: JSESSIONID=0F3ED21172107AC21AE60595C92D2BAF
{"id":"1","locationGroup":{"id":"ff8081816605e69901660671db73000e","name":"Regional"},"locationType":{"description":"Depot","id":"2","locationTypeCode":"DEPOT","name":"Depot|fr:D"},"name":"Bahirdar PFSA-Hub","sortOrder":0,"hasBinLocationSupport":false},"name":"Request from DMarkos Health Center","origin":{"id":"3","locationType":{"description":"Depot","id":"2","locationTypeCode":"DEPOT","name":"Depot|fr:D"},"name":"DMarkos Health Center","sortOrder":0,"hasBinLocationSupport":false},"requestedBy":{"email":"jmiranda@pih.org","firstName":"Justin","id":"3","lastName":"Miranda","name":"Justin Miranda","username":"jmiranda"},"isTemplate":false}

try sending flat attributes like this:

POST [http://10.42.0.1:8080/openboxes-qf/api/generic/requisition](http://10.42.0.1:8080/openboxes-qf/api/generic/requisition) http/1.1
Content-Type: application/json; charset=UTF-8
Content-Length: 703
Accept: */*
Connection: keep-alive
Cookie: JSESSIONID=0F3ED21172107AC21AE60595C92D2BAF
{"origin.id":"3","destination.id":"1","name":"My first requisition","requestedBy.id":"3","dateRequested":"12/27/2018 00:00 +03:00"}