| Line 8... |
Line 8... |
| 8 |
import com.spice.profitmandi.common.util.FormattingUtils;
|
8 |
import com.spice.profitmandi.common.util.FormattingUtils;
|
| 9 |
import com.spice.profitmandi.common.util.StringUtils;
|
9 |
import com.spice.profitmandi.common.util.StringUtils;
|
| 10 |
import com.spice.profitmandi.common.util.Utils;
|
10 |
import com.spice.profitmandi.common.util.Utils;
|
| 11 |
import com.spice.profitmandi.common.web.client.RestClient;
|
11 |
import com.spice.profitmandi.common.web.client.RestClient;
|
| 12 |
import com.spice.profitmandi.dao.cart.SmartCartService;
|
12 |
import com.spice.profitmandi.dao.cart.SmartCartService;
|
| - |
|
13 |
import com.spice.profitmandi.dao.entity.catalog.Category;
|
| 13 |
import com.spice.profitmandi.dao.entity.catalog.Item;
|
14 |
import com.spice.profitmandi.dao.entity.catalog.Item;
|
| 14 |
import com.spice.profitmandi.dao.entity.catalog.TagListing;
|
15 |
import com.spice.profitmandi.dao.entity.catalog.TagListing;
|
| 15 |
import com.spice.profitmandi.dao.entity.catalog.UpgradeOffer;
|
16 |
import com.spice.profitmandi.dao.entity.catalog.UpgradeOffer;
|
| 16 |
import com.spice.profitmandi.dao.entity.dtr.*;
|
17 |
import com.spice.profitmandi.dao.entity.dtr.*;
|
| 17 |
import com.spice.profitmandi.dao.entity.fofo.*;
|
18 |
import com.spice.profitmandi.dao.entity.fofo.*;
|
| Line 217... |
Line 218... |
| 217 |
|
218 |
|
| 218 |
@Autowired
|
219 |
@Autowired
|
| 219 |
private OrderRepository orderRepository;
|
220 |
private OrderRepository orderRepository;
|
| 220 |
|
221 |
|
| 221 |
@Autowired
|
222 |
@Autowired
|
| - |
|
223 |
private CategoryRepository categoryRepository;
|
| - |
|
224 |
|
| - |
|
225 |
@Autowired
|
| 222 |
private HygieneDataRepository hygieneDataRepository;
|
226 |
private HygieneDataRepository hygieneDataRepository;
|
| 223 |
|
227 |
|
| 224 |
@Autowired
|
228 |
@Autowired
|
| 225 |
private SessionFactory sessionFactory;
|
229 |
private SessionFactory sessionFactory;
|
| 226 |
|
230 |
|
| Line 578... |
Line 582... |
| 578 |
Map<Integer, Set<InventoryItem>> inventoryItemsToBill = new HashMap<>();
|
582 |
Map<Integer, Set<InventoryItem>> inventoryItemsToBill = new HashMap<>();
|
| 579 |
Map<Integer, Integer> inventoryItemIdQuantityUsed = new HashMap<>(); // to keep track of inventoryitem quanity
|
583 |
Map<Integer, Integer> inventoryItemIdQuantityUsed = new HashMap<>(); // to keep track of inventoryitem quanity
|
| 580 |
// used for scan records insertion
|
584 |
// used for scan records insertion
|
| 581 |
|
585 |
|
| 582 |
LOGGER.info("itemMap keys {}", itemMap.keySet());
|
586 |
LOGGER.info("itemMap keys {}", itemMap.keySet());
|
| - |
|
587 |
|
| - |
|
588 |
// N+1 fix: Fetch live demo serial numbers once before the loop (was being fetched per serialized item)
|
| - |
|
589 |
Set<String> liveDemoSerialNumbers = new HashSet<>(liveDemoBillingRespository.selectAllSerialNumber());
|
| - |
|
590 |
// Batch-fetch LiveDemoSerialNumber entities for all matching serialized inventory serials
|
| - |
|
591 |
List<String> matchingLiveDemoSerials = serializedInventoryItemMap.values().stream()
|
| - |
|
592 |
.flatMap(Set::stream)
|
| - |
|
593 |
.map(InventoryItem::getSerialNumber)
|
| - |
|
594 |
.filter(liveDemoSerialNumbers::contains)
|
| - |
|
595 |
.collect(Collectors.toList());
|
| - |
|
596 |
Map<String, LiveDemoSerialNumber> liveDemoSerialNumberMap = new HashMap<>();
|
| - |
|
597 |
if (!matchingLiveDemoSerials.isEmpty()) {
|
| - |
|
598 |
liveDemoSerialNumberMap = liveDemoBillingRespository.selectBySerialNumbers(matchingLiveDemoSerials).stream()
|
| - |
|
599 |
.collect(Collectors.toMap(LiveDemoSerialNumber::getSerialNumber, ld -> ld, (a, b) -> a));
|
| - |
|
600 |
}
|
| - |
|
601 |
|
| 583 |
// Lets reduce quantity and decide what inventory items to use.
|
602 |
// Lets reduce quantity and decide what inventory items to use.
|
| 584 |
for (Item item : items) {
|
603 |
for (Item item : items) {
|
| 585 |
if (item.getType().equals(ItemType.SERIALIZED)) {
|
604 |
if (item.getType().equals(ItemType.SERIALIZED)) {
|
| 586 |
// TODO:handle null
|
605 |
// TODO:handle null
|
| 587 |
if (serializedInventoryItemMap.get(item.getId()) == null || itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().size() != serializedInventoryItemMap.get(item.getId()).size()) {
|
606 |
if (serializedInventoryItemMap.get(item.getId()) == null || itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().size() != serializedInventoryItemMap.get(item.getId()).size()) {
|
| Line 589... |
Line 608... |
| 589 |
if (itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().size() != insuredModels.size()) {
|
608 |
if (itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().size() != insuredModels.size()) {
|
| 590 |
List<String> invalidSerialNumbers = itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());
|
609 |
List<String> invalidSerialNumbers = itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());
|
| 591 |
throw new ProfitMandiBusinessException("invalidSerialNumbers", invalidSerialNumbers, "FFORDR_1004");
|
610 |
throw new ProfitMandiBusinessException("invalidSerialNumbers", invalidSerialNumbers, "FFORDR_1004");
|
| 592 |
}
|
611 |
}
|
| 593 |
}
|
612 |
}
|
| 594 |
List<String> serialNumberList = liveDemoBillingRespository.selectAllSerialNumber();
|
- |
|
| 595 |
|
613 |
|
| 596 |
Set<InventoryItem> inventoryItemsSerializedserialized = serializedInventoryItemMap.get(item.getId());
|
614 |
Set<InventoryItem> inventoryItemsSerializedserialized = serializedInventoryItemMap.get(item.getId());
|
| 597 |
for (InventoryItem inventoryItem : inventoryItemsSerializedserialized) {
|
615 |
for (InventoryItem inventoryItem : inventoryItemsSerializedserialized) {
|
| 598 |
inventoryItem.setGoodQuantity(0);
|
616 |
inventoryItem.setGoodQuantity(0);
|
| 599 |
inventoryItemIdQuantityUsed.put(inventoryItem.getId(), 1);
|
617 |
inventoryItemIdQuantityUsed.put(inventoryItem.getId(), 1);
|
| 600 |
if (serialNumberList.contains(inventoryItem.getSerialNumber())) {
|
618 |
LiveDemoSerialNumber liveDemoSerialNumber = liveDemoSerialNumberMap.get(inventoryItem.getSerialNumber());
|
| 601 |
LiveDemoSerialNumber liveDemoSerialNumber = liveDemoBillingRespository.selectBySerialNumber(inventoryItem.getSerialNumber());
|
619 |
if (liveDemoSerialNumber != null) {
|
| 602 |
liveDemoBillingRespository.delete(liveDemoSerialNumber);
|
620 |
liveDemoBillingRespository.delete(liveDemoSerialNumber);
|
| 603 |
}
|
621 |
}
|
| 604 |
}
|
622 |
}
|
| 605 |
inventoryItemsToBill.put(item.getId(), inventoryItemsSerializedserialized);
|
623 |
inventoryItemsToBill.put(item.getId(), inventoryItemsSerializedserialized);
|
| 606 |
} else {
|
624 |
} else {
|
| Line 675... |
Line 693... |
| 675 |
gstRateMap = stateGstRateRepository.getStateTaxRate(new ArrayList<>(itemMap.keySet()), stateId);
|
693 |
gstRateMap = stateGstRateRepository.getStateTaxRate(new ArrayList<>(itemMap.keySet()), stateId);
|
| 676 |
} else {
|
694 |
} else {
|
| 677 |
gstRateMap = stateGstRateRepository.getIgstTaxRate(new ArrayList<>(itemMap.keySet()));
|
695 |
gstRateMap = stateGstRateRepository.getIgstTaxRate(new ArrayList<>(itemMap.keySet()));
|
| 678 |
}
|
696 |
}
|
| 679 |
|
697 |
|
| - |
|
698 |
// N+1 fix: Collect created FofoOrderItems during the loop instead of re-querying
|
| - |
|
699 |
List<FofoOrderItem> fofoItems = new ArrayList<>();
|
| 680 |
for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
|
700 |
for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {
|
| 681 |
FofoOrderItem fofoOrderItem = this.createAndGetFofoOrderItem(customFofoOrderItem, fofoOrder.getId(), itemMap, inventoryItemsToBill.get(customFofoOrderItem.getItemId()), tagListingMap, gstRateMap);
|
701 |
FofoOrderItem fofoOrderItem = this.createAndGetFofoOrderItem(customFofoOrderItem, fofoOrder.getId(), itemMap, inventoryItemsToBill.get(customFofoOrderItem.getItemId()), tagListingMap, gstRateMap);
|
| - |
|
702 |
fofoItems.add(fofoOrderItem);
|
| 682 |
|
703 |
|
| 683 |
Item item = itemMap.get(customFofoOrderItem.getItemId());
|
704 |
Item item = itemMap.get(customFofoOrderItem.getItemId());
|
| 684 |
if (item.getType().equals(ItemType.NON_SERIALIZED)) {
|
705 |
if (item.getType().equals(ItemType.NON_SERIALIZED)) {
|
| 685 |
if (customFofoOrderItem.getCustomSerialNumbers() != null && !customFofoOrderItem.getCustomSerialNumbers().isEmpty()) {
|
706 |
if (customFofoOrderItem.getCustomSerialNumbers() != null && !customFofoOrderItem.getCustomSerialNumbers().isEmpty()) {
|
| 686 |
persistNonSerializedWithCustomSerialNumber(customFofoOrderItem, fofoOrderItem.getId());
|
707 |
persistNonSerializedWithCustomSerialNumber(customFofoOrderItem, fofoOrderItem.getId());
|
| Line 697... |
Line 718... |
| 697 |
this.updateCurrentInventorySnapshot(currentInventorySnapshots, fofoId, customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
|
718 |
this.updateCurrentInventorySnapshot(currentInventorySnapshots, fofoId, customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());
|
| 698 |
|
719 |
|
| 699 |
this.updateInventoryItemsAndScanRecord(inventoryItems, fofoId, inventoryItemIdQuantityUsed, fofoOrder.getId());
|
720 |
this.updateInventoryItemsAndScanRecord(inventoryItems, fofoId, inventoryItemIdQuantityUsed, fofoOrder.getId());
|
| 700 |
}
|
721 |
}
|
| 701 |
|
722 |
|
| 702 |
List<FofoOrderItem> fofoItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
|
- |
|
| 703 |
|
- |
|
| 704 |
// Use existing itemMap instead of querying DB per item (N+1 fix)
|
723 |
// Use existing itemMap instead of querying DB per item (N+1 fix)
|
| 705 |
boolean smartPhone = items.stream().anyMatch(Item::isSmartPhone);
|
724 |
boolean smartPhone = items.stream().anyMatch(Item::isSmartPhone);
|
| 706 |
if (smartPhone) {
|
725 |
if (smartPhone) {
|
| 707 |
LOGGER.info("Smartphone found in order items");
|
726 |
LOGGER.info("Smartphone found in order items");
|
| 708 |
} else {
|
727 |
} else {
|
| Line 716... |
Line 735... |
| 716 |
// insurance calculation is insurance flag is enabled
|
735 |
// insurance calculation is insurance flag is enabled
|
| 717 |
//
|
736 |
//
|
| 718 |
if (insuredModels.size() > 0) {
|
737 |
if (insuredModels.size() > 0) {
|
| 719 |
LOGGER.info("Processing insurane for serialNumbers");
|
738 |
LOGGER.info("Processing insurane for serialNumbers");
|
| 720 |
LOGGER.info("InsuranceModels {}", insuredModels);
|
739 |
LOGGER.info("InsuranceModels {}", insuredModels);
|
| - |
|
740 |
if (createOrderRequest.getCustomer() == null || createOrderRequest.getCustomer().getDateOfBirth() == null) {
|
| - |
|
741 |
throw new ProfitMandiBusinessException("Order", "Customer Date of Birth", "Customer date of birth is required for insurance");
|
| - |
|
742 |
}
|
| 721 |
LocalDate customerDateOfBirth = LocalDate.from(createOrderRequest.getCustomer().getDateOfBirth());
|
743 |
LocalDate customerDateOfBirth = LocalDate.from(createOrderRequest.getCustomer().getDateOfBirth());
|
| 722 |
fofoOrder.setDateOfBirth(customerDateOfBirth);
|
744 |
fofoOrder.setDateOfBirth(customerDateOfBirth);
|
| 723 |
for (InsuranceModel insuranceModel : insuredModels) {
|
745 |
for (InsuranceModel insuranceModel : insuredModels) {
|
| 724 |
LOGGER.info("G- {}", insuranceModel.getInsuranceId());
|
746 |
LOGGER.info("G- {}", insuranceModel.getInsuranceId());
|
| 725 |
LOGGER.info("insuranceModel- {}", insuranceModel);
|
747 |
LOGGER.info("insuranceModel- {}", insuranceModel);
|
| Line 1467... |
Line 1489... |
| 1467 |
pdfModel.setCustomer(getCustomCustomer(fofoOrder, customRetailer.getAddress()));
|
1489 |
pdfModel.setCustomer(getCustomCustomer(fofoOrder, customRetailer.getAddress()));
|
| 1468 |
pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
|
1490 |
pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());
|
| 1469 |
pdfModel.setTotalAmount(fofoOrder.getTotalAmount());
|
1491 |
pdfModel.setTotalAmount(fofoOrder.getTotalAmount());
|
| 1470 |
|
1492 |
|
| 1471 |
|
1493 |
|
| 1472 |
List<CustomOrderItem> customerFofoOrderItems = new ArrayList<>();
|
1494 |
List<CustomOrderItem> regularFofoItems = new ArrayList<>();
|
| - |
|
1495 |
List<CustomOrderItem> marginSchemeFofoItems = new ArrayList<>();
|
| - |
|
1496 |
boolean hasMarginSchemeItems = false;
|
| 1473 |
for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
|
1497 |
for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
|
| 1474 |
float discount = fofoOrderItem.getDiscount();
|
1498 |
float discount = fofoOrderItem.getDiscount();
|
| 1475 |
CustomOrderItem customFofoOrderItem = new CustomOrderItem();
|
1499 |
CustomOrderItem customFofoOrderItem = new CustomOrderItem();
|
| 1476 |
float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
|
1500 |
float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
|
| 1477 |
float taxableSellingPrice = (fofoOrderItem.getSellingPrice() + discount) / (1 + totalTaxRate / 100);
|
- |
|
| 1478 |
float taxableDiscountPrice = discount / (1 + totalTaxRate / 100);
|
- |
|
| 1479 |
|
1501 |
|
| 1480 |
customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
|
- |
|
| 1481 |
customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
|
1502 |
customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
|
| 1482 |
Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
|
1503 |
Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());
|
| 1483 |
List<FofoNonSerializeSerial> nonSerializeSerials = fofoNonSerializeSerialRepository.selectByItemIdAndOrderId(fofoOrderItem.getId());
|
1504 |
List<FofoNonSerializeSerial> nonSerializeSerials = fofoNonSerializeSerialRepository.selectByItemIdAndOrderId(fofoOrderItem.getId());
|
| 1484 |
// Extract serial numbers from FofoNonSerializeSerial entities
|
- |
|
| 1485 |
List<String> customSerialNumbers = nonSerializeSerials.stream().map(FofoNonSerializeSerial::getSerialNumber).collect(Collectors.toList());
|
1505 |
List<String> customSerialNumbers = nonSerializeSerials.stream().map(FofoNonSerializeSerial::getSerialNumber).collect(Collectors.toList());
|
| 1486 |
LOGGER.info("nonSerializeSerials {}", nonSerializeSerials);
|
1506 |
LOGGER.info("nonSerializeSerials {}", nonSerializeSerials);
|
| 1487 |
if (!serialNumbers.isEmpty()) {
|
1507 |
if (!serialNumbers.isEmpty()) {
|
| 1488 |
customFofoOrderItem.setDescription(
|
1508 |
customFofoOrderItem.setDescription(
|
| 1489 |
customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
|
1509 |
customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
|
| 1490 |
}
|
1510 |
}
|
| 1491 |
if (!customSerialNumbers.isEmpty()) {
|
1511 |
if (!customSerialNumbers.isEmpty()) {
|
| 1492 |
customFofoOrderItem.setDescription(
|
1512 |
customFofoOrderItem.setDescription(
|
| 1493 |
customFofoOrderItem.getDescription() + "\n SerialNumber - " + String.join(", ", customSerialNumbers));
|
1513 |
customFofoOrderItem.getDescription() + "\n SerialNumber - " + String.join(", ", customSerialNumbers));
|
| 1494 |
}
|
1514 |
}
|
| 1495 |
customFofoOrderItem.setRate(taxableSellingPrice);
|
- |
|
| 1496 |
customFofoOrderItem.setDiscount(taxableDiscountPrice);
|
- |
|
| 1497 |
customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
|
1515 |
customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());
|
| 1498 |
customFofoOrderItem.setNetAmount(fofoOrderItem.getSellingPrice() * fofoOrderItem.getQuantity());
|
- |
|
| 1499 |
float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
|
- |
|
| 1500 |
float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
|
- |
|
| 1501 |
float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
|
- |
|
| 1502 |
customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
|
- |
|
| 1503 |
customFofoOrderItem.setIgstAmount(igstAmount);
|
- |
|
| 1504 |
customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
|
- |
|
| 1505 |
customFofoOrderItem.setCgstAmount(cgstAmount);
|
- |
|
| 1506 |
customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
|
- |
|
| 1507 |
customFofoOrderItem.setSgstAmount(sgstAmount);
|
- |
|
| 1508 |
customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
|
1516 |
customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());
|
| - |
|
1517 |
|
| - |
|
1518 |
// Check if this is a margin scheme item
|
| - |
|
1519 |
boolean isMarginItem = false;
|
| - |
|
1520 |
try {
|
| - |
|
1521 |
Item item = itemRepository.selectById(fofoOrderItem.getItemId());
|
| - |
|
1522 |
Category category = categoryRepository.selectById(item.getCategoryId());
|
| - |
|
1523 |
isMarginItem = category.isMarginOnly() && !serialNumbers.isEmpty();
|
| - |
|
1524 |
} catch (Exception e) {
|
| - |
|
1525 |
LOGGER.warn("Could not check margin scheme for fofo order item {}", fofoOrderItem.getId(), e);
|
| - |
|
1526 |
}
|
| - |
|
1527 |
|
| - |
|
1528 |
if (isMarginItem) {
|
| - |
|
1529 |
// Margin Scheme: GST on margin only
|
| - |
|
1530 |
// Purchase price = what FOFO paid (from fofo.inventory_item.unitPrice)
|
| - |
|
1531 |
float purchasePrice = getFofoPurchasePrice(serialNumbers.iterator().next(), fofoOrder.getFofoId());
|
| - |
|
1532 |
float sellingPrice = fofoOrderItem.getSellingPrice();
|
| - |
|
1533 |
float margin = Math.max(0, sellingPrice - purchasePrice);
|
| - |
|
1534 |
float taxableMargin = margin / (1 + totalTaxRate / 100);
|
| - |
|
1535 |
|
| - |
|
1536 |
customFofoOrderItem.setMarginScheme(true);
|
| - |
|
1537 |
customFofoOrderItem.setPurchasePrice(purchasePrice);
|
| - |
|
1538 |
customFofoOrderItem.setSellingPrice(sellingPrice);
|
| - |
|
1539 |
customFofoOrderItem.setMargin(margin);
|
| - |
|
1540 |
customFofoOrderItem.setRate(sellingPrice);
|
| - |
|
1541 |
customFofoOrderItem.setDiscount(0);
|
| - |
|
1542 |
customFofoOrderItem.setAmount(taxableMargin * fofoOrderItem.getQuantity());
|
| - |
|
1543 |
customFofoOrderItem.setNetAmount(fofoOrderItem.getSellingPrice() * fofoOrderItem.getQuantity());
|
| - |
|
1544 |
|
| - |
|
1545 |
float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
|
| - |
|
1546 |
float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
|
| - |
|
1547 |
float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
|
| - |
|
1548 |
customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
|
| - |
|
1549 |
customFofoOrderItem.setIgstAmount(igstAmount);
|
| - |
|
1550 |
customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
|
| - |
|
1551 |
customFofoOrderItem.setCgstAmount(cgstAmount);
|
| - |
|
1552 |
customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
|
| - |
|
1553 |
customFofoOrderItem.setSgstAmount(sgstAmount);
|
| - |
|
1554 |
|
| - |
|
1555 |
marginSchemeFofoItems.add(customFofoOrderItem);
|
| - |
|
1556 |
hasMarginSchemeItems = true;
|
| - |
|
1557 |
} else {
|
| - |
|
1558 |
// Regular: GST on full selling price
|
| - |
|
1559 |
float taxableSellingPrice = (fofoOrderItem.getSellingPrice() + discount) / (1 + totalTaxRate / 100);
|
| - |
|
1560 |
float taxableDiscountPrice = discount / (1 + totalTaxRate / 100);
|
| - |
|
1561 |
|
| - |
|
1562 |
customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));
|
| - |
|
1563 |
customFofoOrderItem.setRate(taxableSellingPrice);
|
| - |
|
1564 |
customFofoOrderItem.setDiscount(taxableDiscountPrice);
|
| - |
|
1565 |
customFofoOrderItem.setNetAmount(fofoOrderItem.getSellingPrice() * fofoOrderItem.getQuantity());
|
| - |
|
1566 |
|
| - |
|
1567 |
float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
|
| - |
|
1568 |
float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;
|
| - |
|
1569 |
float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;
|
| - |
|
1570 |
customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());
|
| - |
|
1571 |
customFofoOrderItem.setIgstAmount(igstAmount);
|
| - |
|
1572 |
customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());
|
| - |
|
1573 |
customFofoOrderItem.setCgstAmount(cgstAmount);
|
| - |
|
1574 |
customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());
|
| - |
|
1575 |
customFofoOrderItem.setSgstAmount(sgstAmount);
|
| - |
|
1576 |
|
| 1509 |
customerFofoOrderItems.add(customFofoOrderItem);
|
1577 |
regularFofoItems.add(customFofoOrderItem);
|
| - |
|
1578 |
}
|
| 1510 |
}
|
1579 |
}
|
| - |
|
1580 |
// Regular items first, then margin scheme items
|
| - |
|
1581 |
List<CustomOrderItem> customerFofoOrderItems = new ArrayList<>(regularFofoItems);
|
| - |
|
1582 |
customerFofoOrderItems.addAll(marginSchemeFofoItems);
|
| 1511 |
pdfModel.setOrderItems(customerFofoOrderItems);
|
1583 |
pdfModel.setOrderItems(customerFofoOrderItems);
|
| - |
|
1584 |
pdfModel.setHasMarginSchemeItems(hasMarginSchemeItems);
|
| - |
|
1585 |
if (hasMarginSchemeItems) {
|
| - |
|
1586 |
List<String> declarations = new ArrayList<>();
|
| - |
|
1587 |
declarations.add("Items marked under Margin Scheme are taxed under Rule 32(5) of CGST Rules, 2017.");
|
| - |
|
1588 |
declarations.add("GST is charged on the margin (Selling Price - Purchase Price) and not on the full value of supply.");
|
| - |
|
1589 |
declarations.add("Input Tax Credit is not available on margin scheme items.");
|
| - |
|
1590 |
pdfModel.setMarginSchemeDeclarations(declarations);
|
| - |
|
1591 |
}
|
| 1512 |
String customerAddressStateCode = "";
|
1592 |
String customerAddressStateCode = "";
|
| 1513 |
String partnerAddressStateCode = stateRepository.selectByName(pdfModel.getRetailer().getAddress().getState()).getCode();
|
1593 |
String partnerAddressStateCode = stateRepository.selectByName(pdfModel.getRetailer().getAddress().getState()).getCode();
|
| 1514 |
if (pdfModel.getCustomer() != null && pdfModel.getCustomer().getAddress() != null &&
|
1594 |
if (pdfModel.getCustomer() != null && pdfModel.getCustomer().getAddress() != null &&
|
| 1515 |
pdfModel.getCustomer().getAddress().getState() != null &&
|
1595 |
pdfModel.getCustomer().getAddress().getState() != null &&
|
| 1516 |
!pdfModel.getCustomer().getAddress().getState().trim().isEmpty()) {
|
1596 |
!pdfModel.getCustomer().getAddress().getState().trim().isEmpty()) {
|
| Line 1532... |
Line 1612... |
| 1532 |
pdfModel.setTncs(tncs);
|
1612 |
pdfModel.setTncs(tncs);
|
| 1533 |
return pdfModel;
|
1613 |
return pdfModel;
|
| 1534 |
|
1614 |
|
| 1535 |
}
|
1615 |
}
|
| 1536 |
|
1616 |
|
| - |
|
1617 |
private float getFofoPurchasePrice(String serialNumber, int fofoId) {
|
| - |
|
1618 |
try {
|
| - |
|
1619 |
InventoryItem fofoInventoryItem = inventoryItemRepository.selectBySerialNumberFofoId(serialNumber, fofoId);
|
| - |
|
1620 |
if (fofoInventoryItem != null) {
|
| - |
|
1621 |
return fofoInventoryItem.getUnitPrice();
|
| - |
|
1622 |
}
|
| - |
|
1623 |
} catch (Exception e) {
|
| - |
|
1624 |
LOGGER.error("Could not fetch FOFO purchase price for serial: {}, fofoId: {}", serialNumber, fofoId, e);
|
| - |
|
1625 |
}
|
| - |
|
1626 |
return 0;
|
| - |
|
1627 |
}
|
| - |
|
1628 |
|
| 1537 |
private CustomCustomer getCustomCustomer(FofoOrder fofoOrder, CustomAddress retailerAddress) throws
|
1629 |
private CustomCustomer getCustomCustomer(FofoOrder fofoOrder, CustomAddress retailerAddress) throws
|
| 1538 |
ProfitMandiBusinessException {
|
1630 |
ProfitMandiBusinessException {
|
| 1539 |
Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
|
1631 |
Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
|
| 1540 |
CustomCustomer customCustomer = new CustomCustomer();
|
1632 |
CustomCustomer customCustomer = new CustomCustomer();
|
| 1541 |
customCustomer.setFirstName(customer.getFirstName());
|
1633 |
customCustomer.setFirstName(customer.getFirstName());
|
| Line 2330... |
Line 2422... |
| 2330 |
|
2422 |
|
| 2331 |
List<CustomOrderItem> customerFofoOrderItems = new ArrayList<>();
|
2423 |
List<CustomOrderItem> customerFofoOrderItems = new ArrayList<>();
|
| 2332 |
|
2424 |
|
| 2333 |
FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(creditNote.getFofoOrderItemId());
|
2425 |
FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(creditNote.getFofoOrderItemId());
|
| 2334 |
float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
|
2426 |
float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();
|
| 2335 |
float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
|
- |
|
| 2336 |
float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
|
- |
|
| 2337 |
|
2427 |
|
| 2338 |
CustomOrderItem customFofoOrderItem = new CustomOrderItem();
|
2428 |
CustomOrderItem customFofoOrderItem = new CustomOrderItem();
|
| 2339 |
customFofoOrderItem.setAmount(customerReturnItems.size() * (taxableSellingPrice - taxableDiscountPrice));
|
- |
|
| 2340 |
customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
|
2429 |
customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " " + fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());
|
| 2341 |
|
2430 |
|
| - |
|
2431 |
List<String> serialNumbers = new ArrayList<>();
|
| 2342 |
if (ItemType.SERIALIZED.equals(itemRepository.selectById(fofoOrderItem.getItemId()).getType())) {
|
2432 |
if (ItemType.SERIALIZED.equals(itemRepository.selectById(fofoOrderItem.getItemId()).getType())) {
|
| 2343 |
Set<Integer> inventoryItemIds = customerReturnItems.stream().map(x -> x.getInventoryItemId()).collect(Collectors.toSet());
|
2433 |
Set<Integer> inventoryItemIds = customerReturnItems.stream().map(x -> x.getInventoryItemId()).collect(Collectors.toSet());
|
| 2344 |
List<String> serialNumbers = inventoryItemRepository.selectByIds(inventoryItemIds).stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());
|
2434 |
serialNumbers = inventoryItemRepository.selectByIds(inventoryItemIds).stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());
|
| 2345 |
customFofoOrderItem.setDescription(
|
2435 |
customFofoOrderItem.setDescription(
|
| 2346 |
customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
|
2436 |
customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));
|
| 2347 |
}
|
2437 |
}
|
| 2348 |
|
2438 |
|
| - |
|
2439 |
// Check if margin scheme item
|
| - |
|
2440 |
boolean isMarginItem = false;
|
| - |
|
2441 |
try {
|
| - |
|
2442 |
Item item = itemRepository.selectById(fofoOrderItem.getItemId());
|
| - |
|
2443 |
Category category = categoryRepository.selectById(item.getCategoryId());
|
| - |
|
2444 |
isMarginItem = category.isMarginOnly() && !serialNumbers.isEmpty();
|
| - |
|
2445 |
} catch (Exception e) {
|
| - |
|
2446 |
LOGGER.warn("Could not check margin scheme for credit note item {}", fofoOrderItem.getId(), e);
|
| - |
|
2447 |
}
|
| - |
|
2448 |
|
| - |
|
2449 |
if (isMarginItem) {
|
| - |
|
2450 |
// Margin Scheme credit note: reverse GST on margin only
|
| - |
|
2451 |
float purchasePrice = getFofoPurchasePrice(serialNumbers.get(0), fofoOrder.getFofoId());
|
| - |
|
2452 |
float sellingPrice = fofoOrderItem.getSellingPrice();
|
| - |
|
2453 |
float margin = Math.max(0, sellingPrice - purchasePrice);
|
| - |
|
2454 |
float taxableMargin = margin / (1 + totalTaxRate / 100);
|
| - |
|
2455 |
|
| - |
|
2456 |
customFofoOrderItem.setMarginScheme(true);
|
| - |
|
2457 |
customFofoOrderItem.setPurchasePrice(purchasePrice);
|
| - |
|
2458 |
customFofoOrderItem.setSellingPrice(sellingPrice);
|
| - |
|
2459 |
customFofoOrderItem.setMargin(margin);
|
| - |
|
2460 |
customFofoOrderItem.setRate(sellingPrice);
|
| - |
|
2461 |
customFofoOrderItem.setDiscount(0);
|
| - |
|
2462 |
customFofoOrderItem.setAmount(taxableMargin * customerReturnItems.size());
|
| - |
|
2463 |
} else {
|
| - |
|
2464 |
float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);
|
| - |
|
2465 |
float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);
|
| - |
|
2466 |
customFofoOrderItem.setAmount(customerReturnItems.size() * (taxableSellingPrice - taxableDiscountPrice));
|
| 2349 |
customFofoOrderItem.setRate(taxableSellingPrice);
|
2467 |
customFofoOrderItem.setRate(taxableSellingPrice);
|
| 2350 |
customFofoOrderItem.setDiscount(taxableDiscountPrice);
|
2468 |
customFofoOrderItem.setDiscount(taxableDiscountPrice);
|
| - |
|
2469 |
}
|
| - |
|
2470 |
|
| 2351 |
customFofoOrderItem.setQuantity(customerReturnItems.size());
|
2471 |
customFofoOrderItem.setQuantity(customerReturnItems.size());
|
| 2352 |
customFofoOrderItem.setNetAmount(
|
2472 |
customFofoOrderItem.setNetAmount(
|
| 2353 |
(fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * customFofoOrderItem.getQuantity());
|
2473 |
(fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * customFofoOrderItem.getQuantity());
|
| 2354 |
|
2474 |
|
| 2355 |
float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
|
2475 |
float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;
|
| Line 2373... |
Line 2493... |
| 2373 |
pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));
|
2493 |
pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));
|
| 2374 |
pdfModel.setTitle("Credit Note");
|
2494 |
pdfModel.setTitle("Credit Note");
|
| 2375 |
pdfModel.setRetailer(customRetailer);
|
2495 |
pdfModel.setRetailer(customRetailer);
|
| 2376 |
pdfModel.setTotalAmount(customFofoOrderItem.getNetAmount());
|
2496 |
pdfModel.setTotalAmount(customFofoOrderItem.getNetAmount());
|
| 2377 |
pdfModel.setOrderItems(customerFofoOrderItems);
|
2497 |
pdfModel.setOrderItems(customerFofoOrderItems);
|
| - |
|
2498 |
pdfModel.setHasMarginSchemeItems(isMarginItem);
|
| 2378 |
|
2499 |
|
| 2379 |
CreditNotePdfModel creditNotePdfModel = new CreditNotePdfModel();
|
2500 |
CreditNotePdfModel creditNotePdfModel = new CreditNotePdfModel();
|
| 2380 |
creditNotePdfModel.setCreditNoteDate(FormattingUtils.formatDate(creditNote.getCreateTimestamp()));
|
2501 |
creditNotePdfModel.setCreditNoteDate(FormattingUtils.formatDate(creditNote.getCreateTimestamp()));
|
| 2381 |
creditNotePdfModel.setCreditNoteNumber(creditNote.getCreditNoteNumber());
|
2502 |
creditNotePdfModel.setCreditNoteNumber(creditNote.getCreditNoteNumber());
|
| 2382 |
creditNotePdfModel.setPdfModel(pdfModel);
|
2503 |
creditNotePdfModel.setPdfModel(pdfModel);
|