<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SmartDukaan &#x2013; //trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/</title><description>WebSVN RSS feed &#x2013; SmartDukaan</description><lastBuildDate>Thu, 08 Oct 2026 04:28:57 +0530</lastBuildDate><generator>WebSVN 2.8.6-DEV</generator><language>en</language><link>https://svn.smartdukaan.com/log.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;max=40&amp;</link><atom:link href="https://svn.smartdukaan.com/rss.php?isdir=1&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;repname=SmartDukaan" rel="self" type="application/rss+xml" />
<item><pubDate>Wed, 16 Sep 2026 15:13:38 +0530</pubDate><dc:creator>vikas</dc:creator><title>Rev 37651 – LMS click to call</title><description>&lt;div&gt;&lt;strong&gt;vikas – 63 file(s) modified&lt;/strong&gt;&lt;br/&gt;LMS click to call&lt;/div&gt;~ /trunk/profitmandi-dao/build.gradle&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/config/AsyncConfig.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/auth/VonageAgent.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/user/LeadActivity.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/user/LeadCall.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/user/LeadDnd.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/user/LeadRecordingAccess.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/user/MetaLead.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/user/MetaLeadImport.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/enumuration/dtr/LeadCallProvider.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/enumuration/dtr/LeadCallStatus.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/enumuration/dtr/MetaLeadDistribution.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/enumuration/dtr/MetaLeadOutcome.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/auth/VonageAgentRepository.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/auth/VonageAgentRepositoryImpl.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/LeadCallRepository.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/LeadCallRepositoryImpl.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/LeadDndRepository.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/LeadDndRepositoryImpl.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/LeadRecordingAccessRepository.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/LeadRecordingAccessRepositoryImpl.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/LeadRepository.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/LeadRepositoryImpl.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/MetaLeadRepository.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/dtr/MetaLeadRepositoryImpl.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/vonage&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/vonage/vbc&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/vonage/vbc/VbcDialerProvider.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/vonage/vbc/VbcTelephonyService.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/vonage/vbc/VbcTokenService.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/vonage/VonageDialerProvider.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/vonage/VonageJwtService.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/vonage/VonageVoiceService.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/lms&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/lms/LmsDialerProvider.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/lms/meta&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/lms/meta/MetaLeadFileParser.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/lms/meta/MetaLeadImportService.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/lms/meta/MetaLeadRow.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/lms/RecordingAccessService.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/lms/RecordingArchiveService.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/lms/RecordingArchiveWorker.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/LmsDashboardService.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/storage&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/storage/ObjectStoreService.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/resources/shared-prod.properties&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/resources/shared-staging.properties&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/config/WebConfig.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/LmsDashboardController.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/LmsDialerController.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/LmsLeadController.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/LmsRecordingController.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/MetaLeadImportController.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/service/RecordingArchiveScheduler.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/util/CatalogMonitorTypeCsvValidator.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/resources/META-INF/env.property&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/resources/js/lead.js&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/admin.vm&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/edit-lead.vm&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/lead-record.vm&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/lms-dashboard-standalone.vm&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/meta-lead-import.vm&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/util/CatalogMonitorTypeCsvValidatorTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37651</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37651</guid></item>
<item><pubDate>Thu, 10 Sep 2026 14:55:17 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37580 – web offer: state an EMI scheme the circular gave without ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 3 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer: state an EMI scheme the circular gave without months&lt;br /&gt;
&lt;br /&gt;
  Rs.2,500 on Credit Card EMI (CIB) with IDFC First Bank, Kotak Mahindra Bank&lt;br /&gt;
&lt;br /&gt;
52 Sep&apos;26 offers have a bare &apos;CIB&apos; tenure cell - the circular names the EMI type and&lt;br /&gt;
gives no months. TenureParser correctly yields no tenure row for a cell with no digits,&lt;br /&gt;
so the type vanished and the badge said only &apos;on Credit Card EMI&apos;. Every one of those&lt;br /&gt;
52 carries a cashback, so it was 52 offers&apos; worth of SKUs silent about the EMI they&lt;br /&gt;
apply to.&lt;br /&gt;
&lt;br /&gt;
The type is stated because the circular stated it. The MONTHS are not invented,&lt;br /&gt;
because it did not give them - the same line the CIB expansion was left on.&lt;br /&gt;
&lt;br /&gt;
Read from offer_raw_row.col_emi_tenure rather than stored: &apos;scheme, no month&apos; is not a&lt;br /&gt;
tenure, and offer_tenure.tenure_months is NOT NULL, so persisting it would mean a fake&lt;br /&gt;
0 row standing for a fact that is not a tenure.&lt;br /&gt;
&lt;br /&gt;
Only ever attached to an EMI mode, and real tenures always win over the bare code.&lt;br /&gt;
&lt;br /&gt;
ModelOfferTest 8 -&gt; 11.&lt;/div&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/offers/WebOfferSyncRepositoryImpl.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/ModelOfferTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37580</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37580</guid></item>
<item><pubDate>Thu, 10 Sep 2026 13:47:02 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37579 – web offer: one badge per model, consolidating everything the circular ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer: one badge per model, consolidating everything the circular grants it&lt;br /&gt;
&lt;br /&gt;
Edge 60 Pro 12+256 carried five badges - a Full Swipe cashback, an EMI cashback and&lt;br /&gt;
three EMI schemes - and the partner&apos;s card listed all five. It now carries one:&lt;br /&gt;
&lt;br /&gt;
  SEPTEMBER 2026 Motorola Cashback Offer-2,500 On Credit Card EMI&lt;br /&gt;
                                         &amp; 2,000 On Credit Card Full Swipe&lt;br /&gt;
