<?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-dao/src/main/java/com/spice/profitmandi/dao/entity/fofo/PartnerInvestment.java</title><description>WebSVN RSS feed &#x2013; SmartDukaan</description><lastBuildDate>Wed, 07 Oct 2026 02:58:05 +0530</lastBuildDate><generator>WebSVN 2.8.6-DEV</generator><language>en</language><link>https://svn.smartdukaan.com/log.php?repname=SmartDukaan&amp;path=%2Ftrunk%2Fprofitmandi-dao%2Fsrc%2Fmain%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fdao%2Fentity%2Ffofo%2FPartnerInvestment.java&amp;max=40&amp;</link><atom:link href="https://svn.smartdukaan.com/rss.php?path=%2Ftrunk%2Fprofitmandi-dao%2Fsrc%2Fmain%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fdao%2Fentity%2Ffofo%2FPartnerInvestment.java&amp;repname=SmartDukaan" rel="self" type="application/rss+xml" />
<item><pubDate>Fri, 11 Sep 2026 20:09:50 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37599 – Reuse the managed snapshot row in the sweep instead of ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 2 file(s) modified&lt;/strong&gt;&lt;br/&gt;Reuse the managed snapshot row in the sweep instead of building a second instance&lt;br /&gt;
&lt;br /&gt;
Every sweep after the first failed with &apos;A different object with the same&lt;br /&gt;
identifier value was already associated with the session :&lt;br /&gt;
PartnerInvestment#107198&apos; and wrote nothing.&lt;br /&gt;
&lt;br /&gt;
selectByFofoIds returns managed entities. The loop then constructed a fresh&lt;br /&gt;
PartnerInvestment for the same id and called saveOrUpdate on it, which Hibernate&lt;br /&gt;
rejects. Sweep one survived only because the table was empty, so no row was&lt;br /&gt;
managed - the failure could not appear until a second run.&lt;br /&gt;
&lt;br /&gt;
Now mutates the row already in the session when there is one, falling back to a&lt;br /&gt;
new instance only for partners with no snapshot. The previous base and gross stock&lt;br /&gt;
are captured before mutation, since comparing the row against itself afterwards&lt;br /&gt;
would report nothing as ever changed.&lt;br /&gt;
&lt;br /&gt;
persist() is kept: a no-op for the managed rows (dirty checking flushes them), and&lt;br /&gt;
still the INSERT for partners appearing between sweeps.&lt;br /&gt;
&lt;br /&gt;
Drops baseDiffersFrom(), now unused - the comparison is against the captured prior&lt;br /&gt;
value, still rounded to paise by the setter on both sides.&lt;/div&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/fofo/PartnerInvestment.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/PartnerInvestmentSweepService.java&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2Ftrunk%2Fprofitmandi-dao%2Fsrc%2Fmain%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fdao%2Fentity%2Ffofo%2FPartnerInvestment.java&amp;rev=37599</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2Ftrunk%2Fprofitmandi-dao%2Fsrc%2Fmain%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fdao%2Fentity%2Ffofo%2FPartnerInvestment.java&amp;rev=37599</guid></item>
<item><pubDate>Fri, 11 Sep 2026 19:19:38 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37592 – Fix live-demo deduction lost in the investment snapshot; maintain aged-Apple ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 8 file(s) modified&lt;/strong&gt;&lt;br/&gt;Fix live-demo deduction lost in the investment snapshot; maintain aged-Apple qty&lt;br /&gt;
&lt;br /&gt;
BUG FIX to r37588. InventoryService.getTotalAmountInStock() returns stock net of&lt;br /&gt;
live-demo units held past 90 days, and both original investment paths assigned&lt;br /&gt;
that netted value to inStockAmount - which is why&lt;br /&gt;
PartnerDailyInvestment.getTotalInvestment() carries no separate demo term. The&lt;br /&gt;
sweep stored the RAW snapshot sum and never applied the deduction, overstating&lt;br /&gt;
investment for 328 partners by Rs 5.19 crore and their limits by roughly Rs 1.3&lt;br /&gt;
crore. Maxwell validated clean earlier only because he holds no demo stock.&lt;br /&gt;
&lt;br /&gt;
Fixed by storing what is measured and deriving what is computed: the column is&lt;br /&gt;
now in_stock_gross_amount and getNetInStockAmount() applies the haircut. The demo&lt;br /&gt;
holding moves on its own daily clock, so storing the netted figure would have&lt;br /&gt;
meant re-netting it in three places every time the haircut changed - the same&lt;br /&gt;
&apos;two things must move together&apos; trap behind the original cache bug. Deriving it&lt;br /&gt;
means a daily demo refresh flows through to stock and base with nothing to sync.&lt;br /&gt;
&lt;br /&gt;
Also:&lt;br /&gt;
- aged_apple_qty stored on the snapshot and maintained on the same daily cycle as&lt;br /&gt;
  aged_apple_stock_amount, so the partner banner reads a saved count instead of&lt;br /&gt;
  running a count query per dashboard load, and count and value can never disagree&lt;br /&gt;
- selectPartnerStockCountMap mirrors selectPartnerStockValueMap, including the&lt;br /&gt;
  activated exclusion&lt;br /&gt;
- selectAgedAppleStock lists the units behind the haircut for the partner view&lt;br /&gt;
- FofoUser exposes aged_apple_stock / aged_apple_qty&lt;br /&gt;
- stock-moved detection compares GROSS: a demo unit crossing 90 days changes net&lt;br /&gt;
  stock but nothing physically moved, and that is the daily refresh&apos;s job&lt;br /&gt;
