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

588 lines
32 KiB
Java

package com.utopiaindustries.service;
import com.utopiaindustries.dao.ctp.*;
import com.utopiaindustries.model.ctp.*;
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;
public InventoryService( JobCardItemDAO jobCardItemDAO, CutPieceDAO cutPieceDAO, BundleDAO bundleDAO, InventoryTransactionLegDAO inventoryTransactionLegDAO, InventoryTransactionDAO inventoryTransactionDAO, JobCardDAO jobCardDAO, CryptographyService cryptographyService, MasterBundleDAO masterBundleDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO) {
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;
}
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) {
// create + save bundles
List<Bundle> bundles = createBundles( jobCardItem, piecesMap.get( jobCardItem.getId( ) ) );
// create transactions
createTransactions( bundles, jobCardItem.getAccountId( ), InventoryArtifactType.BUNDLE.name( ));
jobCardItem.setActualProduction( jobCardItemIdToActualProdMap.getOrDefault( jobCardItem.getId( ) , BigDecimal.ZERO ) );
}
// update items with quantity
jobCardItemDAO.saveAll( items );
// update job card inv status
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( ));
// set balance
BigDecimal initialBalance = calculateBalance( accountId, artifact.getItemId( ), parentDocumentType, artifact.getType( ));
if ( transactionType.equalsIgnoreCase( InventoryTransactionLeg.Type.IN.name( ))) {
initialBalance = initialBalance.add( inventoryTransactionLeg.getQuantity( ));
} 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,
List<CutPiece> jobCardItemPieces ) {
Authentication authentication = SecurityContextHolder.getContext( ).getAuthentication( );
if ( jobCardItemPieces != null && !jobCardItemPieces.isEmpty( )) {
List<Bundle> bundles = new ArrayList<>( );
// create bundle against every cut piece
for ( CutPiece cutPiece : jobCardItemPieces ) {
Bundle bundle = new Bundle( );
bundle.setItemId( jobCardItem.getItemId( ));
bundle.setSku( jobCardItem.getSku( ));
bundle.setJobCardId( jobCardItem.getJobCardId( ) );
bundle.setWrapQuantity( cutPiece.getQuantity( ));
bundle.setType( cutPiece.getType( ));
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
createInventoryTransactionLeg( transaction, bundle, toAccount, InventoryTransactionLeg.Type.IN.name( ), InventoryArtifactType.BUNDLE.name( ));
}
}
// update status
masterBundle.setIsReceived( true);
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) {
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( JobCard jobCard) {
List<JobCardItem> jobCardItems = jobCard.getItems( );
List<JobCardItem> updatedItems = new ArrayList<>( );
// validate items
validateItems( jobCardItems);
// check whether all bundles are received against finish goods
checkAllBundleAreReceived( jobCard.getId( ), jobCardItems);
for ( JobCardItem item : jobCardItems) {
// select which has inventory
if ( item.getProduction( ).compareTo( BigDecimal.ZERO ) != 0 ) {
// production is completed out bundles
if ( item.getActualProduction( ).compareTo( item.getTotalProduction( ).add( item.getProduction( ))) == 0) {
// create out transactions of bundles in master bundles
List<Bundle> bundles = bundleDAO.findByItemIdAndCardId( item.getItemId( ), jobCard.getId( ));
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 Stitching to Stitched Offline Item");
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( ));
}
}
}
}
// create finished items
List<StitchingOfflineItem> stitchingOfflineItems = createStitchingOfflineItems( item);
// create IN Transactions of Finished Items into account
createTransactions( stitchingOfflineItems, jobCard.getToAccountId( ), InventoryArtifactType.STITCHING_OFFLINE.name( ));
item.setTotalProduction( item.getTotalProduction( ).add( item.getProduction( )));
item.setJobCardId( jobCard.getId( ));
updatedItems.add( item);
}
}
// save all
jobCardItemDAO.saveAll( updatedItems);
}
/*
* create finished items
* */
public List<StitchingOfflineItem> createStitchingOfflineItems( JobCardItem jobCardItem) {
Authentication authentication = SecurityContextHolder.getContext( ).getAuthentication( );
List<StitchingOfflineItem> items = new ArrayList<>( );
if ( jobCardItem != null) {
for ( int i = 1; i <= jobCardItem.getProduction( ).intValue( ); i++) {
StitchingOfflineItem stitchingOfflineItem = new StitchingOfflineItem( );
stitchingOfflineItem.setCreatedAt( LocalDateTime.now( ));
stitchingOfflineItem.setCreatedBy( authentication.getName( ));
stitchingOfflineItem.setItemId( jobCardItem.getItemId( ));
stitchingOfflineItem.setSku( jobCardItem.getSku( ));
stitchingOfflineItem.setJobCardId( jobCardItem.getId( ));
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 ) {
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<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 i f 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 ( stitchingOfflineItem.getQaStatus( ).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.setStitchedItemId( stitchingOfflineItem.getId( ));
finishedItem.setJobCardId( stitchingOfflineItem.getJobCardId( ));
finishedItem.setIsQa( false);
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);
// 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, stitchingOfflineItem, fromAccount, InventoryTransactionLeg.Type.OUT.name( ), InventoryArtifactType.FINISHED_ITEM.name( ));
}
// create IN in finishing Account Finished Item
finishedItems.add( preCreatedItem );
}
}
}
for ( FinishedItem finishedItem : finishedItems) {
// IN
createInventoryTransactionLeg( transaction, finishedItem, wrapper.getFinishedAccountId( ), InventoryTransactionLeg.Type.IN.name( ), InventoryArtifactType.FINISHED_ITEM.name( ));
}
// save updated stitched items
stitchingOfflineItemDAO.saveAll( wrapper.getItems( ));
}
}
/*
* segregate finish items
* */
@Transactional( rollbackFor = Exception.class, propagation = Propagation.NESTED )
public void segregateFinishedItems( FinishedItemWrapper wrapper) {
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);
/*
* item is not approved and washed is selected then item remain in Finishing account
* */
/*
* item is approved and alter is selected then finished item will to stitching account
* */
if ( finishedItem.getQaStatus( ).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( ));
}
}
/*
* item is approved and grade is selected then fI is move to grade account
*/
if ( finishedItem.getQaStatus( ).equalsIgnoreCase( "APPROVED") && finishedItem.getAccountId( ) != 0) {
// 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
createInventoryTransactionLeg( transaction, finishedItem, finishedItem.getAccountId( ), InventoryTransactionLeg.Type.IN.name( ), InventoryArtifactType.FINISHED_ITEM.name( ));
}
finishedItem.setIsSegregated( true);
}
updatedItems.add( finishedItem);
}
finishedItemDAO.saveAll( updatedItems);
// save finish items
}
}
/*
* find item summary by account
* */
public List<InventorySummary> findItemSummaryByAccountId( long accountId) {
return inventoryTransactionLegDAO.findSummaryByAccountId( accountId);
}
}