add sku based cut-piece fetch on job card creating screen

pull/8/head
Usama Khan 2025-02-17 21:05:29 -08:00
parent 2c1aeda4c4
commit 0d61494a3f
9 changed files with 241 additions and 25 deletions

View File

@ -21,6 +21,7 @@ public class CutPieceTypeDAO {
private final String SELECT_ALL_QUERY = String.format( "SELECT * FROM %s ORDER BY id DESC", TABLE_NAME );
private final String DELETE_QUERY = String.format( "DELETE FROM %s WHERE id = :id", TABLE_NAME );
private final String INSERT_QUERY = String.format( "INSERT INTO %s (id, title) VALUES (:id, :title) ON DUPLICATE KEY UPDATE title = VALUES(title)", TABLE_NAME );
private final String SELECT_BY_TITLE = String.format("SELECT * FROM %s WHERE title = :title", TABLE_NAME);
public CutPieceTypeDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
@ -30,7 +31,7 @@ public class CutPieceTypeDAO {
private MapSqlParameterSource prepareInsertQueryParams( CutPieceType cutPieceType ) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue( "id", cutPieceType.getId() )
.addValue( "title", cutPieceType.getTitle() );
.addValue( "title", cutPieceType.getType() );
return params;
}
@ -44,6 +45,16 @@ public class CutPieceTypeDAO {
.orElse( new CutPieceType() );
}
// find
public CutPieceType findByTitle( String title ) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue( "title", title );
return namedParameterJdbcTemplate.query( SELECT_BY_TITLE, params, new CutPieceTypeRowMapper() )
.stream()
.findFirst()
.orElse( new CutPieceType() );
}
// find all
public List<CutPieceType> findAll() {
return namedParameterJdbcTemplate.query( SELECT_ALL_QUERY, new CutPieceTypeRowMapper() );

View File

@ -10,7 +10,7 @@ public class CutPieceTypeRowMapper implements RowMapper<CutPieceType> {
public CutPieceType mapRow( ResultSet rs, int rowNum ) throws SQLException {
CutPieceType cutPieceType = new CutPieceType();
cutPieceType.setId( rs.getLong( "id" ) );
cutPieceType.setTitle( rs.getString( "title" ) );
cutPieceType.setType( rs.getString( "title" ) );
return cutPieceType;
}
}

View File

@ -0,0 +1,18 @@
package com.utopiaindustries.dao.ctp;
import com.utopiaindustries.model.ctp.CutPiece;
import com.utopiaindustries.model.ctp.SkuCutPieces;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SkuCutPieceRowMapper implements RowMapper<SkuCutPieces> {
public SkuCutPieces mapRow(ResultSet rs, int rowNum) throws SQLException {
SkuCutPieces skuCutPieces = new SkuCutPieces();
skuCutPieces.setId(rs.getLong("id"));
skuCutPieces.setSku(rs.getString("sku"));
skuCutPieces.setType(rs.getString("title"));
return skuCutPieces;
}
}

View File

@ -0,0 +1,96 @@
package com.utopiaindustries.dao.ctp;
import com.utopiaindustries.model.ctp.CutPieceType;
import com.utopiaindustries.model.ctp.SkuCutPieces;
import com.utopiaindustries.util.KeyHolderFunctions;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
@Repository
public class SkuCutPiecesDAO {
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private final String TABLE_NAME = "cut_to_pack.sku_cut_piece";
private final String SELECT_QUERY = String.format( "SELECT * FROM %s WHERE id = :id", TABLE_NAME );
private final String SELECT_ALL_QUERY = String.format( "SELECT * FROM %s ORDER BY id DESC", TABLE_NAME );
private final String DELETE_QUERY = String.format( "DELETE FROM %s WHERE id = :id", TABLE_NAME );
private final String INSERT_QUERY = String.format("INSERT INTO %s (sku, title) VALUES (:sku, :title) ON DUPLICATE KEY UPDATE sku = VALUES(sku), title = VALUES(title)", TABLE_NAME);
private final String FIND_BY_SKU = String.format( "SELECT * FROM %s WHERE sku = :sku", TABLE_NAME );
private final String CHECK_EXISTENCE_QUERY = String.format("SELECT COUNT(*) FROM %s WHERE title = :title AND sku = :sku", TABLE_NAME);
public SkuCutPiecesDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
// prepare query params
private MapSqlParameterSource prepareInsertQueryParams(SkuCutPieces skuCutPieces ) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue( "id", skuCutPieces.getId() )
.addValue( "sku", skuCutPieces.getSku())
.addValue("title",skuCutPieces.getType());
return params;
}
// find
public SkuCutPieces find( long id ) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue( "id", id );
return namedParameterJdbcTemplate.query( SELECT_QUERY, params, new SkuCutPieceRowMapper() )
.stream()
.findFirst()
.orElse( new SkuCutPieces() );
}
public boolean doesExist(String type, String sku) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("title", type);
params.addValue("sku", sku);
Long count = namedParameterJdbcTemplate.queryForObject(CHECK_EXISTENCE_QUERY, params, Long.class);
return count > 0;
}
//find by sku
public List<SkuCutPieces> findBySku(String sku) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("sku", sku);
return namedParameterJdbcTemplate.query(FIND_BY_SKU, params, new SkuCutPieceRowMapper());
}
// find all
public List<CutPieceType> findAll() {
return namedParameterJdbcTemplate.query( SELECT_ALL_QUERY, new CutPieceTypeRowMapper() );
}
// save
public long save( SkuCutPieces skuCutPieces ) {
KeyHolder keyHolder = new GeneratedKeyHolder();
MapSqlParameterSource params = prepareInsertQueryParams( skuCutPieces );
namedParameterJdbcTemplate.update( INSERT_QUERY, params, keyHolder );
return KeyHolderFunctions.getKey( skuCutPieces.getId(), keyHolder );
}
// save all
public int[] saveAll( List<SkuCutPieces> skuCutPieces ) {
List<MapSqlParameterSource> batchArgs = new ArrayList<>();
for ( SkuCutPieces cutPieceType: skuCutPieces ) {
MapSqlParameterSource params = prepareInsertQueryParams( cutPieceType );
batchArgs.add( params );
}
return namedParameterJdbcTemplate.batchUpdate( INSERT_QUERY, batchArgs.toArray(new MapSqlParameterSource[skuCutPieces.size()]) );
}
// delete
public boolean delete( long id ) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue( "id", id );
return namedParameterJdbcTemplate.update( DELETE_QUERY, params ) > 0;
}
}

