Remove a thing from a state (list) but can't reference the thing since it's in an RG

Hi Bubblers,

I can’t seem to figure out how to remove a thing from a state since the thing is in a repeating RG.

For context, I’m currently building the shopping basket page for one of our apps.

Like any other shopping basket feature, users could select products in the basket to check out. (Basically adding the products in a list of products state)

Now, there are some cases where the selected products just went out of stock. What I want to do with these products is to automatically remove them from the list of products state. However, we all know that we can’t reference things and data inside a repeating group.

There are some plugins like Orchestra that would allow us to bypass this restriction and gain access to the data inside an RG. However, these plugins are mainly for events that are action-based. I want to automatically fire my workflows using a do when condition is true event.

Sure, we could fire these plugin events non-stop (using do every x seconds) to check if the products’ stocks are still enough but since this is a repeating group, I’m afraid that would be too inefficient and costly WU-wise.

I can’t think of any other way at the moment. I’d greatly appreciate it if you guys have any ideas or workarounds.

Cheers,

I don’t know your exact setup but if you can’t refence your custom state because its in the cell, how are you going to reference them to convert to an order later?

Hey Tyler, appreciate the response.

No, the custom states aren’t inside the repeating group. It’s on a container outside the RG that is specifically for storing states.

For the process of adding products to the state, I simply have a button inside each cell and if it is clicked, add the parent group’s product to the state.

Okay I see, so it sounds like you can put a “When condition is true” (Everytime) event checking for if any of them in that custom state go out of stock, then if so remove it from the custom state (very hypothetical, not sure the exact expression you would use or what determines out of stock)

Then inside the RG cell you just need a conditional on the “Add to cart” button checking if its not in stock, if its not then grey it out and make it not clickable (again not sure the expression here without knowing data structure)

If you get the whole thing working, reverse the logic so the buttons aren’t clickable by default but become clickable if in stock. Also put the same condition on the workflow itself.

I’m afraid that won’t work, Tyler.

It seems like we are unable to add operators such as is, <, >, , and the like to the numerical values of the things if they are in a list. These are the only available operators:

We can’t use each item is empty since 0 is still a value. I also forgot to add that I will not only be removing the orders in the list if the products are out of stock but also if the order’s quantity is greater than the product’s remaining stocks.

Out of stocks is basically the same with the latter but it just uses is 0or < 1 instead of order's quantity > product's stocks. I can get away by using the latter expression. But then again, numerical operators are unavailable for things that are in a list. Moreover, if I were to use the latter expression, it would be too complex already since I can’t reference to the order’s quantity anymore because the expression would be too deep / nested.

Adding more each item's operators to a list would simply further nest the expression.

Yep, I already made the buttons for adding to cart hidden if the product is out of stock.

What I’m worrying about is if when they add a product that is still available to their list, and suddenly, because of other user orders, that product is then either out of stock or does not have enough stocks to cater to their order’s quantity, the order would still be in the state.

I use this said state to further process their order. Now, If I can’t catch these errors of products not having enough stocks beforehand, the transactions would still be processed — resulting in negative stocks for the products and incomplete order quantities for our users.

When do you want an item to be considered subtracted from stock?

I think typically stores just have it check again at the time of checkout, and they tell them certain things were out of stock between the time it was added and the time checkout happened. Then subtract from the custom state list.

Or do you want it so if a user adds the last item to their cart, should that (at least temporarily) subtract from stock, indicating all users that its now out of stock in realtime?

Personally I like doing a shopping cart live in the database, no messing with custom states or updating values when other database changes happen.

Yes, this is what we’re doing.

As much as possible, we want to deduct the stocks only when they check out their order/s.

Just had an idea.

If we’re really out of options to make this work, I think the only way we could go about this is to use a recursive workflow upon check out.

We’re already using a recursive workflow when users check out but it just simply updates the orders’ status.

What we can probably do is to add a checker in the recursive workflow to check if the product’s stocks is greater than the order’s quantity and if yes, proceed to change the order’s status.

