Subversion Repositories SmartDukaan

Rev

Show changed files | Directory listing | RSS feed

Filtering Options

Rev Age Author Path Log message Diff
37699 1 h 17 m amit /trunk/profitmandi-fofo/src/main/ Fix: movement availability popover rendered empty except the closing note

The breakdown was built as a table. Bootstrap 3.4.1 sanitizes popover content against a
whitelist that includes neither table nor its rows and cells, and it removes a non-whitelisted
element together with everything inside it - so the whole table was dropped and only the note
survived, leaving a popover that referred to orders that were not shown.

Rebuilt from divs and spans, which are whitelisted. Sanitizing stays on rather than being
switched off for this popover: the content carries PO numbers and warehouse names read out of
the database.

Also stops the zero-quantity note pointing at orders that are not there - a warehouse whose
only stock is still inbound has nothing promised to point at. jsVersion bumped.
 
37698 1 h 27 m amit /trunk/profitmandi-web/src/main/java/com/spice/profitmandi/web/v2/controller/fofo/ V2 getPricing: carry internal movement availability alongside the price

Mirrors the fofo change so the two /getPricing endpoints answer alike. V2 is dormant but
component-scanned, so it has to keep compiling against the service signature.
 
37697 1 h 28 m amit /trunk/profitmandi-fofo/src/ PO create: show what can move, and which orders hold the rest, while the quantity is typed

Picking an item on a movement order already called getPricing, which read the sending
warehouse's stock and returned only a price. It now returns the availability too, so the row
can show it: an info marker beside the quantity box opens the breakdown - in stock, promised
with each holding order named by PO number and date, anything still arriving, and the quantity
this order can take.

The quantity box flags the moment what is typed passes that cap, so it is corrected before
submitting rather than after being refused. The marker turns amber when stock is partly
promised and red when none can move.

Outside vendors are unaffected: their pricing response carries no availability and their rows
are left exactly as they were. jsVersion bumped so the screen picks up the new script.

Tests cover the four cases that matter: what can move with orders named, zero movable reported
rather than refused, this order's cap kept separate from what the warehouse holds when stock
came in at two costs, and a warehouse holding none of the item still refusing.
 
37696 1 h 28 m amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/ Internal movement: report what a warehouse can actually send, not just refuse on submit

The quantity a movement order can take was only discovered by submitting the order and being
refused. The stock reading that decides it already computed everything needed to say so in
advance - what is on the shelf, what older orders have promised, what is still arriving - and
then discarded it.

selectOpenOutboundCommitments returns those promises one row per order, with the PO number,
PO date and destination, instead of a single summed quantity. applyOutboundCommitments now
aggregates those rows and behaves exactly as before, so no extra query is run.

describeAvailability answers with the price plus that working. It shares one stock reading with
priceFor via examine(), so the cap shown while choosing a quantity and the cap enforced on
submit cannot drift apart. Unlike pricing it reports rather than refuses: stock that is entirely
promised comes back as zero movable with the orders holding it named, which is what lets someone
chase an abandoned order rather than only see a smaller number.
 
37695 5 h 54 m amit /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/service/warehouse/ test(warehouse): cost layer tests; update movement tests for cost-based allocation

- InventoryCostLayerTest: local-DB tests for layers vs stock on hand, movement priced at recorded cost, refusal across costs, promised stock held back, pending inbound offered but not dispatchable, and GRN recording vendor and cost
- InternalMovementPricingServiceTest: layers now keyed by cost, so same-cost stock moves together and a different cost needs its own order
- BillingPricingServiceTest: compare against recorded origins rather than the serial-trace source
 
37694 5 h 54 m amit /trunk/profitmandi-dao/src/main/ feat(warehouse): record where stock came from and what it cost; price internal movements at that cost

- inventoryItem.origin_vendor_id / receipt_unit_cost and lineitem.origin_vendor_id (sql/add_inventory_cost_layer_20260917.sql, applied on prod 2026-09-17 in 75s): GRN copies both from the PO line it arrived on, so origin survives any number of hops and non-serialised stock keeps it too. Unknowable origin stays NULL - never a guess, never an internal supplier
- A movement now moves stock at the cost it was received at, not the origin vendor's current catalog TP. Layers are grouped by cost; a quantity spanning two costs is refused with both numbers, since a PO line carries one price
- Stock already promised on open outbound movement orders is no longer offered again (176 item/warehouse pairs on prod are fully promised today)
- Stock on open inbound POs is offered for planning at that order's price and reported as 'on the way in', but cannot be dispatched until received; the PO item picker lists those items too
- Backfill: 4,010 of 4,646 in-stock rows on prod got origin and cost; 636 stay unknown and are priced from the latest approved external catalog price as before
 
