Shopware 6 custom endpoint for admin api doesn't return only the requested fields - shopware6

I have a custom endpoint for the admin api which returns some products.
{% block response %}
{% set criteria = {
"includes": {
"product": ["id", "name"],
"cover": ['id']
},
"associations": {
"cover": {},
},
}%}
{% set products = services.repository.search('product', criteria) %}
{% set response = services.response.json({ 'products': products }) %}
{% do hook.setResponse(response) %}
{% endblock %}
When i call this endpoint i want to receive only the products ids and names as described in the criteria. But i get the full object.
I posted an example response below:
{
"apiAlias": "api_feed_data_response",
"products": {
"entity": "product",
"total": 50,
"aggregations": [],
"page": 1,
"limit": 100,
"elements": [
{
"parentId": null,
"childCount": 0,
"taxId": "a4440e5086e14cf793627c9d670694aa",
"manufacturerId": "cc1c20c365d34cfb88bfab3c3e81d350",
"unitId": null,
"active": true,
"displayGroup": "75eef7154e9f22229e54e37b3ca0e54b",
"manufacturerNumber": null,
"ean": null,
"sales": 0,
...
}
How can i get only the requested fields (id, name) ?

Starting with 6.5 of shopware it will be possible with:
{% block response %}
{% set criteria = {
"fields": {
"product": ["id", "name"],
"cover": ['id']
},
"associations": {
"cover": {},
},
}%}
...
{% endblock %}
So you should use fields instead of includes.
The difference between those two is that includes are only filtered out at the CRUD-API level,but before the response is encoded in the API layer the entities contain all fields. As you have a custom API-endpoint the filtering does not work in this case.
The fields are filtered out directly at the DB level, so that only the defined fields are fetched from the database, that means that your response in your custom API endpoint will also only include those fields.

Related

Shopware 6: how to delete all products via admin api

How to delete all products via admin api?
To achieve the goal i try to use the Bulk Payloads | Deleting entities
The doc says:
[...] To delete entities, the payload of an operation contains the IDs. [...]
Questions:
to delete all products i have to read first all product.id's?
or is there a alternative way with a type of "wildcard"?
My current request body (using Postman) ...:
{
"delete-product": {
"entity": "product",
"action": "delete",
"payload": []
}
}
... response with (products remains in db):
{
"extensions": [],
"success": true,
"data": {
"delete-product": {
"extensions": [],
"result": []
}
},
"deleted": [],
"notFound": []
}
EDIT #1
With id's provided...:
...
const obj = {
"delete-products": {
"entity": "product",
"action": "delete",
"payload": [
{"id": "73af65014974440b95450f471b3afed8"},
{"id": "784f25a29e034fad9a416923f964ba8a"}
]
}
}
apiClient.request({
"url": "/_action/sync",
"method": "POST",
obj
})
...
... the request fails in class Symfony\\Component\\Serializer\\Encoder\\JsonDecode with message:
detail: "Syntax error"
Debugging the request, payload is missing (empty content):
What is wrong with the configuration of the /api/_action/sync call?
Indeed, what it means is that you will need a low impacting query to get all product id's, store it into a variable & delete them. Use includes:["id"] filter to just get the ID's.
Here is an example of me deleting some products in Postman.
Request body:
{
"delete-product": {
"entity": "product",
"action": "delete",
"payload": {{gen_dynamic_products}}
}
}
Pre-request script (you'll need to adjust this sightly to get your ID's):
const map = new Array(30).fill(0).map((val, index) => {
return { id: pm.environment.get('gen_product_list_sub_' + index) };
});
pm.variables.set('gen_dynamic_products', JSON.stringify(map));
to delete all products i have to read first all product.id's?
Yes, that is what you'll have to do. This is necessary to maintain the extendibility of the platform. The core or other plugins may react to the deletion of products by subscribing to an entity lifecycle event. This event includes the id of the deleted entity. Hence why it is necessary to explicitly provide the ids of the entities in the first place.

Shopify add cart properties. How do this properties work? It disappears after page refresh

I am setting properties when adding to cart.
Ex:
var formdata=[
"items":{
id:123456,
quantity:1
properties:{'flag':true}
}
];
added using api : /cart/add.js
Details I get from cart.js without refresh
response from : /cart/add.js and cart.js
[
{
"id": 32423423423423,
"properties": {
"flag": true
},
"quantity": 1,
"variant_id": 42705234345345,
}
]
The above items get added successfully to cart. After adding I again fetch the cart details and It has this properties value.But when I refresh the page cart items properties does not have any value.
Ex Currently I am getting this only when page is refreshed:
response from cart.js after page refresh
properties:{
Ref: 0
}
What this properties is?
Why is this happening? If worked, will this properties be available on order create webhook? It only disappears when refreshed. Moreover main reason to add this properties is to receive this properties in order-create webhook to distinguish from normal order. If anyone having other alternative please suggest.
Adding a product to the cart like so:
fetch('/cart/add.js', {
method: "post",
headers: {
"content-type": "application/json"
},
body: JSON.stringify({
items: [
{
quantity: 1,
id: 33116507373620,
properties: {
'flag': true
}
}
]
})
})
And getting the cart.js like so:
fetch('/cart/add.js').then(res => res.json()).then(res => console.log(res))
Will get you result like so:
{
...
"items": [
{
"id": 33116507373620,
"properties": {
"flag": true
},
"quantity": 1,
...
}
],
...
}
From there on what you are doing to not get this result I'm not sure, since this is working/tested and there is no issue.
Please double check if you are targeting the correct object once you get the cart.js response. (there is no properties direct object, it's under items[0].properties in this case)

Update input field total from variable number of input fields in Vue2

I have variable number of input fields for product quantity input generating from API response that takes number as input. I need to update the total price for each items and subtotal for all the items once user changes the input field value.
Here is what i am trying
data:
"productList": [
{
"id": 27,
"product_id": "2362",
"product_name": "nengra",
"unit": "box",
"minimum_order": "1",
"unit_price": "890",
"photo_url": "http://45.114.85.21:11011/micro_product/mv8gigsx2e_7a4i2twgv6.jpg"
},
{
"id": 29,
"product_id": "2365",
"product_name": "nengra",
"unit": "box",
"minimum_order": "1",
"unit_price": "890",
"photo_url": "http://45.114.85.21:11011/micro_product/qdmiugpabf_4ojvtkryym.jpg"
}
]
template:
<div v-for="{{products in productList}}" :key="products.product_id">
<input type="number" v-model="products.qty" v-on:change="updateCart" >
<p>{{products.productsTotal}}</p>
</div>
<p>{{subTotal}}</p>
Script:
data(){
return{
qty:[],
cartID: null,
productList: [],
total: 0,
subtotal: 0,
productTotal: 0
}
},
methods: {
updateCart: function (){
this.products.productTotal = this.products.qty * this.productList.price
}
}
I am very newbee in Vue2 Please help me to sort it out. Thanks
You can use a computed property like this for subTotal:
computed: {
subTotal: function () {
return this.productList.reduce(
(p, np) => p.productTotal + np.productTotal
);
},
},
Pass a reference like v-on:change="updateCart(product)" to clicked product to update it's values:
methods: {
updateCart: function (product) {
product.productTotal = Number(product.qty) * Number(product.unit_price);
},
},
Every time we update the product.productTotal here, subTotal will automatically update since it is a computed property.
Side note: I've added productTotal property to each product. If your data doesn't contain it, you can add it manually in API success callback before setting the data.

Mongodb select document using Phalcon php ODM

I am developing an application using phalcon php and Mongo DB. I want to select post_type = 'page' from the following document
{
"_id" : ObjectId("53f896db461584542200002b"),
"post_con" : {
"post_date" : "12-05-14",
"post_title" : "Test",
"post_content" : "test content",
"post_category" : "test cat",
"post_type" : "page",
"post_status" : "published",
"post_modified" : "12-05-14"
},
"comment_status" : "open",
"link_code" : "test-page",
"seo" : {
"meta_desc" : "test desc",
"meta_key" : "test key"
}
}
For those who are searching for the same, here is the full code.
$post = Posts::find(array(
'conditions'=>array('post_con.post_type'=>'blog') ));
$this->view->postlist = $post;
And in view,
{% for posts in postlist %}
{{ posts.post_con['post_title'] }}
{{ posts.post_con['post_content'] }}
{% endfor %}
Hoe this will help for someone.

Getting Collection Names Of Products in Shopify

In Shopify how do I fetch names of custom collection that a particular product belongs to ?
Like for example to get SKU I can use {{ line_item.sku }} or to get Price I can use {{ line_item.line_price }}
From the API docs, to list all custom collections for a certain product_id:
GET /admin/custom_collections.json?product_id=632910392
Response:
HTTP/1.1 200 OK
{
"custom_collections": [
{
"body_html": "<p>The best selling ipod ever</p>",
"handle": "ipods",
"id": 841564295,
"published_at": "2008-02-01T19:00:00-05:00",
"sort_order": "manual",
"template_suffix": null,
"title": "IPods",
"updated_at": "2008-02-01T19:00:00-05:00",
"image": {
"created_at": "2012-12-11T12:01:29-05:00",
"src": "http://cdn.shopify.com/s/files/1/0006/9093/3842/collections/ipod_nano_8gb.jpg?0"
}
}
]
}