PWaddict Posted September 5 Share Posted September 5 Hello! Let's say an admin is editing a product page that contains a quantity field with the value "10". During that time a user is completing an order with the product that currently the admin is editing and the quantity field value is changed programatically to "9". All good so far. Here is the problem: If the admin finished editing the page and press Save, the quantity field value will be changed back to "10" even though he didn't touched that value as that was the value when he opened the page to edit. How can I prevent this? How do you solve this issue? Link to comment Share on other sites More sharing options...
bernhard Posted September 5 Share Posted September 5 The only bullet proof solution is called "event sourcing". The first 4 minutes will explain the concept very well and will answer your question from a theoretic point of view 🙂 But it's not really easy to implement 😅 Link to comment Share on other sites More sharing options...
BrendonKoz Posted September 5 Share Posted September 5 The ProDevTools module of User Activity is another possible option. I haven't used it, so I'm not 100% sure if it prevents this from happening, or just alerts users when the possibility of a collision exists. https://processwire.com/store/pro-dev-tools/user-activity/ 2 Link to comment Share on other sites More sharing options...
bernhard Posted September 5 Share Posted September 5 One idea to solve this in a quite easy way: Add a hidden field to your template called "quantity_before_edit" Add a saveReady hook that calculates the difference between "quantity_before_edit" and "quantity" Use that delta to calculate the new "quantity" Example: Quantity is 10 User A visits the public website (quantity = 10) User B visits the backend (quantity = 10, quantity_before_edit = 10) User A orders 2 pieces and the page gets saved (quantity = 8 ) User B saves the page without editing the quantity (quantity = 10, quantity_before_edit = 10) saveReady hook kicks in: quantity = 10, quantity_before_edit = 10 ---> diff = 0 get current quantity from uncached page from the database, quantity = 8 add diff and write result to $page->quantity = 8 ideally show a warning to the user that a quantity has been saved that is different from his/her input page is saved, final result is quantity = 8 2 Link to comment Share on other sites More sharing options...
Robin S Posted September 6 Share Posted September 6 5 hours ago, BrendonKoz said: The ProDevTools module of User Activity is another possible option. To expand on this, these two User Activity options (marked "experimental") would be useful for this case: 2 Link to comment Share on other sites More sharing options...
szabesz Posted September 6 Share Posted September 6 10 hours ago, BrendonKoz said: The ProDevTools module of User Activity is another possible option. I decided not to use that approach for this issue. It would be quite odd to inform the customer "randomly" with a message like, "Hey, the owner of the store is currently editing your cart!" My client and I believe that customers should not be notified in the same way that other backend users are. Such a level of transparency is not what my client wants. Therefore, I opted for the "simplest" solution: locking the cart. However, even locking the cart is not entirely straightforward. In my code, I address not only quantity and price-related issues but also other validation concerns, like this: When a customer loads the cart on the frontend, the system detects all invalid items (it contains outdated prices or product configurations, for example), logs them, and presents the list to the customer before automatically removing them. Based on this log, the backend administrator will receive a daily digest, while customers can optionally request the system to send the list to their registered email address. When a customer loads a cart that is locked by backend users, they are notified that their cart is temporarily locked by the shop owner. They are also presented with a button to click, which will send an automated request email to customer service. The customer will not have to write anything, as the email will contain all the information needed for customer service to unlock the cart. When a backend user accesses a cart edit page, they are presented with any invalid item errors. In this case, we do not want to automatically remove invalid cart items, as the backend user may be working on them, and we cannot determine their intentions. Because of this, no automatic action can be taken, except for one: the cart will be automatically locked if any invalid items are detected. It is then up to the backend user to resolve all issues to make each order item valid again. The backend user must click the 'Save + Unlock Cart' button to make it available for the client again. For editing the cart when there are initially no invalid items, backend users should start their editing session by using the 'Save + Lock Cart' button before proceeding with their edits. As long as no backend user is editing carts, there should be no instances of the cart being locked. Any unfinished tasks by backend users related to editing items should never occur, but they will probably happen a lot of the time. Backend users will receive red error messages that provide clear explanations about invalid items. As long as they do not unlock the cart, the last red error message instructing them to unlock it will remain visible. However, no one is perfect, so backend users will receive an email digest of any carts that may have been left locked accidentally. Our backend users rarely edit cart items, so I believe this relatively simple solution will suffice. 1 Link to comment Share on other sites More sharing options...
PWaddict Posted September 10 Author Share Posted September 10 Thank you guys for the suggestions. Since I don't have the ProDevTools module yet I will try @bernhard's idea soon. Link to comment Share on other sites More sharing options...
da² Posted September 10 Share Posted September 10 Another idea close to the @bernhard one: lock the quantity field so it's not editable add a field "quantity to add" in saveReady hook, load page without cache to get real quantity and update it with "quantity to add" field. 2 Link to comment Share on other sites More sharing options...
poljpocket Posted September 19 Share Posted September 19 (edited) Thanks @bernhard for that video. This puts a name on the concept I have used a bunch of times and I think is the only real way to solve OPs problem. Most ERP systems and also some well-known e-commerce systems out there (I know of Shopfiy and Shopware which do that) don't let you manage an item's quantity with a simple text field or a simple "number". Instead, the quantity is "event sourced" (as in the video) with a log of changes. This even includes the initial value. The video also says it, but as an example, one could come up with the current item's stock quantity of 8 by looking at this "event log": +10 from incoming shipment -2 from order -1 from order +3 from incoming shipment -1 from order -1 from order In ProcessWire, you could create a repeater to achieve this. Just record all your "incoming" lines with a repeater in your product (remember to add a datetime field) and add hooks to orders which automatically add lines when orders are placed/refunded/cancelled. The only remaining thing is to modify the repeater editor to only allow the user to edit new items. But a combination of limiting edit access to the entire repeater and a "update quantity" field like @bernhard and @da² suggested will get you there. Edited September 19 by poljpocket 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now