&lt;br /&gt;
Models whose consolidated terms are IDENTICAL share a badge, so 314 models collapse to&lt;br /&gt;
~107 rows while every model still appears in exactly one.&lt;br /&gt;
&lt;br /&gt;
Rules, from the taxonomy: any model has cashback on Full Swipe and/or EMI, instant or&lt;br /&gt;
deferred, plus NCE/LCE/CIB with tenures, and any of it may differ per bank.&lt;br /&gt;
- &apos;Upto&apos; only where a mode carries several values - which is what per-bank pricing&lt;br /&gt;
  looks like. One value is stated plainly.&lt;br /&gt;
- Highest value first.&lt;br /&gt;
- Banks ride with each line only when they DIFFER; one shared set is hoisted to a&lt;br /&gt;
  single trailing &apos;Banks:&apos; line. A third of models need the per-line form.&lt;br /&gt;
- An amount whose window is narrower than the badge&apos;s states its own end date. Apple&lt;br /&gt;
  1025780 pays Rs.6,000 to the 16th then Rs.4,000 to the 26th; without this the badge&lt;br /&gt;
  would advertise Rs.6,000 for ten days it is not available.&lt;br /&gt;
&lt;br /&gt;
⚠️ Banks and tenures belong to the OFFER a line came from, never to the model. On Edge&lt;br /&gt;
60 Pro the no-cost EMI is ICICI on 3 and 6 months but SBI on 3 only, and the EMI&lt;br /&gt;
cashback is IDFC/Kotak with no tenure at all. Attaching the model&apos;s tenures to its&lt;br /&gt;
cashback would promise no-cost EMI on a bank that never offered it. This also corrects&lt;br /&gt;
an earlier reading of mine that called the SBI 3-month line a duplicate of ICICI&apos;s -&lt;br /&gt;
it is a different bank, not noise.&lt;br /&gt;
&lt;br /&gt;
New ModelOfferTest, 8 cases, every one taken from a real Sep&apos;26 row.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/ModelOfferTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37579</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37579</guid></item>
<item><pubDate>Thu, 10 Sep 2026 13:17:50 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37577 – web offer: an EMI cashback names its tenures WITH their ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer: an EMI cashback names its tenures WITH their scheme&lt;br /&gt;
&lt;br /&gt;
  Rs.2,500 on Credit Card EMI (NCE 3, 6; LCE 9, 12 months)&lt;br /&gt;
&lt;br /&gt;
A bare &apos;3, 6, 9, 12 months&apos; says which tenures earn the cashback but not which of&lt;br /&gt;
them are no-cost - and at the counter the two facts are only useful together.&lt;br /&gt;
&lt;br /&gt;
The trailing scheme sentence is dropped when an EMI benefit already carried it, since&lt;br /&gt;
it would state the same thing twice. It stays when the cashback is on Full Swipe only:&lt;br /&gt;
EMI is still available, it just is not what the cashback is on.&lt;br /&gt;
&lt;br /&gt;
Tenures whose scheme the circular never gave keep their months but carry no label -&lt;br /&gt;
the months are real, the scheme would be invented.&lt;br /&gt;
&lt;br /&gt;
Tests 16 -&gt; 18.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/WebOfferSyncServiceTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37577</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37577</guid></item>
<item><pubDate>Thu, 10 Sep 2026 12:45:42 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37574 – web offer: print the EMI scheme code, not a guessed ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer: print the EMI scheme code, not a guessed expansion&lt;br /&gt;
&lt;br /&gt;
NCE / LCE / CIB are industry standard and now appear verbatim:&lt;br /&gt;
&lt;br /&gt;
  Instant cashback. Rs.3,000 on Credit Card EMI (3, 6 months);&lt;br /&gt;
  Rs.3,000 on Credit Card Full Swipe. LCE on 3, 6 months. Banks: ...&lt;br /&gt;
