mrichar1 / pinia-jsonapi

Use a JSONAPI api with a Pinia store, with data restructuring/normalization. Topics
GNU Affero General Public License v3.0
8 stars 2 forks source link

support ofetch for use in Nuxt 3 #1

Closed mdrews21 closed 4 months ago

mdrews21 commented 6 months ago

Is there a way to support ofetch client rather than using axios, since axios is not natively supported in Nuxt 3 anymore. Using axios anyways result in authentication problems in nuxt. Thank You!

mrichar1 commented 6 months ago

pinia-jsonapi expects to be handed an api object which behaves like axios - however it's agnostic as to what library you actually use. It should therefore be possible to map ofetch properties and functions onto axios equivalents so that they behave the same as far as pinia-jsonapi is concerned.

I've not thoroughly tested it, but creating an api function as follows instead of using axios seems to work as expected:

import { ofetch } from "ofetch";

const baseURL = 'https://example.com'

// 'req' contains a subset of axios configuration properties: https://axios-http.com/docs/req_config
const api = async (req) => {
  // Construct the URL
  let url = `${baseURL}/${req.url}`

 // Construct the ofetch config
  let oCfg = {
    headers: {
      'Content-Type': 'application/vnd.api+json',
      Accept: 'application/vnd.api+json',
    },
    method: req.method,
    params: req.params,
    parseResponse: JSON.parse,
  }

  // Add body if data is defined (POST/PATCH)
  if ('data' in req) {
    oCfg.body = req.data
  }

  let result = await ofetch(url, oCfg)
  // axios returns JSON nested under 'data' property.
  return { data: result }
}

I'd be interested to know if this works for you, or if you find any problems with it, as it would be good to formally support other clients including fetch, which should be manageable in the same way.

If this works I can look at creating an api instance 'map' which has working examples for different clients.

mdrews21 commented 5 months ago

Thank you and sorry for my late response. Its working fine with ofetch but some things are not working either: The "meta" and "included" properties of the api response are missing from the result. preserveJson: true is set and there is a key "_jv", but the keys are missing. grafik

mdrews21 commented 5 months ago

Please can you provide an installation guide for Nuxt 3 ? I know this is not your part but I would love to use this package and therefor I need to get it up and running with nuxt 3 and vue 3 composition api

mrichar1 commented 5 months ago

Thank you and sorry for my late response. Its working fine with ofetch but some things are not working either: The "meta" and "included" properties of the api response are missing from the result. preserveJson: true is set and there is a key "_jv", but the keys are missing. grafik

Can I confirm that your normalised response looks something like:

{
  _jv: {
    json: {
      data: {},
    }
  }
}

But there are no meta or included keys alongside data? (it might help if you can share a copy of the response object)

mdrews21 commented 5 months ago

Our Response from API looks like this (shortened a bit):

 {
"data": [
        {
            "attributes": {
                "created_at": "2024-02-09 14:50:46",
                "description": "Test 123",
                "externalsales_as_main": false,
                "g": "-89.80000",
                "inherit_payment_terms": false,
                "lvp": 38805,
                "r": "0.0",
                "sk": "0.0",
                "state": "Bearbeitung abgeschlossen",
                "state_color": "waiting",
                "state_description": "Bearbeitung abgeschlossen. Der Preis muss festgelegt werden",
                "state_icon": "mdiCashLockOpen",
                "updated_at": "2024-02-13 09:24:38",
                "vtp": "0.0"
            },
            "id": 4,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/sales/quotes/AN24-0004"
            },
            "no": "AN24-0004",
            "no_slug": "an24-0004",
            "relationships": {
                "backoffice": {
                    "data": {
                        "id": 1,
                        "type": "employees"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/backoffice",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/backoffice"
                    }
                },
                "customer": {
                    "data": {
                        "attributes": {
                            "name": "philippka GmbH & Co. KG",
                            "shortname": "Philippka"
                        },
                        "id": 4,
                        "type": "customers"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/customer",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/customer"
                    }
                },
            },
            "type": "quotes"
        }
    ],
    "included": [
        {
            "attributes": {
                "name": "Martin",
            },
            "id": 4,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/employees/4"
            },
            "type": "employees"
        },

        {
            "attributes": {
                "created_at": "2024-02-01 15:10:13",
                "name": "Customer XY",
                "updated_at": "2024-02-09 14:07:27"
            },
            "id": 4,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/sales/customers/4"
            },
            "type": "customers"
        }
    ],
    "links": {
        "first": "http://127.0.0.1:8000/api/v1/sales/quotes?page%5Bnumber%5D=1",
        "last": "http://127.0.0.1:8000/api/v1/sales/quotes?page%5Bnumber%5D=1",
        "next": null,
        "prev": null,
        "self": "http://127.0.0.1:8000/api/v1/sales/quotes"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "active": false,
                "label": "« Previous",
                "url": null
            },
            {
                "active": true,
                "label": "1",
                "url": "http://127.0.0.1:8000/api/v1/sales/quotes?page%5Bnumber%5D=1"
            },
            {
                "active": false,
                "label": "Next »",
                "url": null
            }
        ],
        "path": "http://127.0.0.1:8000/api/v1/sales/quotes",
        "per_page": 15,
        "to": 1,
        "total": 1
    }
}

console.log on the result is giving only one object of data:

