| Rev |
Age |
Author |
Path |
Log message |
Diff |
| 37343 |
53 d 22 h |
vikas |
/trunk/profitmandi-fofo/src/main/ |
Update PJP, Visit quality flags |
|
| 37337 |
54 d 0 h |
amit |
/trunk/profitmandi-fofo/ |
Move offer-circular ingest out of cron and into the portal
The parse now runs in profitmandi-fofo, on a background thread, triggered by the
upload that produced the document.
Why: splitting one feature across two artifacts with independent deploy cadences
cost a full day. fofo shipped, cron did not, and a valid upload sat in DRAFT with
nothing on the server able to parse it - the deployed cron jar contained none of the
ingest classes. One 9-page PDF a month never justified a batch tier, and the portal
already ships two PDF stacks, so the isolation argument for keeping PDFBox out was
weaker than it looked.
- 13 parser classes move verbatim from com.smartdukaan.cron.offercircular to
com.spice.profitmandi.web.offercircular. No logic changed.
- CircularIngestScheduler becomes CircularIngestRunner: the @Scheduled(every 5 min)
entry point and the offer.circular.ingest.enabled flag are gone, replaced by a
single-threaded daemon executor. All claim, ingest and notification logic is
unchanged.
- Upload hands the document id to the runner AFTER COMMIT, not inline. The DRAFT row
is written inside the request transaction; a worker starting immediately would race
that commit, find nothing to claim and silently do nothing - which is precisely the
stuck-on-DRAFT symptom this change removes.
- The guarded claim is KEPT even though there is now one trigger. It still stops a
double-submit, a second portal node, and a re-ingest racing an in-flight parse.
- Re-ingest parses immediately instead of queueing for a scheduler.
- The stall reaper runs when the review screen loads. There is no timer here any
more, and a document stranded by a redeploy mid-parse only matters when somebody
looks for it - which matters more now the parse lives in the web application.
- tabula moves to this module with its exclusions intact, as does the
dumpCircularClasspath helper the local ingest harness depends on.
- Screen no longer claims "the ingest job runs every 5 minutes", which was untrue the
moment cron stopped being the route; poll interval 15s -> 3s to match a parse that
takes seconds. jsVersion 404 -> 405.
- offer.circular.review.url added here, since the runner sends that email now.
Verified: full ingest of the Aug'26 circular through the relocated code is identical
to the reference - 239 offers, 663 products, 279 AUTO_EXACT, 361 benefits, 511
tenures, 911 bank links. ProductNamesTest 11/11 in its new home. |
|
| 37332 |
54 d 2 h |
amit |
/trunk/profitmandi-fofo/src/main/ |
Move the offer-circular upload directory off a developer home path
Every upload in production failed with a 400 on mkdirs. offer.circular.dir was
never set in any environment, so it fell back to the code default
/users/amit/uploads/offer-circulars; Tomcat runs as the tomcat user, which cannot
create /users at the filesystem root, and the controller threw "Circular storage
directory is not writable".
- default is now /var/lib/smartdukaan/offer-circulars, a real server path
- offer.circular.dir set explicitly in prod.properties, and pointed at the
developer's own space in dev.properties, since /var/lib needs sudo on a
workstation
- staging.properties deliberately untouched; the new default covers it
The location has two hard constraints, now recorded on the field itself:
- OUTSIDE webapps/. A redeploy wipes anything under it, and
offer_document.stored_path is how both re-ingest and re-download resolve the
PDF, so a wipe breaks them permanently. Stray PDFs are already sitting in
WEB-INF/classes/META-INF on the server from exactly this mistake.
- OUTSIDE any web root. A circular carries the OEM's confidential cashback
economics and must never be servable as a static file. Hence /var/lib rather
than /var/www, whose local precedent /var/www/partner_stats is chmod 777.
Only fofo needs the key: the cron ingest resolves the PDF from
offer_document.stored_path and reads it as root, so 0750 tomcat:tomcat is enough.
Deploying this alone does not fix production - the directory must also exist and
be writable by tomcat. |
|
| 37331 |
54 d 13 h |
amit |
/trunk/profitmandi-fofo/src/main/ |
Add offer circular review and curation screen
Shows the nine verbatim PDF columns beside what the parser made of them, uploads a
new monthly circular, and resolves the products the matcher could not.
Upload deliberately does not parse - it stores the PDF, sha256-deduped, and
registers it DRAFT, so an upload can never half-populate the offer tables. The cron
ingest job picks it up from there.
The curation queue groups by distinct (division, raw text) because that is the
product_alias key: one answer clears every row carrying that text, on this circular
and on every later one. On the Aug'26 circular that turns 152 unresolved rows into
106 decisions. Three actions mirror product_alias.action - PIN to a catalog id,
REWRITE to the catalog's spelling and match again, or IGNORE.
- Writes product_alias only, so nothing the screen does can set manually_curated
and lock a circular against re-ingest. Coverage decisions, which do need that,
are listed but visibly parked rather than offered a naming answer.
- A saved decision changes nothing until re-ingest, because aliases are read at
ingest time; the queue says so and the re-ingest button puts the document back
to DRAFT for the scheduler. The portal cannot run the ingest itself - that lives
in profitmandi-cron, which fofo does not depend on.
- The closest rejected match is shown for context and never pre-selected. Four new
OnePlus models each "nearly" matched a 2015 OnePlus 2 at 0.80-0.84, and offering
that as a suggestion invites a reviewer to confirm it. Where the catalog has no
such SKU the search says so and steers to IGNORE.
- aliasExport emits every decision as replayable SQL, because the portal writes to
one database and environments would otherwise drift apart silently.
Access is an email allowlist AND the admin role. Both are enforced in the
controller; the sidebar entry repeats the allowlist because visibility in auth.menu
is role-driven and cannot express a per-email rule.
No jsVersion bump: offer-circular-review.js is a new file that was never cached,
so it needs no cache-buster, and churning that shared counter only conflicts with
whoever is mid-edit on it. |
|
| 37327 |
54 d 20 h |
ranu |
/trunk/ |
super retailer club 5 live |
|
| 37324 |
54 d 21 h |
aman |
/trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ |
Lead Management: restrict lead view to field-level sales only (L1-L3). Any SALES position at any level previously forced the own+reportees lead filter, so senior sales heads (L4+ BM/RSM/NSM/co-founder L7) lost visibility of all leads and their dashboard charts collapsed. hasCategory check replaced with isFieldSales() at both view-filter sites; assignee validation untouched. |
|
| 37319 |
57 d 19 h |
amit |
/trunk/ |
Fix partner-performance tertiary: aggregate order items (qty*mop), not the POS-typed order header
The tertiary panel summed fofo_order.total_amount - a price typed at the partner POS
and never validated against the catalogue - and attributed each whole order to its
first line item's brand via .get(0). One mistyped digit inflated reported sell-out
10x, and mixed-brand orders booked 100% to the first brand, leaving the rest at zero.
Defect dates from r32000/r32034 (May 2023); the panel was the only tertiary consumer
diverging from the qty*mop basis.
- New FofoOrder.selectMonthlyBrandTertiary: sum(quantity*mop) grouped by
(year*100+month) and item brand - the same basis selectPartnerTertiarySales
already uses for the DSR and the partner tier calculation
- PerformanceController: replaces two entity-loading queries (every FofoOrder and
FofoOrderItem for 6 months) with one aggregate; all items now count, each under
its own brand
- Month labels unchanged - toMonthLabel rebuilds the MMM''uu key, template untouched
- Remove V2FofoPerformanceController, the /v2/fofo JSON copy carrying the same defect
Verified against dev DB for fofo_id 175139501: Jul 2026 now 16,94,939 (panel
previously showed 50,92,440); all six months match the qty*mop basis. |
|
| 37312 |
58 d 2 h |
ranu |
/trunk/ |
one assist ew at 99 up to 20k |
|
| 37310 |
58 d 17 h |
vikas |
/trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/scratch/ |
Scratch Offers now selects only active partners |
|
| 37309 |
58 d 19 h |
vikas |
/trunk/ |
Scratch Offers now selects only active partners |
|
| 37288 |
61 d 19 h |
ranu |
/trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ |
all active brand in hot deals |
|
| 37287 |
61 d 20 h |
ranu |
/trunk/ |
warehouse access |
|
| 37286 |
61 d 20 h |
ranu |
/trunk/ |
warehouse access |
|
| 37285 |
61 d 20 h |
ranu |
/trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ |
warehouse access |
|
| 37282 |
61 d 21 h |
amit |
/trunk/profitmandi-fofo/src/main/ |
hot deals: remove legacy tag_listing hot-deals endpoints and catalog-item UI (replaced by model_hot_deal admin flow) |
|
| 37277 |
62 d 1 h |
vikas |
/trunk/profitmandi-fofo/src/main/ |
Updated Escalation Level |
|
| 37272 |
62 d 3 h |
amit |
/trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ |
Fix duplicate super-catalog mapping rows on save
The add-row flow in super_catalog.js always posts mapping id 0, so saving a
catalog that was already mapped inserted a second row. That duplicated the
catalog inside superCatalogVariants_s, which surfaced as repeated storage
variant chips on the partner catalog card.
processCatalogMapping now falls back to a (catalogId, superCatalogId) lookup
when no mapping id is supplied and updates the existing row instead of
inserting. Also removes a latent NPE when a stale mapping id was posted.
Backed by a new UNIQUE(catalog_id, super_catalog_id) on
catalog.super_catalog_mapping; 5 pre-existing surplus rows were removed. |
|
| 37270 |
62 d 3 h |
amit |
/trunk/profitmandi-fofo/src/main/ |
Hot deals admin: activated -> fresh (labels, params, row editors); manual Push to Solr for selected models (checkbox selection + /hotDeals/pushSolr calling FofoSolr.updateSingleCatalog directly, bypasses prod-gated event so Category team curation is searchable immediately); jsVersion 395 |
|
| 37264 |
62 d 20 h |
ranu |
/trunk/ |
rbm assignement event and new edm mail committed |
|
| 37263 |
62 d 22 h |
ranu |
/trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ |
commit for loi form |
|