Remove items from list field based on value

I have a data field that is a list of items on the user data type. The items are related to another data type called Earnings. The Earnings data type has a field ‘value’, which is a number.

I want to be able to remove from the list field on the user data type the ‘Earnings’ entries based on a dynamic aggregate value.

For example, each entry of ‘Earnings’ field ‘value’ is 30. In the user data type field there are 10 ‘Earnings’ entries, so that would equate to a total value of 300 (30 for each value x 10 entries).

If there is a dynamic value that is 140 for example, I want to be able to remove from the list of ‘Earnings’ the entries whose ‘values’ combine up to the dynamic value of 140, which would result in the list of ‘Earnings’ being reduced by 4 entries (30x4=120) and to also make a change to another field on the ‘Earnings’ data type for the 5th entry whose ‘value’ of 30 would be used for the remaining 20 (difference from the 4 items removed with total value of 120 from the dynamic value of 140), where on that 5th entry another field ‘value remaining’ would be updated to 10 (‘value’ of 30 less the 20 difference = 10 values remaining).

This would need to be done in backend workflows. The dynamic value of 140 in the example will always be unknown in advance of running the functions. The ‘value’ field of 30 in the example might not always be the same for each ‘Earnings’ entry.

I can do this simple enough in a recursive backend workflow, but the goal is to not incur the WU costs of running the recursive backend workflow, so I’m hoping there might be a way to achieve this without a recursive backend workflow.

Any ideas?

This is for a referral credits system. The ‘value’ is the earned credits, which will be used to reduce the costs of a purchase or subscription fee. The ‘Earnings’ data type is tracking the user that earned the credits (ie: ‘value’), status of the ‘Earnings’. Once the ‘Earnings’ status turns to available, it is added to the list field on the User data type.

The goal is to remove from the list field on the User data type the ‘Earnings’ entries whose ‘value’ is applied to a purchase or subscription fee, as well as update an ‘Earnings’ entry whose ‘value’ total was not used so as to track the difference of what was the original value versus what had been used from that specific ‘Earnings’ entry to reduce the purchase or subscription fee. It should be that the purchase price or subscription fee can be reduced to Zero in the event there are enough credits available in the list of ‘Earnings’ on the user data type and any partially used credits can be logged onto the ‘Earnings’ entry whose value of credits was not fully used.

I’m not sure to understand why not just calculate the total earnings in one fields and reduce this earnings value?

I’m wanting to have other data types involved to have historical records for when Bubble issues cause problems.

I am using a field that is a number that is the total credits available, which is the primary field used in conditions on whether or not credits get applied to the purchase, but I need this other data type involved to keep a status to show if the earnings has been applied or credited. A status of applied shows the user who made a service booking with the referral code has had their service completed, and only then will the referrer credits be applied to the referrer. Then once the referrer uses those credits in a purchase we change status to applied, indicating they have already been used.

Just take the WU hit, it’s only a little bit, and if it’s a referral system, then surely the value added by the tracking feature outweighs the WU cost by orders of magnitude?

I don’t think there’s a magical fix for you. I can think of way you could do it with Schedule API workflow on a list that’d run quicker and slightly cheaper but it’s not worth it.

The only other option I can see, and only if all earnings entry have the same value (30 in your example) is to use math to know how many item you need to load (140/30 = 4.67:floor, so 4 items). make change to list and load using Do a search: item until # (calc) (and where item not fully used and full earnings is available. You will need to process the remaining amount in another WF (You should, I guess first check if there’s already an item that is < 30, to reduce this one, and if there’s a remaining amount, reduce another one).

Not sure how much you will save on WU…

Matthew, I’m a bit confused on statuses (is “applied” status when the refer-ee completed the service or when the referer redeems those credits?)

But I would think that unless you want to use @Jici calculations (which are spot on but wouldn’t save much WU and would be difficult to debug) I would personally just expand the Earnings data type to be more of an earnings transaction data type.

Then, any time a user gets credits or redeems them, there’s another Earnings thing created; and when it’s using the credits, it’s a debit → so a negative number. So for your example, I’d just add a Earnings thing for the user with a -140 value. This easily allows you to log / track all earnings transactions (the user, date and time and purchase can be in the Earnings debit record).

My personal preference would be to also store on the user (or sub user table) the number of available unredeemed credits, which would be a simple sum of all Earnings things for the user.

In your case, there would be 11 Earnings records for the user (10 with 30 each and then 1 with -140 for the redemption) so the unredeemed credits would be easily calculated as 160.

hey @boston85719 :wave:

I have decided to attack this as a brain teaser. You can do it with some custom coding. I did this on the frontend, I am not sure how it would reflect to backend. Because I had to use js2bubble element to get the values back to Bubble. See the demo below:
brave_i0DoJeMzy5

Of course, this is no way no-code :slight_smile:

By the way, I just marked the elements to delete or update instead of actually doing it to show the demo.

If you still want to explore and play with it, here it is: Bubble Demos by Flusk | Bubble Editor

bdk_512x512 @Huseyin from Flusk | Discover the #1 Security and Monitoring Tool for Bubble

This is awesome and pretty much inline with what I was hoping was possible, but as I’m a no-coder, it was beyond me on how to structured the scripts. Thankyou for this.

BTW

Do you think it is possible to do this with the toolbox plugins server script action?

I’ve tried to re-create what you provider using the server script action but I’m getting an error in the way I set it up.

Workflow error - Plugin action Server script error: ReferenceError: bubble_fn_findelements is not defined at eval (eval at <anonymous> (eval at build_function (/var/task/util/util_harness.js:37:12)), <anonymous>:24:1) at eval (eval at build_function (/var/task/util/util_harness.js:37:12), <anonymous>:41:14) at eval (eval at build_function (/var/task/util/util_harness.js:37:12), <anonymous>:66:8) at /var/task/plugin_api_v4_alpha.js:198:35 at harness (/var/task/harness.js:115:21) at /var/task/harness.js:154:70 at withGlobalHandlers (/var/task/harness.js:66:41) at Runtime.myHandler [as handler] (/var/task/harness.js:154:16) at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)




Screen Shot 2024-06-05 at 1.41.30 PM

From what I can tell it is due to the reference in the script used on front end which has the Bubble_fn element, but in the server script that obviously is not available.

Screen Shot 2024-06-05 at 1.44.52 PM

I’m doing this for the backend workflows currently used for tracking application of credits towards subscription charges. Using Stripe for payment processing, when the subscription invoice is created, it remains in a draft status for 1 hour, which gives an hours time to update the invoice items to reduce the cost of the subscription.

So, I’m using a webhook to be notified of the invoice creation, then what is nice about the application of credits to a subscription, is that should the credits applied exceed the current invoices value (ie: credits is 200 and invoice is $150) Stripe, if we send the update invoice item amount value as -200, will handle the credits and automatically put them toward the subsequent months invoice. This results in the current invoice due set to 0 and the next invoice due set to $100 as there was a credit of 50 applied to the next invoice.

So, in that scenario, I’m able to simply apply all currently available credits and run the backend workflow on a list on all the ‘earnings’ data entries to change their status and as last action in that flow remove them from the list field on the user data type.

If unable to apply the javascript approach on the backend, I think I just might have to run a recursive backend for the credits as they are applied to a one off product purchase.

This is the issue that I have. The system is setup so the app owner can change an option set value for the credits earned, which means some may have a value of 30 but at a certain point if app owner changes this, others will be more or less. Also, with the application of partial credits based on the value, that number would change even if the original was 30, so I can not do the mathematical approach to it.

Status of applied is when the referrer redeems those credits.

This is an approach potentially worth exploring. Currently the user data type has the field which is a list of ‘earnings’ as well as a field ‘credits available’. The credits available is just a number, similar to your preference

So, the use of the list field on the user of ‘earnings’ is probably unnecessary, and likely is adding complication to the system. So, if just simply relying on the ‘credits available’ field as a number, as I currently am doing on the checkout flow to have conditions using that value to apply the appropriate number of credits to the purchase, I can after receiving webhook for completed payment, run a backend workflow on a list, the list of which is populated with a search of ‘earnings’ whose status is ‘available’ so that the status can be changed to ‘applied’. Following that there would also be a action to change the ‘value’ of the ‘earnings’ which may have had a partial usage of available ‘value’ (ie: credits).

I mean fundamentally, it’d be a trivial task with a loop. We don’t have native loops in Bubble, other than recursive workflows. Therefore, if you want to keep it entirely in Bubble, use recursive workflows.

You could create a simple JS or serverless function that takes a list of unapplied credits + unique IDs, and returns a list of the same unique IDs and their adjusted credit remaining (then Make changes to list of things), but is it worth the extra time?

1 Like

As you rightly noted, it is referring to a frontend element to pass values from JS to Bubble back. I will check if something like this exists in the backend script in toolbox. If it is, it should be easy.

bdk_512x512 @Huseyin from Flusk | Discover the #1 Security and Monitoring Tool for Bubble

1 Like

@boston85719 , Matthew, the amount of words you write per day is simply astounding!

To clarify my approach, instead of using the receiving webhook to trigger a back-end WF on a list (to mark those earnings as applied) and then updating credits available on the user,

I would just:

  1. create a new Earnings record with all relevant redemption information, with the value being the amount of credits redeemed * -1 (so it’s a debit of the other credits) and then
  2. Update the credits available on the user to be the current number minus (-) the credits redeemed.

That way, if anything goes wonky, you can always recalculate the credits available by a sum of the value fields of all earnings for the user.

With my approach, the list is unnecessary. However, if you continue to edit the existing earnings (to mark them as applied) you may want to have a list of earnings for the user to save WUs for searches. It prob shouldn’t be on the user itself but a sub dataset for the user.

Had to take a typing course in Freshman year of High School in 1998. So, I type around 80+ words per minute.

This part is necessary for when we reduce the cost of the subscription payment. Users that have redeemable credits and are on subscriptions, will, when the webhook is received, have their current months subscription payment reduced via API call by the number of credits they have available. For the subscriptions it is easier, since we just apply all available credits in the User data type, as Stripe will handle the credits on the customer object that exceed the current months subscription fee by crediting subsequent month subscription fee.

I am using a checkout session webhook for the confirmation of payment for a one-off purchase as well, since the system is designed to allow users to make a booking which at the end of booking process shows the checkout summary where they enter their promotion codes (separate discount), referrer codes (when being referred by another user) as well as referrer credits (when earned a referral credit). The referrer credits are automatically applied up to the specific one-off booking cost (Stripe has minimum $0.50 charge - so need to have separate backend workflow to modify referrer credits applied when the booking required payment, which can be done from webhook notification chain, or the booking required no payment as referrer credits available exceed the cost of the booking).

For that part, on one-off bookings, I am running a recursive backend workflow that has multiple parameters.

Screen Shot 2024-06-06 at 1.32.20 PM

credits-used-in-purchase is a number
credits-remaining-in-backend-flow is a number
first-items-available-credit is a number

This recursive flow first makes changes to the referrer earnings

Screen Shot 2024-06-06 at 1.33.35 PM

Then makes changes to the User list field of referrer-earnings to remove the item from the list if its’ credit available is used completely

Screen Shot 2024-06-06 at 1.34.10 PM

Then makes changes to the referrer-earnings credit available if the credits were not used completely

Screen Shot 2024-06-06 at 1.35.15 PM

Then schedules itself to run again, tracking the parameter numbers against what had been used in the current ‘loop’ if the current referrer-earnings credits available were used completely

And lastly updates the user field of credits available when on the last item of the parameter for referrer-earnings

Screen Shot 2024-06-06 at 1.48.16 PM

This all starts by getting scheduled with dynamic parameters as below

I believe this setup has a lot of the same approaches involved that others and you have suggested. I believe it requires this extra complications I’ve added due to the complex nature of the platform itself, with bookings on a subscription basis, one off bookings with payment and one off bookings without payment. Having the user data type with a list field for referrer-earnings makes it a bit easier to call up the available credits without performing a search of all referring-earnings with filters when performing the checkout related processes. Then on the dashboard where showing all referrer-earnings I am using a search with filters/sorting.

1 Like