@@ -238,7 +238,99 @@ $response = $client->getXmlRpcClient('object')->send($msg);
238238// what the Odoo message_post() function returns.
239239
240240$result = $client->valueToNative($response->value());
241- ```
241+ ```
242+
243+ # Load Function
244+
245+ Odoo offers a loader API that handles resource loading easily.
246+ This package offers the ` load() ` and ` loadOne() ` methods to
247+ access that API.
248+
249+ The loader uses ` id ` as the external ID.
250+ It will find the resource if it already exists and update it,
251+ otherwise it will create the resource if it does not exist.
252+
253+ Each resource in the list can be specified with different
254+ fields, but all must be for the same resporce model.
255+
256+ ``` php
257+ // Load one or more partners.
258+
259+ $loadResult = $client->load('res.partner', [
260+ [
261+ "name" => "JJ Test",
262+ "active" => "TRUE",
263+ "type" => "developer",
264+ "id" => "external.partner_12345",
265+ ],
266+ // Further records for this model...
267+ ]);
268+ ```
269+
270+ The response will be an array with two elements, ` ids ` and ` messages ` ,
271+ both collections.
272+
273+ The ` ids ` collection will contain the * internal* IDs of any resources updated
274+ or created.
275+ The ` messages ` collection will contain any validation errors for failed
276+ updates or resource creation.
277+ There may be multiple messages for a single failed record.
278+
279+ ``` php
280+ // Example response with no errors and two resources updated or created.
281+
282+ array:2 [
283+ "ids" => Collection {
284+ #items: array:2 [
285+ 0 => 7252
286+ 1 => 7251
287+ ]
288+ }
289+ "messages" => Collection {
290+ #items: []
291+ }
292+ ]
293+
294+ // Example with oen validation error.
295+ // Note no records are loaded at all if any record fails validation.
296+
297+ array:2 [
298+ "ids" => Collection {
299+ #items: []
300+ }
301+ "messages" => Collection {
302+ #items: array:1 [
303+ 0 => array:5 [
304+ "field" => "year"
305+ "rows" => array:2 [
306+ "to" => 1
307+ "from" => 1
308+ ]
309+ "record" => 1
310+ "message" => "'2019x' does not seem to be an integer for field 'My Year'"
311+ "type" => "error"
312+ ]
313+ ]
314+ }
315+ ]
316+ ```
317+
318+ Although the record keys can vary between records,
319+ the Odoo API does not support that internally.
320+ This package works around that by grouping the records with
321+ identical keys and loading them in groups.
322+ This means that a validation error in one group will not
323+ prevent records loading from another group, so the result
324+ can be a mix of failed and loaded records.
325+
326+ An exception will be thrown on unrecoverable errors in Odoo,
327+ such as a database integrity constraint violcation.
328+
329+ The ` loadOne() ` method works in a similar way,
330+ but accepts just one record to load.
331+ It will return an ` id ` element with the integer ` internal ID `
332+ or ` null ` if the record failed to load, along with a collection
333+ for the messages.
242334
243335# TODO
244336
@@ -258,3 +350,4 @@ $result = $client->valueToNative($response->value());
258350 point, so moving some of the XML-RPC specific stuff (message creation, data
259351 conversion) would be best moved to a separate connection class).
260352* Positional parameter builder helper.
353+ * Some more explicit exceptions.
0 commit comments