| Rev |
Age |
Author |
Path |
Log message |
Diff |
| 37379 |
30 m |
amit |
/trunk/profitmandi-common/ |
Restore insurance lines on invoice PDFs dropped by the r37066 renderer refactor
The modular doc-generation extraction moved the item table into ItemsTableSection,
which iterates only DocumentData.items() -> model.getOrderItems(). The legacy
renderer also emitted a row per CustomInsurancePolicy (PdfUtils r36674, lines
241-261); that block was lost in the extraction and nothing consumed
getInsurancePolicies() any more.
Effect: an extended-warranty policy is not a catalog item, so it has no
fofo_order_item row. Insurance sold after the device sale gets its own invoice
whose only line is the policy, so the whole table came out empty and the totals
- which SummarySection derives from the table, not from FofoOrder.totalAmount -
printed as 0.00 / 'Zero Rupees Only' (e.g. HRJND1424/94). On a combined
device+insurance invoice the policy line vanished silently and the invoice total
and GST were understated by the premium. InsuranceController's insurer document
pack, whose model carries policies and no order items at all, hit an NPE.
Fold the policies in at DocumentData.items(), the single accessor every section
reads, so the fix covers all callers at once. Column mapping mirrors the legacy
renderer: quantity 1, no discount, taxable value repeated in the Rate column.
Only the applicable tax side is populated (CGST/SGST or IGST) rather than both
as the policy model carries them, matching how real order items are built, so
ItemsTableSection's taxAmount = cgst+sgst+igst stays correct on margin-scheme
invoices. With no policies the model's own list is returned untouched.
Tests: InsuranceInvoiceRenderTest asserts on extracted PDF text (insurance-only,
intra/inter-state GST split, combined invoice, and a no-insurance control), so it
holds on any machine unlike the pixel goldens; three golden baselines added.
Verified all 14 pre-existing golden fixtures render byte-identical before and
after.
Also set java.awt.headless=true on the test JVM: the golden harness rasterizes
through PDFBox, whose font handling calls
GraphicsEnvironment.getLocalGraphicsEnvironment() and made the forked JVM attach
to the macOS window server as a Foreground app, stealing focus on every run.
Test-only property, no effect on the built war. |
|
| 37378 |
1 h 26 m |
amit |
/trunk/profitmandi-fofo/src/main/ |
Put the action-pending returns at the top of Sale Returns, and filter by partner
Sorting the received list pending-first changed nothing on screen, because every return
that still needs an action was missing from it. The list was built from purchase return
orders inside the date window, and a return order only exists once the warehouse has
received the goods - so a debit note awaiting receipt had no row to sort, and a return
sitting unrefunded for weeks fell out of the window entirely.
The screen is now two lists:
- Action Pending, on top, with no date bound. It merges the three shapes a pending return
takes - a debit note never received, a return order received but unrefunded, and one
rejected but not yet acknowledged - into a single row type, oldest first, with the age
in days beside it. Each row carries only the action that actually applies to it
- Settled Returns below, refunded and cancelled only, still bound to From/To. The pending
rows were lifted out of it, so nothing is listed twice
Two things worth recording:
- a debit note has no warehouse of its own. It is placed through the item's invoice and
the order that invoice was raised on, and a note that cannot be placed is dropped rather
than shown to a warehouse it may not belong to
- debit notes raised before the receive/refund flow existed were settled the old way and
cannot be worked from this screen. The cutoff is read from the earliest return order in
the database, so it needs no maintenance, and the page says so in a footnote instead of
quietly hiding them
The partner filter reuses the shared /partners typeahead and passes the id down into both
queries. Only a picked suggestion filters, so a half-typed name cannot blank the page. Its
handlers sit inline in the template, next to the markup they drive, following the pattern
add-wallet-request.vm already uses - which leaves the now-unused #invoice-return-date-apply
handler in return.js dead, to be removed with the return.js work already in flight.
Rendered offline through Velocity with the app's own directive.set.null.allowed to confirm
all four action variants emit the right buttons. |
|
| 37377 |
1 h 27 m |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/repository/fofo/ |
Queries behind the Sale Returns action-pending queue
The Sale Returns screen could only ever list purchase return orders received inside the
chosen date window, which left the returns that actually need someone unreachable: a
return order is written at receive time, so a debit note the warehouse has not received
yet has no return order at all and could not appear however the list was sorted.
- selectPendingByWarehouseIds returns every unsettled return order with no date bound -
received but unrefunded, or rejected but not yet acknowledged by the retailer. A return
nobody acted on only gets older, so bounding it by date is what buried it
- selectUnreceivedSince finds debit notes with no return order against them, which is the
only place a not-yet-received return exists. Cancelled notes are excluded
- selectEarliestCreateTimestamp exposes when the receive/refund flow went live. Notes
raised before the first return order ever recorded were settled through the older
item-level flow and are not a queue anyone can work, so the caller uses this to bound
the lookup off the data rather than off a date pinned in code
- both listing queries now take an optional fofoId, so the partner filter is a predicate
rather than a post-filter - filtering after the 200 row cap would silently drop a
partner's older rows
Counts on live data: 6 unsettled return orders, 24 unreceived debit notes since the flow
started, against 5,618 older notes correctly left out. |
|
| 37376 |
20 h 17 m |
ranu |
/trunk/profitmandi-fofo/src/main/webapp/WEB-INF/views/ftl/ |
total show on warehouse wise stock value on item detail |
|
| 37375 |
20 h 21 m |
ranu |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/dao/ |
total show on warehouse wise stock value on item detail |
|
| 37374 |
21 h 6 m |
ranu |
/trunk/ |
total show on warehouse wise stock value on item detail |
|
| 37373 |
1 d 0 h |
vikas |
/trunk/profitmandi-web/src/main/java/com/spice/profitmandi/web/v2/controller/ |
Active Scratch Offers |
|
| 37372 |
1 d 2 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/common/util/ |
Fixed mail sender everywhere |
|
| 37371 |
1 d 2 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/gstpro/ |
Fixed mail sender everywhere |
|
| 37370 |
1 d 3 h |
amit |
/trunk/profitmandi-dao/src/main/java/com/spice/profitmandi/service/integrations/gstpro/ |
Fixed mail sender everywhere |
|
| 37369 |
1 d 4 h |
amit |
/trunk/ |
Fixed mail sender everywhere |
|
| 37368 |
1 d 19 h |
amit |
/trunk/profitmandi-cron/src/main/ |
Cron: raise SMTP timeouts, rotate app password, add offer-circular ingest keys
- SMTP 10s -> 30s connect / 120s read-write on both senders; the 10s read timeout was
cutting off larger attachment sends. App password rotated to match the current
Google account credential.
- offer.circular.ingest.enabled / offer.circular.review.url added to dev, staging and
prod. Off by default in all three: enabling it makes the job pick up DRAFT circulars
uploaded from the FOFO portal, parse them and mail the uploader, which should only be
switched on once offer.circular.dir is a real path in that environment. There is no
fallback between profiles, so the key has to exist in each one. |
|
| 37367 |
1 d 19 h |
amit |
/trunk/profitmandi-web/src/main/ |
Mail: raise SMTP timeouts and rotate the sdtech app password
The 10s read timeout was cutting off larger attachment sends (policy PDFs, invoice
attachments) and surfacing as a send failure the outbox then retried. Raised to 30s
connect / 120s read-write on both senders. App password rotated to match the current
Google account credential.
Also fills in new.solr.url and store.app.url in staging.properties - staging carries no
fallback to dev/prod, so a missing key stops the context from starting. |
|
| 37366 |
1 d 19 h |
amit |
/trunk/profitmandi-fofo/src/main/resources/META-INF/ |
Staging config: fill in the keys fofo needs to start on staging
staging.properties is much thinner than dev/prod and there is no fallback between
profiles - a missing key stops the context from starting. Adds react.app.url (no
dedicated staging build of the react partner app exists, so it points at the prod
host), app.token.url (profitmandi-web is co-deployed on the same Tomcat there) and
media.document.url. |
|
| 37365 |
1 d 19 h |
amit |
/trunk/profitmandi-fofo/src/main/ |
Debit note receive: surface the partner-declared condition and warn before rejecting
The receive screen defaulted every row's condition to GOOD regardless of what the
partner declared, so a warehouse user could not see what they were disagreeing with -
and the backend treats any disagreement as a rejection of the whole debit note.
- Show 'Declared By Partner' per row and preselect the condition to match it, so
submitting unchanged is a genuine agreement rather than an accident of the default.
- A changed row now switches the submit button to 'Reject Return', shows what rejection
means (no refund; partner, Logistics, RBM and Sales notified), makes the remark
mandatory and confirms before posting.
- SMTP timeouts raised to 30s connect / 120s read-write; the 10s read timeout was
cutting off larger attachment sends.
- jsVersion 405 -> 406 for the return.js change. |
|
| 37364 |
1 d 19 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 |
1 d 19 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 |
1 d 19 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 |
1 d 19 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 |
1 d 19 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. |
|