Inhalte aufrufen

Profilbild

WebApi: Best practise Product attributes

textfelder

  • Bitte melden Sie sich an, um eine Antwort zu verfassen.
21 Antworten zu diesem Thema

#1 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 16 January 2020 - 15:44

I'm confused what to best way is to work with ProductAttributes via the WebAPI, the goal is to add/update/delete them

 

For example i have several different product that all needs a ProductAttribute like Color. However the available colors is different per product. Also to ProductAttribute has to be multi language.

 

If i follow this guide: https://docs.smartst...ging Attributes then it would create a  ProductAttribute for each product and also double if an product is updated and therefore the POST ManageAttributes is called again.



#2 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3565 Beiträge

Geschrieben: 16 January 2020 - 16:02

Maybe a custom plugin is more suitable for this task. All functions of the service layer are available via a plugin. In contrast, implementing complex tasks using HTTP API endpoints can be difficult or even impossible. It is likely that you will miss something.

Schöne Grüße aus Düsseldorf,
Marcus Gesing


#3 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 16 January 2020 - 16:52

A custom plugin is at this stage a nogo, we have a middleware application running on a server that keeps all stuff in sync including our newly SmartStore. So the WebApi should be the way to go... Could you give an example based on the WebApi?



#4 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 21 January 2020 - 08:55

Was hoping that you could provide me of a best pratice example to add and manage Product Attributes. Let's say for example i have type color:

 

Name: Color

Subvalues: 

  • Red
  • Green
  • Blue

Attributes has to be assigned to a product ANDALSO be available in two languages.



#5 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 22 January 2020 - 16:05

Is there a full object view of https://docs.smartst...ging Attributes this?



#6 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3565 Beiträge

Geschrieben: 22 January 2020 - 16:53

Only by OData metadata document. See parameter type ManageAttributeType.
 

Schöne Grüße aus Düsseldorf,
Marcus Gesing


#7 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 23 January 2020 - 09:11

Looking at the metadata document it would be great if the paramater LanguageID andalso "description" could be added. In this way i imagine that you can call the API and assign the language of the Attribute. This would make it so much easier!

 

For example:

 

English:

{
   "Synchronize":true,
   "LanguageID":1,
   "Attributes":[
      {
         "Name":"Color",

         "Description": "Select a color:",
         "IsRequired":false,
         "Values":[
            {
               "Name":"Red"
            },
            {
               "Name":"Green",
               "IsPreSelected":true
            },
            {
               "Name":"Blue"
            }
         ]
      }
   ]
}

 

Dutch:

{
   "Synchronize":true,
   "LanguageID":2,
   "Attributes":[
      {
         "Name":"Kleur",

         "Description": "Selecteer kleur: ",
         "IsRequired":false,
         "Values":[
            {
               "Name":"Rood"
            },
            {
               "Name":"Groen",
               "IsPreSelected":true
            },
            {
               "Name":"Blauw"
            }
         ]
      }
   ]
}



#8 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3565 Beiträge

Geschrieben: 23 January 2020 - 14:12

I have added an issue for this.


Schöne Grüße aus Düsseldorf,
Marcus Gesing


#9 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 23 January 2020 - 14:57

Great that you added this the the todo list! Could you give a estimation when this will be available? 



#10 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3565 Beiträge

Geschrieben: 23 January 2020 - 21:32

No, I cannot give a date at the moment when this will be available.


Schöne Grüße aus Düsseldorf,
Marcus Gesing


#11 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 07 February 2020 - 10:48

I'm trying to work with the ManageAttributes but and i'm able to create a Attribute but what is the ControltypeID for? Is just used to set the "Control Type" property? If so is there an enum/ list of the values for this? 

 

EDIT: Never mind found it in SmartStore.Core.Domain.Catalog.AttributeControlType

 

However you said to look at the ManageAttributeType in the OData metadata document. If i used these objects then i get an error back saying: "Cannot convert a primitive value to the expected type 'Edm.Decimal'"

 

The JSON i send is:

{
  "Synchronize": true,
  "Attributes": [
    {
      "Name": "Color",
      "ControlTypeId": 40,
      "IsRequired": true,
      "Values": [
        {
          "Name": "Red",
          "Alias": "Red",
          "Color": "#ff0000",
          "PriceAdjustment": 0.0,
          "WeightAdjustment": 0.0,
          "IsPreSelected": false
        }
      ]
    }
  ]
}

That's exactly how it is show in the OData metadata document:

<Schema xmlns="http://schemas.microsoft.com/ado/2009/11/edm" Namespace="SmartStore.WebApi.Services">
    <ComplexType Name="ManageAttributeType">
        <Property Name="Name" Type="Edm.String"/>
        <Property Name="ControlTypeId" Type="Edm.Int32" Nullable="false"/>
        <Property Name="IsRequired" Type="Edm.Boolean" Nullable="false"/>
        <Property Name="Values" Type="Collection(SmartStore.WebApi.Services.ManageAttributeValue)" Nullable="false"/>
    </ComplexType>
    <ComplexType Name="ManageAttributeValue">
        <Property Name="Name" Type="Edm.String"/>
        <Property Name="Alias" Type="Edm.String"/>
        <Property Name="Color" Type="Edm.String"/>
        <Property Name="PriceAdjustment" Type="Edm.Decimal" Nullable="false"/>
        <Property Name="WeightAdjustment" Type="Edm.Decimal" Nullable="false"/>
        <Property Name="IsPreSelected" Type="Edm.Boolean" Nullable="false"/>
    </ComplexType>
