| Rev |
Age |
Author |
Path |
Log message |
Diff |
| 37845 |
3 d 4 h |
amit |
/trunk/profitmandi-dao/src/ |
feat(warehouse): ACTIVE/SUSPENDED/INACTIVE status + label on sellerwarehouse replace WAREHOUSE_MAP - BillingWarehouseService (active for dashboards, active+suspended for warehouse screens, names in every state, 5 min cache); setup service: guarded status change (no suspend while franchise stores or brand mapping route there, no close while stock/unshipped orders), rename, all-warehouse overview with usage; partner store assignable only to an active warehouse; daily stock alert for suspended/inactive warehouses to logistics/accounts top 2 staffed levels + leadership; dashboard warehouse list = active (replaces r37834 stock-holding loop); migration sellerwarehouse_status_display_name_20261005.sql (applied on hadb1) |
|
| 37830 |
6 d 21 h |
amit |
/trunk/profitmandi-dao/src/ |
feat(movement): one PO per source vendor warehouse and cost - layers carry their GOOD/OURS vendor warehouse, orders are raised pinned to it, holds of pinned orders come off their own warehouse, billing takes units at the order's price first |
|
| 37826 |
6 d 23 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/warehouse/ |
feat(warehouse): previewMovementPurchaseOrders - read-only view of the POs an internal movement would be raised as (margin-scheme apart, one per cost) |
|
| 37822 |
7 d 1 h |
amit |
/trunk/profitmandi-dao/src/ |
feat(warehouse): physical warehouse setup service, supplier mapping PO guard, address active flag
- WarehouseSetupService + WarehouseSetupValidator: create seller (state from GSTIN,
unique label/GSTIN), address master (city stored last, 6-digit pin, contact),
physical warehouse (OURS/BAD vendor 40 + Dummy/G + sellerwarehouse + mapping in
one transaction), activate/deactivate (sellerwarehouse.is_active), remap address
with internal store sync. Limits follow column sizes (sql_mode is empty).
- WarehouseAddressMaster.active: only active addresses are offered for assignment.
Migration sql/20261001_warehouseaddressmaster_active.sql (applied on hadb1).
- PO guard: createPurchaseOrder refuses a supplier with no OURS/GOOD vendor
warehouse at the destination (GRN could never receive it).
InventoryWarehouseRepository.hasGoodSupplierWarehouse / selectSupplierIdsWithGoodWarehouse
use existence checks; 67 pairs carry duplicate OURS/GOOD rows.
- SellerService.syncInternalStoreAddress(store); RetailerServiceImpl syncs an
INTERNAL store's address when it moves warehouse or becomes internal.
- Record of 2026-10-01 HR Gurugram setup SQL (seller 21, warehouses 13368/13370/13372).
- Tests: WarehouseSetupValidatorTest (10), WarehouseSetupServiceImplTest (7). |
|
| 37817 |
8 d 6 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/ |
fix(movement): shelf stock before arriving, one PO per cost, close PO on invoice cancel
- Internal movement fills from shelf stock before stock still arriving (a pending PO dated at
midnight ranked ahead of same-day receipts, pricing movements from units that never shipped).
- A quantity spanning stock at different costs is raised as one PO per cost at once instead of
being refused (first PO takes every item's oldest cost, the next the following cost).
- Refuse a movement from a warehouse to itself.
- Cancelling a movement's invoice/DC takes the order's qty off its PO and pre-closes it when
nothing is left open, as refunds already did. |
|
| 37776 |
14 d 2 h |
amit |
/trunk/profitmandi-dao/src/main/ |
returns: reverse a refunded debit-note return whose goods never reached the warehouse
Once a return was refunded nothing could undo it - rejectReturn refuses an already
refunded one - so a return booked and paid for goods that never arrived left phantom
warehouse stock, the unit missing from partner stock, the order marked returned, a
wallet credit and a filed credit note, with no way back.
ReturnReversalService.reverse(imei, reason, by, dryRun) undoes exactly one unit:
the warehouse return scan (row deleted so a genuine return later is not rejected as a
duplicate) and the stock it added, partner stock with its schemes/price drop/offers,
the order's return quantity and status, the wallet refund as a REVERSAL entry, and the
return item / debit note. Guards refuse anything that has moved since the refund, and a
dry run reports the plan without writing.
The credit note follows movement and the NIC clock: inside the 24h window, and only
when the note credits nothing but this unit, its IRN is cancelled and the note marked
cancelled; past it a DBN with its own IRN is issued against the note
(CreditNoteService.issueReturnReversalDebitNote, stored as CN_CANCELLATION with no
margin month so the statement does not show it twice - the wallet REVERSAL is the
statement line); a note never filed at NIC is voided locally. Every local write happens
first and NIC last, so a refusal rolls the whole reversal back.
fofo.return_reversal (return_reversal_20260921.sql) records each reversal and, unique
per return item, makes it once-only. Also adds cancelled=0 to the RETURNS_CN branches of
the account statement queries, without which a cancelled note keeps crediting the
statement - no current effect, no RETURNS note is cancelled today. |
|
| 37769 |
14 d 4 h |
amit |
/trunk/profitmandi-dao/src/ |
fix(movement): receive a movement invoice only against its own PO, stop auto-closing movements, cancel reduces the PO line
- GRN: movement invoice resolves invoice -> orders -> transaction -> its own movement PO (or a receive-only PO
from the billing warehouse); supplier/warehouse keyed at entry must match; scanned IMEIs must be the billed ones
- Cancelling an unbilled movement order takes its qty off the PO line; PO CLOSED/PRECLOSED once nothing is open
- reopenedAt removed (movements no longer auto-close); PO records createdBy
- SupplierStateResolver: a supplier's state is derived from its GSTIN on save
- sql: add_po_created_by (applied), drop_po_reopened_at (run AFTER fofo/cron/web deploy) |
|
| 37762 |
14 d 9 h |
ranu |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/warehouse/ |
aging po approval process |
|
| 37761 |
14 d 10 h |
ranu |
/trunk/ |
aging po approval process |
|
| 37756 |
15 d 3 h |
ranu |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/warehouse/ |
aging po approval process |
|
| 37755 |
15 d 3 h |
ranu |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/warehouse/ |
aging po approval process |
|
| 37751 |
15 d 3 h |
ranu |
/trunk/ |
aging po approval mail to some collected users |
|
| 37750 |
15 d 4 h |
ranu |
/trunk/ |
aging sku purchasing need to approval of niranjan kala sir |
|
| 37722 |
20 d 5 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/ |
Movement PO availability: list stock arriving into the sending warehouse, per PO
The popup showed in stock, promised and can-move, but not stock on its way in once it was
fully promised - so UP to Noida read 'in stock 0, promised 4, can move 0' with the 4 units
arriving on PO 54031 nowhere, and looked wrong. It now reads as a sum:
in stock + arriving - promised = can move.
- selectOpenInboundPurchases: open POs into the warehouse, one row per PO, same filter as the
pending-stock layer so the rows add up to the arriving total
- InternalMovementAvailabilityModel: arrivingTotal (before holds) + arriving breakup;
inbound (after holds) unchanged, still used by the refusal message
- describeAvailability (single + batch) carries both; batch doc: quantities are no longer
checked at bulk upload, the screen flags them and order creation enforces them |
|
| 37713 |
20 d 17 h |
amit |
/trunk/profitmandi-dao/src/main/ |
fix(warehouse): record the order's own vendor when a receipt line carries no origin
- r37694 took the origin only from lineitem.origin_vendor_id, which exists on orders raised from that revision onward, so goods arriving on older open orders landed with a cost but no vendor - 282 rows on the first day
- A purchase from an outside vendor now falls back to that supplier; internal movements are unchanged and an unknowable origin still stays NULL
- sql/backfill_receipt_origin_20260918.sql repairs the 282 already received (run on prod 2026-09-18; bak warehouse._bak_receipt_origin_20260918); in-stock unknown 895 -> 648 |
|
| 37711 |
20 d 18 h |
amit |
/trunk/ |
Bulk-uploaded PO rows show the same availability breakdown as hand-picked ones
A row added by hand showed what the warehouse holds, what older orders have promised and how many
units the order could take; the same row arriving from a bulk upload showed none of it. The file
was the one place the numbers behind a quantity were hidden, which is the case where a mistake is
least visible and hardest to unpick afterwards.
describeAvailability now also answers for a list of items. Both reads it needs already took a
list, so a whole file costs the same two queries a single item does rather than two per row. An
item the warehouse holds nothing of is left out of the result instead of failing the upload - its
quantity is still checked when the order is priced, and the row simply shows no breakdown.
The single-item and batch paths build their answer from one shared method, so the two cannot drift
apart, and the screen reuses the renderer it already had. |
|
| 37704 |
20 d 18 h |
amit |
/trunk/ |
Reopen a movement PO whose stock arrived late, and stop stranding GRN price corrections
Internal movements auto-close after four days, which fits 99.6% of them - 5,491 of 5,515 receipts
land inside the window. The remainder leave the PO closed with the stock still in transit and
nowhere to receive it: 998 internal POs closed during 2026 still holding 21,996 unreceived units.
A closed movement PO can now be reopened from the purchase order list. Reopening stamps
reopenedAt, and auto-close measures from WarehousePurchaseOrder.getOpenSince() - reopenedAt when
set, the PO date otherwise - so a reopened PO gets the same fresh window a new one gets instead of
being closed straight back on the next sweep. Only movements between our own warehouses: an
external vendor PO that has closed is settled with that vendor, not reopened unilaterally.
Separately, a GRN price correction now checks that the PO it just raised is one the invoice can
actually be received against. Matching reads POs that are open and approved for the same supplier
and warehouse dated on or before the invoice; it never looks at the PO being corrected, so what
matters is that the new PO is receivable. 54 were not - backdated into INIT by the old approval
gate, hence outside the match - and each stranded silently: original line discarded, GRN completed
without it, the correction left holding a reservation for stock that had already arrived.
isOpen() names the open set - INIT, READY, PARTIALLY_FULFILLED - that the movement and commitment
queries already read.
Migration sql/add_po_reopened_at_20260918.sql adds reopenedAt, nullable and additive. It must run
before this ships: the entity maps the column. |
|
| 37703 |
20 d 18 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/ |
GRN price mismatch: ask for the original PO to be reopened instead of stranding a correction PO
Resolving a price mismatch raised a correction PO dated to the supplier invoice, and stored its id
on the GRN request item to receive against. But by then the stock has already arrived and the PO it
corrects is closed - every one of the 54 raised this way had its mapped PO in CLOSED. The
correction therefore had nowhere to land: the GRN completed against the original, nothing was ever
received against the correction, and it sat holding a reservation for stock that was not coming.
Backdated by nature, it also parked in INIT under the old approval gate, so it could not have been
received even if anyone tried.
Resolving a mismatch against a closed PO now says so and names it, asking for that purchase order
to be reopened first, rather than silently creating a second PO that cannot be used.
WarehousePurchaseOrder.isOpen() names the open set - INIT, READY, PARTIALLY_FULFILLED - that the
movement and commitment queries already read, so it stops being restated per caller. |
|
| 37702 |
20 d 18 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/ |
Internal movement: an unapproved PO no longer dispatches stock
A PO raised on one of our own warehouses also raises the order that moves the stock, and that
order pays and processes immediately - so raising it ships goods. The approval gate never
governed that half. It set the PO to INIT and mailed an approval link, then created and processed
the order anyway, several lines later and without consulting the status it had just set. The gate
held back receiving - PO list, GRN matching, auto-close all skip INIT - while dispatch went ahead
unconditionally.
That is how PO/07-26/52029 was delivered and invoiced while frozen out of GRN. Its goods had to be
received against a second PO raised for the purpose, leaving the first holding a phantom
unfulfilled quantity for two months.
Order creation now waits on approval. WarehousePurchaseOrder.isApproved() names the rule once -
INIT is the only state before approval, every other state is something the order has already been
approved to do - matching how the PO list, GRN matching and the auto-close sweep already read it,
so callers stop restating it.
Backdated POs are approved at creation since r37682, so this holds nothing up today; it is what
keeps the two halves from separating again if any future rule leaves a PO unapproved. Nothing
raises the order later, so such a PO simply does not move stock and has to be raised again once
approved - the safe failure, and it is logged. |
|
| 37700 |
20 d 21 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/ |
Internal movement: order against expected stock, and stop reserving lines that can no longer ship
Two rules changed, both about stock that was being treated as unavailable when it is not.
Stock still to arrive now counts toward what a movement order can be raised for. A movement is
planned against what the warehouse will hold, so the order is raised now and dispatched once the
stock lands; previously a warehouse holding only inbound stock refused outright, even though the
receipt was already on an open order.
A purchase order line stops reserving stock once its own order moves past being submitted for
processing. Billed or shipped means the units have already come off the shelf; cancelled means
the line can never dispatch them. Holding either back a second time hid stock that was genuinely
free - on prod, 660 of 675 reserved units were on lines whose orders had already moved on. A line
whose order has not been raised at all is still a live promise and keeps its hold, and a line is
held only for the quantity still sitting in an in-process order, so a partly-shipped order
releases the rest.
priceFor and describeAvailability continue to read stock through one shared examine(), so what is
shown while choosing a quantity stays exactly what the order is created against. |
|