37693 5 h 57 m ranu /trunk/profitmandi-cron/src/main/java/com/smartdukaan/cron/migrations/ rbm ranking mailer  
37692 6 h 1 m vikas /trunk/ LMS + Airtel Calling  
37691 6 h 2 m ranu /trunk/profitmandi-cron/src/main/java/com/smartdukaan/cron/migrations/ rbm rankijng mail  
37690 6 h 12 m ranu /trunk/profitmandi-cron/src/main/java/com/smartdukaan/cron/migrations/ notification scheduler  
37689 6 h 13 m ranu /trunk/profitmandi-cron/src/main/java/com/smartdukaan/cron/migrations/ notification scheduler  
37688 6 h 14 m amit /trunk/profitmandi-dao/src/main/resources/sql/ Record that the counter/privatedealuser rename was applied on hadb1 (suffix _dropped_20260917)  
37687 6 h 14 m ranu /trunk/profitmandi-cron/src/main/java/com/smartdukaan/cron/ rbm ranking mailer  
37686 6 h 17 m ranu /trunk/ for rbm ranking mail on month end  
37685 6 h 20 m amit /trunk/profitmandi-fofo/ Remove selenium from the fofo portal entirely

No browser starts in this WAR any more, and the selenium-java and
webdrivermanager dependencies are gone with it. Verified: no source reference to
selenium/WebDriver/ChromeDriver anywhere in the module, and zero selenium
artifacts on the runtime classpath.

Three pieces:

1. The insights schedule and its pull move to profitmandi-cron (r37684) and dao
(r37683). This service keeps only the READ paths -- redis, then in-memory,
then cs.agent_daily_insight -- plus refreshInsights(), which now asks the dao
sync service to run once and re-reads what it wrote. The portal therefore
holds no credentials at all: KNOWLARITY_USERNAME/PASSWORD are deleted from
this source, along with INSIGHTS_PAGE_URL and the 200-character CSS selector
the scrape depended on.

2. KnowlarityScraperService deleted. It was dead, not merely idle: zero
references anywhere, both @Scheduled annotations commented out, and its
@PostConstruct selenium block commented out with the note 'DISABLED - Live
status now comes from WebSocket via profitmandi-cron'. SVN backs that up --
r36057/r36058 (25-Mar) moved agent status to the websocket and r36072/r36075
(26-Mar) created KnowlarityBreakLogService in dao, but nobody removed the
corpse. It kept selenium in this WAR for six months after nothing used it.
The data agrees: 'On Break - <reason>' rows in cs.rbm_break_log stop on
25-27 March and plain 'Break' takes over, which is exactly that handover.

⚠ Consequence worth knowing: break-REASON granularity (lunch/meeting/sick)
was lost at that migration and is not coming back from the websocket feed.

3. setTokens() and POST /indent/set_knowlarity_tokens removed -- the method had
already been reduced to a log line, and the pull now authenticates itself per
run. Also retired the orphan knowlarity.scraper.enabled property (nothing read
it; it was still 'true' in prod), and corrected a stale section header and a
doc comment that promised 'current tokens' which no longer exist.

Not touched, deliberately: POST update_agent_status / bulk_update_agent_status /
update_status_by_name still exist and still write cs.rbm_break_log through
AgentLiveStatusService. They are orphaned -- the deleted scraper was their only
feeder and no view or script in the deployed WAR calls them -- but they are
public HTTP surface, so proving there is no INTERNAL caller is not the same as
proving no external one. Left for a separate decision.
 
37684 6 h 20 m amit /trunk/profitmandi-cron/src/main/ Schedule the knowlarity insights pull here instead of in the fofo tomcat

Eight times a day, unchanged times (11:40, 13:40, 15:40, 17:40, 18:40, 19:15,
20:00, 20:40) so the shape of the day's data does not move. Calls
KnowlarityInsightsSyncService (dao r37683).

This lands next to KnowlarityCallMonitorScheduler on purpose: that one owns the
WebSocket status feed into cs.rbm_break_log, this one owns the periodic KPI pull
into cs.agent_daily_insight. They are the two halves of the same integration and
were previously split across two processes for no reason other than history.

What it replaces: the same schedule inside the fofo tomcat, where every run
started an ~850MB headless chrome on a box that holds a -Xmx8g tomcat and a
-Xmx2g cron jar on 16GB and has been kernel-OOM-killed twice. A run is now four
HTTPS calls, ~2-3 seconds.

