Subversion Repositories SmartDukaan

Rev

Go to most recent revision | Show changed files | Directory listing | RSS feed

Filtering Options

Rev Age Author Path Log message Diff
37364 51 d 18 h amit /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/ Offer circular ingest: report discarded rows instead of counting attempts

Pairs with the repository change that makes insertBenefit/insertTenure/insertBank return
their affected row count. The summary now bumps only when a row actually landed, and
records a drop naming the likely unseeded master (offers.txn_mode / emi_scheme / bank)
when it did not. Without this an ingest over empty masters reported a full, healthy
parse while writing nothing.
 
37363 51 d 18 h amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/offers/ Offer circular ingest: return affected rows so INSERT IGNORE cannot hide an FK failure

insertBenefit/insertTenure/insertBank use INSERT IGNORE for idempotency, which also
makes MySQL downgrade a foreign key violation to a warning. Production was bootstrapped
without the bank / txn_mode / emi_scheme masters, so all 872 benefit and tenure inserts
were silently discarded: the ingest reported PUBLISHED with 239 offers carrying no
amounts, no tenures and no bank eligibility, and nothing anywhere said so.

The three methods now return the affected row count (1 written, 0 discarded) so the
caller can count what landed rather than what it attempted.
 
37362 51 d 18 h amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/external/ External feed: keep placeholder 'Any Colour' SKUs out of the partner feed

catalog.item rows whose color is a placeholder ("Any Colour", "f_Any Color", ...) are
not real sellable variants and must never reach partners. Excluded from every feed and
count query via a single NO_PLACEHOLDER_SKU predicate so the SKU list and its count
cannot drift apart. The boundary check leaves real colors like "Rainbow" untouched.
 
37361 51 d 18 h amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/ Mail outbox: one transaction per mail, retry once more, stable Message-ID

processPendingMails ran the whole batch in a single REQUIRES_NEW transaction, so a
crash mid-batch rolled back the status of every mail already delivered in that cycle
and the next run re-sent them.

- Split into selectPendingIds (read-only) plus sendOne per mail, each REQUIRES_NEW via
a @Lazy self-reference so the proxy actually applies. Outcome is committed as soon
as it is known; a crash now loses at most the mail in flight.
- MailOutbox.selectPending retries FAILED rows once more (retryCount < 2).
- Stable per-row Message-ID so a retry arrives as the same message and the receiving
server can collapse it instead of showing a duplicate.
 
37360 51 d 18 h amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/icicilombard/ ICICI policy issuance: stop losing policies to a proposal read timeout

hitAfinityProposal called ICICI's gadget proposal endpoint on the default 10s socket
timeout. That POST issues the policy, so a read timeout abandons a request ICICI is
still completing. The exception then unwound through generateIciciLombardPolicy into
the controller's @Transactional(rollbackFor = Throwable.class), rolling back the whole
request - including the wallet debit - before the tracker row was ever touched. Result:
policy possibly live at ICICI, no trace on our side, and the 'policy already exists'
retry path dead-ends because its Redis cache is only written on a parsed success.

- Proposal and policy-certificate calls move to a dedicated RestClient built on
HttpClientFactory.insuranceIssuanceRequestConfig() (socket 45s). JWT and quote stay
on the default client - fast, and no remote write.
- Transport failures are classified via HttpTransportFailures and reported as 'outcome
unknown', not as an ICICI rejection.
- IciciPolicyTrackerBookkeeping writes the tracker in REQUIRES_NEW, so both the UNKNOWN
outcome and the issued policy number survive the request rollback. Recovery from an
UNKNOWN row is the existing recoverPolicyNumberByProposalNumber path.

Code only, no DDL: status is varchar(20) and remarks is text on prod already.
 
37359 51 d 18 h amit /trunk/profitmandi-common/src/main/java/com/spice/profitmandi/common/web/client/ ICICI proposal read timeout: add insurance-issuance HTTP config + shared transport-failure classifier

The default RestClient carries a 10s socket timeout, sized for quick lookups. ICICI's
gadget proposal endpoint underwrites and issues the policy synchronously and needs
longer; abandoning the read discards the only response carrying the policy and
proposal numbers for a policy that is already live at the insurer.

- HttpClientFactory.insuranceIssuanceRequestConfig(): connect 5s, socket 45s. Not
slowRegulatorRequestConfig() - its contract forbids request-thread use with an open
transaction, which is exactly the ICICI call site.
- HttpTransportFailures: cause-chain check separating 'the call never completed' from
'the remote said no'. Needed because RestClient rewraps transport errors as
RuntimeException(GE_1006), so the top-level exception type is uninformative.
 
37358 51 d 21 h ranu /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/ total show on warehouse wise stock value on item detail  
37357 51 d 21 h amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/cs/ Add CsService.getAuthUsersByPartnerIdAndCategory for partner+category+escalation lookup

sendMailForActionOnDispatch mailed every L1 position on the partner, which on live data
means the DESIGN (17), SALES (4) and WAREHOUSE (11) owners as well as the RBM (18). It
also hand-rolled the partner_position -> position -> auth_user walk against repositories.

