| Line 4... |
Line 4... |
| 4 |
import com.spice.profitmandi.common.model.BulkOrderModel;
|
4 |
import com.spice.profitmandi.common.model.BulkOrderModel;
|
| 5 |
import com.spice.profitmandi.common.model.LineItemModel;
|
5 |
import com.spice.profitmandi.common.model.LineItemModel;
|
| 6 |
import com.spice.profitmandi.common.model.ProfitMandiConstants;
|
6 |
import com.spice.profitmandi.common.model.ProfitMandiConstants;
|
| 7 |
import com.spice.profitmandi.common.model.TransactionApprovalModel;
|
7 |
import com.spice.profitmandi.common.model.TransactionApprovalModel;
|
| 8 |
import com.spice.profitmandi.common.util.ExcelUtils;
|
8 |
import com.spice.profitmandi.common.util.ExcelUtils;
|
| - |
|
9 |
import com.spice.profitmandi.common.util.Utils;
|
| 9 |
import com.spice.profitmandi.dao.cart.CartService;
|
10 |
import com.spice.profitmandi.dao.cart.CartService;
|
| 10 |
import com.spice.profitmandi.dao.entity.auth.AuthUser;
|
11 |
import com.spice.profitmandi.dao.entity.auth.AuthUser;
|
| 11 |
import com.spice.profitmandi.dao.entity.catalog.Bid;
|
12 |
import com.spice.profitmandi.dao.entity.catalog.Bid;
|
| 12 |
import com.spice.profitmandi.dao.entity.catalog.Item;
|
13 |
import com.spice.profitmandi.dao.entity.catalog.Item;
|
| 13 |
import com.spice.profitmandi.dao.entity.catalog.TagListing;
|
14 |
import com.spice.profitmandi.dao.entity.catalog.TagListing;
|
| Line 15... |
Line 16... |
| 15 |
import com.spice.profitmandi.dao.entity.fofo.LoanTransaction;
|
16 |
import com.spice.profitmandi.dao.entity.fofo.LoanTransaction;
|
| 16 |
import com.spice.profitmandi.dao.entity.transaction.LineItem;
|
17 |
import com.spice.profitmandi.dao.entity.transaction.LineItem;
|
| 17 |
import com.spice.profitmandi.dao.entity.transaction.Order;
|
18 |
import com.spice.profitmandi.dao.entity.transaction.Order;
|
| 18 |
import com.spice.profitmandi.dao.entity.transaction.Transaction;
|
19 |
import com.spice.profitmandi.dao.entity.transaction.Transaction;
|
| 19 |
import com.spice.profitmandi.dao.entity.transaction.TransactionApproval;
|
20 |
import com.spice.profitmandi.dao.entity.transaction.TransactionApproval;
|
| - |
|
21 |
import com.spice.profitmandi.dao.entity.user.StoreTimelinetb;
|
| - |
|
22 |
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
|
| - |
|
23 |
import com.spice.profitmandi.dao.enumuration.dtr.StoreTimeline;
|
| 20 |
import com.spice.profitmandi.dao.enumuration.transaction.TransactionApprovalStatus;
|
24 |
import com.spice.profitmandi.dao.enumuration.transaction.TransactionApprovalStatus;
|
| 21 |
import com.spice.profitmandi.dao.model.CartItem;
|
25 |
import com.spice.profitmandi.dao.model.CartItem;
|
| 22 |
import com.spice.profitmandi.dao.model.UserCart;
|
26 |
import com.spice.profitmandi.dao.model.UserCart;
|
| 23 |
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
|
27 |
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
|
| 24 |
import com.spice.profitmandi.dao.repository.catalog.BidRepository;
|
28 |
import com.spice.profitmandi.dao.repository.catalog.BidRepository;
|
| Line 47... |
Line 51... |
| 47 |
import org.apache.poi.ss.usermodel.Row;
|
51 |
import org.apache.poi.ss.usermodel.Row;
|
| 48 |
import org.apache.poi.xssf.usermodel.XSSFRow;
|
52 |
import org.apache.poi.xssf.usermodel.XSSFRow;
|
| 49 |
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
53 |
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
| 50 |
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
54 |
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
| 51 |
import org.springframework.beans.factory.annotation.Autowired;
|
55 |
import org.springframework.beans.factory.annotation.Autowired;
|
| - |
|
56 |
import org.springframework.mail.javamail.JavaMailSender;
|
| 52 |
import org.springframework.stereotype.Service;
|
57 |
import org.springframework.stereotype.Service;
|
| 53 |
import org.springframework.transaction.annotation.Transactional;
|
- |
|
| 54 |
import org.springframework.web.multipart.MultipartFile;
|
58 |
import org.springframework.web.multipart.MultipartFile;
|
| 55 |
|
59 |
|
| 56 |
import java.math.BigDecimal;
|
60 |
import java.math.BigDecimal;
|
| 57 |
import java.time.LocalDateTime;
|
61 |
import java.time.LocalDateTime;
|
| 58 |
import java.util.ArrayList;
|
62 |
import java.util.ArrayList;
|
| Line 111... |
Line 115... |
| 111 |
com.spice.profitmandi.dao.repository.user.UserRepository user_userRepository;
|
115 |
com.spice.profitmandi.dao.repository.user.UserRepository user_userRepository;
|
| 112 |
|
116 |
|
| 113 |
@Autowired
|
117 |
@Autowired
|
| 114 |
FofoStoreRepository fofoStoreRepository;
|
118 |
FofoStoreRepository fofoStoreRepository;
|
| 115 |
|
119 |
|
| - |
|
120 |
@Autowired
|
| - |
|
121 |
JavaMailSender mailSender;
|
| - |
|
122 |
|
| - |
|
123 |
@Autowired
|
| - |
|
124 |
com.spice.profitmandi.service.user.StoreTimelineTatService storeTimelineTatService;
|
| - |
|
125 |
|
| - |
|
126 |
@Autowired
|
| - |
|
127 |
com.spice.profitmandi.dao.repository.dtr.PartnerOnBoardingPanelRepository partnerOnBoardingPanelRepository;
|
| - |
|
128 |
|
| - |
|
129 |
@Autowired
|
| - |
|
130 |
com.spice.profitmandi.dao.repository.user.StoreTimelinetbRepository storeTimelinetbRepository;
|
| - |
|
131 |
|
| 116 |
|
132 |
|
| 117 |
public void parseBulkOrders(MultipartFile file, int creatorId) throws Exception {
|
133 |
public void parseBulkOrders(MultipartFile file, int creatorId) throws Exception {
|
| 118 |
XSSFWorkbook myWorkBook = new XSSFWorkbook(file.getInputStream());
|
134 |
XSSFWorkbook myWorkBook = new XSSFWorkbook(file.getInputStream());
|
| 119 |
|
135 |
|
| 120 |
myWorkBook.setMissingCellPolicy(Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
|
136 |
myWorkBook.setMissingCellPolicy(Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
|
| Line 254... |
Line 270... |
| 254 |
}
|
270 |
}
|
| 255 |
}
|
271 |
}
|
| 256 |
|
272 |
|
| 257 |
LOGGER.info("finalBidStatus: {}",finalBidStatus);
|
273 |
LOGGER.info("finalBidStatus: {}",finalBidStatus);
|
| 258 |
if (finalBidStatus.equals(ProfitMandiConstants.BID_ENUM.CLOSED)) {
|
274 |
if (finalBidStatus.equals(ProfitMandiConstants.BID_ENUM.CLOSED)) {
|
| - |
|
275 |
// Check if this is the first PO for this partner (before creating the new transaction)
|
| - |
|
276 |
List<Transaction> existingTransactions = transactionRepository.selectByRetailerId(fofoId);
|
| - |
|
277 |
boolean isFirstPO = (existingTransactions == null || existingTransactions.isEmpty());
|
| - |
|
278 |
|
| - |
|
279 |
// Block first PO if FULL_STOCK_PAYMENT is not done (for LOI-flow partners only)
|
| - |
|
280 |
if (isFirstPO && fofoStore != null && !fofoStore.isInternal() && fofoStore.getCode() != null) {
|
| - |
|
281 |
com.spice.profitmandi.dao.entity.fofo.PartnerOnBoardingPanel pob =
|
| - |
|
282 |
partnerOnBoardingPanelRepository.selectByCode(fofoStore.getCode());
|
| - |
|
283 |
if (pob != null) {
|
| - |
|
284 |
StoreTimelinetb fspEntry = storeTimelinetbRepository.selectByOnboardingIdAndEvent(
|
| - |
|
285 |
pob.getId(), StoreTimeline.FULL_STOCK_PAYMENT);
|
| - |
|
286 |
if (fspEntry == null) {
|
| - |
|
287 |
LOGGER.warn("PO creation blocked for fofoId={}, onboardingId={}: FULL_STOCK_PAYMENT not done", fofoId, pob.getId());
|
| - |
|
288 |
throw new ProfitMandiBusinessException(
|
| - |
|
289 |
"Full Stock Payment is required before creating PO",
|
| - |
|
290 |
fofoStore.getCode(),
|
| - |
|
291 |
"Full Stock Payment must be completed before first PO can be created");
|
| - |
|
292 |
}
|
| - |
|
293 |
}
|
| - |
|
294 |
}
|
| - |
|
295 |
|
| 259 |
LOGGER.info("totalPayableAmount - {}", totalPayableAmount);
|
296 |
LOGGER.info("totalPayableAmount - {}", totalPayableAmount);
|
| 260 |
int transactionId = transactionService.createTransactionInternally(userCart, totalPayableAmount, 0);
|
297 |
int transactionId = transactionService.createTransactionInternally(userCart, totalPayableAmount, 0);
|
| 261 |
//Set here created by
|
298 |
//Set here created by
|
| 262 |
Transaction transaction = transactionRepository.selectById(transactionId);
|
299 |
Transaction transaction = transactionRepository.selectById(transactionId);
|
| 263 |
transaction.setCreatedBy(creatorId);
|
300 |
transaction.setCreatedBy(creatorId);
|
| Line 272... |
Line 309... |
| 272 |
loanTransactionRepository.persist(loanTransaction);
|
309 |
loanTransactionRepository.persist(loanTransaction);
|
| 273 |
}
|
310 |
}
|
| 274 |
} else {
|
311 |
} else {
|
| 275 |
transactionService.processTransaction(transactionId, loanId);
|
312 |
transactionService.processTransaction(transactionId, loanId);
|
| 276 |
}
|
313 |
}
|
| - |
|
314 |
|
| - |
|
315 |
// Send approval email to Sales L3 only for first PO
|
| - |
|
316 |
if (isFirstPO) {
|
| - |
|
317 |
try {
|
| - |
|
318 |
sendFirstPOApprovalEmail(fofoStore, transactionId, totalPayableAmount, creatorId);
|
| - |
|
319 |
} catch (Exception e) {
|
| - |
|
320 |
LOGGER.error("Failed to send first PO approval email for fofoId: " + fofoId, e);
|
| - |
|
321 |
}
|
| - |
|
322 |
// Track PO_CREATION on timeline for first PO
|
| - |
|
323 |
try {
|
| - |
|
324 |
if (fofoStore != null && fofoStore.getCode() != null) {
|
| - |
|
325 |
com.spice.profitmandi.dao.entity.fofo.PartnerOnBoardingPanel pob =
|
| - |
|
326 |
partnerOnBoardingPanelRepository.selectByCode(fofoStore.getCode());
|
| - |
|
327 |
if (pob != null) {
|
| - |
|
328 |
storeTimelineTatService.onPoCreationComplete(pob.getId());
|
| - |
|
329 |
// If no approval required, PO is auto-approved
|
| - |
|
330 |
if (!approvalRequired) {
|
| - |
|
331 |
storeTimelineTatService.onPoApprovalComplete(pob.getId());
|
| - |
|
332 |
}
|
| - |
|
333 |
}
|
| - |
|
334 |
}
|
| - |
|
335 |
} catch (Exception e) {
|
| - |
|
336 |
LOGGER.error("Failed to track PO_CREATION timeline for fofoId: " + fofoId, e);
|
| - |
|
337 |
}
|
| - |
|
338 |
}
|
| 277 |
}
|
339 |
}
|
| 278 |
|
340 |
|
| 279 |
}
|
341 |
}
|
| 280 |
return finalBidStatus;
|
342 |
return finalBidStatus;
|
| 281 |
}
|
343 |
}
|
| Line 390... |
Line 452... |
| 390 |
approvalModelList.add(model);
|
452 |
approvalModelList.add(model);
|
| 391 |
}
|
453 |
}
|
| 392 |
return approvalModelList;
|
454 |
return approvalModelList;
|
| 393 |
}
|
455 |
}
|
| 394 |
|
456 |
|
| - |
|
457 |
private void sendFirstPOApprovalEmail(FofoStore fofoStore, int transactionId, double totalAmount, int creatorId) throws Exception {
|
| - |
|
458 |
String partnerName = "Partner";
|
| - |
|
459 |
if (fofoStore.getUserAddress() != null && fofoStore.getUserAddress().getName() != null) {
|
| - |
|
460 |
partnerName = fofoStore.getUserAddress().getName();
|
| - |
|
461 |
}
|
| - |
|
462 |
String storeCode = fofoStore.getCode() != null ? fofoStore.getCode() : "";
|
| - |
|
463 |
|
| - |
|
464 |
String createdByName = "";
|
| - |
|
465 |
if (creatorId > 0) {
|
| - |
|
466 |
AuthUser creator = authRepository.selectById(creatorId);
|
| - |
|
467 |
if (creator != null) {
|
| - |
|
468 |
createdByName = creator.getFullName();
|
| - |
|
469 |
}
|
| - |
|
470 |
}
|
| - |
|
471 |
|
| - |
|
472 |
String subject = "First PO Created - Approval Required - " + partnerName + " (" + storeCode + ")";
|
| - |
|
473 |
|
| - |
|
474 |
StringBuilder sb = new StringBuilder();
|
| - |
|
475 |
sb.append("<html><body>");
|
| - |
|
476 |
sb.append("<p>Dear Team,</p>");
|
| - |
|
477 |
sb.append("<p>The <strong>first Purchase Order</strong> has been created for the below partner. Please review and approve.</p><br/>");
|
| - |
|
478 |
sb.append("<table style='border:1px solid black; border-collapse: collapse;'>");
|
| - |
|
479 |
sb.append("<tbody>");
|
| - |
|
480 |
sb.append("<tr>");
|
| - |
|
481 |
sb.append("<th style='border:1px solid black; padding: 5px;'>Partner Name</th>");
|
| - |
|
482 |
sb.append("<th style='border:1px solid black; padding: 5px;'>Store Code</th>");
|
| - |
|
483 |
sb.append("<th style='border:1px solid black; padding: 5px;'>Transaction ID</th>");
|
| - |
|
484 |
sb.append("<th style='border:1px solid black; padding: 5px;'>Total Amount</th>");
|
| - |
|
485 |
sb.append("<th style='border:1px solid black; padding: 5px;'>Created By</th>");
|
| - |
|
486 |
sb.append("</tr>");
|
| - |
|
487 |
sb.append("<tr>");
|
| - |
|
488 |
sb.append("<td style='border:1px solid black; padding: 5px;'>").append(partnerName).append("</td>");
|
| - |
|
489 |
sb.append("<td style='border:1px solid black; padding: 5px;'>").append(storeCode).append("</td>");
|
| - |
|
490 |
sb.append("<td style='border:1px solid black; padding: 5px;'>").append(transactionId).append("</td>");
|
| - |
|
491 |
sb.append("<td style='border:1px solid black; padding: 5px;'>").append(String.format("%.2f", totalAmount)).append("</td>");
|
| - |
|
492 |
sb.append("<td style='border:1px solid black; padding: 5px;'>").append(createdByName).append("</td>");
|
| - |
|
493 |
sb.append("</tr>");
|
| - |
|
494 |
sb.append("</tbody></table>");
|
| - |
|
495 |
sb.append("<br/><p>Please approve this order from the <strong>Transaction Approvals</strong> panel.</p>");
|
| - |
|
496 |
sb.append("<br/><p>Regards,<br/>Smart Dukaan</p>");
|
| - |
|
497 |
sb.append("</body></html>");
|
| - |
|
498 |
|
| - |
|
499 |
// Send to Sales L3
|
| - |
|
500 |
List<AuthUser> salesL3Users = csService.getAuthUserByCategoryId(
|
| - |
|
501 |
ProfitMandiConstants.TICKET_CATEGORY_SALES, EscalationType.L3);
|
| - |
|
502 |
|
| - |
|
503 |
List<String> sendTo = new ArrayList<>();
|
| - |
|
504 |
if (!salesL3Users.isEmpty()) {
|
| - |
|
505 |
sendTo.addAll(salesL3Users.stream().map(AuthUser::getEmailId).collect(Collectors.toList()));
|
| - |
|
506 |
}
|
| - |
|
507 |
|
| - |
|
508 |
if (!sendTo.isEmpty()) {
|
| - |
|
509 |
String[] emailArray = sendTo.toArray(new String[0]);
|
| - |
|
510 |
Utils.sendMailWithAttachments(mailSender, emailArray, null, subject, sb.toString());
|
| - |
|
511 |
LOGGER.info("First PO approval email sent for fofoId: {} transactionId: {}", fofoStore.getId(), transactionId);
|
| - |
|
512 |
}
|
| - |
|
513 |
}
|
| - |
|
514 |
|
| 395 |
}
|
515 |
}
|