store.search("sales/quotes", {params})
        .then((res) => {
            console.log(res)
        })
{
    "4": {
        "_jv": {
            "id": 4,
            "isData": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/sales/quotes/AN24-0004"
            },
            "no": "AN24-0004",
            "no_slug": "an24-0004",
            "relationships": {
                "backoffice": {
                    "data": {
                        "id": 1,
                        "type": "employees"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/backoffice",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/backoffice"
                    }
                },
                "customer": {
                    "data": {
                        "attributes": {
                            "name": "XXX"
                        },
                        "id": 4,
                        "type": "customers"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/customer",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/customer"
                    }
                }
            },
            "type": "quotes"
        },
        "backoffice": {
        },
        "created_at": "2024-02-09 14:50:46",
        "customer": {
        },
        "description": "Test 123",
        "documents": {
        },
        "externalsales": {
        },
        "externalsales_as_main": false,
        "g": "-89.80000",
        "inherit_payment_terms": false,
        "lvp": 38805,
        "r": "0.0",
        "sk": "0.0",
        "state": "Bearbeitung abgeschlossen",
        "state_color": "waiting",
        "state_description": "Bearbeitung abgeschlossen. Der Preis muss festgelegt werden",
        "state_icon": "mdiCashLockOpen",
        "updated_at": "2024-02-13 09:24:38",
        "vtp": "0.0"
    }
}
mdrews21 commented 5 months ago

Also same behaviour with store.get. Im also noticing that the pinia store "jv" stays empty on get requests.

mrichar1 commented 5 months ago

I can't replicate this issue here using the example ofetch code I provided - my response contains json key with all the relevant sub-keys (meta, included etc).

Looking again at your request, I think you might be hitting a more fundamental issue here with how pinia-jsonapi is interpreting the endpoint you are passing in.

pinia-jsonapi can take either a string, or jsonapi object as the endpoint to fetch. If it is a string, then it assumes the format is collection/id. So quotes would get all quotes, while quotes/1 would get quote with id 1.

However your API seems to have nested endpoints, so that sales/quotes is the collection endpoint. This is likely confusing things.

The quick way to test this is to set the base url to include sales/ and then make store.get just ask for quotes.

There are ways to handle this kind of layout in pinia-jsonapi - such as using url-encoded string (sales%2Fquotes) or using a jsonapi object as the endpoint/settng self links.

However if you are in control of the API you might want to consider using a different 'flat' endpoint namespace to avoid this confusion.

If this does seem to be where the issue lies, and you need to discuss further, please open a new issue so that we can keep this one about ofetch.

mdrews21 commented 5 months ago

Thank you for your response. Because the api is working pretty well with nuxt2 (vue2) and your jsonapi-vuex plugin I dont think its an api related problem. I found out that using store.get('sales/quotes') is working fine with this collection endpoint when using without params. I think there is a problem when using params in request like

const params = {
    "filter[search]": "test"
}
store.get('sales/quotes', {params: params})

The params are always empty when logging the fetch request: grafik

Do you have any idea what the problem is?

mrichar1 commented 5 months ago

For historic reasons¹ actions in pinia-jsonapi only expect a single argument - either the endpoint, or an array consisting of endpoint and params - something like:

store.get(['foo', { params: params }])

This might explain why included is missing at least, if the included params to the API are being dropped?

¹ In Vuex, dispatch can only take a single argument, so jsonapi-vuex accepts an array (or a single endpoint argument, which is converted to an array internally). It's on my todo list to investigate making things more flexible with pinia so the array braces are optional.

mdrews21 commented 5 months ago

Thank you for your hint using array braces. Now it works for included property and the store is filled correctly, also when using params in store.get() action.

But still meta and links property from the same level are missing. So i cannot use infos like page and pageCount from api requests to collections.

mrichar1 commented 5 months ago

The exact jsonapi returned by the API always be present in {_jv: json: {} } in the response from the API assuming preserveJson is set to true in the pinia-jsonapi config. Can you confirm if you have a json property in the response, and if so, what it contains?