&lt;br /&gt;
The expansions were not ours to invent. emi_scheme.display_name carries &apos;Cashback&lt;br /&gt;
Instant Benefit&apos; for CIB, and the evidence contradicts it: the Sep&apos;26 cell&lt;br /&gt;
&apos;3 NC 6,9,12 CIB&apos; puts CIB in ONE ladder with NCE, so it describes who bears the&lt;br /&gt;
interest on a tenure rather than how a cashback is delivered - and 53 of 55 CIB rows&lt;br /&gt;
carry a separate cashback amount anyway, which that expansion would make redundant.&lt;br /&gt;
Pine Labs&apos; own docs define ICB as Instant Cashback on UPI; the circular writes CIB 60&lt;br /&gt;
times and ICB never.&lt;br /&gt;
&lt;br /&gt;
A guessed expansion on a partner badge risks stating the opposite of the truth - for&lt;br /&gt;
CIB, advertising a benefit where the customer may in fact be bearing the interest.&lt;br /&gt;
The code cannot be wrong that way.&lt;br /&gt;
&lt;br /&gt;
A scheme is still stated ONLY when the circular gave one; tenures with no scheme are&lt;br /&gt;
described as nothing at all.&lt;br /&gt;
&lt;br /&gt;
Also fixes the singular: &apos;NCE on 3 month&apos;, not &apos;3 months&apos;.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/WebOfferSyncServiceTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37574</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37574</guid></item>
<item><pubDate>Thu, 10 Sep 2026 12:34:31 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37572 – web offer: state the whole offer in the title, and ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer: state the whole offer in the title, and the EMI scheme in the detail&lt;br /&gt;
&lt;br /&gt;
Title now states EVERY payment mode, highest first, in the house style of the&lt;br /&gt;
hand-written rows:&lt;br /&gt;
&lt;br /&gt;
  SEPTEMBER 2026 Samsung Cashback Offer-3000 On Credit Card Full Swipe&lt;br /&gt;
                                        &amp; 3000 On Credit Card EMI &amp; 3000 On UPI&lt;br /&gt;
&lt;br /&gt;
A partner scanning the card should see the whole offer, not just its best number.&lt;br /&gt;
Brand keeps its catalog casing (Samsung, not SAMSUNG). A scheme-only offer is still&lt;br /&gt;
titled by its scheme - calling it a cashback offer is what produced the live&lt;br /&gt;
&apos;Cashback Offer- NA&apos; badges.&lt;br /&gt;
&lt;br /&gt;
Detail additions:&lt;br /&gt;
- the EMI scheme, when the circular gave one: &apos;... Low Cost EMI on 3, 6 months.&apos;&lt;br /&gt;
  The circular states it in its own column (&apos;3m,6m LCE&apos; beside &apos;3000 CC Full&lt;br /&gt;
  Swipe/CC EMI/UPI&apos;) and a partner needs both halves.&lt;br /&gt;
- eligible tenures on an EMI benefit: &apos;Rs.3,000 on Credit Card EMI (3, 6 months)&apos;.&lt;br /&gt;
  Cashback &apos;on Credit Card EMI&apos; is not actionable without knowing which tenures&lt;br /&gt;
  qualify. Full Swipe and UPI carry no tenure, so they get none.&lt;br /&gt;
