farmOS 2.X adding Quantities to logs via API

I thought I had the API fairly well figured out at this stage, but I’m finding adding quantities to logs a little troublesome. From the documentation I see the quantity should be created first and the the log created with a relationship referencing the quantity UUID.

So I can create the quantities with no issue, but when I create the log and add the relationship using either POST or PATCH after the fact, the relationship is not saved, I get no errors and receive status code 201. All other details in the POST request are saved OK too.

eg:
POST

{"type":"log--transplanting","attributes":{"data":"2022-W17 Zucchini HVW11-N","status":"done","notes":{"value":"Length (m): 16; Nr of plants: 20"},"flag":[],"is_movement":true},"relationships":{"location":{"data":[{"type":"asset--land","id":"be022fa6-fbfb-4557-aff7-ffab7503914d"}]},"asset":{"data":[{"type":"asset--plant","id":"df263fee-d226-42b3-804f-15d33ef866a3"}]},"quantity":{"data":[{"type":"quantity--standard","id":"56227855-36b9-4a77-a37e-7cd8cb6ad636"},{"type":"quantity--standard","id":"d14cbabc-9f25-4c18-a584-9dd8409a7ed8"}]}}}

Returns

{"type":"log--transplanting","id":"0d4bc521-0960-47e4-bfb6-7b759c900685","links":{"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685"}},"attributes":{"drupal_internal__id":61,"drupal_internal__revision_id":128,"langcode":"en","revision_created":"2022-05-08T11:21:36+00:00","revision_log_message":null,"name":"Transplanting log 61","timestamp":"2022-05-08T11:21:36+00:00","status":"done","created":"2022-05-08T11:21:36+00:00","changed":"2022-05-08T11:21:36+00:00","default_langcode":true,"revision_translation_affected":true,"data":"2022-W17 Zucchini HVW11-N","notes":{"value":"Length (m): 16; Nr of plants: 20","format":null,"processed":"<p>Length (m): 16; Nr of plants: 20</p>\n"},"flag":[],"is_group_assignment":null,"geometry":null,"is_movement":true},"relationships":{"log_type":{"data":{"type":"log_type--log_type","id":"20e6447d-c7c1-449b-b0c1-e47cb0293975","meta":{"drupal_internal__target_id":"transplanting"}},"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/log_type"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/log_type"}}},"revision_user":{"data":{"type":"user--user","id":"8fd752ad-31de-4141-a541-4338322b9f94","meta":{"drupal_internal__target_id":1}},"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/revision_user"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/revision_user"}}},"uid":{"data":{"type":"user--user","id":"8fd752ad-31de-4141-a541-4338322b9f94","meta":{"drupal_internal__target_id":1}},"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/uid"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/uid"}}},"category":{"data":[],"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/category"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/category"}}},"file":{"data":[],"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/file"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/file"}}},"image":{"data":[],"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/image"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/image"}}},"group":{"data":[],"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/group"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/group"}}},"location":{"data":[{"type":"asset--land","id":"be022fa6-fbfb-4557-aff7-ffab7503914d","meta":{"drupal_internal__target_id":28}}],"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/location"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/location"}}},"asset":{"data":[{"type":"asset--plant","id":"df263fee-d226-42b3-804f-15d33ef866a3","meta":{"drupal_internal__target_id":33}}],"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/asset"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/asset"}}},"quantity":{"data":[],"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/quantity"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/quantity"}}},"owner":{"data":[{"type":"user--user","id":"8fd752ad-31de-4141-a541-4338322b9f94","meta":{"drupal_internal__target_id":1}}],"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/owner"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/owner"}}},"equipment":{"data":[],"links":{"related":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/equipment"},"self":{"href":"http://192.168.1.34/api/log/transplanting/0d4bc521-0960-47e4-bfb6-7b759c900685/relationships/equipment"}}}}}

I’m sure I’m missing something relatively simple.

1 Like

Ah @Farmer-Ed I think the issue here might be that you need to specify the revision ID in addition to the resource ID. Quantities are unique in that they don’t use the standard entity_reference field type but the entity_reference_revisions field type. This is because we want changes to the quantity values to be included as a new log revision; if the quantity value changes then it should also be a new revision of the log.

You can specify the revision in the meta section of the relationship. Here is a python example:

# Create the quantity.
harvest_quantity = client.resource.send('quantity', 'standard', harvest_quantity_data)