And if not, simply do not update it.

But in this flow, we would then need to return the orders that were not processed. We can’t return values from an API workflow natively, right? Unless, we make our own API in the API connector.

I personally think this would be way too overcomplicated already for something that should be easy to do.

What do you think, @tylerboodman ?

Correct you need to make an API call to your own app to return values, but hold on on the recursive workflow cause I hate those unless we really have to…

1 Like

What is this custom state exactly? It isn’t a list of Products right? Cause then you can’t contain the qty. Is it a list of some Cart Items in your database?

Yes, it’s not just a list of products.

What we basically do is when a user either adds to cart or buys now, we create a thing called order and in an order, there are fields containing the order data such as:

  • product
  • quantity
  • total
  • status

and etc.

Also, I forgot to mention: Our product DB schema can have variations so another sub field of product — making the structure and checks really complex :laughing:

Almost every process for the order, we would need to check if an order has variations or not

Yea a tricky one for sure…you want it to just kick them back to cart if not everything was in stock once they checked out?

This might be dumb but you could do Order Items:each item's Qty:sum ≤ Order Items:each item's Product:each item's Stock

Then if that’s the case continue the workflow, if its < then don’t proceed and tell them there’s an issue.

If you said there’s product variations now then… maybe it can be restructured to a search instead.

:thinking:

Nevermind don’t do that, stupid idea since one item could have extra in stock, another short on stock, but the numbers would match. Let me think about this one.

We could do this two ways:

  1. Automatically remove the order from the list of orders state and show an alert if order's product or variation's stock < order's quantity
    Edit: We don’t even need an alert. We could just remove it from the list. We’re already showing something like this anyway:

  2. Upon clicking check out, process the orders that have enough stocks, do not process the orders that don’t have enough stocks and return the unprocessed orders — showing an error in the UI that x orders were not processed

I may be have misunderstood your question, by “kick them back to cart” are you referring to the orders or the user navigation e.g. redirect them back to the shopping cart page?

Yeah this would be inaccurate for the product’s stocks.

Yea unless you/I think of something just do a recursive workflow to check each one may be the way to do it for now…

Yeah, sadly.

I just thought of a couple more possible workarounds. Will let you know as soon as I finished brainstorming :brain: :laughing:

When they hit checkout you could set all the order’s statuses to “Processing” then have a database trigger from that status change. Then have that check stock levels, subtract levels, then change status to Order Placed. Or have it change to Error status (or just the default status again) and put it back in their cart

1 Like

Yep, that could work too.

I was able to come up with a couple of workarounds but most of them were inefficient.

This was the best one I could come up since it also fits our DB schema:

Basically, I’ll have to stop using states entirely to store selected orders and replace it with an entirely new field in the shopping cart named selected orders

Every time a user selects an order, it will be added to the list field and vice versa for unselecting orders. The button to add the order is only viewable if order's quantity < order's product's stocks. Otherwise, it’ll be hidden and will show an error.

Using a list field instead of states enables me to automatically remove an order in the list by using a DB trigger to check if order's quantity < order's product's stocks. Moreover, we could remove an order if a product has been unlisted.

This is by far, the most flexible and easiest to implement for our use case.

Now, let’s talk performance:

This flow is a bit, if not, much slower than states. Moreover, it might be unwise to do lists if the number of objects exceed 100 — I’m hoping our users won’t behave this way :laughing:

It might be slower but it’s a tradeoff to making this work.

What do you think? @tylerboodman

Update:

I was able to make it work without implementing any major changes in the DB structure or making any overcomplicated recursive workflows.

Made it work using advanced filters.

I used to think advanced filters are unsafe and slow but it turns out that isn’t the case if you already loaded your data, it’s relatively fast. It’s similarly fast to daisy chain filtering (probably because they work the same where they simply filter loaded data)

Advanced filters on searches, however, is a different story :laughing: