event is triggered several times (sales_order_save_commit_after) - magento

Could you please tell me why sales_order_save_commit_after is triggered twice when order is completed?
I moved all logic to sales_order_save_before, but I use sales_order_save_commit_after to make sure that it's called only once. I want to make sure that there are no superflous writing to database. I tried to use debugger to understand how it works, but I haven't understood so far, it seems rather complicated.
I see 2 callbacks but I can't understand why is there 2 callbacks for model order.
Does magento write to database several times that triggers sales_order_save_commit_after multiple times?

If an order contains configurable products, the collection returned by $order->getAllItems(); will contain parent and child products resulting in double element count for this product type. It is safer to use $order->getAllVisibleItems()

Related

Flow Triggering Itself(Possibly), Each run hits past IDs that were edited

I am pretty new to power automate. I created a flow that triggers when an item is created or modified. It initializes some variables and then does some switch cases to assign values to each of them. The variables then go into an array and another variable is incremented to get the total of the array. I then have a conditional to assign a value to a column in the list. I tested the flow specifically going into the modern view of the list and clicking the save button. This worked a bunch of times and I sent it for user testing. One of the users edited multiple items by double clicking into the item which saves after each column change(which I assume triggers a run of the flow)
The flow seemingly works but seemed to get bogged down at a point based on run history. I let it sit overnight and then tested again and now it shows runs from multiple IDs at a time even though I only edited one specific one.
I had another developer take a look at my flow and he could not spot anything wrong with it and it never had a hard error in testing only warnings about conditionals causing a loop but all my conditionals rectify. Pictures included. I am just not sure of any caveats I might be missing.
I am currently letting the flow sit to see if it finishes getting caught up. I read about the concurrent run option as well as conditions on the trigger itself. I am curious as to why it seems to run on two records(or more) all at once without me or anyone editing each one.
You might be able to ignore the updates from the service account/account which is used in the connection of the actions by using the following trigger condition expression:
#not(equals(triggerOutputs()?['body/Editor/Claims'], 'i:0#.f|membership|johndoe#contoso.onmicrosoft.com'))

GA3 Event Push Neccesary fields in Request

I am trying to push a event towards GA3, mimicking an event done by a browser towards GA. From this Event I want to fill Custom Dimensions(visibile in the user explorer and relate them to a GA ID which has visited the website earlier). Could this be done without influencing website data too much? I want to enrich someone's data from an external source.
So far I cant seem to find the minimum fields which has to be in the event call for this to work. Ive got these so far:
v=1&
_v=j96d&
a=1620641575&
t=event&
_s=1&
sd=24-bit&
sr=2560x1440&
vp=510x1287&
je=0&_u=QACAAEAB~&
jid=&
gjid=&
_u=QACAAEAB~&
cid=GAID&
tid=UA-x&
_gid=GAID&
gtm=gtm&
z=355736517&
uip=1.2.3.4&
ea=x&
el=x&
ec=x&
ni=1&
cd1=GAID&
cd2=Companyx&
dl=https%3A%2F%2Fexample.nl%2F&
ul=nl-nl&
de=UTF-8&
dt=example&
cd3=CEO
So far the Custom dimension fields dont get overwritten with new values. Who knows which is missing or can share a list of neccesary fields and example values?
Ok, a few things:
CD value will be overwritten only if in GA this CD's scope is set to the user-level. Make sure it is.
You need to know the client id of the user. You can confirm that you're having the right CID by using the user explorer in GA interface unless you track it in a CD. It allows filtering by client id.
You want to make this hit non-interactional, otherwise you're inflating the session number since G will generate sessions for normal hits. non-interactional hit would have ni=1 among the params.
Wait. Scope calculations don't happen immediately in real-time. They happen later on. Give it two days and then check the results and re-conduct your experiment.
Use a throwaway/test/lower GA property to experiment. You don't want to affect the production data while not knowing exactly what you do.
There. A good use case for such an activity would be something like updating a life time value of existing users and wanting to enrich the data with it without waiting for all of them to come in. That's useful for targeting, attribution and more.
Thank you.
This is the case. all CD's are user Scoped.
This is the case, we are collecting them.
ni=1 is within the parameters of each event call.
There are so many parameters, which parameters are neccesary?
we are using a test property for this.
We also got he Bot filtering checked out:
Bot filtering
It's hard to test when the User Explorer has a delay of 2 days and we are still not sure which parameters to use and which not. Who could help on the parameter part? My only goal is to update de CD's on the person. Who knows which parameters need to be part of the event call?

How to handle data composition and retrieval with dependencies in Flux?

I'm trying to figure out what is the best way to handle a quite commons situation in medium complex apps using Flux architecture, how to retrieve data from the server when the models that compose the data have dependencies between them. For example:
An shop web app, has the following models:
Carts (the user can have multiple carts)
Vendors
Products
For each of the models there is an Store associated (CartsStore, VendorsStore, ProductsStore).
Assuming there are too many products and vendors to keep them always loaded, my problem comes when I want to show the list of carts.
I have a hierarchy of React.js components:
CartList.jsx
Cart.jsx
CartItem.jsx
The CartList component is the one who retrieves all the data from the Stores and creates the list of Cart components passing the specific dependencies for each of them. (Carts, Vendors, Products)
Now, if I knew beforehand which products and vendors I needed I would just launch all three requests to the server and use waitFor in the Stores to synch the data if needed. The problem is that until I get the carts and I don't know which vendors or products I need to request to the server.
My current solution is to handle this in the CartList component, in getState I get the Carts, Vendors and Products from each of the Stores, and on _onChange I do the whole flow:
This works for now, but there a few things I don't like:
1) The flow seems a bit brittle to me, specially because the component is listening to 3 stores but there is only entry point to trigger "something has changed in the data event", so I'm not able to distinguish what exactly has changed and react properly.
2) When the component is triggering some of the nested dependencies, it cannot create any action, because is in the _onChange method, which is considering as still handling the previous action. Flux doesn't like that and triggers an "Cannot dispatch in the middle of a dispatch.", which means that I cannot trigger any action until the whole process is finished.
3) Because of the only entry point is quite tricky to react to errors.
So, an alternative solution I'm thinking about is to have the "model composition" logic in the call to the API, having a wrapper model (CartList) that contains all 3 models needed, and storing that on a Store, which would only be notified when the whole object is assembled. The problem with that is to react to changes in one of the sub models coming from outside.
Has anyone figured out a nice way to handle data composition situations?
Not sure if it's possible in your application, or the right way, but I had a similar scenario and we ended up doing a pseudo implementation of Relay/GraphQL that basically gives you the whole tree on each request. If there's lots of data, it can be hard, but we just figured out the dependencies etc on the server side, and then returned it in a nice hierarchical format so the React components had everything they needed up to the level where the call came from.
Like I said, depending on details this might not be feasible, but we found it a lot easier to sort out these dependencies server-side with stuff like SQL/Java available rather than, like you mentioned, making lots of async calls and messing with the stores.

Magento - Splitting an order into 2

I am trying to make a functionnality so that a customer will be able to split his order into 2, in case some articles are temporarily unavailable and if they wish that we send them part of their order first. So the idea is to create 2 new orders and cancelling the old one.
Do you have any idee about how to do this programmatically please ?
What you're describing doesn't sound necessary... You're talking about sending part of the order first... Notice in the Magento Admin once an order is place you can create an invoice, take note that you do not have to invoice everything at one time, the same is true when you create a shipment. You'll need to make sure you're merchant / payment gateway supports multiple partial captures against a single authorization.
However, if you really want to split the orders in two, it is a rather complicated process. We've done it, and its very tricky... you need to modify the opcheckout.js file, you'll need to modify the template since you will have to create seperate shipping methods for each order. You'll need to modify the OnePage controller & Model files very significantly. There are tricky areas in terms of re-executing the totals and making sure data on the order and subsequent quote and address models is precisely what is required by Magento. Maintaining the other checkout functionality requires diligence, such as saving the customer's address when checking out. If you're really going down the path of coding something that splits an order into two orders during the checkout process, feel free to send me a message and we can talk more in-depth and I'll send you some code.

How to efficiently allow a user to sort a list with AJAX

In my application, users have a list of items that they can put in any order they like. The database schema looks like this:
Items
+ Id : int
+ Name : string
+ Order : int
so when the user puts things in order, it sets the Order field accordingly, so that I can sort it later. Great.
Now, I want to make the sort ajax-y, such that the user can drag and drop items into order (and use up/down arrows), and it will just automagically save everything. (If you're familiar with Netflix, they do a similar thing.)
The issue I'm having is that in order to persist the user's changes as they make them, I will need to do an AJAX call every time they do something. If the user moves an item from position 10 to position 1, that implies that I have to update 10 records in that little ajax call. Meanwhile, the user may have queued up 3 more AJAX calls to update other records.
This seems inefficient and like it might be error prone (due to race conditions and so on, if the AJAX calls take a long time.) Should I be worrying about this? Is there a more efficient way to do this? If it makes a difference, I expect most users will have fewer than 5 items to sort.
Since Javascript can't synchronize code, I agree that it would be difficult to implement code that would be sure to avoid race conditions, although I did find this article on implementing a Mutex in Javascript.
However, personally I think that rather than choose an option that is likely to result in race conditions, I would go with one of the following options:
Create a save button above the items, that when clicked will save the order to the database.
Create a timer that will save the order every five seconds (or whatever), if something has changed. You would still want a save button for this, so the users could force a save.
I would lean towards the latter. Obviously in both cases you would want some visual cue to the users that they have unsaved changes (like changing the background color of the items, for instance). You would most likely want to implement something that makes sure the user wants to leave the page with unsaved changes if you go with either of those options (like in Gmail, when you have unsaved changes in an email that you are composing).

Resources