Re: Updating order and customer metafields from line item metafields

Updating order and customer metafields from line item metafields

jake_mitchell
Shopify Partner
120 2 55

Hello, 

We have lots of product metafields for things like department, category, type, brand etc. 

We would like to be able to pass these metafield values from the products (lineItems) to the order when an order comes in using Shopify flow. 

The product metafields are set up with defined lists of acceptable values. This is roughly how it should work. 

 

jake_mitchell_0-1673181559261.png

 

 

The update order metafield  uses this code: 

{% for lineItems_item in order.lineItems %}
{% for metafields_item in lineItems_item.product.metafields %}
{% if metafields_item.namespace == "product" and metafields_item.key == "department" %}
{{ metafields_item.value }} {% endif %} {% endfor %} {% endfor %}

It will pass the metafield value over only if there is one line item and the source metafield contains only one value. 

 

What we want to be able to do is ensure that no matter how many line items are in the order, and no matter how many each MF values those line items have we can pass over the values to the order. 

Does anyone have any ideas how this might be accomplished? 

 

What I'm thinking at the moment is that I might need to do the following for each MF we want to pass over

- Assign variable 

- Update variable with all mf values from the line item MF namespace and key

- then pass the variable into the order metafield

 

I don't necessarily need someone to write this for me (although, if you do I'd be incredibly grateful) but I'm so stuck I just need some thoughts from other people. 

 

Thanks all. 

Replies 5 (5)

jake_mitchell
Shopify Partner
120 2 55

I've now got this working for any metafields that accept lists the code is:

 

[{% for lineItems_item in order.lineItems %}
    {% capture VARNAME %}
        {% for metafields_item in lineItems_item.product.metafields %}
            {% if metafields_item.namespace == "NAMESPACE" and metafields_item.key == "KEY" %}
                {{ metafields_item.value | remove: "[" | remove: "]" }}
            {% endif %}       
        {% endfor %}
    {% endcapture%}
    {{VARNAME}}
    {% unless forloop.last %} ,{%endunless%}
{% endfor %}]

 

It doesn't work on metafields that accept only one value, but that can be a challenge for another day. 

 

The code above seems a bit much for what I'm doing. I think what I'm doing is deconstructing and then rebuilding an array format for the data (assuming [ ] is an array in liquid). 

 

It does get where I need it to go but it seems like a long way round/not particularly elegant. 

 

If anyone sees this and can improve on the code above I would love to know.

jake_mitchell
Shopify Partner
120 2 55

Hi, 

 

Thanks for that. The flow you're suggesting uses advanced workflows which we don't have yet. 

 

The other issue is that when passing metafields to customers you need to be aware of the fact that customers can already have Mf values on their record. Therefore the thing you eventually pass back needs to be a combined list of what was already on the customer record and the values from all line items that is de-deuped to create a list of unique values (you don't want Menswear Menswear Menswear for someone who buys menswear a lot for example). 

 

I've got that working now. It's a bit of a workaround to push it all into an array to then de-dupe it and pass it back as an acceptable string. It works though. 

It was quite a challenge to work around liquid's limitations, but fun all the same. 

{% for customer_mf in order.customer.metafields %}
    {% if customer_mf.namespace == "CustomerNAMESPACE" and customer_mf.key == "CustomerKEY" %}
        {% assign customer_info = customer_mf | map: "value"  %}
    {% endif %}
{% endfor %}

{% for lineItems_item in order.lineItems %}
    {% for metafields_item in lineItems_item.product.metafields %}
        {% if metafields_item.namespace == "ProductNAMESPACE" and metafields_item.key == "ProductKEY" %}
            {% assign inner = metafields_item | map: "value"  %}
            {% assign customer_info = customer_info | concat: inner %}
        {% endif %}
    {% endfor %}        
{% endfor %}

{% assign final_list = customer_info | join: "," | remove: "[" | remove: "]" %}
{% assign final_list = final_list | split: "," | uniq %}
{% assign final_list = final_list | join: "," %}
[{{final_list}}]

 

dpnz2
Visitor
2 0 0

Hi Jake, just to piggy back off your knowledge with a similar metafield flow request. 

I'm wanting to update an orders notes field with a single custom metafield from a product, using flow.

I've got as far printing all product meta fields into the order notes, but I only want this custom product metafield : custom.incoming_stock_message 

 

Ideally it would be print the line item name beside it, so that in the scenario there is two products on the order with their own custom.incoming_stock_message, you can identify which belongs to which product. 

What I've got so far is just printing all metafields from the product:

 

{% for lineItems_item in order.lineItems %}
{% for metafields_item in lineItems_item.product.metafields %}
Pre-order msg was: {{metafields_item.value}}
{% endfor %}
{% endfor %}

 



dpnz2
Visitor
2 0 0

After a bit of trial and error, plus some code from another thread, I've made it work for my custom metafield. Hopefully this helps someone:

Note that in the code below, you need to update NAMESPACE and KEY with your own metafield namespace and key. In the case of a custom metafield such as "custom.backorder_date" the NAMESPACE = "custom" and KEY = "backorder_date"

I also included the product title in this loop to appear before the metafield as well, so remove if not required. 

 

{% for lineItems_item in order.lineItems %}
{% for metafields_item in lineItems_item.product.metafields %}
{% if metafields_item.namespace == "NAMESPACE" and metafields_item.key == "KEY" %} {{ lineItems_item.product.title }} {{metafields_item.value}} {% endif %}{% endfor %}{% endfor %}

 

 

EricaDixon
Shopify Partner
3 0 0

Hi, similar to the above, we are looking to copy a customer metadatafield value to a customer order under the 'additional details' section. Can you confirm how we would go about setting this up in Flow?

 

Customer metafield = custom.khaos_urn 

And we want this to map to the 'additional details' section on the order

 

Thanks,
Erica