&lt;br /&gt;
⚠️ A scheme is stated ONLY when the circular gave one. Tenures with no scheme are&lt;br /&gt;
described as nothing at all - naming them would read as a no-cost or low-cost claim&lt;br /&gt;
that was never made.&lt;br /&gt;
&lt;br /&gt;
Tests 14 -&gt; 16.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/WebOfferSyncServiceTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37572</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37572</guid></item>
<item><pubDate>Thu, 10 Sep 2026 12:34:19 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37571 – offer circular: the month unit was swallowing the EMI scheme ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;offer circular: the month unit was swallowing the EMI scheme marker&lt;br /&gt;
&lt;br /&gt;
&apos;M&apos; is the month UNIT, not a separator, but the token loop flushed on it. &apos;3m,6m LCE&apos;&lt;br /&gt;
tokenises to 3, M, 6, M, LCE - each M banked its month as NONE, so the LCE arrived&lt;br /&gt;
with nothing pending and was silently lost.&lt;br /&gt;
&lt;br /&gt;
74 Sep&apos;26 offers carry a scheme in the tenure cell that never reached offer_tenure;&lt;br /&gt;
22 of them through this path (&apos;3m,6m LCE&apos;, &apos;6m,9m LCE&apos;, &apos;3m &amp; 6m LCE&apos;, &apos;3m, 6m, 9m,&lt;br /&gt;
12m, 18m, 24m LCE&apos;). The rest are bare &apos;CIB&apos; cells with no months at all, which is a&lt;br /&gt;
separate case and left alone.&lt;br /&gt;
&lt;br /&gt;
It also fixes &apos;3M (NCE), 6M &amp; Above LCE&apos;, where the M flushed BOTH groups before&lt;br /&gt;
either marker was seen - so an offer that is no-cost on 3 months and low-cost beyond&lt;br /&gt;
recorded neither.&lt;br /&gt;
&lt;br /&gt;
This is money: no-cost EMI costs the customer nothing and low-cost does not, so a lost&lt;br /&gt;
marker is a term a partner could quote wrongly at the counter.&lt;br /&gt;
&lt;br /&gt;
Months with no marker anywhere still bank as NONE via the end-of-cell flush - the same&lt;br /&gt;
answer the M branch used to give for a genuinely unmarked cell.&lt;br /&gt;
&lt;br /&gt;
New TenureParserTest, 6 cases, covering the regression and the shapes that must not&lt;br /&gt;
change.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/TenureParser.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/TenureParserTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37571</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37571</guid></item>
<item><pubDate>Wed, 09 Sep 2026 13:34:48 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37554 – web offer: put the brand back in the title  ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer: put the brand back in the title&lt;br /&gt;
&lt;br /&gt;
  SEPTEMBER 2026 MOTOROLA Rs.1,000 cashback on Credit Card Full Swipe&lt;br /&gt;
  SEPTEMBER 2026 MOTOROLA No Cost EMI on 3, 6 months&lt;br /&gt;
&lt;br /&gt;
Month and brand now both match the convention of the 3,850 hand-written rows, which&lt;br /&gt;
is how the admin listing is scanned. What stays gone is the redundant&lt;br /&gt;
&apos;Cashback Offer-&apos; label: the value already states what the offer is, and calling a&lt;br /&gt;
scheme-only row a cashback offer is what produced the live &apos;Cashback Offer- NA&apos;&lt;br /&gt;
badges on 81 SKUs.&lt;br /&gt;
&lt;br /&gt;
Brand comes from the division&apos;s catalog brand, falling back to its display name, so&lt;br /&gt;
a division with no catalog.brand row (Google) still reads sensibly rather than&lt;br /&gt;
emitting an empty gap.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/WebOfferSyncServiceTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37554</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37554</guid></item>
<item><pubDate>Wed, 09 Sep 2026 12:42:06 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37551 – web offer: keep the month in the title   ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer: keep the month in the title&lt;br /&gt;
&lt;br /&gt;
  SEPTEMBER 2026 Up to Rs.4,000 cashback&lt;br /&gt;
  SEPTEMBER 2026 Rs.1,500 cashback on Credit Card EMI&lt;br /&gt;
  SEPTEMBER 2026 No Cost EMI on 3, 6 months&lt;br /&gt;
&lt;br /&gt;
Matches the convention of the 3,850 hand-written rows and is how the admin listing is&lt;br /&gt;
scanned. The brand stays out - the product card already shows it, so that was the&lt;br /&gt;
redundant half, and dropping it is what makes room for the value to lead.&lt;br /&gt;
&lt;br /&gt;
The month comes from the OFFER&apos;s own start date, not the circular&apos;s period: offers&lt;br /&gt;
run past a month end - four Aug&apos;26 Apple offers ran to 26 September - and labelling&lt;br /&gt;
one of those AUGUST on a badge read in September would be wrong.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/WebOfferSyncServiceTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37551</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37551</guid></item>
<item><pubDate>Wed, 09 Sep 2026 12:37:13 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37550 – web offer: partner-facing titles, and stop calling a scheme offer ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 3 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer: partner-facing titles, and stop calling a scheme offer a cashback offer&lt;br /&gt;
&lt;br /&gt;
web_offer.title is partner-facing - StoreController and DealsController map it into&lt;br /&gt;
the product&apos;s offer list - so it now leads with the value rather than a filing label:&lt;br /&gt;
&lt;br /&gt;
  Up to Rs.4,000 cashback&lt;br /&gt;
  Rs.1,500 cashback on Credit Card EMI&lt;br /&gt;
  10% cashback up to Rs.7,500 on Credit Card EMI&lt;br /&gt;
  No Cost EMI on 3, 6 months&lt;br /&gt;
