An operator records 12 incoming pieces and 5 outgoing pieces. Can the outgoing pieces come from this new delivery, or only from stock already on hand? If the connection drops after sending the entry, should the operator send it again? The answers affect the stock count, not just the screen.

Gudang Snack’s existing online screen lets an operator choose a stock item, see its balance, enter quantities, and preview the result. This article proposes the server rules and recovery process needed behind that screen. It does not describe an implemented offline queue that stores entries locally and sends them later.

Start with what happened to the stock

Before designing the save process, I would ask what physically happened: did goods arrive, get used, move elsewhere, or get counted for a correction? Can incoming and outgoing pieces belong to the same event? Who defines the units, and who approves a correction when the physical count differs from the recorded count? These are questions to investigate, not findings from completed operator interviews.

A movement journal is the history of stock changes: what happened, how much moved, and who recorded it. The stock balance is the amount available now. Changing only the balance would lose the explanation for how it reached that number.

Hands move a boxed stock item beside bins, a blank paper movement record, and a tablet for digital entry. Open full-size illustration

Concept illustration of understanding the workflow, not an operator interview or the actual application.

Read the three parts of the illustration

  • Left — hands and stock bins: the hands move a boxed item from a bin, representing a physical stock movement.
  • Center — blank grid sheet: this represents a paper movement record, not a completed stock ledger.
  • Right — tablet: this represents a separate way to enter the movement digitally. It is not an application screenshot.

Takeaway: confirm how the physical movement, paper record, and digital entry relate. They are not automatically the same thing.

Check who may change each item

In this proposal, an operator records movements only for assigned stock items, called assets in the system. A supervisor handles corrections after a physical stock count separately. Neither role may act as another person or bypass the quantity rules.

The server identifies the person from their signed-in session and checks access to the item. It does not trust a person’s name supplied in the form. Hiding a button is not an access check. The screen’s preview helps catch mistakes, but the server makes the final decision using the current stock record.

Illustrative workflow: an operator prepares a movement, the client previews it, and the server authorizes and atomically records the journal and stock balance. Open full-size diagram

The existing online form informs this workflow. The server design for saving the related records together is proposed.

Follow the form into the proposed server

  • Left — operator and form: choose the stock item and unit, then preview the quantities from top to bottom.
  • Dashed center line — where responsibility changes: the red arrows carry the submission to the proposed server on the right. They show sequence, not failure.
  • Right — access check, then pink save box: a previously saved submission returns its receipt. A new one saves the movement history, balance, and receipt together. Pink groups the protected save; it does not mean an error.

Takeaway: a useful preview does not grant permission or save a stock change.

Check outgoing stock before adding incoming stock

The online form already compares outgoing quantity with stock on hand before adding incoming stock. The proposed server keeps that rule and allows both quantities in one movement. Saving safely and recovering after a lost response remain proposed server behavior, not implemented backend features. If the business needs separate incoming and outgoing events instead, that decision must be settled before implementation.

With 20 pieces available, incoming 12 and outgoing 5 leaves 27 pieces: 20 + 12 − 5 = 27. First, the outgoing 5 must fit within the existing 20.

With the same 20 pieces on hand, incoming 30 with outgoing 21 must therefore be rejected. The final calculation would produce a positive balance of 29, but only 20 pieces were available before this entry. Incoming stock in the same submission cannot cover the outgoing quantity.

QuestionProposed rule
Which unit may be entered?Whole pieces, matching the stock item’s unit held by the server.
May a quantity be negative or left empty?No. Both quantities must be supplied, and at least one must be greater than zero.
May an operator enter one and a half pieces?No. Piece counts must be whole numbers.
What if a quantity is extremely large?Reject quantities or calculated balances outside the range the system can store as exact whole numbers. Do not round them.

Items measured by weight would need a separate agreed unit and precision, such as whole grams. Quietly rounding a fraction would hide a stock difference instead of resolving it.

Notice when someone else changes the balance

Suppose the screen shows 20 pieces with version 7. A version is a number that changes whenever the stock record changes. The proposed submission includes the version the operator saw, so the server can recognize an entry based on an outdated count.

After accepting incoming 12 and outgoing 5, the server saves 27 pieces at version 8. A different movement still using version 7 is a version conflict: someone changed the record after that operator viewed it. The operator must refresh the balance and review the movement rather than have it accepted silently.

