cut-to-pack-service/src/main/java/com/utopiaindustries/service/InventoryService.java

741 lines
39 KiB
Java

package com.utopiaindustries.service;
import com.utopiaindustries.dao.ctp.*;
import com.utopiaindustries.model.ctp.*;
import com.utopiaindustries.model.ctp.BundleWrapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
public class InventoryService {
private final JobCardItemDAO jobCardItemDAO;
private final CutPieceDAO cutPieceDAO;
private final BundleDAO bundleDAO;
private final InventoryTransactionLegDAO inventoryTransactionLegDAO;
private final InventoryTransactionDAO inventoryTransactionDAO;
private final JobCardDAO jobCardDAO;
private final CryptographyService cryptographyService;
private final MasterBundleDAO masterBundleDAO;
private final FinishedItemDAO finishedItemDAO;
private final StitchingOfflineItemDAO stitchingOfflineItemDAO;
private final PackagingItemsDAO packagingItemsDAO;
public InventoryService(JobCardItemDAO jobCardItemDAO, CutPieceDAO cutPieceDAO, BundleDAO bundleDAO, InventoryTransactionLegDAO inventoryTransactionLegDAO, InventoryTransactionDAO inventoryTransactionDAO, JobCardDAO jobCardDAO, CryptographyService cryptographyService, MasterBundleDAO masterBundleDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO, PackagingItemsDAO packagingItemsDAO) {
this.jobCardItemDAO = jobCardItemDAO;
this.cutPieceDAO = cutPieceDAO;
this.bundleDAO = bundleDAO;
this.inventoryTransactionLegDAO = inventoryTransactionLegDAO;
this.inventoryTransactionDAO = inventoryTransactionDAO;
this.jobCardDAO = jobCardDAO;
this.cryptographyService = cryptographyService;
this.masterBundleDAO = masterBundleDAO;
this.finishedItemDAO = finishedItemDAO;
this.stitchingOfflineItemDAO = stitchingOfflineItemDAO;
this.packagingItemsDAO = packagingItemsDAO;
}
private void updateJobCardInventoryStatus(JobCard card) {
List<JobCardItem> items = jobCardItemDAO.findByCardId(card.getId());
for (JobCardItem item : items) {
// check if item is received
if (item.getActualProduction() == null || item.getActualProduction().compareTo(BigDecimal.ZERO) == 0) {
return;
}
}
card.setInventoryStatus(JobCard.InventoryStatus.RECEIVED.name());
jobCardDAO.save(card);
}
/*
* receive inv from job card
* */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
public void receiveJobCardInventory(long jobCardId, JobCardWrapper jobCardWrapper) {
if (jobCardId == 0 || jobCardWrapper.getItems() == null || jobCardWrapper.getItems().isEmpty()) {
throw new RuntimeException(" JobCard can`t be empty");
}
JobCard jobCard = jobCardDAO.find(jobCardId);
// get job cad items
List<JobCardItemWrapper> jobCardItemWrappers = jobCardWrapper.getItems();
List<Long> jobCardItemWrapperIds = jobCardItemWrappers.stream()
.map(JobCardItemWrapper::getJobCardItemId)
.collect(Collectors.toList());
Map<Long, BigDecimal> jobCardItemIdToActualProdMap = jobCardItemWrappers.stream()
.collect(Collectors.toMap(JobCardItemWrapper::getJobCardItemId, JobCardItemWrapper::getActualProduction));
List<JobCardItem> items = jobCardItemDAO.findByIds(jobCardItemWrapperIds);
if (items != null && !items.isEmpty()) {
// get job card item ids
List<Long> jobCardItemIds = items.stream()
.map(JobCardItem::getId)
.collect(Collectors.toList());
// save updated cut pieces
// List<CutPiece> cutPieces = jobCardItemWrappers.stream()
// .flatMap(wrapper -> wrapper.getPieces().stream())
// .collect(Collectors.toList());
// cutPieceDAO.saveAll(cutPieces);
// Map<Long, List<CutPiece>> piecesMap = cutPieceDAO.findByJobCardItemIds(jobCardItemIds)
// .stream()
// .collect(Collectors.groupingBy(CutPiece::getJobCardItemId));
for (JobCardItem jobCardItem : items) {
int quantity = jobCardItemWrappers.stream()
.filter(e -> e.getJobCardItemId() == jobCardItem.getId())
.mapToInt(JobCardItemWrapper::getPerBundleQuantity)
.findFirst()
.orElse(0);
boolean cuttingComplete = jobCardItemWrappers.stream()
.filter(e -> e.getJobCardItemId() == jobCardItem.getId())
.map(JobCardItemWrapper::getCuttingComplete)
.findFirst()
.orElse(false);
BigDecimal production = jobCardItemWrappers.stream()
.filter(e -> e.getJobCardItemId() == jobCardItem.getId())
.map(JobCardItemWrapper::getActualProduction)
.findFirst()
.orElse(BigDecimal.ZERO);
List<Bundle> bundles = createBundles(jobCardItem, quantity, jobCardItemIdToActualProdMap.getOrDefault(jobCardItem.getId(), BigDecimal.ZERO));
// create transactions
createTransactions(bundles, jobCardItem.getAccountId(), InventoryArtifactType.BUNDLE.name());
jobCardItem.setActualProduction(jobCardItemIdToActualProdMap.getOrDefault(jobCardItem.getId(), BigDecimal.ZERO).add(jobCardItem.getActualProduction()));
jobCardItem.setComplete(cuttingComplete);
}
// update items with quantity
jobCardItemDAO.saveAll(items);
// update job card inv status
if (jobCardItemDAO.checkAllItemsComplete(jobCardId, jobCardItemIds)) {
updateJobCardInventoryStatus(jobCard);
}
} else {
throw new RuntimeException("Items Not found in Job Card");
}
}
/*
* t create transactions
* */
private void createTransactions(List<? extends InventoryArtifact> artifacts, long accountId, String parentDocumentType) {
if (!artifacts.isEmpty()) {
InventoryTransaction transaction = createInventoryTransaction("Transaction Against " + parentDocumentType);
for (InventoryArtifact artifact : artifacts) {
InventoryTransactionLeg leg = createInventoryTransactionLeg(transaction, artifact, accountId, InventoryTransactionLeg.Type.IN.name(), parentDocumentType);
}
}
}
/*
* create and save transaction
* */
private InventoryTransaction createInventoryTransaction(String notes) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
InventoryTransaction transaction = new InventoryTransaction();
transaction.setGeneratedBy(authentication.getName());
transaction.setTransactionDateTime(LocalDateTime.now());
transaction.setNotes(notes);
transaction.setId(inventoryTransactionDAO.save(transaction));
return transaction;
}
/*
* create and save inventory transaction
* */
private InventoryTransactionLeg createInventoryTransactionLeg(InventoryTransaction transaction,
InventoryArtifact artifact,
long accountId,
String transactionType,
String parentDocumentType) {
InventoryTransactionLeg inventoryTransactionLeg = new InventoryTransactionLeg();
inventoryTransactionLeg.setTransactionId(transaction.getId());
inventoryTransactionLeg.setType(transactionType);
inventoryTransactionLeg.setQuantity(BigDecimal.valueOf(1L));
inventoryTransactionLeg.setAccountId((int) accountId);
inventoryTransactionLeg.setItemId(artifact.getItemId());
inventoryTransactionLeg.setSku(artifact.getSku());
inventoryTransactionLeg.setParentDocumentType(parentDocumentType);
inventoryTransactionLeg.setParentDocumentId(artifact.getId());
inventoryTransactionLeg.setParentDocumentPieceType(artifact.getType());
inventoryTransactionLeg.setTransactionLegDateTime(LocalDateTime.now());
inventoryTransactionLeg.setJobCardId(artifact.getJobCardId());
// set balance
BigDecimal initialBalance = calculateBalance(accountId, artifact.getItemId(), parentDocumentType, artifact.getType());
if (transactionType.equalsIgnoreCase(InventoryTransactionLeg.Type.IN.name())) {
initialBalance = initialBalance.add(inventoryTransactionLeg.getQuantity());
} else if (transactionType.equalsIgnoreCase(InventoryTransactionLeg.Type.OUT.name())) {
if (inventoryTransactionLeg.getQuantity().equals(BigDecimal.ZERO)) {
initialBalance = BigDecimal.ZERO;
} else {
initialBalance = initialBalance.subtract(inventoryTransactionLeg.getQuantity());
}
}
inventoryTransactionLeg.setBalance(initialBalance);
inventoryTransactionLeg.setId(inventoryTransactionLegDAO.save(inventoryTransactionLeg));
return inventoryTransactionLeg;
}
// calculate balance
private BigDecimal calculateBalance(long accountId, long itemId, String parentType, String pieceType) {
// find the last transaction leg of the current account Id with itemId
InventoryTransactionLeg lastTransactionLeg = inventoryTransactionLegDAO.findLastByAccountIdAndItemIdAndParentType(accountId, itemId, parentType, pieceType);
if (lastTransactionLeg.getBalance() != null) {
return lastTransactionLeg.getBalance();
}
return BigDecimal.ZERO;
}
// create bundles from cut pieces
private List<Bundle> createBundles(JobCardItem jobCardItem,
int perBundleWrap, BigDecimal value) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (value != null && !value.equals(BigDecimal.ZERO)) {
List<Bundle> bundles = new ArrayList<>();
int quantity = value.intValue();
int batchSize = perBundleWrap;
int iterations = (int) Math.ceil((double) quantity / batchSize);
for (int i = 0; i < iterations; i++) {
int start = i * batchSize + 1; // Start index
int end = Math.min((i + 1) * batchSize, quantity); // Last index
int perBundleQuantity = end - start + 1;
Bundle bundle = new Bundle();
bundle.setItemId(jobCardItem.getItemId());
bundle.setSku(jobCardItem.getSku());
bundle.setJobCardId(jobCardItem.getJobCardId());
bundle.setWrapQuantity(BigDecimal.valueOf(perBundleQuantity));
bundle.setType("BUNDLE");
bundle.setCreatedAt(LocalDateTime.now());
bundle.setCreatedBy(authentication.getName());
bundles.add(bundle);
bundle.setId(bundleDAO.save(bundle));
bundle.setBarcode(cryptographyService.generateRandomString(15));
// save again after barcode generation
bundle.setId(bundleDAO.save(bundle));
}
// for ( Map.Entry<JobCardItem, List<CutPiece>> entry : jobCardItemPieces ) {
// JobCardItem key = entry.getKey( );
// List<CutPiece> value = entry.getValue( );
//
//
// }
return bundles;
}
return new ArrayList<>();
}
/*
* receive inventory from master barcode
* */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
public void receiveInventoryFromMasterBarcode(long masterId, long toAccount) {
if (masterId == 0 || toAccount == 0) {
throw new RuntimeException("Master Barcode | Account can`t be empty");
}
MasterBundle masterBundle = masterBundleDAO.find(masterId);
// find bundles from master barcode
List<Bundle> bundles = bundleDAO.findByMasterId(masterId);
if (bundles != null && !bundles.isEmpty()) {
// bundle ids
List<Long> bundleIds = bundles.stream().map(Bundle::getId).collect(Collectors.toList());
Map<Long, InventoryTransactionLeg> lastBundleIdInTransactionMap = inventoryTransactionLegDAO
.findLastTransactionByParentIdAndParentType(InventoryTransactionLeg.Type.IN.name(), bundleIds, InventoryArtifactType.BUNDLE.name())
.stream()
.collect(Collectors.toMap(InventoryTransactionLeg::getParentDocumentId, Function.identity()));
// create Transaction
InventoryTransaction transaction = createInventoryTransaction("Against Movement from Cutting to Stitching");
inventoryTransactionDAO.save(transaction);
// create transaction legs
for (Bundle bundle : bundles) {
InventoryTransactionLeg lastInvTransaction = lastBundleIdInTransactionMap.getOrDefault(bundle.getId(), null);
if (lastInvTransaction != null) {
// OUT
long fromAccount = lastInvTransaction.getAccountId();
createInventoryTransactionLeg(transaction, bundle, fromAccount, InventoryTransactionLeg.Type.OUT.name(), InventoryArtifactType.BUNDLE.name());
// IN
bundle.setType("BUNDLE");
createInventoryTransactionLeg(transaction, bundle, toAccount, InventoryTransactionLeg.Type.IN.name(), InventoryArtifactType.STITCH_BUNDLE.name());
}
}
// update status
masterBundle.setIsReceived(true);
masterBundle.setAccountId(toAccount);
masterBundleDAO.save(masterBundle);
}
}
private void validateItems(List<JobCardItem> cardItems) {
if (cardItems == null || cardItems.isEmpty()) {
throw new RuntimeException("Item cant be Empty | null");
}
for (JobCardItem jobCardItem : cardItems) {
if (jobCardItem.getTotalProduction() != null) {
int finalQuantity = jobCardItem.getActualProduction().compareTo(jobCardItem.getTotalProduction().add(jobCardItem.getProduction()));
if (finalQuantity < 0) {
throw new RuntimeException(" Items cant be generated because it exceeds from limit of expected Production");
}
}
}
}
private void checkAllBundleAreReceived(long jobCardId,
List<JobCardItem> jobCardItems) {
if (jobCardItems != null && !jobCardItems.isEmpty()) {
List<Long> itemIds = jobCardItems.stream()
.filter(JobCardItem::getIsSelected)
.map(JobCardItem::getItemId).collect(Collectors.toList());
List<Bundle> bundles = bundleDAO.findByItemIdsAndCardId(itemIds, jobCardId);
List<Long> masterBundleIds = bundles.stream().map(Bundle::getMasterBundleId).collect(Collectors.toList());
Map<Long, MasterBundle> idToMasterBundleMap = masterBundleDAO.findByIds(masterBundleIds)
.stream()
.collect(Collectors.toMap(MasterBundle::getId, Function.identity()));
for (Bundle bundle : bundles) {
// check all bundles are received
MasterBundle masterBundle = idToMasterBundleMap.getOrDefault(bundle.getMasterBundleId(), null);
if (masterBundle == null || !masterBundle.getIsReceived()) {
throw new RuntimeException("Please Receive Bundles Against Master Bundles First to Create Finished Item");
}
}
}
}
/*
* create finished items from master bundles
* */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
public void createStitchingOfflineItemsFromJobCard(BundleWrapper wrapper) {
List<JobCardItem> updatedItems = new ArrayList<>();
List<Bundle> updateBundles = new ArrayList<>();
JobCard jobCard = null;
//switching table transaction in Transaction Table
InventoryTransaction transaction = createInventoryTransaction("Against Movement from Stitching to Stitched Offline Item");
inventoryTransactionDAO.save(transaction);
//TransactionLeg Transaction
List<Long> bundleIds = wrapper.getBundles().stream().map(Bundle::getId).collect(Collectors.toList());
Map<Long, InventoryTransactionLeg> lastBundleIdInTransactionMap = inventoryTransactionLegDAO
.findLastTransactionByParentIdAndParentType(InventoryTransactionLeg.Type.IN.name(), bundleIds, InventoryArtifactType.STITCH_BUNDLE.name())
.stream()
.collect(Collectors.toMap(InventoryTransactionLeg::getParentDocumentId, Function.identity()));
for (Bundle subBundle : wrapper.getBundles()) {
long accountId = masterBundleDAO.find(subBundle.getMasterBundleId()).getAccountId();
if (subBundle.getCurrentProduction() != null && subBundle.getCurrentProduction().compareTo(BigDecimal.ZERO) != 0) {
Bundle bundle = bundleDAO.find(subBundle.getId());
jobCard = jobCardDAO.find(subBundle.getJobCardId());
long production = (bundle.getProduction() == null) ? 0 : bundle.getProduction().longValue();
long wrapQuantity = bundle.getWrapQuantity().longValue();
JobCardItem jobCardItem = jobCardItemDAO.findByCardIdAndItemId(subBundle.getJobCardId(), subBundle.getItemId());
BigDecimal previousTotalProduction = jobCardItem.getTotalProduction() == null ? BigDecimal.ZERO : jobCardItem.getTotalProduction();
InventoryTransactionLeg lastInvTransaction = lastBundleIdInTransactionMap.getOrDefault(subBundle.getId(), null);
if (lastInvTransaction != null) {
if (wrapQuantity == production + subBundle.getCurrentProduction().longValue()) {
// OUT
long fromAccount = lastInvTransaction.getAccountId();
createInventoryTransactionLeg(transaction, subBundle, accountId, InventoryTransactionLeg.Type.OUT.name(), InventoryArtifactType.STITCH_BUNDLE.name());
}
}
// create stitchingOfflineItems items
List<StitchingOfflineItem> stitchingOfflineItems = createStitchingOfflineItems(subBundle.getCurrentProduction(), jobCardItem, subBundle.getId());
// create IN Transactions of Finished Items into account
createTransactions(stitchingOfflineItems, accountId, InventoryArtifactType.STITCHING_OFFLINE.name());
jobCardItem.setTotalProduction(previousTotalProduction.add(subBundle.getCurrentProduction()));
jobCardItem.setJobCardId(jobCard.getId());
updatedItems.add(jobCardItem);
BigDecimal pro = BigDecimal.valueOf(production + subBundle.getCurrentProduction().longValue());
bundle.setProduction(pro);
bundleDAO.save(bundle);
}
}
jobCardItemDAO.saveAll(updatedItems);
}
/*
* create finished items
* */
public List<StitchingOfflineItem> createStitchingOfflineItems(BigDecimal totalItem, JobCardItem jobCardItem, long bundleId) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
List<StitchingOfflineItem> items = new ArrayList<>();
if (jobCardItem != null) {
for (int i = 1; i <= totalItem.intValue(); i++) {
StitchingOfflineItem stitchingOfflineItem = new StitchingOfflineItem();
stitchingOfflineItem.setCreatedAt(LocalDateTime.now());
stitchingOfflineItem.setCreatedBy(authentication.getName());
stitchingOfflineItem.setItemId(jobCardItem.getItemId());
stitchingOfflineItem.setSku(jobCardItem.getSku());
stitchingOfflineItem.setBundleId(bundleId);
stitchingOfflineItem.setJobCardId(jobCardItem.getJobCardId());
stitchingOfflineItem.setIsQa(false);
long id = stitchingOfflineItemDAO.save(stitchingOfflineItem);
stitchingOfflineItem.setId(id);
stitchingOfflineItem.setBarcode(cryptographyService.generateRandomString(15));
stitchingOfflineItemDAO.save(stitchingOfflineItem);
items.add(stitchingOfflineItem);
}
}
return items;
}
/*
* find transactions by account id
* */
public List<InventoryTransactionLeg> findTransactionByAccountId(long accountId) {
List<InventoryTransactionLeg> legs = inventoryTransactionLegDAO.findByAccountId(accountId);
List<Long> tIds = legs.stream().map(InventoryTransactionLeg::getTransactionId).collect(Collectors.toList());
Map<Long, InventoryTransaction> idToTransactioMap = inventoryTransactionDAO.findByIds(tIds).stream().collect(Collectors.toMap(InventoryTransaction::getId, Function.identity()));
legs.forEach(leg -> leg.setTransaction(idToTransactioMap.get(leg.getTransactionId())));
return legs;
}
/*
*
* */
@Transactional(rollbackFor = Exception.class)
public void markFinishedItemsApproved(List<Long> fItemIds, long toAccount) {
if (fItemIds.isEmpty() || toAccount == 0) {
throw new RuntimeException("Finished Item Ids | Account can`t be empty");
}
List<FinishedItem> finishedItems = finishedItemDAO.findByIds(fItemIds);
if (finishedItems != null && !finishedItems.isEmpty()) {
// bundle ids
List<Long> finishedItemIds = finishedItems.stream().map(FinishedItem::getId).collect(Collectors.toList());
Map<Long, InventoryTransactionLeg> lastBundleIdInTransactionMap = inventoryTransactionLegDAO
.findLastTransactionByParentIdAndParentType(InventoryTransactionLeg.Type.IN.name(), finishedItemIds, InventoryArtifactType.STITCHING_OFFLINE.name())
.stream()
.collect(Collectors.toMap(InventoryTransactionLeg::getParentDocumentId, Function.identity()));
// create Transaction
InventoryTransaction transaction = createInventoryTransaction("Against Movement from Stitching to Packaging After QA");
inventoryTransactionDAO.save(transaction);
// create transaction legs
for (FinishedItem finishedItem : finishedItems) {
InventoryTransactionLeg lastInvTransaction = lastBundleIdInTransactionMap.getOrDefault(finishedItem.getId(), null);
if (lastInvTransaction != null) {
// OUT
long fromAccount = lastInvTransaction.getAccountId();
createInventoryTransactionLeg(transaction, finishedItem, fromAccount, InventoryTransactionLeg.Type.OUT.name(), InventoryArtifactType.STITCHING_OFFLINE.name());
// IN
createInventoryTransactionLeg(transaction, finishedItem, toAccount, InventoryTransactionLeg.Type.IN.name(), InventoryArtifactType.STITCHING_OFFLINE.name());
}
finishedItem.setIsQa(true);
}
finishedItemDAO.saveAll(finishedItems);
}
}
/*
* generate finished items against stitched items
* */
@Transactional(rollbackFor = Exception.class)
public void createFinishedItemsAgainstStitchedItems(StitchedItemWrapper wrapper, String qaStatus) {
if (wrapper.getItems() != null && wrapper.getFinishedAccountId() != 0) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
List<StitchingOfflineItem> stitchingOfflineItems = wrapper.getItems();
List<StitchingOfflineItem> updatedStitchedItems = new ArrayList<>();
List<FinishedItem> finishedItems = new ArrayList<>();
List<FinishedItem> finishedItemsForUlter = new ArrayList<>();
List<Long> stitchedItemIds = stitchingOfflineItems.stream()
.map(StitchingOfflineItem::getId)
.collect(Collectors.toList());
Map<Long, InventoryTransactionLeg> lastStitchedIdInTransactionMap = inventoryTransactionLegDAO
.findLastTransactionByParentIdAndParentType(InventoryTransactionLeg.Type.IN.name(), stitchedItemIds, InventoryArtifactType.STITCHING_OFFLINE.name())
.stream()
.collect(Collectors.toMap(InventoryTransactionLeg::getParentDocumentId, Function.identity()));
// get finished items from stitched items if exists
List<Long> preCreatedFinishedItemIds = finishedItemDAO.findByStitchedItemIds(stitchedItemIds).stream().
map(FinishedItem::getId).collect(Collectors.toList());
Map<Long, InventoryTransactionLeg> lastFinishedItemInTransactionMap = inventoryTransactionLegDAO
.findLastTransactionByParentIdAndParentType(InventoryTransactionLeg.Type.IN.name(), preCreatedFinishedItemIds, InventoryArtifactType.FINISHED_ITEM.name())
.stream()
.collect(Collectors.toMap(InventoryTransactionLeg::getParentDocumentId, Function.identity()));
InventoryTransaction transaction = createInventoryTransaction("Against Movement From Stitching Offline to Finished Item");
// generate FI for SI
for (StitchingOfflineItem stitchingOfflineItem : stitchingOfflineItems) {
if (qaStatus.equalsIgnoreCase("APPROVED")) {
// check finished item is already created
FinishedItem preCreatedItem = finishedItemDAO.findByStitchedItem(stitchingOfflineItem.getId());
if (preCreatedItem == null) {
FinishedItem finishedItem = new FinishedItem();
finishedItem.setItemId(stitchingOfflineItem.getItemId());
finishedItem.setSku(stitchingOfflineItem.getSku());
finishedItem.setBarcode(stitchingOfflineItem.getBarcode());
finishedItem.setCreatedBy(authentication.getName());
finishedItem.setCreatedAt(LocalDateTime.now());
finishedItem.setOperationDate(LocalDateTime.now());
finishedItem.setQaStatus("-");
finishedItem.setStitchedItemId(stitchingOfflineItem.getId());
finishedItem.setJobCardId(stitchingOfflineItem.getJobCardId());
finishedItem.setIsQa(true);
finishedItem.setId(finishedItemDAO.save(finishedItem));
finishedItems.add(finishedItem);
InventoryTransactionLeg lastInvTransaction = lastStitchedIdInTransactionMap.getOrDefault(stitchingOfflineItem.getId(), null);
if (lastInvTransaction != null) {
// OUT
long fromAccount = lastInvTransaction.getAccountId();
createInventoryTransactionLeg(transaction, stitchingOfflineItem, fromAccount, InventoryTransactionLeg.Type.OUT.name(), InventoryArtifactType.STITCHING_OFFLINE.name());
}
// update stitched item
stitchingOfflineItem.setIsQa(true);
stitchingOfflineItem.setQaStatus(qaStatus);
updatedStitchedItems.add(stitchingOfflineItem);
// if FI is already created
} else {
// create OUT from stitching account Finished Item
InventoryTransactionLeg lastInvTransaction = lastFinishedItemInTransactionMap.getOrDefault(preCreatedItem.getId(), null);
if (lastInvTransaction != null) {
// OUT
long fromAccount = lastInvTransaction.getAccountId();
createInventoryTransactionLeg(transaction, preCreatedItem, fromAccount, InventoryTransactionLeg.Type.OUT.name(), InventoryArtifactType.FINISHED_ITEM.name());
}
stitchingOfflineItem.setIsQa(true);
preCreatedItem.setIsQa(true);
finishedItemsForUlter.add(preCreatedItem);
// create IN in finishing Account Finished Item
finishedItems.add(preCreatedItem);
}
} else {
FinishedItem preCreatedItem = finishedItemDAO.findByStitchedItem(stitchingOfflineItem.getId());
if (preCreatedItem != null) {
preCreatedItem.setIsQa(false);
finishedItemsForUlter.add(preCreatedItem);
}
stitchingOfflineItem.setIsQa(false);
}
stitchingOfflineItem.setQaStatus(qaStatus);
stitchingOfflineItem.setQcDoneAt(LocalDateTime.now());
updatedStitchedItems.add(stitchingOfflineItem);
}
for (FinishedItem finishedItem : finishedItems) {
// IN
createInventoryTransactionLeg(transaction, finishedItem, wrapper.getFinishedAccountId(), InventoryTransactionLeg.Type.IN.name(), InventoryArtifactType.FINISHED_ITEM.name());
}
// save updated stitched items
finishedItemDAO.saveAll(finishedItemsForUlter);
stitchingOfflineItemDAO.saveAll(updatedStitchedItems);
}
}
/*
* segregate finish items
* */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
public void segregateFinishedItems(FinishedItemWrapper wrapper, String status) {
if (wrapper != null && wrapper.getItems() != null) {
List<FinishedItem> items = wrapper.getItems();
List<FinishedItem> updatedItems = new ArrayList<>();
// finished ids
List<Long> finishedItemIds = items.stream().map(FinishedItem::getId)
.collect(Collectors.toList());
// stitched ids
List<Long> stitchedItemIds = items.stream().map(FinishedItem::getStitchedItemId)
.collect(Collectors.toList());
// create parent doc type last IN transaction map
Map<Long, InventoryTransactionLeg> lastFinishedItemIdInTransactionMap = inventoryTransactionLegDAO
.findLastTransactionByParentIdAndParentType(InventoryTransactionLeg.Type.IN.name(), finishedItemIds, InventoryArtifactType.FINISHED_ITEM.name())
.stream()
.collect(Collectors.toMap(InventoryTransactionLeg::getParentDocumentId, Function.identity()));
// create parent doc type last OUT transaction map
Map<Long, InventoryTransactionLeg> lastStitchedItemOutTransactionMap = inventoryTransactionLegDAO
.findLastTransactionByParentIdAndParentType(InventoryTransactionLeg.Type.OUT.name(), stitchedItemIds, InventoryArtifactType.STITCHING_OFFLINE.name())
.stream()
.collect(Collectors.toMap(InventoryTransactionLeg::getParentDocumentId, Function.identity()));
// create transaction
InventoryTransaction transaction = createInventoryTransaction("Against Segregation of Finished Items");
// create IN and OUT for all approved items
for (FinishedItem finishedItem : items) {
InventoryTransactionLeg lastInvTransaction = lastFinishedItemIdInTransactionMap.getOrDefault(finishedItem.getId(), null);
finishedItem.setIsQa(true);
finishedItem.setOperationDate(LocalDateTime.now());
/*
* item is approved and alter is selected then finished item will to stitching account
* */
if (status.equalsIgnoreCase("ALTER")) {
// create OUT and IN transactions for FI
if (lastInvTransaction != null) {
// OUT
long fromAccount = lastInvTransaction.getAccountId();
createInventoryTransactionLeg(transaction, finishedItem, fromAccount, InventoryTransactionLeg.Type.OUT.name(), InventoryArtifactType.FINISHED_ITEM.name());
// IN
// get the stitching account id
long stitchedItemId = finishedItem.getStitchedItemId();
InventoryTransactionLeg lastOutTransaction = lastStitchedItemOutTransactionMap.getOrDefault(stitchedItemId, null);
createInventoryTransactionLeg(transaction, finishedItem, lastOutTransaction.getAccountId(), InventoryTransactionLeg.Type.IN.name(), InventoryArtifactType.FINISHED_ITEM.name());
finishedItem.setQaStatus("ALTER");
finishedItem.setIsSegregated(false);
}
}
/*
* item is not approved and washed is selected then item remain in Finishing account
* */
if (status.equalsIgnoreCase("WASHED")) {
finishedItem.setIsSegregated(false);
finishedItem.setQaStatus("WASHED");
}
/*
* item is not approved and B grade is selected then item remain in Finishing account because after
* alteration item will be moved to A grade account for segregation
* */
if (status.equalsIgnoreCase("B GRADE")) {
finishedItem.setIsSegregated(false);
finishedItem.setQaStatus("B GRADE");
}
/*
* item is not approved and C grade is selected then item remain in Finishing account because after
* alteration item will be moved to A grade account for segregation
* */
if (status.equalsIgnoreCase("REJECT")) {
finishedItem.setIsSegregated(false);
finishedItem.setQaStatus("REJECT");
}
/*
* item is approved and grade is selected then fI is move to grade account
*/
if (status.equalsIgnoreCase("APPROVED")) {
finishedItem.setQaStatus("APPROVED");
finishedItem.setIsSegregated(true);
}
updatedItems.add(finishedItem);
}
// save finish items
finishedItemDAO.saveAll(updatedItems);
}
}
/*
* Packaging items
* */
@Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
public void createPackagingItemAndTransaction(FinishedItemWrapper wrapper) {
if (wrapper != null && wrapper.getItems() != null) {
List<FinishedItem> items = wrapper.getItems();
List<FinishedItem> updatedItems = new ArrayList<>();
List<PackagingItems> packagingItems = new ArrayList<>();
// finished ids
List<Long> finishedItemIds = items.stream().map(FinishedItem::getId)
.collect(Collectors.toList());
// stitched ids
List<Long> stitchedItemIds = items.stream().map(FinishedItem::getStitchedItemId)
.collect(Collectors.toList());
// find parent doc type last IN transaction map
Map<Long, InventoryTransactionLeg> lastFinishedItemIdInTransactionMap = inventoryTransactionLegDAO
.findLastTransactionByParentIdAndParentType(InventoryTransactionLeg.Type.IN.name(), finishedItemIds, InventoryArtifactType.FINISHED_ITEM.name())
.stream()
.collect(Collectors.toMap(InventoryTransactionLeg::getParentDocumentId, Function.identity()));
// create transaction
InventoryTransaction transaction = createInventoryTransaction("Against Segregation of Finished Items");
// create IN and OUT for all approved items
for (FinishedItem finishedItem : items) {
InventoryTransactionLeg lastInvTransaction = lastFinishedItemIdInTransactionMap.getOrDefault(finishedItem.getId(), null);
finishedItem.setIsQa(true);
if (finishedItem.getQaStatus().equalsIgnoreCase("APPROVED") && finishedItem.getIsSegregated()) {
// create OUT and IN transactions for FI
PackagingItems packagingItems1 = (createPackagingItem(finishedItem));
packagingItems1.setId(packagingItemsDAO.save(packagingItems1));
if (lastInvTransaction != null) {
// OUT
long fromAccount = lastInvTransaction.getAccountId();
createInventoryTransactionLeg(transaction, finishedItem, fromAccount, InventoryTransactionLeg.Type.OUT.name(), InventoryArtifactType.FINISHED_ITEM.name());
// IN
createInventoryTransactionLeg(transaction, packagingItems1, 8, InventoryTransactionLeg.Type.IN.name(), InventoryArtifactType.PACKAGING.name());
}
finishedItem.setIsSegregated(true);
finishedItem.setPackaging(true);
packagingItems.add(packagingItems1);
}
updatedItems.add(finishedItem);
}
// save finish items
finishedItemDAO.saveAll(updatedItems);
packagingItemsDAO.saveAll(packagingItems);
}
}
/*
* find item summary by account
* */
public List<InventorySummary> findItemSummaryByAccountId(long accountId) {
return inventoryTransactionLegDAO.findSummaryByAccountId(accountId);
}
private PackagingItems createPackagingItem(FinishedItem finishedItem) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
PackagingItems packagingItems = new PackagingItems();
packagingItems.setItemId(finishedItem.getItemId());
packagingItems.setAccountId(finishedItem.getAccountId());
packagingItems.setFinishedItemId(finishedItem.getId());
packagingItems.setJobCardId(finishedItem.getJobCardId());
packagingItems.setJobCard(finishedItem.getJobCard());
packagingItems.setSku(finishedItem.getSku());
packagingItems.setBarcode(finishedItem.getBarcode());
packagingItems.setCreatedAt(LocalDateTime.now());
packagingItems.setCreatedBy(authentication.getName());
packagingItems.setIsQa(finishedItem.getIsQa());
packagingItems.setIsSegregated(finishedItem.getIsSegregated());
packagingItems.setQaStatus(finishedItem.getQaStatus());
return packagingItems;
}
}