(These aren't propagated to the store as they are 'per-request' values rather than than relating to the data, so the user is responsible for using these 'manually' by extracting them from the response).

mdrews21 commented 5 months ago

Original response from ofetch.raw(url, oCfg) is: grafik

with records under _data.data and meta under _data.meta While

store.get(["sales/quotes",{params: params}])
    .then((res) =>{ 
        console.log(res)
    })

gives

{
    "4": {
        "_jv": {
            "id": 4,
            "isData": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/sales/quotes/AN24-0004"
            },
            "no": "AN24-0004",
            "no_slug": "an24-0004",
            "relationships": {
                "backoffice": {
                    "data": {
                        "id": 1,
                        "type": "employees"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/backoffice",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/backoffice"
                    }
                },
                "contact": {
                    "data": {
                        "id": 19,
                        "type": "contacts"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/contact",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/contact"
                    }
                },
                "contents": {
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/content",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/content"
                    }
                },
                "customer": {
                    "data": {
                        "attributes": {
                            "name": "philippka GmbH & Co. KG",
                            "shortname": "Philippka"
                        },
                        "id": 4,
                        "type": "customers"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/customer",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/customer"
                    }
                },
                "documents": {
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/documents",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/documents"
                    }
                },
                "externalsales": {
                    "data": {
                        "id": 4,
                        "type": "employees"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/externalsales",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/externalsales"
                    }
                },
                "paymentmethod": {
                    "data": {
                        "attributes": {
                            "name": "gegen Rechnung"
                        },
                        "id": 1,
                        "links": {
                            "self": "http://127.0.0.1:8000/api/v1/accounting/paymentmethods/1"
                        },
                        "type": "paymentmethods"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/paymentmethod",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/paymentmethod"
                    }
                },
                "paymenttarget": {
                    "data": {
                        "attributes": {
                            "name": "2% 8 Tage, 30 Tage netto",
                            "skontosatz1": "2.0",
                            "skontosatz2": "0.0",
                            "skontotage1": 8,
                            "skontotage1_plus_till_end_of_month": false,
                            "skontotage2": null,
                            "skontotage2_plus_till_end_of_month": false,
                            "zahlungsziel": 30,
                            "zahlungsziel_plus_till_end_of_month": false
                        },
                        "id": 1,
                        "links": {
                            "self": "http://127.0.0.1:8000/api/v1/accounting/paymenttargets/1"
                        },
                        "type": "paymenttargets"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/paymenttarget",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/paymenttarget"
                    }
                },
                "products": {
                    "data": [
                        {
                            "id": "pr24-9v7h",
                            "no": "PR24-9V7H",
                            "no_slug": "pr24-9v7h",
                            "type": "products"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/products",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/products"
                    }
                },
                "quoteproducts": {
                    "data": [
                        {
                            "attributes": {
                                "name": "Zeitschrift 4+80S A4 Euroskala BDG 200+100g"
                            },
                            "id": 1,
                            "links": {
                                "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1"
                            },
                            "relationships": {
                                "contents": {
                                    "data": {
                                        "category": "productdesc",
                                        "id": 7,
                                        "type": "contents"
                                    },
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/content",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/relationships/contents"
                                    }
                                },
                                "products": {
                                    "data": {
                                        "id": "pr24-9v7h",
                                        "no": "PR24-9V7H",
                                        "no_slug": "pr24-9v7h",
                                        "type": "products"
                                    },
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/product",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/relationships/products"
                                    }
                                },
                                "quoteproductworkflows": {
                                    "data": [
                                        {
                                            "id": 1,
                                            "type": "quoteproductworkflows"
                                        }
                                    ],
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/quoteproductworkflows",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/relationships/quoteproductworkflows"
                                    }
                                },
                                "quotes": {
                                    "data": {
                                        "attributes": {
                                            "description": "Test 123"
                                        },
                                        "id": 4,
                                        "no": "AN24-0004",
                                        "no_slug": "an24-0004",
                                        "type": "quotes"
                                    },
                                    "links": [
                                    ]
                                },
                                "workflows": {
                                    "data": [
                                        {
                                            "id": 2,
                                            "type": "workflows"
                                        }
                                    ],
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/workflows",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/relationships/workflows"
                                    }
                                }
                            },
                            "type": "quoteproducts"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/quoteproducts",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/quoteproducts"
                    }
                },
                "quoteproductworkflows": {
                    "data": [
                        {
                            "attributes": {
                                "behavior_on_cost_change": 0,
                                "g": "-89.8",
                                "lowerlimit_g": "-25.0",
                                "lowerlimit_lvp": 286032,
                                "lowerlimit_price_per_unit": 146683,
                                "lvp": 38805,
                                "mode": "automatisch",
                                "price_per_unit": 19900,
                                "show_in_quote": true,
                                "state": "OK",
                                "state_color": "madang",
                                "state_description": "OK",
                                "state_icon": "mdiCheckCircle",
                                "suggested_g": "2.5",
                                "suggested_lvp": 390910,
                                "suggested_price_per_unit": 200466
                            },
                            "id": 1,
                            "links": {
                                "self": "http://127.0.0.1:8000/api/v1/sales/quoteproductworkflows/1"
                            },
                            "relationships": {
                                "latestprecalculation": [
                                ],
                                "lowerlimitpricecodes": [
                                ],
                                "quote": {
                                    "data": {
                                        "attributes": {
                                            "description": "Test 123"
                                        },
                                        "id": 4,
                                        "no": "AN24-0004",
                                        "no_slug": "an24-0004",
                                        "type": "quotes"
                                    }
                                },
                                "suggestedpricecodes": [
                                ],
                                "workflows": {
                                    "data": {
                                        "id": 2,
                                        "type": "workflows"
                                    }
                                }
                            },
                            "type": "quoteproductworkflows"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/quoteproductworkflows",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/quoteproductworkflows"
                    }
                }
            },
            "type": "quotes"
        },
        "backoffice": {
            "_jv": {
                "id": 1,
                "isIncluded": true,
                "links": {
                    "self": "http://127.0.0.1:8000/api/v1/employees/1"
                },
                "type": "employees"
            },
            [...]
        },
        "contact": {
        },
        "contents": {
        },
        "created_at": "2024-02-09 14:50:46",
        "customer": {
            "_jv": {
                "id": 4,
                "isIncluded": true,
                "links": {
                    "self": "http://127.0.0.1:8000/api/v1/sales/customers/4"
                },
                [...],
                "type": "customers"
            },
            "addresses": {
                "8": {
                }
            },
            "contacts": {
                "19": {
                }
            },
            [...]
        },
        "description": "Test 123",
        "documents": {
        },
        "externalsales": {
        },
        "externalsales_as_main": false,
        "g": "-89.80000",
        "inherit_payment_terms": false,
        "lvp": 38805,
        "paymentmethod": {
        },
        "paymenttarget": {
        },
        "products": {
            "pr24-9v7h": {
            }
        },
        "quoteproducts": {
            "1": {
            }
        },
        "quoteproductworkflows": {
            "1": {
            }
        },
        "r": "0.0",
        "sk": "0.0",
        "state": "Bearbeitung abgeschlossen",
        "state_color": "waiting",
        "state_description": "Bearbeitung abgeschlossen. Der Preis muss festgelegt werden",
        "state_icon": "mdiCashLockOpen",
        "updated_at": "2024-02-13 09:24:38",
        "vtp": "0.0"
    }
}

preserveJson: true is set. useOfetchApi() -Composable returns underlying _data as data:

const result = await ofetch.raw(url, oCfg)
        // axios returns JSON nested under 'data' property.
        return {data: result._data}

Same result with

const result = await ofetch(url, oCfg)
        // axios returns JSON nested under 'data' property.
        return {data: result.}
mrichar1 commented 5 months ago

That's interesting... I would expect it to work with return { data: result._data }. It looks like preserveJSON functionality is either not being called, or is not adding the JSON to the request, otherwise your response should look something like:

{ 4: { // normalised data... }, _jv: { json: { // JSONAPI as returned by API... }}, }

To do a bit of debugging, if in your project you edit node_modules/pinia_jsonapi/src/lib.js you should be able to add some logging into the preserveJSON function. Maybe something like:

preserveJSON(data, json) {
    console.log('Preserving JSON', this.conf, json)
    // rest of function...
}

That should confirm that the preserveJSON code-path is being executed; that the config contains preserveJson: true; and that the json from the API contains the relevant includes/meta/links. (You could also log data which is the restructured data, but this is probably fine as we're seing correct data in the response/store.

mdrews21 commented 4 months ago

I think preserveJson is not working as expected because logging as you said gives preserveJson: false

{
    "jvtag": "_jv",
    "followRelationshipsData": true,
    "preserveJson": false,
    "mergeRecords": false,
    "clearOnUpdate": false,
    "cleanPatch": false,
    "cleanPatchProps": [],
    "recurseRelationships": false,
    "maxStatusID": -1,
    "relatedIncludes": true,
    "conf": {
        "preserveJSON": true
    }
}

Logging data is the same as i wrote above. So there is a correct response from api with meta and included. Logging json has this result:

{
    "an24-0004": {
        "_jv": {
            "id": "an24-0004",
            "isData": true,
            "links": {
                "self": "http://127.0.0.1:8000/api/v1/sales/quotes/AN24-0004"
            },
            "no": "AN24-0004",
            "no_slug": "an24-0004",
            "relationships": {
                "backoffice": {
                    "data": {
                        "id": 1,
                        "type": "employees"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/backoffice",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/backoffice"
                    }
                },
                "contact": {
                    "data": null,
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/contact",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/contact"
                    }
                },
                "contents": {
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/content",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/content"
                    }
                },
                "customer": {
                    "data": {
                        "attributes": {
                            "name": "XXX",
                            "shortname": "XXX"
                        },
                        "id": 4,
                        "type": "customers"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/customer",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/customer"
                    }
                },
                "documents": {
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/documents",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/documents"
                    }
                },
                "externalsales": {
                    "data": {
                        "id": 4,
                        "type": "employees"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/externalsales",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/externalsales"
                    }
                },
                "paymentmethod": {
                    "data": {
                        "attributes": {
                            "name": "gegen Rechnung"
                        },
                        "id": 1,
                        "links": {
                            "self": "http://127.0.0.1:8000/api/v1/accounting/paymentmethods/1"
                        },
                        "type": "paymentmethods"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/paymentmethod",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/paymentmethod"
                    }
                },
                "paymenttarget": {
                    "data": {
                        "attributes": {
                            "name": "2% 8 Tage, 30 Tage netto",
                            "skontosatz1": "2.0",
                            "skontosatz2": "0.0",
                            "skontotage1": 8,
                            "skontotage1_plus_till_end_of_month": false,
                            "skontotage2": null,
                            "skontotage2_plus_till_end_of_month": false,
                            "zahlungsziel": 30,
                            "zahlungsziel_plus_till_end_of_month": false
                        },
                        "id": 1,
                        "links": {
                            "self": "http://127.0.0.1:8000/api/v1/accounting/paymenttargets/1"
                        },
                        "type": "paymenttargets"
                    },
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/paymenttarget",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/paymenttarget"
                    }
                },
                "products": {
                    "data": [
                        {
                            "id": "pr24-9v7h",
                            "no": "PR24-9V7H",
                            "no_slug": "pr24-9v7h",
                            "type": "products"
                        }
                    ],
                    "links": {
                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/products",
                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/products"
                    }
                },
            },
            "type": "quotes"
        },
        "backoffice": {
            "_jv": {
                "id": 1,
                "isIncluded": true,
                "links": {
                    "self": "http://127.0.0.1:8000/api/v1/employees/1"
                },
                "type": "employees"
            },
            "email": "XXX",
            [...]
        },
        "contact": {
        },
        "contents": {
        },
        "created_at": "2024-02-09 14:50:46",
        "customer": {
            "_jv": {
                "id": 4,
                "isData": true,
                "isIncluded": true,
                "links": {
                    "self": "http://127.0.0.1:8000/api/v1/sales/customers/4"
                },
                "relationships": {
                    "addresses": {
                        "data": [
                            {
                                "attributes": {
                                    [...]
                                },
                                "id": 8,
                                "links": {
                                    "self": "http://127.0.0.1:8000/api/v1/addresses/8"
                                },
                                "type": "addresses"
                            }
                        ],
                        "links": {
                            "related": "http://127.0.0.1:8000/api/v1/sales/customers/4/addresses",
                            "self": "http://127.0.0.1:8000/api/v1/sales/customers/4/relationships/addresses"
                        }
                    },
                    "contacts": {
                        "data": [
                            {
                                "id": 19,
                                "type": "contacts"
                            }
                        ],
                        "links": {
                            "related": "http://127.0.0.1:8000/api/v1/sales/customers/4/contacts",
                            "self": "http://127.0.0.1:8000/api/v1/sales/customers/4/relationships/contacts"
                        }
                    },
                    "products": {
                        "data": [
                        ],
                        "links": {
                            "related": "http://127.0.0.1:8000/api/v1/sales/customers/4/products",
                            "self": "http://127.0.0.1:8000/api/v1/sales/customers/4/relationships/products"
                        }
                    },
                    "remarks": {
                        "links": [
                        ]
                    },
                    "termofpayment": {
                        "data": null,
                        "links": [
                        ]
                    }
                },
                "type": "customers"
            },
            "addresses": {
                "8": {
                    "_jv": {
                        "id": 8,
                        "isIncluded": true,
                        "links": {
                            "self": "http://127.0.0.1:8000/api/v1/addresses/8"
                        },
                        "type": "addresses"
                    },
                    "city": "Münster",
                    [...]
                }
            },
            "contacts": {
                "19": {
                    "_jv": {
                        "id": 19,
                        "isIncluded": true,
                        "links": {
                            "self": "http://127.0.0.1:8000/api/v1/contacts/19"
                        },
                        "type": "contacts"
                    },
                    "created_at": "2024-02-01 15:10:13",
                    "fax": null,
                    "firstname": "XXX",
                    [...]
                }
            },
            "created_at": "2024-02-01 15:10:13",
            "email": "XXX",
            "fax": "XXX",
            [...]
            "termofpayment": {
            },
            "title": null,
            "updated_at": "2024-02-09 14:07:27"
        },
        "description": "Hallo Welt1",
        "documents": {
        },
        "externalsales": {
            "_jv": {
                "id": 4,
                "isIncluded": true,
                "links": {
                    "self": "http://127.0.0.1:8000/api/v1/employees/4"
                },
                "type": "employees"
            },
            "email": "XXX",
            [...]
        },
        "externalsales_as_main": false,
        "g": "-89.80000",
        "inherit_payment_terms": false,
        "lvp": 38805,
        "paymentmethod": {
        },
        "paymenttarget": {
            "_jv": {
                "id": 1,
                "isIncluded": true,
                "links": {
                    "self": "http://127.0.0.1:8000/api/v1/accounting/paymenttargets/1"
                },
                "type": "paymenttargets"
            },
            "behavior_on_cost_change": 0,
            "created_at": "2024-04-04 15:15:07",
            "description": null,
            "editable": true,
            "email": "XXX",
            "fax": "XXX",
            "file_path": null,
            "firstname": "XXX",
            "fullname": "XXX",
            "g": "-89.8",
            "ismailed": false,
            "isprinted": false,
            "lastname": "XXX",
            "lowerlimit_g": "-25.0",
            "lowerlimit_lvp": 286032,
            "lowerlimit_price_per_unit": 146683,
            "lvp": 38805,
            "mode": "automatisch",
            "name": "2% 8 Tage, 30 Tage netto",
            "personalnr": 539,
            "price_per_unit": 19900,
            "show_in_quote": true,
            "skontosatz1": "2.0",
            "skontosatz2": "0.0",
            "skontotage1": 8,
            "skontotage1_plus_till_end_of_month": false,
            "skontotage2": null,
            "skontotage2_plus_till_end_of_month": false,
            "state": "OK",
            "state_color": "madang",
            "state_description": "OK",
            "state_icon": "mdiCheckCircle",
            "suggested_g": "2.5",
            "suggested_lvp": 390910,
            "suggested_price_per_unit": 200466,
            "telephone": "XXX",
            "title": "i.A.",
            "updated_at": "2024-04-04 15:15:07",
            "valid": true,
            "version": 1,
            "zahlungsziel": 30,
            "zahlungsziel_plus_till_end_of_month": false
        },
        "products": {
            "pr24-9v7h": {
                "_jv": {
                    "id": "pr24-9v7h",
                    "isIncluded": true,
                    "links": {
                        "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h"
                    },
                    "no": "PR24-9V7H",
                    "no_slug": "pr24-9v7h",
                    "relationships": {
                        "amounts": {
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/amounts",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/amounts"
                            }
                        },
                        "components": {
                            "data": [
                                {
                                    "id": 1,
                                    "type": "components"
                                },
                                {
                                    "id": 2,
                                    "type": "components"
                                }
                            ],
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/components",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/components"
                            }
                        },
                        "contents": {
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/contents",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/contents"
                            }
                        },
                        "processings": {
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/processings",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/processings"
                            }
                        },
                        "producttype": {
                            "data": {
                                "id": 1,
                                "type": "producttypes"
                            },
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/producttype",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/producttype"
                            }
                        },
                        "quoteproducts": {
                            "data": [
                            ],
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/quoteproducts",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/quoteproducts"
                            }
                        },
                        "quotes": {
                            "data": [
                                {
                                    "attributes": {
                                        "description": "Hallo Welt1"
                                    },
                                    "id": "an24-0004",
                                    "no": "AN24-0004",
                                    "no_slug": "an24-0004",
                                    "type": "quotes"
                                }
                            ],
                            "links": [
                            ]
                        },
                        "tags": {
                            "data": [
                                {
                                    "attributes": {
                                        "created_at": "2024-02-01 15:17:35",
                                        "name": "Rückstichheftung",
                                        "order_column": 1,
                                        "slug": "ruckstichheftung",
                                        "updated_at": "2024-02-01 15:17:35"
                                    },
                                    "id": 1,
                                    "links": [
                                    ],
                                    "type": "tags"
                                },
                                {
                                    "attributes": {
                                        "created_at": "2024-02-01 15:17:35",
                                        "name": "A4",
                                        "order_column": 2,
                                        "slug": "a4",
                                        "updated_at": "2024-02-01 15:17:35"
                                    },
                                    "id": 2,
                                    "links": [
                                    ],
                                    "type": "tags"
                                },
                                {
                                    "attributes": {
                                        "created_at": "2024-02-01 15:17:35",
                                        "name": "Bilderdruck",
                                        "order_column": 3,
                                        "slug": "bilderdruck",
                                        "updated_at": "2024-02-01 15:17:35"
                                    },
                                    "id": 3,
                                    "links": [
                                    ],
                                    "type": "tags"
                                },
                                {
                                    "attributes": {
                                        "created_at": "2024-02-01 15:17:35",
                                        "name": "Dispersionslack",
                                        "order_column": 4,
                                        "slug": "dispersionslack",
                                        "updated_at": "2024-02-01 15:17:35"
                                    },
                                    "id": 4,
                                    "links": [
                                    ],
                                    "type": "tags"
                                }
                            ],
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/tags",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/tags"
                            }
                        },
                        "unit_costs": {
                            "data": {
                                "attributes": {
                                    "name": "Stück",
                                    "name_plural": "Stück",
                                    "shortname": "Expl."
                                },
                                "id": 1,
                                "type": "units"
                            },
                            "links": [
                            ]
                        },
                        "variables": {
                            "data": [
                                {
                                    "id": 26,
                                    "type": "variables"
                                }
                            ],
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/variables",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/variables"
                            }
                        },
                        "variants": {
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/variants",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/variants"
                            }
                        },
                        "workflows": {
                            "data": [
                                {
                                    "id": 2,
                                    "type": "workflows"
                                }
                            ],
                            "links": {
                                "related": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/workflows",
                                "self": "http://127.0.0.1:8000/api/v1/production/products/pr24-9v7h/relationships/workflows"
                            }
                        }
                    },
                    "type": "products"
                },
                "amounts": {
                },
                "components": {
                    "1": {
                    },
                    "2": {
                    }
                },
                "contents": {
                },
                "created_at": "2024-02-01 15:52:34",
                "description": "Broschüre Rückstichheftung DINA4 Bilderdruck Glänzend 4/4-frbg Euroskala, UM 200g + außen Dispersionslack, INH 80S 100g",
                "multiplier_cost": 1000,
                "name": "Zeitschrift 4+80S A4 Euroskala BDG 200+100g",
                "processings": {
                },
                "producttype": {
                },
                "quotes": {
                    "an24-0004": {
                        "_jv": {
                            "id": "an24-0004",
                            "isData": true,
                            "links": {
                                "self": "http://127.0.0.1:8000/api/v1/sales/quotes/AN24-0004"
                            },
                            "no": "AN24-0004",
                            "no_slug": "an24-0004",
                            "relationships": {
                                "backoffice": {
                                    "data": {
                                        "id": 1,
                                        "type": "employees"
                                    },
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/backoffice",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/backoffice"
                                    }
                                },
                                "contact": {
                                    "data": null,
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/contact",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/contact"
                                    }
                                },
                                "contents": {
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/content",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/content"
                                    }
                                },
                                "customer": {
                                    "data": {
                                        "attributes": {
                                            "name": "XXX",
                                            "shortname": "XXX"
                                        },
                                        "id": 4,
                                        "type": "customers"
                                    },
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/customer",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/customer"
                                    }
                                },
                                "documents": {
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/documents",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/documents"
                                    }
                                },
                                "externalsales": {
                                    "data": {
                                        "id": 4,
                                        "type": "employees"
                                    },
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/externalsales",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/externalsales"
                                    }
                                },
                                "paymentmethod": {
                                    "data": {
                                        "attributes": {
                                            "name": "gegen Rechnung"
                                        },
                                        "id": 1,
                                        "links": {
                                            "self": "http://127.0.0.1:8000/api/v1/accounting/paymentmethods/1"
                                        },
                                        "type": "paymentmethods"
                                    },
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/paymentmethod",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/paymentmethod"
                                    }
                                },
                                "paymenttarget": {
                                    "data": {
                                        "attributes": {
                                            "name": "2% 8 Tage, 30 Tage netto",
                                            "skontosatz1": "2.0",
                                            "skontosatz2": "0.0",
                                            "skontotage1": 8,
                                            "skontotage1_plus_till_end_of_month": false,
                                            "skontotage2": null,
                                            "skontotage2_plus_till_end_of_month": false,
                                            "zahlungsziel": 30,
                                            "zahlungsziel_plus_till_end_of_month": false
                                        },
                                        "id": 1,
                                        "links": {
                                            "self": "http://127.0.0.1:8000/api/v1/accounting/paymenttargets/1"
                                        },
                                        "type": "paymenttargets"
                                    },
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/paymenttarget",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/paymenttarget"
                                    }
                                },
                                "products": {
                                    "data": [
                                        {
                                            "id": "pr24-9v7h",
                                            "no": "PR24-9V7H",
                                            "no_slug": "pr24-9v7h",
                                            "type": "products"
                                        }
                                    ],
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/products",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/products"
                                    }
                                },
                                "quoteproducts": {
                                    "data": [
                                        {
                                            "attributes": {
                                                "name": "Zeitschrift 4+80S A4 Euroskala BDG 200+100g"
                                            },
                                            "id": 1,
                                            "links": {
                                                "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1"
                                            },
                                            "relationships": {
                                                "contents": {
                                                    "data": {
                                                        "category": "productdesc",
                                                        "id": 7,
                                                        "type": "contents"
                                                    },
                                                    "links": {
                                                        "related": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/content",
                                                        "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/relationships/contents"
                                                    }
                                                },
                                                "products": {
                                                    "data": {
                                                        "id": "pr24-9v7h",
                                                        "no": "PR24-9V7H",
                                                        "no_slug": "pr24-9v7h",
                                                        "type": "products"
                                                    },
                                                    "links": {
                                                        "related": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/product",
                                                        "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/relationships/products"
                                                    }
                                                },
                                                "quoteproductworkflows": {
                                                    "data": [
                                                        {
                                                            "id": 1,
                                                            "type": "quoteproductworkflows"
                                                        }
                                                    ],
                                                    "links": {
                                                        "related": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/quoteproductworkflows",
                                                        "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/relationships/quoteproductworkflows"
                                                    }
                                                },
                                                "quotes": {
                                                    "data": {
                                                        "attributes": {
                                                            "description": "Hallo Welt1"
                                                        },
                                                        "id": "an24-0004",
                                                        "no": "AN24-0004",
                                                        "no_slug": "an24-0004",
                                                        "type": "quotes"
                                                    },
                                                    "links": [
                                                    ]
                                                },
                                                "workflows": {
                                                    "data": [
                                                        {
                                                            "id": 2,
                                                            "type": "workflows"
                                                        }
                                                    ],
                                                    "links": {
                                                        "related": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/workflows",
                                                        "self": "http://127.0.0.1:8000/api/v1/sales/quoteproducts/1/relationships/workflows"
                                                    }
                                                }
                                            },
                                            "type": "quoteproducts"
                                        }
                                    ],
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/quoteproducts",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/quoteproducts"
                                    }
                                },
                                "quoteproductworkflows": {
                                    "data": [
                                        {
                                            "attributes": {
                                                "behavior_on_cost_change": 0,
                                                "g": "-89.8",
                                                "lowerlimit_g": "-25.0",
                                                "lowerlimit_lvp": 286032,
                                                "lowerlimit_price_per_unit": 146683,
                                                "lvp": 38805,
                                                "mode": "automatisch",
                                                "price_per_unit": 19900,
                                                "show_in_quote": true,
                                                "state": "OK",
                                                "state_color": "madang",
                                                "state_description": "OK",
                                                "state_icon": "mdiCheckCircle",
                                                "suggested_g": "2.5",
                                                "suggested_lvp": 390910,
                                                "suggested_price_per_unit": 200466
                                            },
                                            "id": 1,
                                            "links": {
                                                "self": "http://127.0.0.1:8000/api/v1/sales/quoteproductworkflows/1"
                                            },
                                            "relationships": {
                                                "latestprecalculation": [
                                                ],
                                                "lowerlimitpricecodes": [
                                                ],
                                                "quote": {
                                                    "data": {
                                                        "attributes": {
                                                            "description": "Hallo Welt1"
                                                        },
                                                        "id": "an24-0004",
                                                        "no": "AN24-0004",
                                                        "no_slug": "an24-0004",
                                                        "type": "quotes"
                                                    }
                                                },
                                                "suggestedpricecodes": [
                                                ],
                                                "workflows": {
                                                    "data": {
                                                        "id": 2,
                                                        "type": "workflows"
                                                    }
                                                }
                                            },
                                            "type": "quoteproductworkflows"
                                        }
                                    ],
                                    "links": {
                                        "related": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/quoteproductworkflows",
                                        "self": "http://127.0.0.1:8000/api/v1/sales/quotes/an24-0004/relationships/quoteproductworkflows"
                                    }
                                }
                            },
                            "type": "quotes"
                        },
                        "backoffice": {
                            "_jv": {
                                "id": 1,
                                "isIncluded": true,
                                "links": {
                                    "self": "http://127.0.0.1:8000/api/v1/employees/1"
                                },
                                "type": "employees"
                            },
                            "email": "XXX",
                            "fax": "XXX",
                            "firstname": "XXX",
                            "fullname": "XXX,
                            "lastname": "XX",
                            [...]
                        },
                        "contact": {
                        },
                        "contents": {
                        },
                        "created_at": "2024-02-09 14:50:46",
                        "customer": {
                            "_jv": {
                                "id": 4,
                                "isData": true,
                                "isIncluded": true,
                                "links": {
                                    "self": "http://127.0.0.1:8000/api/v1/sales/customers/4"
                                },
                                "relationships": {
                                    "addresses": {
                                        "data": [
                                            {
                                                "attributes": {
                                                    "city": "XXX",
                                                    "country": "DE",
                                                    "country_name": "Deutschland",
                                                    "distance": null,
                                                    "duration": null,
                                                    "formatted_address": null,
                                                    "is_billing": true,
                                                    "is_primary": true,
                                                    "is_shipping": true,
                                                    "is_shipping_primary": false,
                                                    "latitude": null,
                                                    "longitude": null,
                                                    "name1": "XXX",
                                                    "name2": null,
                                                    "name3": null,
                                                    "nonrecurring": false,
                                                    "reference": "XXX",
                                                },
                                                "id": 8,
                                                "links": {
                                                    "self": "http://127.0.0.1:8000/api/v1/addresses/8"
                                                },
                                                "type": "addresses"
                                            }
                                        ],
                                        "links": {
                                            "related": "http://127.0.0.1:8000/api/v1/sales/customers/4/addresses",
                                            "self": "http://127.0.0.1:8000/api/v1/sales/customers/4/relationships/addresses"
                                        }
                                    },
                                    "contacts": {
                                        "data": [
                                            {
                                                "id": 19,
                                                "type": "contacts"
                                            }
                                        ],
                                        "links": {
                                            "related": "http://127.0.0.1:8000/api/v1/sales/customers/4/contacts",
                                            "self": "http://127.0.0.1:8000/api/v1/sales/customers/4/relationships/contacts"
                                        }
                                    },
                                    "products": {
                                        "data": [
                                        ],
                                        "links": {
                                            "related": "http://127.0.0.1:8000/api/v1/sales/customers/4/products",
                                            "self": "http://127.0.0.1:8000/api/v1/sales/customers/4/relationships/products"
                                        }
                                    },
                                    "remarks": {
                                        "links": [
                                        ]
                                    },
                                    "termofpayment": {
                                        "data": null,
                                        "links": [
                                        ]
                                    }
                                },
                                "type": "customers"
                            },
                            "addresses": {
                                "8": {
                                    "_jv": {
                                        "id": 8,
                                        "isIncluded": true,
                                        "links": {
                                            "self": "http://127.0.0.1:8000/api/v1/addresses/8"
                                        },
                                        "type": "addresses"
                                    },
                                    "city": "XXX",
                                    "country": "DE",
                                    "country_name": "Deutschland",
                                    "distance": null,
                                    "duration": null,
                                    "formatted_address": null,
                                    "is_billing": true,
                                    "is_primary": true,
                                    "is_shipping": true,
                                    "is_shipping_primary": false,
                                    "latitude": null,
                                    "longitude": null,
                                    "name1": "XXX",
                                    "name2": null,
                                    "name3": null,
                                    "nonrecurring": false,
                                    "post_code": "48159",
                                    "reference": "XXX",
                                    "street": "XXX"
                                }
                            },
                            "contacts": {
                                "19": {
                                    "_jv": {
                                        "id": 19,
                                        "isIncluded": true,
                                        "links": {
                                            "self": "http://127.0.0.1:8000/api/v1/contacts/19"
                                        },
                                        "type": "contacts"
                                    },
                                    "created_at": "2024-02-01 15:10:13",
                                    "fax": null,
                                    [...]
                                }
                            },
                            "created_at": "2024-02-01 15:10:13",
                            "email": "XXX",
                            "fax": "XXX",
                            "firstname": "XXX",
                            "fullname": "XXX",
                            [...]
                            "products": {
                            },
                            "remarks": {
                            },
                            "shortname": "XXX",
                            "termofpayment": {
                            },
                            "title": null,
                            "updated_at": "2024-02-09 14:07:27"
                        },
                        "description": "Hallo Welt1",
                        "documents": {
                        },
                        "externalsales": {
                            "_jv": {
                                "id": 4,
                                "isIncluded": true,
                                "links": {
                                    "self": "http://127.0.0.1:8000/api/v1/employees/4"
                                },
                                "type": "employees"
                            },
                            "email": "XXX",
                            "fax": "XXX",
                            "firstname": "XXX",
                            "fullname": "XXX",
                            "lastname": "XXX",
                            [...]
                        },
                        "externalsales_as_main": false,
                        "g": "-89.80000",
                        "inherit_payment_terms": false,
                        "lvp": 38805,
                        "paymentmethod": {
                        },
                        "paymenttarget": {
                            "_jv": {
                                "id": 1,
                                "isIncluded": true,
                                "links": {
                                    "self": "http://127.0.0.1:8000/api/v1/accounting/paymenttargets/1"
                                },
                                "type": "paymenttargets"
                            },
                            "behavior_on_cost_change": 0,
                            "created_at": "2024-04-04 15:15:07",
                            "description": null,
                            "editable": true,
                            "email": "XXX",
                            "fax": "XXX",
                            "file_path": null,
                            "firstname": "XXX",
                            "fullname": "XXX",
                            "g": "-89.8",
                            "ismailed": false,
                            "isprinted": false,
                            "lastname": "XXX",
                            "lowerlimit_g": "-25.0",
                            "lowerlimit_lvp": 286032,
                            "lowerlimit_price_per_unit": 146683,
                            "lvp": 38805,
                            "mode": "automatisch",
                            "name": "2% 8 Tage, 30 Tage netto",
                            "personalnr": 539,
                            "price_per_unit": 19900,
                            "show_in_quote": true,
                            "skontosatz1": "2.0",
                            "skontosatz2": "0.0",
                            "skontotage1": 8,
                            "skontotage1_plus_till_end_of_month": false,
                            "skontotage2": null,
                            "skontotage2_plus_till_end_of_month": false,
                            "state": "OK",
                            "state_color": "madang",
                            "state_description": "OK",
                            "state_icon": "mdiCheckCircle",
                            "suggested_g": "2.5",
                            "suggested_lvp": 390910,
                            "suggested_price_per_unit": 200466,
                            "title": "i.A.",
                            "updated_at": "2024-04-04 15:15:07",
                            "valid": true,
                            "version": 1,
                            "zahlungsziel": 30,
                            "zahlungsziel_plus_till_end_of_month": false
                        },
                        "products": {
                            "pr24-9v7h": {
                                "_jv": {
                                    "id": "pr24-9v7h",
                                    "type": "products"
                                }
                            }
                        },
                        "quoteproducts": {
                            "1": {
                            }
                        },
                        "quoteproductworkflows": {
                            "1": {
                            }
                        },
                        "r": "0.0",
                        "sk": "0.0",
                        "state": "Bearbeitung abgeschlossen",
                        "state_color": "waiting",
                        "state_description": "Bearbeitung abgeschlossen. Der Preis muss festgelegt werden",
                        "state_icon": "mdiCashLockOpen",
                        "updated_at": "2024-04-19 10:17:52",
                        "vtp": "0.0"
                    }
                },
                "state": "OK",
                "state_color": "madang",
                "state_description": "Das Produkt ist korrekt kalkuliert und kann produziert werden",
                "state_icon": "mdiCheckCircle",
                "tags": {
                    "1": {
                    },
                    "2": {
                    },
                    "3": {
                    },
                    "4": {
                    }
                },
                "template": false,
                "unit_costs": {
                },
                "updated_at": "2024-02-01 15:54:11",
                "variables": {
                    "26": {
                    }
                },
                "variants": {
                },
                "workflows": {
                    "2": {
                    }
                }
            }
        },
        "quoteproducts": {
            "1": {
            }
        },
        "quoteproductworkflows": {
            "1": {
            }
        },
        "r": "0.0",
        "sk": "0.0",
        "state": "Bearbeitung abgeschlossen",
        "state_color": "waiting",
        "state_description": "Bearbeitung abgeschlossen. Der Preis muss festgelegt werden",
        "state_icon": "mdiCashLockOpen",
        "updated_at": "2024-04-19 10:17:52",
        "vtp": "0.0"
    }
}
mdrews21 commented 4 months ago

Ok, i had a misspelling in conf: I wrote preserveJSONinstead of preserveJson and argument 2 of createJsonApiStore is already an object, so no need to wrap it in {} createJsonapiStore(api, conf)

Sorry for my fault and thank you very much for your help and your amazing repository!