&lt;br /&gt;
Schema: partner_investment_snapshot.sql updated (in_stock_gross_amount,&lt;br /&gt;
aged_apple_qty). Applied to prod - the table was empty, so it was dropped and&lt;br /&gt;
recreated from the script.&lt;/div&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/fofo/PartnerDailyInvestment.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/fofo/PartnerInvestment.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/fofo/InventoryItemRepository.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/fofo/InventoryItemRepositoryImpl.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/FofoUser.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/PartnerInvestmentServiceImpl.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/PartnerInvestmentSweepService.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/resources/sql/partner_investment_snapshot.sql&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2Ftrunk%2Fprofitmandi-dao%2Fsrc%2Fmain%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fdao%2Fentity%2Ffofo%2FPartnerInvestment.java&amp;rev=37592</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2Ftrunk%2Fprofitmandi-dao%2Fsrc%2Fmain%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fdao%2Fentity%2Ffofo%2FPartnerInvestment.java&amp;rev=37592</guid></item>
<item><pubDate>Fri, 11 Sep 2026 17:29:49 +0530</pubDate><dc:creator>amit</dc:creator><title>Rev 37588 – Serve partner investment from a 2-minute snapshot instead of a ...</title><description>&lt;div&gt;&lt;strong&gt;amit – 17 file(s) modified&lt;/strong&gt;&lt;br/&gt;Serve partner investment from a 2-minute snapshot instead of a 3-hour cache&lt;br /&gt;
&lt;br /&gt;
getInvestment() was @Cacheable on a 3-hour Redis cache that addAmountToWallet&lt;br /&gt;
evicted but consumeAmountFromWallet did not. A partner whose advance payment was&lt;br /&gt;
swept straight to a loan had the money counted twice - once as a still-cached&lt;br /&gt;
wallet balance, once as the reduced utilisation - overstating their credit limit&lt;br /&gt;
by the payment x their tier until the cache expired.&lt;br /&gt;
&lt;br /&gt;
Replaced with fofo.partner_investment, refreshed every 2 minutes by&lt;br /&gt;
PartnerInvestmentSweepService. Every coupled term is read in one pass, so wallet&lt;br /&gt;
and utilisation (and in-stock and aged-Apple) can never come from different&lt;br /&gt;
moments. A shorter TTL would only have made the error rarer - it scales with the&lt;br /&gt;
payment, not the delay.&lt;br /&gt;
&lt;br /&gt;
- PartnerInvestment entity/repository + partner_investment_snapshot.sql&lt;br /&gt;
- PartnerInvestmentSweepService: 9 batched reads, stores base_value for change&lt;br /&gt;
  detection, refreshes aged-Apple for partners whose stock moved intra-day&lt;br /&gt;
- getInvestment/getInvestmentsForFofoStores both read the snapshot, so the two&lt;br /&gt;
  paths no longer disagree; live compute retained as fallback&lt;br /&gt;
- selectActivatedStockAmountByFofoIds: batches an N+1 that cost 233ms x 1690&lt;br /&gt;
  partners (6.6 min -&gt; 1.0 s)&lt;br /&gt;
- getFirstBillingDates: batches another N+1 (4.6 s -&gt; 0.67 s)&lt;br /&gt;
- selectPendingGrnOrders(List) now applies the same SD_START_DATE floor as the&lt;br /&gt;
  single-partner overload; the two were reporting different GRN-pending&lt;br /&gt;
- selectPartnerStockValueMap takes excludeActivated: an activated Apple handset&lt;br /&gt;
  held past the aging window was added once to in-stock and subtracted twice&lt;br /&gt;
  (activated stock, then the aged haircut). 90 units, 24 partners, Rs 65.19 lakh&lt;br /&gt;
  double-deducted. Live-demo passes false - no overlap there.&lt;br /&gt;
- applyManualAdjustment: routes the two hand-rolled admin wallet adjustments&lt;br /&gt;
  through WalletServiceImpl so they take the FOR UPDATE lock&lt;br /&gt;
- add_idx_order_grn_pending.sql: covering index, GRN query 1320ms -&gt; 514ms&lt;/div&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/fofo/InventoryItem.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/fofo/PartnerInvestment.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/entity/transaction/Order.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/fofo/InventoryItemRepository.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/fofo/InventoryItemRepositoryImpl.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/fofo/PartnerInvestmentRepository.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/fofo/PartnerInvestmentRepositoryImpl.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/transaction/OrderRepositoryImpl.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/transaction/TransactionRepository.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/transaction/TransactionRepositoryImpl.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/inventory/InventoryServiceImpl.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/PartnerInvestmentServiceImpl.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/PartnerInvestmentSweepService.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/wallet/WalletService.java&lt;br /&gt;~ /trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/wallet/WalletServiceImpl.java&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/resources/sql/add_idx_order_grn_pending.sql&lt;br /&gt;+ /trunk/profitmandi-dao/src/main/resources/sql/partner_investment_snapshot.sql&lt;br /&gt;</description><link>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2Ftrunk%2Fprofitmandi-dao%2Fsrc%2Fmain%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fdao%2Fentity%2Ffofo%2FPartnerInvestment.java&amp;rev=37588</link><guid>https://svn.smartdukaan.com/revision.php?repname=SmartDukaan&amp;path=%2Ftrunk%2Fprofitmandi-dao%2Fsrc%2Fmain%2Fjava%2Fcom%2Fspice%2Fprofitmandi%2Fdao%2Fentity%2Ffofo%2FPartnerInvestment.java&amp;rev=37588</guid></item>
</channel></rss>