&lt;br /&gt;
Month and brand are gone: the card already shows the product, and the offer carries&lt;br /&gt;
its own dates. The full breakdown sits in detailedText below it.&lt;br /&gt;
&lt;br /&gt;
This fixes a live defect. 16 published offers have no cashback at all, and the old&lt;br /&gt;
template rendered them &apos;SEPTEMBER 2026 XIAOMI Cashback Offer- NA&apos; with detail &apos;NA&apos;,&lt;br /&gt;
on 81 SKUs. They are EMI-scheme offers and now say so.&lt;br /&gt;
&lt;br /&gt;
Scheme inference at ingest: Motorola states the scheme in the DESCRIPTION rather than&lt;br /&gt;
the tenure cell - &apos;[3&amp;6 M]&apos; plus &apos;Only NCEMI&apos;, where every other OEM writes&lt;br /&gt;
&apos;6(NCE),9,12(LCE)&apos;. TenureParser is right to return NONE for such a cell; the scheme&lt;br /&gt;
is simply not in it. Recovered in CircularIngestService where both columns are in&lt;br /&gt;
hand, and deliberately narrow: only when EVERY tenure came back without a scheme AND&lt;br /&gt;
the description names exactly one. On Sep&apos;26 that is 10 offers, all Motorola; the&lt;br /&gt;
other 23 scheme-less rows are cashback offers whose descriptions are amounts, and&lt;br /&gt;
inventing a scheme for those would misstate the terms.&lt;br /&gt;
&lt;br /&gt;
This distinction is money: four of the Motorola rows are LOW cost EMI, and calling&lt;br /&gt;
them no-cost would promise a partner something the bank will not honour.&lt;br /&gt;
&lt;br /&gt;
&apos;No cashback.&apos; is dropped everywhere - the absence of an amount says it, and beside a&lt;br /&gt;
Cashback Instant Benefit scheme it flatly contradicted the name.&lt;br /&gt;
&lt;br /&gt;
Tests 8 -&gt; 12.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/CircularIngestService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/WebOfferSyncServiceTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37550</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37550</guid></item>
<item><pubDate>Tue, 08 Sep 2026 19:39:29 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37546 – web offer sync: compose detailed text from the parsed offer ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer sync: compose detailed text from the parsed offer&lt;br /&gt;
&lt;br /&gt;
detailedText is now built from benefit_timing + offer_benefit + offer_bank instead&lt;br /&gt;
of copying the circular&apos;s line:&lt;br /&gt;
&lt;br /&gt;
  Instant cashback. Rs.4,000 on Credit Card EMI; Rs.3,000 on Credit Card Full&lt;br /&gt;
  Swipe. Banks: Axis Bank, ICICI Bank, State Bank of India (credit cards)&lt;br /&gt;
&lt;br /&gt;
Every payment mode is always named, even when the circular&apos;s prose is terse&lt;br /&gt;
(&apos;10% CC EMI&apos;), and the amounts come from offer_benefit - the authoritative&lt;br /&gt;
per-mode source. CC/DC cannot leak here at all, because the mode codes expand&lt;br /&gt;
natively rather than being patched by find-and-replace.&lt;br /&gt;
&lt;br /&gt;
Three cases that would otherwise read badly:&lt;br /&gt;
- 21 offers carry NO benefit (circular cell &apos;NA&apos;, timing NONE). They are tenure-only&lt;br /&gt;
  offers, so they read &apos;No-cost EMI. No cashback.&apos; rather than showing a blank badge.&lt;br /&gt;
- The bank columns often list a bank under both card types while only one carries a&lt;br /&gt;
  benefit. Card types shown are restricted to those actually paid on, or the text&lt;br /&gt;
  would imply a debit offer that does not exist.&lt;br /&gt;
- benefit_timing UPI and NONE are not timings. Nothing is asserted rather than&lt;br /&gt;
  inventing one.&lt;br /&gt;
