| Rev |
Age |
Author |
Path |
Log message |
Diff |
| 37556 |
16 m |
ranu |
/trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/ |
loi process added, revival and code changes process |
|
| 37555 |
25 m |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/offers/ |
web offer sync: one value per SKU per payment mode
The circular says two things about the same phone. Motorola Sep'26 page 9 names
'G37 Power' generically at Rs.1,000 CC Full Swipe (row 12) and 'G37 Power (8+128)'
at Rs.2,000 (row 13), so G37 Power 8+128 carried both badges and a partner could
quote either.
Precedence, per (catalog_id, txn_mode):
1. a specifically named VARIANT beats a generic MODEL - the named line is the OEM
being precise about that SKU
2. at the same level, the higher value wins
3. tie-break on lowest offer id, so the outcome is deterministic
The generic line still covers every variant nobody named: G37 Power 4+64 keeps its
Rs.1,000 Full Swipe while 8+128 takes Rs.2,000. Verified on the live data - 1026311
now resolves to exactly CC_EMI 2500 and CC_FULL_SWIPE 2000, down from four competing
values.
An offer keeps a SKU if it wins on at least one of its own modes, since one badge
carries every mode of its offer. Scheme-only offers are never filtered - no value to
compare.
Deliberately NOT reusing v_offer_applicable, which encodes the same VARIANT-beats-
MODEL rule but has no document or status filter: once August is re-ingested its rows
enter that view and an EXPIRED August variant would silently suppress a live
September model. Scoping to one document avoids that; the view is left alone for
other consumers.
Measured on Sep'26: 557 product links -> 458, 191 badges -> 166. |
|
| 37554 |
1 h 33 m |
amit |
/trunk/profitmandi-fofo/src/ |
web offer: put the brand back in the title
SEPTEMBER 2026 MOTOROLA Rs.1,000 cashback on Credit Card Full Swipe
SEPTEMBER 2026 MOTOROLA No Cost EMI on 3, 6 months
Month and brand now both match the convention of the 3,850 hand-written rows, which
is how the admin listing is scanned. What stays gone is the redundant
'Cashback Offer-' label: the value already states what the offer is, and calling a
scheme-only row a cashback offer is what produced the live 'Cashback Offer- NA'
badges on 81 SKUs.
Brand comes from the division's catalog brand, falling back to its display name, so
a division with no catalog.brand row (Google) still reads sensibly rather than
emitting an empty gap. |
|
| 37553 |
1 h 56 m |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/offers/ |
web offer sync: all_banks is TINYINT(1), so never cast it to Number
ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number, thrown from
selectPublishableOffers on every ingest since 2026-09-08. Confirmed against the live
driver: SELECT all_banks returns java.lang.Boolean.
MySQL Connector/J maps TINYINT(1) to Boolean while Hibernate may hand back a Number,
so the value must be read through isTrue() - the same shape as ScopeConfig.isTrue and
OfferScopeRepositoryImpl.isTrue, both of which exist for exactly this reason and both
of which I had in front of me when writing the cast.
The failure was silent by design: CircularIngestRunner swallows sync exceptions so a
web-offer problem can never fail a good ingest. The circular kept publishing, the
document's processed_at kept moving, and the only symptom was that web_offer.synced_at
stopped advancing - which is what should have been checked before reporting the sync
as working on 8 September. |
|
| 37552 |
2 h 24 m |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/ |
lead/knowlarity: stop a null lookup key from matching every row
selectByEquals maps a null VALUE to NO PREDICATE AT ALL rather than to "= null",
because GenericRepositoryImpl.prepareEqualPredicate skips null entries. So a null
lookup key does not miss -- it selects the whole table and dies on
NonUniqueResultException. Two live call paths were doing exactly that.
RecordingService.updateAgentCallLog read caller_id, which knowlarity has never sent
on push-call-log: a sample of 50 live webhooks contained it zero times. Every call
therefore ran selectByCallerId(null) -> "select every sip_master row" -> throw, and
the whole feed was discarded. 17 of those 50 were Connected calls with a real agent.
Resolve the agent from agent_number instead, which is the field that actually
identifies them and holds the sip_url; it arrives bare, sip:-prefixed, or as the
literals "False"/"None" when nobody picked up. caller_id is still honoured first in
case they ever start sending it. A payload naming no agent is INFO, and an agent
missing from sip_master is WARN (an ops fix, and per-agent, so an ERROR would
fingerprint into one GlitchTip issue per agent).
AuthRepositoryImpl.putEmailOrMobile had the same hole via Long.parseLong(null)
falling into the catch and putting a null email. selectByEmailOrMobile(null)
degenerated to "select all 405 users", and authenticate(null, hash) degenerated to
"does ANY user have this password hash", which would answer true. Both fail closed
today only as an accident of how many rows the table holds, so the guard goes on the
one path they share.
Fixes GlitchTip #58/#1324/#1335 (fofo, 281 events) and #10 (web). |
|
| 37551 |
2 h 25 m |
amit |
/trunk/profitmandi-fofo/src/ |
web offer: keep the month in the title
SEPTEMBER 2026 Up to Rs.4,000 cashback
SEPTEMBER 2026 Rs.1,500 cashback on Credit Card EMI
SEPTEMBER 2026 No Cost EMI on 3, 6 months
Matches the convention of the 3,850 hand-written rows and is how the admin listing is
scanned. The brand stays out - the product card already shows it, so that was the
redundant half, and dropping it is what makes room for the value to lead.
The month comes from the OFFER's own start date, not the circular's period: offers
run past a month end - four Aug'26 Apple offers ran to 26 September - and labelling
one of those AUGUST on a badge read in September would be wrong. |
|
| 37550 |
2 h 30 m |
amit |
/trunk/profitmandi-fofo/src/ |
web offer: partner-facing titles, and stop calling a scheme offer a cashback offer
web_offer.title is partner-facing - StoreController and DealsController map it into
the product's offer list - so it now leads with the value rather than a filing label:
Up to Rs.4,000 cashback
Rs.1,500 cashback on Credit Card EMI
10% cashback up to Rs.7,500 on Credit Card EMI
No Cost EMI on 3, 6 months
Month and brand are gone: the card already shows the product, and the offer carries
its own dates. The full breakdown sits in detailedText below it.
This fixes a live defect. 16 published offers have no cashback at all, and the old
template rendered them 'SEPTEMBER 2026 XIAOMI Cashback Offer- NA' with detail 'NA',
on 81 SKUs. They are EMI-scheme offers and now say so.
Scheme inference at ingest: Motorola states the scheme in the DESCRIPTION rather than
the tenure cell - '[3&6 M]' plus 'Only NCEMI', where every other OEM writes
'6(NCE),9,12(LCE)'. TenureParser is right to return NONE for such a cell; the scheme
is simply not in it. Recovered in CircularIngestService where both columns are in
hand, and deliberately narrow: only when EVERY tenure came back without a scheme AND
the description names exactly one. On Sep'26 that is 10 offers, all Motorola; the
other 23 scheme-less rows are cashback offers whose descriptions are amounts, and
inventing a scheme for those would misstate the terms.
This distinction is money: four of the Motorola rows are LOW cost EMI, and calling
them no-cost would promise a partner something the bank will not honour.
'No cashback.' is dropped everywhere - the absence of an amount says it, and beside a
Cashback Instant Benefit scheme it flatly contradicted the name.
Tests 8 -> 12. |
|
| 37549 |
2 h 31 m |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/offers/ |
web offer sync: read tenures for scheme-only offers
selectTenures, keyed by offer id like the benefit and bank reads.
Needed because an offer with no cashback is still a real offer - a no-cost or
low-cost EMI scheme - and its tenures are the only thing it has to say. Without them
those rows can only be described as 'NA'. |
|
| 37548 |
3 h 6 m |
ranu |
/trunk/ |
v2 version some fixes |
|
| 37547 |
3 h 9 m |
ranu |
/trunk/profitmandi-web/src/main/java/com/spice/profitmandi/web/controller/ |
v2 switch version fixes on server side |
|
| 37546 |
19 h 28 m |
amit |
/trunk/profitmandi-fofo/src/ |
web offer sync: compose detailed text from the parsed offer
detailedText is now built from benefit_timing + offer_benefit + offer_bank instead
of copying the circular's line:
Instant cashback. Rs.4,000 on Credit Card EMI; Rs.3,000 on Credit Card Full
Swipe. Banks: Axis Bank, ICICI Bank, State Bank of India (credit cards)
Every payment mode is always named, even when the circular's prose is terse
('10% CC EMI'), and the amounts come from offer_benefit - the authoritative
per-mode source. CC/DC cannot leak here at all, because the mode codes expand
natively rather than being patched by find-and-replace.
Three cases that would otherwise read badly:
- 21 offers carry NO benefit (circular cell 'NA', timing NONE). They are tenure-only
offers, so they read 'No-cost EMI. No cashback.' rather than showing a blank badge.
- The bank columns often list a bank under both card types while only one carries a
benefit. Card types shown are restricted to those actually paid on, or the text
would imply a debit offer that does not exist.
- benefit_timing UPI and NONE are not timings. Nothing is asserted rather than
inventing one.
smallText keeps the circular's short line - that column is only VARCHAR(256) and the
composed detail runs past it. One flowing paragraph, no line breaks, since the badge
may not render them.
Tests 8 -> 14. |
|
| 37545 |
19 h 28 m |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/offers/ |
web offer sync: read benefits and banks for the composed detail text
selectBenefits and selectBanks, keyed by offer id and fetched once per circular
rather than per offer - 259 offers would otherwise be 518 extra round trips.
The main query now also carries offer_id, benefit_timing and all_banks.
Bank read takes INCLUDE rows only: an EXCLUDE is meaningful only when all_banks=1,
and such an offer is described as 'All banks' rather than by listing an exclusion a
partner cannot act on. |
|
| 37544 |
22 h 28 m |
amit |
/trunk/profitmandi-fofo/src/ |
web offer sync: expand CC and DC to Credit Card and Debit Card
The circular writes 'Rs.4000 Cashback on CC EMI'; a partner reading the badge should
see 'Credit Card EMI'. Applied to the title and the small/detailed text together, so
a badge and its detail never disagree.
Word-bounded and applied BEFORE truncation: an expansion is never cut in half, and
letters inside a word are untouched - the circular's cells carry strings like
'X300 Ext Kit' and 'ACCESSORIES', which an unbounded replace would corrupt.
On Sep'26 this affects 155 of 259 descriptions for CC and 48 for DC.
Two existing expectations updated to the new wording, and two tests added: one for
the expansion, one asserting DCX and ACCESSORIES survive intact. |
|
| 37543 |
1 d 2 h |
amit |
/trunk/profitmandi-fofo/src/main/ |
receive debit note: resolve the DOA section from the declared condition, not from a change
The condition dropdown renders with the partner's declared value already selected, so
a declared BAD - the ordinary DOA case - fired no change event and the DOA certificate
radios stayed hidden. The operator could not supply a certificate, and receiveDebitNoteItems
then refused the receipt for a missing one, making those debit notes unreceivable.
applyDeclaredConditions seeds each dropdown from the row's data-declared and settles the
dependent sections on load; the show/hide logic moves out of the change handler into
syncReceiveConditionState, which reads the current state of the form rather than whatever
was last touched. The change handler now calls the same function.
The server-side 'selected' stays as a fallback: without it a declared BAD would present as
GOOD if the script failed to load, and the server reads that difference as the warehouse
disagreeing with the partner, which rejects the whole debit note.
jsVersion 417 -> 418. |
|
| 37542 |
1 d 21 h |
ranu |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/enumuration/onBorading/onBoardingFormEnums/ |
loi process added, revival and code changes process |
|
| 37541 |
1 d 21 h |
ranu |
/trunk/ |
loi process added, revival and code changes process |
|
| 37540 |
1 d 21 h |
ranu |
/trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/service/ |
loi process added, revival and code changes process |
|
| 37539 |
2 d 2 h |
amit |
/trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ |
Fixed mail sender everywhere |
|
| 37538 |
4 d 9 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/gstpro/ |
gstpro: a shipped delivery challan is a return, not a cancellation
Movement becomes the single discriminator for both document types. Nothing has
left the warehouse, so nothing happened and the document can be withdrawn; once
the goods have shipped the document records a movement that really occurred, and
the only honest reversal is an opposing document - a credit note through finance.
The clock is the only thing that differs. A tax invoice must also be inside its
24h IRN window, because past that NIC will not cancel the IRN. A delivery challan
has no IRN and no acknowledgement - every DC row carries a placeholder irn and a
null ack_date - so no clock applies to it: an unshipped challan stays withdrawable
whatever its age, and its e-way bill is cancelled on that path since nothing moved
under it.
Previously a DC short-circuited to cancellable regardless of shipping, which would
have voided challans whose goods were already in transit. |
|
| 37537 |
4 d 15 h |
amit |
/trunk/profitmandi-cron/src/main/java/com/smartdukaan/cron/scheduled/ |
carlcare activation: retry a transient failure once before giving up
One retry after a 1.5s backoff - long enough to clear the far end's rate window,
short enough to still fit inside a scheduler tick. A transient network blip was
otherwise recorded as a hard activation failure for that IMEI. |
|