597 lines
32 KiB
Java
597 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 if(transactionType.equalsIgnoreCase( InventoryTransactionLeg.Type.OUT.name( )) && 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,
|
|
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) {
|
|
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( 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) {
|
|
if(item.getTotalProduction() == null){
|
|
item.setTotalProduction(BigDecimal.ZERO);
|
|
}
|
|
item.setJobCardId(jobCard.getId());
|
|
// 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.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 ) {
|
|
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 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 ( 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);
|
|
}
|
|
}
|