| Line 82... |
Line 82... |
| 82 |
import com.spice.profitmandi.service.transaction.invoicing.InvoiceService;
|
82 |
import com.spice.profitmandi.service.transaction.invoicing.InvoiceService;
|
| 83 |
import com.spice.profitmandi.service.transaction.scheduled.SDCreditScheduler;
|
83 |
import com.spice.profitmandi.service.transaction.scheduled.SDCreditScheduler;
|
| 84 |
import com.spice.profitmandi.service.user.RetailerService;
|
84 |
import com.spice.profitmandi.service.user.RetailerService;
|
| 85 |
import com.spice.profitmandi.service.wallet.CommonPaymentService;
|
85 |
import com.spice.profitmandi.service.wallet.CommonPaymentService;
|
| 86 |
import com.spice.profitmandi.service.wallet.WalletService;
|
86 |
import com.spice.profitmandi.service.wallet.WalletService;
|
| - |
|
87 |
import com.spice.profitmandi.service.monitors.RbmPerformanceRankingService;
|
| - |
|
88 |
import com.spice.profitmandi.service.warehouse.PoStockApprovalDigestService;
|
| 87 |
import com.spice.profitmandi.service.warehouse.WarehouseInventoryService;
|
89 |
import com.spice.profitmandi.service.warehouse.WarehouseInventoryService;
|
| 88 |
import com.spice.profitmandi.service.warehouse.WarehouseService;
|
90 |
import com.spice.profitmandi.service.warehouse.WarehouseService;
|
| 89 |
import com.spice.profitmandi.common.web.client.HttpClientFactory;
|
91 |
import com.spice.profitmandi.common.web.client.HttpClientFactory;
|
| 90 |
import com.spice.profitmandi.common.web.client.RestClient;
|
92 |
import com.spice.profitmandi.common.web.client.RestClient;
|
| 91 |
import in.shop2020.model.v1.order.OrderStatus;
|
93 |
import in.shop2020.model.v1.order.OrderStatus;
|
| Line 312... |
Line 314... |
| 312 |
private AbmReportSender abmReportSender;
|
314 |
private AbmReportSender abmReportSender;
|
| 313 |
|
315 |
|
| 314 |
@Autowired
|
316 |
@Autowired
|
| 315 |
private SaleRewardService saleRewardService;
|
317 |
private SaleRewardService saleRewardService;
|
| 316 |
|
318 |
|
| - |
|
319 |
@Autowired
|
| - |
|
320 |
private PoStockApprovalDigestService poStockApprovalDigestService;
|
| - |
|
321 |
|
| - |
|
322 |
@Autowired
|
| - |
|
323 |
private RbmPerformanceRankingService rbmPerformanceRankingService;
|
| - |
|
324 |
|
| 317 |
private static final String ACCOUNT_ID = "aZ6flHhrgPIEl18buHdPBdueEN4";
|
325 |
private static final String ACCOUNT_ID = "aZ6flHhrgPIEl18buHdPBdueEN4";
|
| 318 |
private static final String SECRET_KEY = "a7rsX5B4UNNfTTx1-IJ19qdH48BT4YvBKlQJg3n3_KKNe7WWych55g";
|
326 |
private static final String SECRET_KEY = "a7rsX5B4UNNfTTx1-IJ19qdH48BT4YvBKlQJg3n3_KKNe7WWych55g";
|
| 319 |
|
327 |
|
| 320 |
@Autowired
|
328 |
@Autowired
|
| 321 |
private WarehouseInventoryItemRepository warehouseInventoryItemRepository;
|
329 |
private WarehouseInventoryItemRepository warehouseInventoryItemRepository;
|
| Line 1866... |
Line 1874... |
| 1866 |
|
1874 |
|
| 1867 |
public void dailyTrackingReport() throws Exception{
|
1875 |
public void dailyTrackingReport() throws Exception{
|
| 1868 |
locationTrackingService.sendRedesignedReportEmails(LocalDate.now().toString(),LocalDate.now().toString());
|
1876 |
locationTrackingService.sendRedesignedReportEmails(LocalDate.now().toString(),LocalDate.now().toString());
|
| 1869 |
}
|
1877 |
}
|
| 1870 |
|
1878 |
|
| - |
|
1879 |
public void poStockApprovalDailyDigest() throws Exception{
|
| - |
|
1880 |
LOGGER.info("poStockApprovalDailyDigest startTime {}", LocalDateTime.now());
|
| - |
|
1881 |
String summary = poStockApprovalDigestService.sendStockApprovalListForDate(LocalDate.now());
|
| - |
|
1882 |
LOGGER.info("poStockApprovalDailyDigest result: {}", summary);
|
| - |
|
1883 |
}
|
| - |
|
1884 |
/** Test recipient(s) for the RBM ranking probe email. Kept here (not in a config)
|
| - |
|
1885 |
* because this whole flow is a Phase-1 probe — Phase 2 will move recipients into
|
| - |
|
1886 |
* the shipped monthly-email cron. */
|
| - |
|
1887 |
private static final String[] RBM_RANK_PROBE_RECIPIENTS = {
|
| - |
|
1888 |
"ranu.rajput@smartdukaan.com"
|
| - |
|
1889 |
};
|
| - |
|
1890 |
|
| - |
|
1891 |
/**
|
| - |
|
1892 |
* Prints the composite RBM performance ranking for the given month to log
|
| - |
|
1893 |
* AND sends an HTML table by email (direct via googleMailSender — bypasses
|
| - |
|
1894 |
* mail_outbox so dev sends actually deliver). Read-only otherwise: no DB writes.
|
| - |
|
1895 |
* Used to verify the ranking calc reproduces correctly for a completed past
|
| - |
|
1896 |
* month before we wire the monthly-email cron.
|
| - |
|
1897 |
*/
|
| - |
|
1898 |
public void printRbmRankingForMonth(java.time.YearMonth month) {
|
| - |
|
1899 |
LocalDate from = month.atDay(1);
|
| - |
|
1900 |
LocalDate to = month.atEndOfMonth();
|
| - |
|
1901 |
LOGGER.info("[RBM-RANK] === Composite ranking for {} ({} → {}) ===",
|
| - |
|
1902 |
month, from, to);
|
| - |
|
1903 |
List<RbmPerformanceDashboardModel> ranked =
|
| - |
|
1904 |
rbmPerformanceRankingService.buildRanking(from, to);
|
| - |
|
1905 |
LOGGER.info("[RBM-RANK] {} RBMs ranked", ranked.size());
|
| - |
|
1906 |
String header = String.format(
|
| - |
|
1907 |
"%-4s %-25s %6s %8s %8s %10s %8s %6s %8s %8s",
|
| - |
|
1908 |
"RANK", "RBM NAME", "PART", "TALK%", "DRR%",
|
| - |
|
1909 |
"AGING%", ">1L%", "RATE", "RATED%", "SCORE");
|
| - |
|
1910 |
LOGGER.info("[RBM-RANK] {}", header);
|
| - |
|
1911 |
for (RbmPerformanceDashboardModel dm : ranked) {
|
| - |
|
1912 |
double ratedPct = dm.getPartnerCount() > 0
|
| - |
|
1913 |
? dm.getRatingPartnerCount() * 100.0 / dm.getPartnerCount() : 0;
|
| - |
|
1914 |
String rbmName = dm.getRbmName() == null ? "-" : dm.getRbmName();
|
| - |
|
1915 |
if (rbmName.length() > 25) rbmName = rbmName.substring(0, 24) + "…";
|
| - |
|
1916 |
LOGGER.info("[RBM-RANK] {}", String.format(
|
| - |
|
1917 |
"%-4d %-25s %6d %8.1f %8.1f %10.1f %8.1f %6.2f %8.1f %8.2f",
|
| - |
|
1918 |
dm.getRank(), rbmName, dm.getPartnerCount(),
|
| - |
|
1919 |
dm.getTalkPct(), dm.getDrrAchvPct(), dm.getAgingPct(),
|
| - |
|
1920 |
dm.getAbove1LPct(), dm.getPartnerRating(), ratedPct,
|
| - |
|
1921 |
dm.getCompositeScore()));
|
| - |
|
1922 |
}
|
| - |
|
1923 |
LOGGER.info("[RBM-RANK] === End ranking for {} ===", month);
|
| - |
|
1924 |
|
| - |
|
1925 |
// Email the same table so the user can eyeball without tailing logs.
|
| - |
|
1926 |
try {
|
| - |
|
1927 |
sendRbmRankingProbeEmail(month, from, to, ranked);
|
| - |
|
1928 |
} catch (Exception e) {
|
| - |
|
1929 |
LOGGER.error("[RBM-RANK] Email send FAILED (log-only fallback in place): {}", e.getMessage(), e);
|
| - |
|
1930 |
}
|
| - |
|
1931 |
}
|
| - |
|
1932 |
|
| - |
|
1933 |
/** Direct HTML send via googleMailSender — bypasses mail_outbox so dev delivers. */
|
| - |
|
1934 |
private void sendRbmRankingProbeEmail(java.time.YearMonth month, LocalDate from, LocalDate to,
|
| - |
|
1935 |
List<RbmPerformanceDashboardModel> ranked) throws Exception {
|
| - |
|
1936 |
java.time.format.DateTimeFormatter fmt = java.time.format.DateTimeFormatter.ofPattern("MMMM yyyy");
|
| - |
|
1937 |
String monthLabel = month.atDay(1).format(fmt);
|
| - |
|
1938 |
String subject = "RBM Composite Ranking — " + monthLabel + " (" + ranked.size() + " RBMs)";
|
| - |
|
1939 |
|
| - |
|
1940 |
StringBuilder body = new StringBuilder();
|
| - |
|
1941 |
body.append("<p>Composite RBM ranking probe for <b>").append(monthLabel)
|
| - |
|
1942 |
.append("</b> (").append(from).append(" → ").append(to).append(").</p>");
|
| - |
|
1943 |
body.append("<p style='color:#555;font-size:12px'>Score formula: Talk(10%) + DRR(55%) + Aging(2%) + >1L(29%) + Rating(2%) + Rated(2%).</p>");
|
| - |
|
1944 |
body.append("<table border='1' cellpadding='6' cellspacing='0' style='border-collapse:collapse;font-size:12px'>");
|
| - |
|
1945 |
body.append("<thead><tr style='background:#343a40;color:#fff'>")
|
| - |
|
1946 |
.append("<th>Rank</th><th style='text-align:left'>RBM</th><th>Partners</th>")
|
| - |
|
1947 |
.append("<th style='background:#28a745'>Talk%<br><small>(10%)</small></th>")
|
| - |
|
1948 |
.append("<th style='background:#17a2b8'>DRR%<br><small>(55%)</small></th>")
|
| - |
|
1949 |
.append("<th style='background:#fd7e14'>Aging%<br><small>(2%)</small></th>")
|
| - |
|
1950 |
.append("<th style='background:#6f42c1'>>1L%<br><small>(29%)</small></th>")
|
| - |
|
1951 |
.append("<th style='background:#ffc107;color:#000'>Rating<br><small>(2%)</small></th>")
|
| - |
|
1952 |
.append("<th style='background:#e67e22'>Rated%<br><small>(2%)</small></th>")
|
| - |
|
1953 |
.append("<th style='background:#dc3545'>Score</th>")
|
| - |
|
1954 |
.append("</tr></thead><tbody>");
|
| - |
|
1955 |
for (RbmPerformanceDashboardModel dm : ranked) {
|
| - |
|
1956 |
double ratedPct = dm.getPartnerCount() > 0
|
| - |
|
1957 |
? dm.getRatingPartnerCount() * 100.0 / dm.getPartnerCount() : 0;
|
| - |
|
1958 |
String rowStyle = dm.getRank() == 1 ? "background:#fff8e1" :
|
| - |
|
1959 |
dm.getRank() == 2 ? "background:#f5f5f5" :
|
| - |
|
1960 |
dm.getRank() == 3 ? "background:#fff3e0" : "";
|
| - |
|
1961 |
body.append("<tr style='").append(rowStyle).append("'>")
|
| - |
|
1962 |
.append("<td style='text-align:center'>").append(dm.getRank()).append("</td>")
|
| - |
|
1963 |
.append("<td>").append(escapeHtml(dm.getRbmName())).append("</td>")
|
| - |
|
1964 |
.append("<td style='text-align:center'>").append(dm.getPartnerCount()).append("</td>")
|
| - |
|
1965 |
.append("<td style='text-align:right'>").append(String.format("%.1f%%", dm.getTalkPct())).append("</td>")
|
| - |
|
1966 |
.append("<td style='text-align:right'>").append(String.format("%.1f%%", dm.getDrrAchvPct())).append("</td>")
|
| - |
|
1967 |
.append("<td style='text-align:right'>").append(String.format("%.1f%%", dm.getAgingPct())).append("</td>")
|
| - |
|
1968 |
.append("<td style='text-align:right'>").append(String.format("%.1f%%", dm.getAbove1LPct())).append("</td>")
|
| - |
|
1969 |
.append("<td style='text-align:center'>").append(String.format("%.2f", dm.getPartnerRating())).append(" ★</td>")
|
| - |
|
1970 |
.append("<td style='text-align:right'>").append(String.format("%.1f%%", ratedPct)).append("</td>")
|
| - |
|
1971 |
.append("<td style='text-align:right;font-weight:600'>").append(String.format("%.2f", dm.getCompositeScore())).append("</td>")
|
| - |
|
1972 |
.append("</tr>");
|
| - |
|
1973 |
}
|
| - |
|
1974 |
body.append("</tbody></table>");
|
| - |
|
1975 |
body.append("<p style='color:#888;font-size:11px;margin-top:20px'>Phase-1 probe — sent direct (not queued). ")
|
| - |
|
1976 |
.append("Note: for past months, DRR% denominator reads the current month's target snapshot (limitation of the live query).</p>");
|
| - |
|
1977 |
|
| - |
|
1978 |
javax.mail.internet.MimeMessage message = googleMailSender.createMimeMessage();
|
| - |
|
1979 |
org.springframework.mail.javamail.MimeMessageHelper helper =
|
| - |
|
1980 |
new org.springframework.mail.javamail.MimeMessageHelper(message, false, "UTF-8");
|
| - |
|
1981 |
helper.setTo(RBM_RANK_PROBE_RECIPIENTS);
|
| - |
|
1982 |
helper.setSubject(subject);
|
| - |
|
1983 |
helper.setText(body.toString(), true);
|
| - |
|
1984 |
helper.setFrom(new javax.mail.internet.InternetAddress("sdtech@smartdukaan.com", "SmartDukaan Care"));
|
| - |
|
1985 |
googleMailSender.send(message);
|
| - |
|
1986 |
LOGGER.info("[RBM-RANK] Emailed probe to {}", String.join(", ", RBM_RANK_PROBE_RECIPIENTS));
|
| - |
|
1987 |
}
|
| - |
|
1988 |
|
| - |
|
1989 |
private static String escapeHtml(String s) {
|
| - |
|
1990 |
if (s == null || s.isEmpty()) return "-";
|
| - |
|
1991 |
return s.replace("&", "&").replace("<", "<").replace(">", ">")
|
| - |
|
1992 |
.replace("\"", """).replace("'", "'");
|
| - |
|
1993 |
}
|
| - |
|
1994 |
|
| 1871 |
public void setAbmReportSender() throws Exception{
|
1995 |
public void setAbmReportSender() throws Exception{
|
| 1872 |
abmReportSender.abmSendertest();
|
1996 |
abmReportSender.abmSendertest();
|
| 1873 |
}
|
1997 |
}
|
| 1874 |
|
1998 |
|
| 1875 |
public void checkRewardsEligibility() throws Exception {
|
1999 |
public void checkRewardsEligibility() throws Exception {
|