&lt;br /&gt;
smallText keeps the circular&apos;s short line - that column is only VARCHAR(256) and the&lt;br /&gt;
composed detail runs past it. One flowing paragraph, no line breaks, since the badge&lt;br /&gt;
may not render them.&lt;br /&gt;
&lt;br /&gt;
Tests 8 -&gt; 14.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/WebOfferSyncServiceTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37546</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37546</guid></item>
<item><pubDate>Tue, 08 Sep 2026 16:39:19 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37544 – web offer sync: expand CC and DC to Credit Card ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;web offer sync: expand CC and DC to Credit Card and Debit Card&lt;br /&gt;
&lt;br /&gt;
The circular writes &apos;Rs.4000 Cashback on CC EMI&apos;; a partner reading the badge should&lt;br /&gt;
see &apos;Credit Card EMI&apos;. Applied to the title and the small/detailed text together, so&lt;br /&gt;
a badge and its detail never disagree.&lt;br /&gt;
&lt;br /&gt;
Word-bounded and applied BEFORE truncation: an expansion is never cut in half, and&lt;br /&gt;
letters inside a word are untouched - the circular&apos;s cells carry strings like&lt;br /&gt;
&apos;X300 Ext Kit&apos; and &apos;ACCESSORIES&apos;, which an unbounded replace would corrupt.&lt;br /&gt;
&lt;br /&gt;
On Sep&apos;26 this affects 155 of 259 descriptions for CC and 48 for DC.&lt;br /&gt;
&lt;br /&gt;
Two existing expectations updated to the new wording, and two tests added: one for&lt;br /&gt;
the expansion, one asserting DCX and ACCESSORIES survive intact.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/WebOfferSyncServiceTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37544</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37544</guid></item>
<item><pubDate>Thu, 03 Sep 2026 18:22:12 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37531 – offer circular: stop letter-led model names inheriting the previous variant ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;offer circular: stop letter-led model names inheriting the previous variant&lt;br /&gt;
&lt;br /&gt;
A part that is ONLY a memory spec inherits the preceding model name, because Oppo&lt;br /&gt;
writes &apos;RENO 15 PRO 256GB, 512GB&apos; and the second part is not a product. The pattern&lt;br /&gt;
matched too loosely: the optional unit group matched the FIRST letter of a model&lt;br /&gt;
name and the rest fell through the trailing character class, so &apos;G06, G37, G37&lt;br /&gt;
Power&apos; inherited its way to &apos;G06 G37&apos; - two Motorola phones fused into one entity&lt;br /&gt;
that matches no SKU, costing G37 its cashback on five offers.&lt;br /&gt;
&lt;br /&gt;
Requiring a leading digit makes it a memory spec rather than anything that merely&lt;br /&gt;
contains G/T and digits. Realme &apos;GT 7&apos; matches the same way and survived only&lt;br /&gt;
because it never follows a comma.&lt;br /&gt;
&lt;br /&gt;
Same root cause as the word-boundary guards on CAPACITY and MEMORY_PAIR: a digit&lt;br /&gt;
glued to letters belongs to the model name.&lt;br /&gt;
&lt;br /&gt;
ProductNamesTest: 11 -&gt; 12, covering &apos;G06, G37, G37 Power&apos; and &apos;GT 7T, GT 7&apos;.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/ProductNames.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/ProductNamesTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37531</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37531</guid></item>
<item><pubDate>Thu, 03 Sep 2026 18:17:05 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37528 – offer circular: apply the supersede rule on ingest (fofo)  ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 3 file(s) modified&lt;/strong&gt;&lt;br/&gt;offer circular: apply the supersede rule on ingest (fofo)&lt;br /&gt;
&lt;br /&gt;
A published circular now expires still-running offers from earlier circulars, and&lt;br /&gt;
deactivates the web offers they produced, so the same cashback is never current&lt;br /&gt;
twice. The converse also holds: re-ingesting an older circular while a newer one is&lt;br /&gt;
live leaves it expired rather than resurrecting it.&lt;br /&gt;
&lt;br /&gt;
Older offers remain readable as reference - only status changes, never end_date.&lt;br /&gt;
&lt;br /&gt;
Counts appear in the ingest summary as supersededOlderOffers / expiredAsSuperseded&lt;br /&gt;
and, on the web side, supersededOlderMonths / notPublishedSuperseded.&lt;br /&gt;
&lt;br /&gt;
ScopeConfigTest&apos;s stub gains the two new CircularIngestRepository methods - the same&lt;br /&gt;
brittleness the scripts/offer_circular README notes for JdbcIngestRepo.&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/CircularIngestService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/ScopeConfigTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37528</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37528</guid></item>
<item><pubDate>Thu, 03 Sep 2026 17:44:48 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37526 – offer circular: scope config screen, resolve screen, web offer sync ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 17 file(s) modified&lt;/strong&gt;&lt;br/&gt;offer circular: scope config screen, resolve screen, web offer sync (fofo)&lt;br /&gt;
&lt;br /&gt;
Screens (each its own endpoint, under the OFFER CIRCULAR menu):&lt;br /&gt;
- /offerCircularScope - add/edit divisions, take a brand in or out of scope,&lt;br /&gt;
  register label aliases. &apos;Remove&apos; is in_scope=0 + a required reason, never a&lt;br /&gt;
  DELETE: offer.division_id is an FK and the history would go with it.&lt;br /&gt;
- /offerCircularResolve - the product queue, split out of the review screen. The&lt;br /&gt;
  editor was a &amp;lt;td colspan=6&gt; pretending to be a form, which is why it never&lt;br /&gt;
  aligned; it is now master-detail. Naming and Coverage are separate tabs because&lt;br /&gt;
  an alias cannot answer a bundle at all - the coverage panel says so and offers&lt;br /&gt;
  the two answers that ARE safe (ignore, or reclassify as naming).&lt;br /&gt;