# Add quantity to log.
log["relationships"]["quantity"] = {
    "data": [
        {
            "type": "quantity--standard",
            "id": harvest_quantity["data"]["id"],
            "meta": {
                "target_revision_id": harvest_quantity["data"]["attributes"]["drupal_internal__revision_id"]
            }
        },
    ]
}

new_log = client.log.send("harvest", log)

We should include this info in the Quantity API changes: API Changes | farmOS As well as include examples in the client libraries.

I’m not 100% sure that this is the issue, but your example looks good otherwise. Sorry I cant test this further right now. But I think we should try and make your example work - so that the latest revision is added automatically.

2 Likes

That worked perfect @paul121, I knew I was leaving something relatively simple out, but wouldn’t have worked it out either. An update to the documentation would be a big help, also I noticed a few minor typos in the documentation that could do with changing too, not sure if they were addressed already in a recent PR though.

2 Likes

Oh good catch - feel free to open a new PR! :slight_smile: What you see on farmOS.org is the latest. It doesn’t look like any of the PRs that are currently open change the docs.

1 Like

Wow good sleuthing @Farmer-Ed and @paul121 - I wouldn’t have thought of the revision ID either, but now that you mention it it makes sense. Quantities are unique in that regard.

I agree this needs to be documented - both in the v1/v2 changes section as well as in the API docs more generally - although we don’t really have much there at the moment, so there’s isn’t a great “place” for this detail.

@Farmer-Ed I’d be happy to help you get a PR together for this if you feel comfortable getting the ball rolling. Happy to coordinate in chat if so.

1 Like

Ah it looks like there’s an open issue with a merge request in the Entity Reference Revisions module to fix this: Infer "target_revision_id" to be Latest Revision when Only a "target_id" is Provided [#3267304] | Drupal.org

It might be worth testing and including that patch in farmOS…

2 Likes

@mstenta, I could give that a go, might be no harm to get a little practice on the process.

1 Like

@Farmer-Ed that would be awesome! I can guide you through the process. There are a few steps, but ultimately what we need to end up with is a new line in the our composer.json file like this:

That one is for a patch to the entity module. We would need one with a patch for the entity_reference_revisions module.

As you can see, what we need is a *.patch file hosted somewhere that we can pull in. The drupal.org issue has a MR (merge request), not a patch file. Drupal.org historically always dealt in patch files, but more recently introduced MRs (when they integrated with GitLab). In cases like that, what I like to do is use the MR to create a patch, then upload that patch to the same issue for anyone that needs it for composer.json. Here’s an example where I did that for another patch: Remove taxonomy hard dependency on node module [#2339235] | Drupal.org

The process for creating a patch from a MR is basically:

  1. Clone the entity_reference_revisions repository: Entity Reference Revisions | Drupal.org
  2. Checkout the MR branch (instructions in the issue under “Show commands”: Infer "target_revision_id" to be Latest Revision when Only a "target_id" is Provided [#3267304] | Drupal.org)
  3. Generate a patch file using git diff following the standard naming convention of [issue-number]-[comment-number].patch.
    • eg: git diff 8.x-1.x > 3267304-8.patch
  4. Upload the patch to the drupal.org issue. When there is already a MR, it’s good practice to make it clear that the patch is not intended to replace the MR - but is provided for folks who need it for inclusion in composer.json while waiting for upstream to merge.
  5. Add the patch to the farmOS composer.json file, following the pattern of other patches in there.
  6. Open a pull request - this will run tests to see if the patch applies properly.

To test locally, just replace the web/modules/entity_reference_revisions directory with the Git clone, with the MR checked out, and you should be able to try your API commands locally to see if it works.

EDIT: Forgot the step of uploading to the issue -added as step 4.

1 Like

I actually meant updating the documentation :rofl:
But OK I’ll give that a go too.
Will definitely be back for some advice :wink:

2 Likes

LOL! Either way! :joy:

Cheers @mstenta, thanks to your detailed instructions that seems to be working fine, I’ll do a bit more testing after and upload the patch file.

1 Like

PR Open, Update composer.json by Farmer-Eds-Shed · Pull Request #534 · farmOS/farmOS · GitHub

2 Likes

Thanks @Farmer-Ed! Merged! Once the next release of farmOS is tagged and released the revision ID will no longer be required for quantity references. :slight_smile:

1 Like