</Schema>


#12 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3565 Beiträge

Geschrieben: 07 February 2020 - 11:15

Yes.


Schöne Grüße aus Düsseldorf,
Marcus Gesing


#13 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 07 February 2020 - 11:29

Thanks for the link! I already founded and edited my answer. Could you look into that?

 

EDIT:

 

Did some debugging and it goes wrong on the "PriceAdjustment" and "WeightAdjustment" values. If i change them from Edm.Decimal to Edm.String than everything works fine.


Bearbeitet von TripleNico, 07 February 2020 - 11:53,


#14 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3565 Beiträge

Geschrieben: 07 February 2020 - 17:05

See this post.


Schöne Grüße aus Düsseldorf,
Marcus Gesing


#15 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 11 February 2020 - 10:58

Thanks for the reference to an older post of us however if i read the OData document and the XML serialize scheme than a "" around a decimal ins't required. So in order for me to get this to work i have to change it to a string instead of a decimal value.



#16 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 08 April 2020 - 10:24

So i dicided to go for the "advanced" way by adding properties via the /ProductAttributes /ProductAttributeOptionsSets /ProductAttributeOptions. I manage to add them without any error, but the properties doesn't show up at the product.
 
What i do:

  • Retrieve list of /ProductAttributes /ProductAttributeOptionsSets /ProductAttributeOptions
  • If not exists --> create ProductAttribute for propertytype, for example Color (values set: .Name = "Color", .AllowFiltering = True)
  • If not exists --> add ProductAttributeOptionsSet to ProductAttribute, for example Color (values set: .Name = $"product_{_Product.Id}({item.Sku}) - {_ProductAttribute.Name}", .ProductAttributeId = _ProductAttribute.Id)
  • If not exists --> add ProductAttributeOption to ProductAttributeOptionsSet for example:
  • .Alias = OurDatabaseItemID
                .Name = "Blue"
                .LinkedProductId = ProductID
                .ProductAttributeOptionsSetId = ProductAttributeOptionsSetId
                .ValueTypeId = 40
                .Color = "FF0000"

This results in the output as seen in the first attached image. But as you can see in the second attach image, the properties arn't linked to the product.
 
For debug, i attached a wireshark session.
 
Any idea what i'm forgetting?
 
Edit: In addition when i update a ProductAttributeOption with let's say other color and priceadjustment value this isn't also updated in the /Admin/ProductAttribute page. Even if i clear the cache and database cache. But when i edit the ProductAttributeOption the values are there. For example see the last two attachments.

Angehängte Bilder



#17 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3565 Beiträge

Geschrieben: 08 April 2020 - 11:31

But as you can see in the second attach image, the properties arn't linked to the product.
 
Options Sets cannot be linked to products or referenced by products. Instead they work similar like value templates. The merchant can copy the values of an option set to a product attribute on the product edit page. Referring to service method ProductAttributeService.CopyAttributeOptions.

Schöne Grüße aus Düsseldorf,
Marcus Gesing


#18 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 08 April 2020 - 12:14

Aha, that why it isn't working i gues... How would one use this function via de WebApi?

 

Or whould a workarround be to add the values directly to the Product.ProductVariantAttribute collection? (Tried this but stil nothing there, maybe because the objects added don't get an Id?)



#19 TripleNico

TripleNico

    Advanced Member

  • Members
  • 120 Beiträge

Geschrieben: 09 April 2020 - 12:59

I'd let go of the way to work with advanced properties and worked my way back to the "simple" /ManageAttributes endpoint. All is working, like adding localization objects en checking which value is needed except for the priceadjustment property.
 
As stated in the OData metadata XML at ComplexType Name="ManageAttributeValue" property "PriceAdjusment" is of type Edm.Decimal. But when I send a JSON decimal, compliant to the OData documentation I get an error back saying: Cannot convert a primitive value to the expected type 'Edm.Decimal'
 
This seems like incorrect documentation or behavior? If I look at the class then it's also declared as a decimal.
 
Then I created a workaround by changing type Edm.Decimal to Edm.String and parsing the decimal value to string, like for 10 euro with 21% VAT = 13,31 so the string output is "13,3100". This works as expected and also displays correctly on the product page. But when I read back the property value via OData under Product -->> ProductAttributes -->> ProductVariantAttributeValue then .PriceAdjustment = "133100,0000" what I would expect is "13,3100" If I look into the SQL Database at ProductVariantAttributeValue then I see the value I expect: 13,3100

For the record decimals at places like Product.Price or Product.OldPrice don't have this issue

#20 Marcus Gesing

Marcus Gesing

    SmartStore AG

  • Administrators
  • 3565 Beiträge

Geschrieben: 09 April 2020 - 14:20

Send the decimal as a culture invariant formatted string (in quotation marks):

Angehängte Bilder

  • Angehängte Datei  api.png   61.05K   0 Anzahl Downloads

Schöne Grüße aus Düsseldorf,
Marcus Gesing