&lt;br /&gt;
Ingest:&lt;br /&gt;
- ScopeConfig resolves division aliases and carries the canonical label on&lt;br /&gt;
  Decision. insertOffer and ProductAliases.find use it; offer_raw_row keeps the&lt;br /&gt;
  verbatim label, being the source of truth for re-parsing.&lt;br /&gt;
- CircularIngestRunner publishes to dtr.web_offer after the document is marked&lt;br /&gt;
  PUBLISHED, in its own transaction with exceptions swallowed - a circular that&lt;br /&gt;
  parsed correctly must stay published even if the web sync fails.&lt;br /&gt;
&lt;br /&gt;
Review screen:&lt;br /&gt;
- the ingest summary was a raw Map.toString() inside a nowrap span and ran off&lt;br /&gt;
  the card; now parsed into chips with the drop reasons behind a disclosure.&lt;br /&gt;
&lt;br /&gt;
jsVersion -&gt; 417 (merged with r37525&apos;s 412; cssVersion 53 kept from that commit).&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/config/AppConfig.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/OfferCircularController.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/OfferCircularScopeController.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/CircularIngestRunner.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/CircularIngestService.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/ScopeConfig.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/WebOfferSyncService.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/webapp/resources/js/offer-circular-resolve.js&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/resources/js/offer-circular-review.js&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/webapp/resources/js/offer-circular-scope.js&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/admin.vm&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/include-scripts.vm&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/offer-circular-resolve.vm&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/offer-circular-review.vm&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/offer-circular-scope.vm&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/ScopeConfigTest.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/WebOfferSyncServiceTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37526</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37526</guid></item>
<item><pubDate>Tue, 18 Aug 2026 13:37:58 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37337 – Move offer-circular ingest out of cron and into the portal ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 23 file(s) modified&lt;/strong&gt;&lt;br/&gt;Move offer-circular ingest out of cron and into the portal&lt;br /&gt;
&lt;br /&gt;
The parse now runs in profitmandi-fofo, on a background thread, triggered by the&lt;br /&gt;
upload that produced the document.&lt;br /&gt;
&lt;br /&gt;
Why: splitting one feature across two artifacts with independent deploy cadences&lt;br /&gt;
cost a full day. fofo shipped, cron did not, and a valid upload sat in DRAFT with&lt;br /&gt;
nothing on the server able to parse it - the deployed cron jar contained none of the&lt;br /&gt;
ingest classes. One 9-page PDF a month never justified a batch tier, and the portal&lt;br /&gt;
already ships two PDF stacks, so the isolation argument for keeping PDFBox out was&lt;br /&gt;
weaker than it looked.&lt;br /&gt;
&lt;br /&gt;
- 13 parser classes move verbatim from com.smartdukaan.cron.offercircular to&lt;br /&gt;
  com.spice.profitmandi.web.offercircular. No logic changed.&lt;br /&gt;
- CircularIngestScheduler becomes CircularIngestRunner: the @Scheduled(every 5 min)&lt;br /&gt;
  entry point and the offer.circular.ingest.enabled flag are gone, replaced by a&lt;br /&gt;
  single-threaded daemon executor. All claim, ingest and notification logic is&lt;br /&gt;
  unchanged.&lt;br /&gt;
- Upload hands the document id to the runner AFTER COMMIT, not inline. The DRAFT row&lt;br /&gt;
  is written inside the request transaction; a worker starting immediately would race&lt;br /&gt;
  that commit, find nothing to claim and silently do nothing - which is precisely the&lt;br /&gt;
  stuck-on-DRAFT symptom this change removes.&lt;br /&gt;
- The guarded claim is KEPT even though there is now one trigger. It still stops a&lt;br /&gt;
  double-submit, a second portal node, and a re-ingest racing an in-flight parse.&lt;br /&gt;
- Re-ingest parses immediately instead of queueing for a scheduler.&lt;br /&gt;
- The stall reaper runs when the review screen loads. There is no timer here any&lt;br /&gt;
  more, and a document stranded by a redeploy mid-parse only matters when somebody&lt;br /&gt;
  looks for it - which matters more now the parse lives in the web application.&lt;br /&gt;
- tabula moves to this module with its exclusions intact, as does the&lt;br /&gt;
  dumpCircularClasspath helper the local ingest harness depends on.&lt;br /&gt;
