On screen, “Submit Request” looks like a single action. Behind it sits a more consequential question: when has an item actually entered or left the store room?
In the Rumah Plastik inventory system, staff can request incoming or outgoing stock. An admin reviews the request, and a head gives the final approval. Stock changes only after that final decision. This small-looking choice determines whether the number on screen remains trustworthy when several people are working at once.
A request is not a stock movement
When staff submit a request, the system records an intention to move items. That request may still be rejected or need correction. If stock is reduced immediately, a rejection needs a compensating update. That creates another path that can be missed.
I prefer to separate three events: record the request, account for the quantity being requested, and change physical stock after final approval. Each stage has its own status and person responsible. Someone reading a pending request should not have to guess whether the goods have already left.
Available stock is not always recorded stock
Delaying the stock movement does not mean ignoring pending requests. For outgoing goods, the system needs to account for quantities awaiting approval so that the same units are not promised twice.
Imagine 10 units are recorded in stock. One outgoing request for 7 units is still pending. A new request for 5 units should not automatically pass just because the stock column still reads 10. What remains available for new requests must account for the 7 units already allocated. That is where recorded stock and stock still available to request become two different figures.
That distinction also belongs in the interface. If the two figures are mixed without explanation, users may think the application has miscalculated. Clear labels are often more useful than another chart.
The final decision must survive simultaneous clicks
Form validation protects only one side of the process. Two people can open a page at nearly the same time, both see enough stock, and approve requests that conflict. The final check therefore has to happen again when the data is actually written.
This approval flow uses a database transaction and row locking when a decision changes stock. It also checks the request state so that an already handled decision cannot be processed as new. The aim is not only to avoid an error message. It is to make every stock movement traceable to one decision.
A decision trail matters as much as the final number
Once stock changes, the next question is often not “how much is there?” but “why did it change?”. The request, the admin review, the head's decision, and the incoming and outgoing histories provide the answer. Without that trail, the final figure can look tidy while remaining difficult to verify.
That is why I do not treat an approval screen as an admin accessory. It is part of the data model: who asked, who reviewed, who decided, and when stock actually moved.
A principle beyond inventory
The same reasoning applies to purchasing, equipment loans, expense requests, and facility reservations. Do not make one button stand for several business events at once. Decide when a request becomes a commitment, when it merely holds capacity, and when a change is allowed to enter the record.
Once those moments are distinct, the dashboard, validation rules, and reports become much easier to explain. The interface and implementation context are in the Rumah Plastik inventory case study.