Add a single reusable resolver on CsService: active auth users holding one position
category against a partner, optionally narrowed to escalation levels. It follows the
house resolver shape - the partner's own regions plus ALL_PARTNERS_REGION, partner_id in
(0, fofoId) - so region-wide mappings are honoured, and it short-circuits on empty id
lists because selectByIds builds an IN () predicate that breaks on an empty list.

The call site in TransactionServiceImpl went in with r37356; without this commit trunk
does not compile.
 
37356 51 d 21 h amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/transaction/ Fixed max limit to 15 lac for Credit limit  
37355 52 d 1 h aman /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ AI lead intake (fofo, live): assign new leads to a random active BGC L1 instead of the hardcoded Khushbu/Archana round-robin  
37354 52 d 1 h aman /trunk/profitmandi-web/src/main/java/com/spice/profitmandi/web/controller/ AI lead intake: pool is BGC L1 (category 20), not Sales L1 - BGC is the desk that works AI leads  
37353 52 d 2 h aman /trunk/profitmandi-web/src/main/java/com/spice/profitmandi/web/controller/ AI lead intake: assign new leads to a random active Sales L1 instead of fixed auth id 53  
37352 52 d 2 h amit /trunk/profitmandi-cron/src/main/java/com/smartdukaan/cron/scheduled/ Fixed max limit to 15 lac for Credit limit  
37351 52 d 4 h ranu /trunk/ code committed for sales l3 added in bi and other model  
37350 52 d 5 h amit /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/transaction/ Fix SD Credit daily statement showing zero interest on overdue loans

sdDirectService classified each day's interest by exact-matching the
loan_statement description ('Interest On Loan Per Day' /
'Penalty On Loan Per Day'). Once a loan crossed its due date the cron
switches the label to 'Overdue Interest On Loan Per Day', which matched
neither filter, so the daily statement reported 0.00 interest for every
overdue day even though the charge was booked correctly in
loan_statement and loan.interest_accured.

Classify by tenure window against loan.getPenaltyDate() instead - the
same test addInterest() uses to pick the rate - and net the day's full
interest out of the opening balance so penalty days are consistent too.

Seen on loan 120277 (invoice NSLCK35860): Rs.73-83/day accruing from
08-Aug, displayed as 0.00.
 
37349 52 d 20 h ranu /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/transaction/ super retailer club 5 live  
37348 52 d 20 h ranu /trunk/ super retailer club 5 live  
37347 52 d 22 h amit /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/ Give the ingest runner a transaction; it had none on its background thread

Parsing failed instantly on production with

org.hibernate.HibernateException: Could not obtain transaction-synchronized
Session for current thread
at CircularIngestRepositoryImpl.claimForProcessing
at CircularIngestRunner.processOne

The runner works on a background thread. Nothing binds a Hibernate session to it, so
the very first repository call - the claim - threw. Worse, the failure handler called
markFailed, which threw for the same reason, so nothing was recorded: the document sat
in DRAFT with no error, no processed_at and no outward sign that anything had gone
wrong. CircularIngestService.ingest was never reached.

This was latent in the cron version too. It never surfaced because that scheduler was
never actually deployed anywhere.

- New CircularIngestBookkeeping: claim / document / published / failed /
reclaimStalled, each REQUIRES_NEW. Independent transactions matter most for failed(),
which runs after the ingest transaction has already rolled back and must not be
dragged into it.
- It is a SEPARATE bean on purpose. @Transactional on the runner's own methods would be
invoked from inside its own Runnable - a self-invocation never passes through the
Spring proxy, so the annotation would be silently ignored and the bug would come back
wearing a disguise.
- The runner no longer touches CircularIngestRepository at all.

Not caught locally because the RunIngest harness uses JdbcIngestRepo, a plain-JDBC
implementation that bypasses Hibernate entirely - so it can reproduce the parsing but
never a session or transaction problem.
 
37346 52 d 22 h amit /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ Sort sale returns so the ones still needing an action come first

The Recently Received Debit Notes table was ordered purely by receive time, so a
return waiting on a refund or on the partner's acknowledgment sank below rows that
were already refunded and needed nothing. On a busy warehouse the actionable rows
were off the first screen.

- recentOrders is now ranked pending-first (Received - Pending Refund, Rejected -
Pending Acknowledgment) ahead of settled ones (Refunded, Cancelled), with the
existing receiveTimestamp DESC kept as the tie-breaker inside each group
- getPendingActionRank follows the same precedence invoice-return.vm uses to pick
the status badge - reject checked before refund - so the ordering can never
disagree with the label the user sees
- ranked on the return's own state, not on the viewer's canReceive/canRefund
permissions, so a pending return stays at the top for everyone looking at it

Presentation only; no query, entity or lifecycle change. Note that returns never
received at all cannot surface here regardless, since the query filters on
receiveTimestamp BETWEEN the selected dates.
 
37345 52 d 23 h vikas /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ Beat Journey (today): LOI-based 'Onboarded' + last-billing recency board columns, level-filtered orders list (grouped by partner), and flag tuning — remove #1/#3, use per-visit total_distance for #4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
 

Show All