- Screen no longer claims &quot;the ingest job runs every 5 minutes&quot;, which was untrue the&lt;br /&gt;
  moment cron stopped being the route; poll interval 15s -&gt; 3s to match a parse that&lt;br /&gt;
  takes seconds. jsVersion 404 -&gt; 405.&lt;br /&gt;
- offer.circular.review.url added here, since the runner sends that email now.&lt;br /&gt;
&lt;br /&gt;
Verified: full ingest of the Aug&apos;26 circular through the relocated code is identical&lt;br /&gt;
to the reference - 239 offers, 663 products, 279 AUTO_EXACT, 361 benefits, 511&lt;br /&gt;
tenures, 911 bank links. ProductNamesTest 11/11 in its new home.&lt;/div&gt;~ /trunk/profitmandi-fofo/build.gradle&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/config/AppConfig.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/OfferCircularController.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/BankTextParser.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/BenefitParser.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/CatalogIndex.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/CircularExtractor.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/CircularIngestRunner.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/CircularIngestService.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/CircularRow.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/FootnoteParser.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/ProductAliases.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/ProductMatcher.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/ProductNames.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/ScopeConfig.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/SequenceRatio.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/offercircular/TenureParser.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/resources/META-INF/dev.properties&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/resources/META-INF/prod.properties&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/resources/js/offer-circular-review.js&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/offercircular/ProductNamesTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37337</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=37337</guid></item>
<item><pubDate>Fri, 15 May 2026 18:51:49 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 36548 – Monitor type upload: allow duplicate catalog_id (keep first), make dialog ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 3 file(s) modified&lt;/strong&gt;&lt;br/&gt;Monitor type upload: allow duplicate catalog_id (keep first), make dialog scrollable&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/util/CatalogMonitorTypeCsvValidator.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/placement-plan.vm&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/controller/PlacementPlanControllerUploadTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36548</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36548</guid></item>
<item><pubDate>Fri, 01 May 2026 13:44:42 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 36442 – Rename monitor type &apos;normal&apos; to &apos;base&apos; in controller, validator, UI, ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 8 file(s) modified&lt;/strong&gt;&lt;br/&gt;Rename monitor type &apos;normal&apos; to &apos;base&apos; in controller, validator, UI, and tests&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/PlacementPlanController.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/util/CatalogMonitorTypeCsvValidator.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/resources/js/placement-plan.js&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/placement-plan-details.vm&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/placement-plan.vm&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/controller/PlacementPlanControllerUploadTest.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/util/CatalogMonitorTypeCsvValidatorTest.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/test/resources/catalog_monitor_type_10rows.csv&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36442</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36442</guid></item>
<item><pubDate>Wed, 29 Apr 2026 11:26:53 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 36424 – Fix MonitorType enum references: use lowercase values to match DB ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 1 file(s) modified&lt;/strong&gt;&lt;br/&gt;Fix MonitorType enum references: use lowercase values to match DB ENUM definition&lt;/div&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/util/CatalogMonitorTypeCsvValidatorTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36424</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36424</guid></item>
<item><pubDate>Tue, 28 Apr 2026 18:18:16 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 36422 – Fix:MonitorType enum casing — FOCUSED/NORMAL to focused/normal in PlacementPlan test</title><description>&lt;div&gt;&lt;strong&gt;amit – 1 file(s) modified&lt;/strong&gt;&lt;br/&gt;Fix:MonitorType enum casing — FOCUSED/NORMAL to focused/normal in PlacementPlan test&lt;/div&gt;~ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/controller/PlacementPlanControllerUploadTest.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36422</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36422</guid></item>
<item><pubDate>Mon, 27 Apr 2026 14:58:30 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 36404 – Add catalog monitor type upload, sample sheet, Placement Plan UI ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 13 file(s) modified&lt;/strong&gt;&lt;br/&gt;Add catalog monitor type upload, sample sheet, Placement Plan UI tagging (orange/yellow), Today PO csv column, placement-plan-statement.xlsx header coloring&lt;/div&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/ContentController.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/monitors/MonitorController.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/controller/PlacementPlanController.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/main/java/com/spice/profitmandi/web/util/CatalogMonitorTypeCsvValidator.java&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/resources/js/placement-plan.js&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/placement-plan-details.vm&lt;br /&gt;~ /trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/placement-plan.vm&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/controller&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/controller/PlacementPlanControllerUploadTest.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/util&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/java/com/spice/profitmandi/web/util/CatalogMonitorTypeCsvValidatorTest.java&lt;br /&gt;+ /trunk/profitmandi-fofo/src/test/resources/catalog_monitor_type_10rows.csv&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36404</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2F%2Ftrunk%2Fprofitmandi-fofo%2Fsrc%2Ftest%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fweb%2F&amp;isdir=1&amp;rev=36404</guid></item>
</channel></rss>