⚠ Only fires under --spring.profiles.active=scheduled; a one-shot CLI run does
not start the schedulers.

staging.properties gains the knowlarity block. It had NO knowlarity keys at all,
which means the WebSocket call monitor has never run there either -- this fixes
both. Same credentials as prod; there is no separate SR tenant for staging.

Cadence is worth revisiting separately: the 8 slots were chosen when a run cost
75 seconds and 850MB. At 2 seconds, hourly or every 15 minutes during the
10:00-21:00 window (matching the call monitor) would be nearly free.
 
37683 6 h 20 m amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/knowlarity/ Move the knowlarity insights pull into dao, and delete the dead earlier attempt

The pull belongs in dao because its SCHEDULE moves to profitmandi-cron while the
fofo portal still reads the same rows. Both modules depend on dao, so that is the
only place the two can share it.

KnowlarityInsightsSyncService fetches via KnowlarityApiClient (moved here from
fofo, unchanged) and upserts cs.agent_daily_insight. No DDL: every column it
writes already exists.

It writes what the old chrome scrape could not:
- the *_seconds columns. Verified on prod over 7 consecutive days, every row had
logged_in_seconds, break_seconds, available_seconds and talk_seconds = 0. The
API returns fractional seconds as numbers, so they are stored directly rather
than re-parsed out of a display string.
- calls_answered / missed_calls / total_calls, also 0 on every row, because the
scrape never captured them at all.

auth_id resolution keeps the email-PREFIX match from the fofo version: some
stored emails are truncated ('user@smartdukaan.co..'), so matching the whole
address silently misses those agents.

Redis keys are deliberately the same pair the portal reads, so its fast path
stays warm across the process boundary. ⚠ That makes AgentInsightRow's getter
names a contract with fofo's AgentInsightDTO -- rename one without the other and
the portal deserialises blanks.

Also deleted, all with zero external references:
- KnowlarityAgentInsightsService: an earlier, unfinished run at this same API.
Its ALT_INSIGHTS_APIS list of guessed endpoints is the giveaway that it never
worked; nothing ever called it. It owned three redis keys nobody read
(knowlarity:agent:insights, :summary, :lastUpdate) -- distinct from the live
knowlarity:insights:* pair, which stays.
- AgentInsightsDTO / AgentInsightsSummaryDTO: used only by that service.
- KnowlaritySocketTest: a scratch main(), never referenced.
 
37682 7 h 33 m amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/warehouse/ feat(warehouse): auto-approve backdated POs in the creator's name

A backdated PO used to be parked in POStatus.INIT until an HOD clicked a mailed approval link. INIT
keeps a PO out of the PO list, out of GRN/invoice matching and out of the auto-close sweep, so an
unclicked PO was frozen rather than merely pending - 440 had accumulated since 2024, of 2547 approval
rows only 2023 were ever clicked.

- every PO now goes READY at creation, backdated or not
- the warehouse.poapproval row is still written, stamped approvedOn=now and approvedBy=<creator> by
recordAutoApproval(), since that row is what identifies a PO as backdated and who backdated it
- the HOD mail survives as a notification: names the creator, no approval link, PDF still attached
- /approve-po-date/* endpoints kept so links already sent do not 404

Completes r37679-81. Backfill for the three POs still inside POScheduler's window is staged at
profitmandi-dao/src/main/resources/sql/backdated_po_auto_approval_backfill_20260917.sql, not run.
 
37681 7 h 44 m amit /trunk/profitmandi-web/src/main/java/com/spice/profitmandi/web/v2/controller/fofo/ feat(warehouse): resolve the logged-in user on V2 PO creation and GRN mismatch resolution

V2 mirror of r37680, keeping the dormant V2 controllers in step with the fofo MVC ones.

- createPurchaseOrder resolves the logged-in user via getEmailId + authRepository and sets createdBy
- resolvedMismatchRequest passes the resolver through

Pairs with r37679.
 
37680 7 h 44 m amit /trunk/profitmandi-fofo/src/main/ feat(warehouse): resolve the logged-in user on PO creation and GRN mismatch resolution

Backdated POs are auto-approved in their creator's name, so the user has to travel with the request.

- createPurchaseOrder resolves the logged-in user via cookiesProcessor + authRepository and sets createdBy
- resolvedMismatchRequest passes the resolver through, for the correction PO it can raise
- PO create page no longer says backdated POs need HOD approval

Pairs with r37679.
 

Show All