View File

@ -3,7 +3,7 @@ package com.utopiaindustries.model.ctp;
public class CutPieceType {
private long id;
private String title;
private String type;
public long getId() {
return id;
@ -13,19 +13,19 @@ public class CutPieceType {
this.id = id;
}
public String getTitle() {
return title;
public String getType() {
return type;
}
public void setTitle(String title) {
this.title = title;
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "CutPieceType{" +
"id=" + id +
", title='" + title + '\'' +
", title='" + type + '\'' +
'}';
}
}

View File

@ -0,0 +1,43 @@
package com.utopiaindustries.model.ctp;
public class SkuCutPieces {
private long id;
private String sku;
private String type;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getSku() {
return sku;
}
public void setSku(String sku) {
this.sku = sku;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "CutPiece{" +
"id=" + id +
", sku=" + sku +
", type='" + type +
'}';
}
}

View File

@ -1,19 +1,42 @@
package com.utopiaindustries.restcontroller;
import com.utopiaindustries.dao.ctp.CutPieceTypeDAO;
import com.utopiaindustries.dao.ctp.SkuCutPiecesDAO;
import com.utopiaindustries.model.ctp.CutPieceType;
import com.utopiaindustries.model.ctp.SkuCutPieces;
import com.utopiaindustries.service.JobCardService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping( "/rest/cut-pieces" )
public class CutPieceRestController {
private final JobCardService jobCardService;
private final SkuCutPiecesDAO skuCutPiecesDAO;
private final CutPieceTypeDAO cutPieceTypeDAO;
public CutPieceRestController(JobCardService jobCardService) {
public CutPieceRestController(JobCardService jobCardService, SkuCutPiecesDAO skuCutPiecesDAO, CutPieceTypeDAO cutPieceTypeDAO) {
this.jobCardService = jobCardService;
this.skuCutPiecesDAO = skuCutPiecesDAO;
this.cutPieceTypeDAO = cutPieceTypeDAO;
}
@GetMapping
public List<CutPieceType> getBySku(@RequestParam("sku") String sku) {
try {
ArrayList<CutPieceType> cutPieceTypes = new ArrayList<>();
List<SkuCutPieces> skuCutPieces = skuCutPiecesDAO.findBySku(sku);
for (SkuCutPieces skuCutPieces1 : skuCutPieces){
CutPieceType cutPieceType = cutPieceTypeDAO.findByTitle(skuCutPieces1.getType());
cutPieceTypes.add(cutPieceType);
}
return cutPieceTypes;
} catch (Exception e) {
throw new RuntimeException("An error occurred while fetching data for SKU: " + sku, e);
}
}
@PostMapping

View File

@ -35,8 +35,10 @@ public class JobCardService {
private final UserInventoryAccountDAO userInventoryAccountDAO;
private final FinishedItemDAO finishedItemDAO;
private final StitchingOfflineItemDAO stitchingOfflineItemDAO;
private final SkuCutPiecesDAO skuCutPiecesDAO;
public JobCardService(JobCardDAO jobCardDAO, CutPieceTypeDAO cutPieceTypeDAO, JobCardItemDAO jobCardItemDAO, CutPieceDAO cutPieceDAO, ItemDAO itemDAO, LocationSiteDAO locationSiteDAO, PurchaseOrderDAO purchaseOrderDAO, UserInventoryAccountDAO userInventoryAccountDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO) {
public JobCardService(JobCardDAO jobCardDAO, CutPieceTypeDAO cutPieceTypeDAO, JobCardItemDAO jobCardItemDAO, CutPieceDAO cutPieceDAO, ItemDAO itemDAO, LocationSiteDAO locationSiteDAO, PurchaseOrderDAO purchaseOrderDAO, UserInventoryAccountDAO userInventoryAccountDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO, SkuCutPiecesDAO skuCutPiecesDAO) {
this.skuCutPiecesDAO = skuCutPiecesDAO;
this.jobCardDAO = jobCardDAO;
this.cutPieceTypeDAO = cutPieceTypeDAO;
this.jobCardItemDAO = jobCardItemDAO;
@ -138,6 +140,13 @@ public class JobCardService {
long itemId = jobCardItemDAO.save(item);
for (CutPiece cutPiece : item.getCutPieces()) {
cutPiece.setJobCardItemId(itemId);
if (!skuCutPiecesDAO.doesExist(cutPiece.getType(), item.getSku())){
SkuCutPieces skuCutPieces = new SkuCutPieces();
skuCutPieces.setType(cutPiece.getType());
skuCutPieces.setSku(item.getSku());
//save cut-piece for sku next time fetch
skuCutPiecesDAO.save(skuCutPieces);
}
cutPieces.add(cutPiece);
}
}

View File

@ -84,6 +84,24 @@
onItemSelect(itemId, invItem) {
this.item.itemId = invItem.id;
this.item.sku = invItem.sku;
},
searchCutPieceBySku(sku) {
$.ajax({
url: `/ctp/rest/cut-pieces?sku=${sku}`,
method: 'GET',
success: (response) => {
this.$set(this.item, 'cutPieces', response);
},
error: (error) => {
console.error('Error fetching data:', error);
}
});
}
},
watch: {
'item.sku': function(newSku, oldSku) {
console.log('SKU changed:', newSku);
this.searchCutPieceBySku(newSku);
}
},
template: `
@ -161,8 +179,6 @@
</a>
</div>
</div>
</div>
`
});
@ -178,14 +194,16 @@
template: `
<div class="row mt-1">
<input hidden="hidden" v-bind:name="'items[' + pIndex + '].cutPieces[' + index +'].id'" v-bind:value="piece.id">
<input hidden="hidden" v-bind:name="'items[' + pIndex + '].cutPieces[' + index +'].jobCardItemId'" v-bind:value="piece.jobCardItemId">
<input hidden="hidden" v-bind:name="'items[' + pIndex + '].cutPieces[' + index + '].jobCardItemId'" v-bind:value="piece.jobCardItemId || 0">
<div class="col-md-5">
<select class="form-control" v-bind:name="'items[' + pIndex + '].cutPieces[' + index +'].type'" v-model="piece.type" required>
<option value="">Please Select</option>
<option v-for="(type,index) in $types"
v-bind:selected="type.title === piece.type"
v-bind:value="type.title">{{type.title}}</option>
</select>
<select class="form-control"
v-bind:name="'items[' + pIndex + '].cutPieces[' + index +'].type'"
v-model="piece.type" required>
<option value="">Please Select</option>
<option v-for="(title, index) in $types"
v-bind:selected="title.type === piece.type"
v-bind:value="title.type">{{ title.type }}</option>
</select>
</div>
<div class="col-md-5">
<input type="number" class="form-control" v-bind:name="'items[' + pIndex + '].cutPieces[' + index +'].quantity'" v-model="piece.quantity" required>
@ -195,10 +213,8 @@
</div>
</div>
`
});
let app = new Vue({
el: '#jobCardApp',
data: {