The server must protect the stock record while comparing versions and saving the change, so another update cannot slip between those steps. A correction after a physical stock count must use the same protection and advance the same version. Otherwise the balance could change without warning other operators. This rule may require extra review, but avoids accepting a movement against a count the operator never saw.

Save the history, balance, and receipt together

Give each intended submission a unique reference: an identifier used to recognize that same submission if it is sent again. Keep references within the signed-in person’s scope. This person is the actor in the movement record; another person’s matching reference is not the same submission and grants no access to it.

A receipt is the saved confirmation of what the server accepted. A database transaction saves related changes as one unit: either they all save, or none do. The proposed transaction checks the person’s submission reference and protects the stock record. For a new submission, it checks the version and quantities, then records the movement history, updates the balance, and stores the receipt. These three records must save together, never partly.

If the same person sends the same reference with identical movement details, return the saved receipt before checking the current stock version. The first successful submission already changed the version. Checking today’s version first would wrongly reject a repeat that was only trying to recover its receipt.

If the same reference arrives with changed movement details, return a definite reference conflict. It is not an unknown outcome, and it does not permit changing an earlier entry. Find and review the original submission instead of retrying the edited details. If two identical submissions arrive at once, one waits for the other’s save to finish rather than recording the movement twice.

Checking a saved receipt still requires sign-in and access to the stock item. Agree who may review and resolve records, and how long references and receipts must be kept, before implementing this design.

Treat a missing answer differently from a refusal

Illustrative submission states: draft becomes submitting, then confirmed, rejected, outcome unknown, or reference conflict; unknown submissions keep the same details and reference, while changed details under a reused reference require review. Open full-size diagram

Proposed submission states, not an implemented offline queue.

Follow the recovery paths

  • Left to center — Draft → Submitting: send the reviewed movement. Upper right — Confirmed; middle right — Rejected: these are definite answers about saving or refusing the movement.
  • Two pink lower states: the left box, Outcome unknown, means no reliable answer arrived. Its left-hand return arrow keeps the original reference and unchanged details. The right box, Reference conflict, means a reused reference carried changed details. That is a definite conflict, not uncertainty; review the original submission rather than replaying the edits.
  • Outer bottom loop — Rejected back to Draft: review a definite refusal before giving a corrected submission a new reference. Red arrows show transitions, not errors. Pink highlights both the unknown-outcome path and the separate reference-conflict path; it does not mean uncertainty alone.

Takeaway: recover an uncertain submission without changing it. Do not treat a reference conflict as a lost answer.

A timeout or server error does not prove that the movement failed. The database may have saved it while the response was lost. The operator therefore needs an outcome unknown state, meaning there is not yet a reliable answer. That is different from a definite rejection.

Answer or problemOperator action
Invalid quantity or unitReview and correct the draft after the definite rejection.
Permission deniedResolve access instead of sending the entry repeatedly.
Stock is insufficient or its version changedRefresh the balance and review the movement.
The same reference carries changed detailsTreat this as a definite reference conflict. Find and review the original submission; do not keep sending edited details under that reference.
No reliable answer arrivedLook up the receipt or resend the unchanged submission with its original reference.

While the outcome is unknown, preserve the exact submitted details and reference. Sending a new submission with a new reference could count the same physical movement twice. After a definite rejection, a reviewed correction receives a new reference. A reference conflict instead calls for resolving what happened to the original submission before deciding on another entry.

An interrupted client receipt beside a preserved archive, illustrating an uncertain response while the original movement record remains available for recovery. Open full-size illustration

Concept illustration of a lost response, not an implemented recovery screen.

Read the lost-response illustration

  • Left — tablet and yellow ring: the tablet carries the submitted request; the ring marks a pending answer, not a confirmed failure.
  • Center — envelope and crossed dashed line: the answer is interrupted. Right — archive box: the red arrow files the receipt into the archive. It does not show the steps for sending a submission again.
  • Curved red arrow: follow it from the envelope toward the archive to see where the receipt is stored, not as proof that recovery is implemented or guaranteed.

Takeaway: a missing answer does not necessarily mean a missing stock movement.

Before accepting this proposed design, the checks would need to show one movement-history entry for the example ending at 27 pieces, no extra entry when the identical submission is sent again, rejection of competing outdated versions, and recovery after an interrupted response. These are proposed checks, not completed tests or deployment results. The goal is an online stock-entry process with clear recovery rules, not a claim that offline operation is already available.

Further reading: Exact integer limits and conflict response semantics.