add-reporting-dashboard #18
2
pom.xml
2
pom.xml
|
@ -395,7 +395,7 @@
|
|||
<jvmArguments>-Xms1024m</jvmArguments>
|
||||
<jvmArguments>-Xmx8g</jvmArguments>
|
||||
</configuration>
|
||||
</plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>8</source><target>8</target></configuration></plugin>
|
||||
</plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>9</source><target>9</target></configuration></plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
package com.utopiaindustries.controller;
|
||||
|
||||
import com.utopiaindustries.auth.CuttingRole;
|
||||
import com.utopiaindustries.auth.ReportingRole;
|
||||
import com.utopiaindustries.model.ctp.SummaryInventoryReport;
|
||||
import com.utopiaindustries.service.InventoryAccountService;
|
||||
import com.utopiaindustries.service.ReportingService;
|
||||
import com.utopiaindustries.service.SummaryInventoryReportService;
|
||||
import com.utopiaindustries.util.StringUtils;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
|
@ -20,14 +23,19 @@ import java.util.Map;
|
|||
@ReportingRole
|
||||
@RequestMapping( "/reporting" )
|
||||
public class ReportingController {
|
||||
private final ReportingService reportingService;
|
||||
private final SummaryInventoryReportService summaryInventoryReportService;
|
||||
private final InventoryAccountService inventoryAccountService;
|
||||
|
||||
public ReportingController(SummaryInventoryReportService summaryInventoryReportService2) {
|
||||
|
||||
public ReportingController(SummaryInventoryReportService summaryInventoryReportService2, ReportingService reportingService, InventoryAccountService inventoryAccountService) {
|
||||
this.summaryInventoryReportService = summaryInventoryReportService2;
|
||||
this.reportingService = reportingService;
|
||||
this.inventoryAccountService = inventoryAccountService;
|
||||
}
|
||||
|
||||
@GetMapping( "/summary")
|
||||
public String showMasterBundles(@RequestParam(value = "item-id", required = false ) String itemId, @RequestParam(value = "sku" , required = false) String sku, @RequestParam(value = "start-date", required = false) String startDate, @RequestParam(value = "end-date", required = false) String endDate, Model model ){
|
||||
public String summary(@RequestParam(value = "item-id", required = false ) String itemId, @RequestParam(value = "sku" , required = false) String sku, @RequestParam(value = "start-date", required = false) String startDate, @RequestParam(value = "end-date", required = false) String endDate, Model model ){
|
||||
|
||||
LocalDate startDate1 = StringUtils.isNullOrEmpty(startDate) ? LocalDate.now().minusDays(6) : LocalDate.parse(startDate);
|
||||
LocalDate endDate1 = StringUtils.isNullOrEmpty(endDate) ? LocalDate.now().plusDays(1) : LocalDate.parse(endDate);
|
||||
|
@ -40,6 +48,53 @@ public class ReportingController {
|
|||
return "/reporting/inventory-summary";
|
||||
}
|
||||
|
||||
@GetMapping( "/job-card-report")
|
||||
public String jobCardReport(@RequestParam( value = "job-card-id", required = false ) String jobCardId,
|
||||
Model model, RedirectAttributes redirectAttributes ){
|
||||
if( jobCardId == null || jobCardId.isEmpty()) {
|
||||
redirectAttributes.addFlashAttribute("error", "Please Re-Select Job Card" );
|
||||
return "/reporting/job-card-report";
|
||||
}
|
||||
model.addAttribute("totalProduction", reportingService.getTotalProduction(jobCardId));
|
||||
model.addAttribute("phasesTimes", reportingService.getEachPhaseTotalTime(jobCardId));
|
||||
model.addAttribute("segregateItems", reportingService.getSegregateItems(jobCardId));
|
||||
model.addAttribute("pendingStatus", reportingService.countPendingItemsOnDifferentPhases(jobCardId));
|
||||
model.addAttribute("completeProduction", reportingService.getCompleteProduction(jobCardId));
|
||||
model.addAttribute("jobCardProgress", reportingService.getJobCardProgress(jobCardId));
|
||||
model.addAttribute("cuttingDetails", reportingService.getCuttingDetails(jobCardId));
|
||||
model.addAttribute("stitchingDetails", reportingService.getStitchingDetails(jobCardId));
|
||||
model.addAttribute("dailyProgress", reportingService.getPhasesProgressDayWise(jobCardId));
|
||||
|
||||
return "/reporting/job-card-report";
|
||||
}
|
||||
|
||||
@GetMapping( "/po-report")
|
||||
public String poReport(@RequestParam(value = "poName", required = false) String poName, Model model){
|
||||
|
||||
model.addAttribute("allPOs", reportingService.getAllPOs(poName));
|
||||
return "/reporting/po-report";
|
||||
}
|
||||
|
||||
@GetMapping( value = "/po-report-view/{poNo}" )
|
||||
public String showJobCardDetail( @PathVariable("poNo") String poNo, @RequestParam(value = "select-date", required = false) String selectDate ,
|
||||
Model model ){
|
||||
model.addAttribute("allJobCard", reportingService.getAllPoJobCards(poNo, selectDate));
|
||||
return "/reporting/po-job-card-report";
|
||||
}
|
||||
|
||||
@GetMapping( value = "/cutting-report" )
|
||||
public String cuttingReport(@RequestParam(value = "job-card-id", required = false ) String jobCardId, @RequestParam(value = "accountId" , required = false) String accountId, @RequestParam(value = "start-date", required = false) String startDate, @RequestParam(value = "end-date", required = false) String endDate, Model model ){
|
||||
|
||||
LocalDate startDate1 = StringUtils.isNullOrEmpty(startDate) ? LocalDate.now().minusDays(31) : LocalDate.parse(startDate);
|
||||
LocalDate endDate1 = StringUtils.isNullOrEmpty(endDate) ? LocalDate.now() : LocalDate.parse(endDate);
|
||||
model.addAttribute("startDate", startDate1);
|
||||
model.addAttribute("endDate", endDate1);
|
||||
model.addAttribute("accounts", inventoryAccountService.getAllCuttingAccounts() );
|
||||
model.addAttribute("cutting",reportingService.getCuttingTableDetails(jobCardId, accountId, startDate1.toString(), endDate1.toString()));
|
||||
|
||||
return "/reporting/cutting-report";
|
||||
}
|
||||
|
||||
private ArrayList<LocalDate> generateDateList(LocalDate start, LocalDate end) {
|
||||
ArrayList<LocalDate> localDates = new ArrayList<>();
|
||||
while (start.isBefore(end)) {
|
||||
|
|
|
@ -26,10 +26,12 @@ public class BundleDAO {
|
|||
private final String SELECT_BY_LIMIT = String.format( "SELECT * FROM %s ORDER BY id DESC LIMIT :limit", TABLE_NAME );
|
||||
private final String SELECT_BY_MASTER_ID = String.format( "SELECT * FROM %s WHERE master_bundle_id = :master_bundle_id ORDER BY id DESC", TABLE_NAME );
|
||||
private final String SELECT_BY_IDS = String.format( "SELECT * FROM %s WHERE id IN (:ids)", TABLE_NAME );
|
||||
private final String SELECT_BY_ITEM_ID_AND_JOB_CARD = String.format( "SELECT * FROM %s WHERE item_id = :item_id AND job_card_id = :job_card_id", TABLE_NAME );
|
||||
private final String SELECT_BY_JOB_CARD = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id", TABLE_NAME );
|
||||
private final String SELECT_BY_ITEM_IDS_AND_JOB_CARD = String.format( "SELECT * FROM %s WHERE item_id IN (:item_ids) AND job_card_id = :job_card_id", TABLE_NAME );
|
||||
private final String SELECT_LIKE_BARCODE = String.format("SELECT * FROM %s WHERE barcode LIKE :barcode", TABLE_NAME);
|
||||
|
||||
private final String SELECT_FIRST_BUNDLE_BY_JOB_CARD = String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id ORDER BY created_at ASC LIMIT 1", TABLE_NAME);
|
||||
private final String SELECT_LAST_BUNDLE_BY_JOB_CARD = String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id ORDER BY created_at DESC LIMIT 1", TABLE_NAME);
|
||||
private final String SELECT_BY_JOB_CARD_AND_DATE = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR created_at BETWEEN :start_date AND :end_date)", TABLE_NAME );
|
||||
|
||||
public BundleDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
|
||||
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
||||
|
@ -132,11 +134,10 @@ public class BundleDAO {
|
|||
return namedParameterJdbcTemplate.query( SELECT_BY_IDS , params, new BundleRowMapper() );
|
||||
}
|
||||
|
||||
public List<Bundle> findByItemIdAndCardId( long itemId, long cardId ){
|
||||
public List<Bundle> findByCardId( long cardId ){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("item_id", itemId );
|
||||
params.addValue("job_card_id", cardId );
|
||||
return namedParameterJdbcTemplate.query( SELECT_BY_ITEM_ID_AND_JOB_CARD, params, new BundleRowMapper() );
|
||||
return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD, params, new BundleRowMapper() );
|
||||
}
|
||||
|
||||
public List<Bundle> findByItemIdsAndCardId( List<Long> itemIds, long cardId ){
|
||||
|
@ -146,4 +147,27 @@ public class BundleDAO {
|
|||
params.addValue("job_card_id", cardId );
|
||||
return namedParameterJdbcTemplate.query( SELECT_BY_ITEM_IDS_AND_JOB_CARD, params, new BundleRowMapper() );
|
||||
}
|
||||
|
||||
public Bundle findFirstBundleByCardId(long cardId) {
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", cardId);
|
||||
return namedParameterJdbcTemplate.queryForObject(SELECT_FIRST_BUNDLE_BY_JOB_CARD, params, new BundleRowMapper());
|
||||
}
|
||||
|
||||
public Bundle findLastBundleByCardId(long cardId) {
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", cardId);
|
||||
return namedParameterJdbcTemplate.query(SELECT_LAST_BUNDLE_BY_JOB_CARD, params, new BundleRowMapper())
|
||||
.stream()
|
||||
.findFirst().orElse(new Bundle());
|
||||
}
|
||||
|
||||
public List<Bundle> findByCardIdAndDATE( long cardId, String startDate, String endDate){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", cardId );
|
||||
params.addValue( "start_date", startDate );
|
||||
params.addValue( "end_date", endDate );
|
||||
return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD_AND_DATE, params, new BundleRowMapper() );
|
||||
}
|
||||
|
||||
}
|
|
@ -32,6 +32,8 @@ public class FinishedItemDAO {
|
|||
private final String SELECT_BY_TERM = String.format( "SELECT * FROM %s WHERE barcode LIKE :term AND is_segregated = :is_segregated ORDER BY ID DESC", TABLE_NAME );
|
||||
private final String SELECT_BY_STITCHED_ITEM_ID = String.format( "SELECT * FROM %s WHERE stitched_item_id = :stitched_item_id", TABLE_NAME );
|
||||
private final String SELECT_BY_STITCHED_ITEM_IDS = String.format( "SELECT * FROM %s WHERE stitched_item_id IN (:stitched_item_ids)", TABLE_NAME );
|
||||
private final String COUNT_TOTAL_FINISH_ITEM= String.format("SELECT COUNT(*) FROM %s WHERE job_card_id = :job_card_id AND is_segregated IS TRUE ",TABLE_NAME);
|
||||
private final String SELECT_BY_JOB_CARD_AND_DATE = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR created_at BETWEEN :start_date AND :end_date)", TABLE_NAME );
|
||||
|
||||
public FinishedItemDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
|
||||
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
||||
|
@ -168,4 +170,20 @@ public class FinishedItemDAO {
|
|||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public Long calculateTotalFinishItem( long jobCardId ){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", jobCardId );
|
||||
Long count = namedParameterJdbcTemplate.queryForObject(COUNT_TOTAL_FINISH_ITEM, params, Long.class);
|
||||
return count != null ? count : 0;
|
||||
}
|
||||
|
||||
public List<FinishedItem> calculateTotalFinishItem( long jobCardId, String startDate, String endDate ){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", jobCardId );
|
||||
params.addValue( "start_date", startDate );
|
||||
params.addValue( "end_date", endDate );
|
||||
return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD_AND_DATE, params, new FinishedItemRowMapper() );
|
||||
}
|
||||
|
||||
}
|
|
@ -27,6 +27,7 @@ public class InventoryAccountDAO {
|
|||
private final String SELECT_BY_IDS_AND_PARENT_ENTITY_TYPE_AND_PARENT_ID_AND_COUNT = String.format( "SELECT * FROM %s WHERE id IN (:ids) AND parent_entity_id = :parent_entity_id AND parent_entity_type = :parent_entity_type LIMIT :limit", TABLE_NAME );
|
||||
private final String SELECT_BY_IDS_PACKAGING_AND_COUNT = String.format( "SELECT * FROM %s WHERE id IN (:ids) AND is_packaging = :is_packaging LIMIT :limit", TABLE_NAME );
|
||||
private final String SELECT_BY_PARENT_TYPE_AND_PARENT_ID = String.format( "SELECT * FROM %s WHERE active = TRUE AND parent_entity_type = :parent_entity_type AND parent_entity_id = :parent_entity_id" , TABLE_NAME );
|
||||
private final String SELECT_BY_IS_PACKAGING_TRUE = String.format( "SELECT * FROM %s WHERE is_packaging IS TRUE", TABLE_NAME );
|
||||
|
||||
public InventoryAccountDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
|
||||
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
||||
|
@ -144,4 +145,9 @@ public class InventoryAccountDAO {
|
|||
params.addValue("parent_entity_id", parentEntityId );
|
||||
return namedParameterJdbcTemplate.query( SELECT_BY_PARENT_TYPE_AND_PARENT_ID, params, new InventoryAccountRowMapper() );
|
||||
}
|
||||
|
||||
public List<InventoryAccount> getPackagingAccounts(){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
return namedParameterJdbcTemplate.query( SELECT_BY_IS_PACKAGING_TRUE, params, new InventoryAccountRowMapper() );
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.utopiaindustries.dao.ctp;
|
|||
import com.utopiaindustries.model.ctp.InventorySummary;
|
||||
import com.utopiaindustries.model.ctp.InventoryTransactionLeg;
|
||||
import com.utopiaindustries.util.KeyHolderFunctions;
|
||||
import com.utopiaindustries.util.StringUtils;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||
|
@ -21,7 +22,7 @@ public class InventoryTransactionLegDAO {
|
|||
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 (id, transaction_id, item_id, sku, type, quantity, account_id, balance, transaction_leg_datetime, parent_document_type, parent_document_id, parent_document_piece_type) VALUES (:id, :transaction_id, :item_id, :sku, :type, :quantity, :account_id, :balance, :transaction_leg_datetime, :parent_document_type, :parent_document_id, :parent_document_piece_type) ON DUPLICATE KEY UPDATE transaction_id = VALUES(transaction_id), item_id = VALUES(item_id), sku = VALUES(sku), type = VALUES(type), quantity = VALUES(quantity), account_id = VALUES(account_id), balance = VALUES(balance), transaction_leg_datetime = VALUES(transaction_leg_datetime), parent_document_type = VALUES(parent_document_type), parent_document_id = VALUES(parent_document_id), parent_document_piece_type = VALUES(parent_document_piece_type)", TABLE_NAME );
|
||||
private final String INSERT_QUERY = String.format( "INSERT INTO %s (id, transaction_id, item_id, sku, type, quantity, account_id, balance, transaction_leg_datetime, parent_document_type, parent_document_id, parent_document_piece_type, job_card_id) VALUES (:id, :transaction_id, :item_id, :sku, :type, :quantity, :account_id, :balance, :transaction_leg_datetime, :parent_document_type, :parent_document_id, :parent_document_piece_type, :job_card_id) ON DUPLICATE KEY UPDATE transaction_id = VALUES(transaction_id), item_id = VALUES(item_id), sku = VALUES(sku), type = VALUES(type), quantity = VALUES(quantity), account_id = VALUES(account_id), balance = VALUES(balance), transaction_leg_datetime = VALUES(transaction_leg_datetime), parent_document_type = VALUES(parent_document_type), parent_document_id = VALUES(parent_document_id), parent_document_piece_type = VALUES(parent_document_piece_type), job_card_id = VALUES(job_card_id)", TABLE_NAME );
|
||||
private final String SELECT_LAST_ACCOUNT_ID_AND_ITEM_ID = String.format( "SELECT * FROM %s WHERE account_id = :account_id AND item_id = :item_id AND parent_document_type= :parent_document_type AND parent_document_piece_type = :parent_document_piece_type ORDER BY id DESC LIMIT 1", TABLE_NAME );
|
||||
private final String SELECT_BY_ACCOUNT_ID = String.format( "SELECT * FROM %s WHERE account_id = :account_id ORDER BY id DESC" , TABLE_NAME );
|
||||
private final String SELECT_SUMMARY_BY_ACCOUNT_ID = String.format( "SELECT item_id, sku, parent_document_type,parent_document_piece_type," +
|
||||
|
@ -44,11 +45,20 @@ public class InventoryTransactionLegDAO {
|
|||
" WHERE itl.type = :type" +
|
||||
" AND itl.parent_document_type = :parent_document_type"
|
||||
, TABLE_NAME, TABLE_NAME );
|
||||
private final String COUNT_TOTAL_SEGREGATE_ITEMS = String.format("SELECT COUNT(*) FROM %s WHERE parent_document_id IN (:parent_document_id) AND account_id = :account_id", TABLE_NAME);
|
||||
private final String SELECT_FIRST_TRANSACTION_PARENT_TYPE_PARENT_ID = String.format("SELECT * FROM %s WHERE parent_document_id IN (:parent_document_id) AND parent_document_type = :parent_document_type ORDER BY transaction_leg_datetime ASC LIMIT 1", TABLE_NAME);
|
||||
private final String SELECT_GROUP_By_TRANSACTION_PARENT_TYPE_PARENT_ID = String.format("SELECT * FROM %s WHERE parent_document_id IN (:parent_document_id) AND parent_document_type = :parent_document_type GROUP BY account_id", TABLE_NAME);
|
||||
private final String SELECT_JOB_CARD_DATES = String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR transaction_leg_datetime BETWEEN :start_date AND :end_date) AND type = :type ", TABLE_NAME);
|
||||
private final String SELECT_JOB_CARD_And_Date_Type_Account_Id = String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR transaction_leg_datetime BETWEEN :start_date AND :end_date) AND type = :type AND account_id IN (:account_ids)", TABLE_NAME);
|
||||
|
||||
public InventoryTransactionLegDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
|
||||
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
||||
}
|
||||
|
||||
public List<InventoryTransactionLeg> findByQuery(String query ){
|
||||
return namedParameterJdbcTemplate.query( query, new InventoryTransactionLegRowMapper() );
|
||||
}
|
||||
|
||||
// prepare query params
|
||||
private MapSqlParameterSource prepareInsertQueryParams( InventoryTransactionLeg inventoryTransactionLeg ) {
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
|
@ -63,7 +73,9 @@ public class InventoryTransactionLegDAO {
|
|||
.addValue( "transaction_leg_datetime", inventoryTransactionLeg.getTransactionLegDateTime() )
|
||||
.addValue( "parent_document_type", inventoryTransactionLeg.getParentDocumentType() )
|
||||
.addValue( "parent_document_id", inventoryTransactionLeg.getParentDocumentId() )
|
||||
.addValue("parent_document_piece_type", inventoryTransactionLeg.getParentDocumentPieceType() );
|
||||
.addValue("parent_document_piece_type", inventoryTransactionLeg.getParentDocumentPieceType() )
|
||||
.addValue("job_card_id", inventoryTransactionLeg.getJobCardId() );
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
@ -153,4 +165,57 @@ public class InventoryTransactionLegDAO {
|
|||
params.addValue("parent_document_type", parentType );
|
||||
return namedParameterJdbcTemplate.query( SELECT_LAST_LEG_BY_TYPE_AND_PARENT_ID , params, new InventoryTransactionLegRowMapper() );
|
||||
}
|
||||
|
||||
public Long CalculateTotalGradingItems(List<Long> finishItemIds, Integer accountId) {
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("parent_document_id", finishItemIds);
|
||||
params.addValue("account_id", accountId);
|
||||
|
||||
Long count = namedParameterJdbcTemplate.queryForObject(COUNT_TOTAL_SEGREGATE_ITEMS, params, Long.class);
|
||||
return count != null ? count : 0;
|
||||
}
|
||||
|
||||
public InventoryTransactionLeg getFirstStitchBundleTime(List<Long> parentsIds, String parentType) {
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("parent_document_id", parentsIds);
|
||||
params.addValue("parent_document_type", parentType);
|
||||
|
||||
return namedParameterJdbcTemplate.query(SELECT_FIRST_TRANSACTION_PARENT_TYPE_PARENT_ID, params,new InventoryTransactionLegRowMapper())
|
||||
.stream()
|
||||
.findFirst()
|
||||
.orElse( new InventoryTransactionLeg() );
|
||||
}
|
||||
|
||||
public List<InventoryTransactionLeg> getTransactionByParentIdAndType(List<Long> parentIds , String parentType){
|
||||
if ( parentIds == null || parentIds.isEmpty() ){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("parent_document_id", parentIds );
|
||||
params.addValue("parent_document_type", parentType );
|
||||
return namedParameterJdbcTemplate.query( SELECT_GROUP_By_TRANSACTION_PARENT_TYPE_PARENT_ID , params, new InventoryTransactionLegRowMapper() );
|
||||
}
|
||||
|
||||
public List<InventoryTransactionLeg> getTransactionByJobCardAndDatesAndType(long jobCardID, String startDate, String endDate, String type){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", jobCardID );
|
||||
params.addValue("start_date", startDate );
|
||||
params.addValue("end_date", endDate );
|
||||
params.addValue("type", type );
|
||||
System.out.println("Start Date: " + startDate);
|
||||
System.out.println("End Date: " + endDate);
|
||||
|
||||
System.out.println("Params: " + params.getValues());
|
||||
return namedParameterJdbcTemplate.query( SELECT_JOB_CARD_DATES , params, new InventoryTransactionLegRowMapper() );
|
||||
}
|
||||
|
||||
public List<InventoryTransactionLeg> getTransactionByJobCardAndDatesAndTypeAndAccountID(long jobCardID, String startDate, String endDate, String type, List<Integer> accountId){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", jobCardID );
|
||||
params.addValue("start_date", startDate );
|
||||
params.addValue("end_date", endDate );
|
||||
params.addValue("type", type );
|
||||
params.addValue("account_ids", accountId );
|
||||
return namedParameterJdbcTemplate.query( SELECT_JOB_CARD_And_Date_Type_Account_Id , params, new InventoryTransactionLegRowMapper() );
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ public class InventoryTransactionLegRowMapper implements RowMapper<InventoryTran
|
|||
inventoryTransactionLeg.setParentDocumentType( rs.getString( "parent_document_type" ) );
|
||||
inventoryTransactionLeg.setParentDocumentId( rs.getLong( "parent_document_id" ) );
|
||||
inventoryTransactionLeg.setParentDocumentPieceType( rs.getString("parent_document_piece_type"));
|
||||
inventoryTransactionLeg.setJobCardId( rs.getLong("job_card_id"));
|
||||
return inventoryTransactionLeg;
|
||||
}
|
||||
}
|
|
@ -23,11 +23,10 @@ public class JobCardDAO {
|
|||
private final String SELECT_ALL_QUERY = String.format( "SELECT * FROM %s ORDER BY id DESC", TABLE_NAME );
|
||||
private final String SELECT_ALL_QUERY_WITH_LIMIT = String.format( "SELECT * FROM %s ORDER BY id DESC limit :limit", 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, code, job_order_id, created_at, created_by, status, inventory_status, customer, lot_number, purchase_order_id, location_site_id, description) VALUES (:id, :code, :job_order_id, :created_at, :created_by, :status, :inventory_status, :customer, :lot_number, :purchase_order_id, :location_site_id, :description) ON DUPLICATE KEY UPDATE code = VALUES(code), job_order_id = VALUES(job_order_id), created_at = VALUES(created_at), created_by = VALUES(created_by), status = VALUES(status), inventory_status = VALUES(inventory_status), customer = VALUES(customer), lot_number = VALUES(lot_number), purchase_order_id = VALUES(purchase_order_id), location_site_id = VALUES(location_site_id), description = VALUES(description)", TABLE_NAME );
|
||||
private final String INSERT_QUERY = String.format( "INSERT INTO %s (id, code, job_order_id, created_at, created_by, status, inventory_status, customer, lot_number, purchase_order_id, location_site_id, description, poQuantity, articleName) VALUES (:id, :code, :job_order_id, :created_at, :created_by, :status, :inventory_status, :customer, :lot_number, :purchase_order_id, :location_site_id, :description, :poQuantity, :articleName) ON DUPLICATE KEY UPDATE code = VALUES(code), job_order_id = VALUES(job_order_id), created_at = VALUES(created_at), created_by = VALUES(created_by), status = VALUES(status), inventory_status = VALUES(inventory_status), customer = VALUES(customer), lot_number = VALUES(lot_number), purchase_order_id = VALUES(purchase_order_id), location_site_id = VALUES(location_site_id), description = VALUES(description), poQuantity = VALUES(poQuantity), articleName = VALUES(articleName) ", TABLE_NAME );
|
||||
private final String SELECT_BY_LIKE_CODE_AND_INV_STATUS_AND_STATUS = String.format( "SELECT * FROM %s WHERE code like :code AND status = :status AND inventory_status = :inventory_status", TABLE_NAME );
|
||||
private final String SELECT_BY_LIKE_CODE = String.format( "SELECT * FROM %s WHERE code like :code", TABLE_NAME );
|
||||
private final String SELECT_BY_LIMIT = String.format( "SELECT * FROM %s WHERE created_by = :created_by ORDER BY id DESC limit :limit", TABLE_NAME );
|
||||
|
||||
private final String SELECT_BY_LIMIT = String.format( "SELECT * FROM %s WHERE created_by = :created_by ORDER BY id ASC limit :limit", TABLE_NAME );
|
||||
|
||||
// prepare query params
|
||||
private MapSqlParameterSource prepareInsertQueryParams( JobCard jobCard ) {
|
||||
|
@ -40,6 +39,8 @@ public class JobCardDAO {
|
|||
.addValue("status", jobCard.getStatus() )
|
||||
.addValue("inventory_status", jobCard.getInventoryStatus() )
|
||||
.addValue("customer", jobCard.getCustomer() )
|
||||
.addValue("poQuantity", jobCard.getPoQuantity() )
|
||||
.addValue("articleName", jobCard.getArticleName() )
|
||||
.addValue("lot_number", jobCard.getLotNumber() )
|
||||
.addValue("purchase_order_id", jobCard.getPurchaseOrderId() )
|
||||
.addValue("location_site_id", jobCard.getLocationSiteId() )
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.utopiaindustries.dao.ctp;
|
||||
|
||||
import com.utopiaindustries.model.ctp.JobCardItem;
|
||||
import com.utopiaindustries.model.ctp.MasterBundle;
|
||||
import com.utopiaindustries.util.KeyHolderFunctions;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
|
@ -11,7 +10,6 @@ import org.springframework.stereotype.Repository;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Repository
|
||||
public class JobCardItemDAO {
|
||||
|
@ -28,6 +26,7 @@ public class JobCardItemDAO {
|
|||
private final String SELECT_BY_IDS = String.format( "SELECT * FROM %s WHERE id IN (:ids)", TABLE_NAME );
|
||||
private final String SELECT_BY_JOB_CARD_AND_ACCOUNT_IDS = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id AND account_id IN (:account_ids) AND is_complete = FALSE ", TABLE_NAME );
|
||||
private final String SELECT_ALL_ACTIVE_ITEM = String.format("SELECT CASE WHEN MIN(is_complete) = TRUE THEN TRUE ELSE FALSE END FROM %s WHERE job_card_id = :job_card_id AND id IN (:id)", TABLE_NAME);
|
||||
private final String SELECT_BY_JOB_CARD_IDS = String.format( "SELECT * FROM %s WHERE job_card_id IN (:job_card_id)", TABLE_NAME );
|
||||
|
||||
public JobCardItemDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
|
||||
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
||||
|
@ -131,4 +130,10 @@ public class JobCardItemDAO {
|
|||
Boolean allComplete = namedParameterJdbcTemplate.queryForObject(SELECT_ALL_ACTIVE_ITEM, params, Boolean.class);
|
||||
return Boolean.TRUE.equals(allComplete);
|
||||
}
|
||||
|
||||
public List<JobCardItem> findByJobCardIds(List<Long> ids){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", ids);
|
||||
return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD_IDS, params, new JobCardItemRowMapper() );
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ public class JobCardItemRowMapper implements RowMapper<JobCardItem> {
|
|||
jobCardItem.setGsm( rs.getString("gsm" ) );
|
||||
jobCardItem.setWtPly( rs.getString("wt_ply" ) );
|
||||
jobCardItem.setPly( rs.getString("ply" ) );
|
||||
jobCardItem.setComplete( rs.getBoolean("is_complete" ) );
|
||||
return jobCardItem;
|
||||
}
|
||||
}
|
|
@ -23,6 +23,8 @@ public class JobCardRowMapper implements RowMapper<JobCard> {
|
|||
jobCard.setPurchaseOrderId( rs.getString("purchase_order_id") );
|
||||
jobCard.setLocationSiteId( rs.getLong("location_site_id" ) );
|
||||
jobCard.setDescription( rs.getString("description" ) );
|
||||
jobCard.setPoQuantity( rs.getInt("poQuantity" ) );
|
||||
jobCard.setArticleName( rs.getString("articleName" ) );
|
||||
return jobCard;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.utopiaindustries.dao.ctp;
|
||||
|
||||
import com.utopiaindustries.model.ctp.InventoryTransactionLeg;
|
||||
import com.utopiaindustries.model.ctp.StitchingOfflineItem;
|
||||
import com.utopiaindustries.util.KeyHolderFunctions;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
|
@ -28,6 +29,9 @@ public class StitchingOfflineItemDAO {
|
|||
private final String SELECT_BY_IDS = String.format( "SELECT * FROM %s WHERE id IN (:ids)", TABLE_NAME );
|
||||
private final String SELECT_BY_TERM = String.format( "SELECT * FROM %s WHERE barcode LIKE :term ORDER BY ID DESC", TABLE_NAME );
|
||||
private final String SELECT_BY_MASTER_ID = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id", TABLE_NAME );
|
||||
private final String COUNT_TOTAL_QA_ITEMS= String.format("SELECT COUNT(*) FROM %s WHERE job_card_id = :job_card_id AND is_qa IS TRUE",TABLE_NAME);
|
||||
private final String SELECT_BY_TIME_AND_CARD_ID= String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id ORDER BY created_at DESC LIMIT 1;",TABLE_NAME);
|
||||
private final String SELECT_BY_JOB_CARD_AND_DATE = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR created_at BETWEEN :start_date AND :end_date)", TABLE_NAME );
|
||||
|
||||
public StitchingOfflineItemDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
|
||||
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
||||
|
@ -141,4 +145,28 @@ public class StitchingOfflineItemDAO {
|
|||
return totalCounts;
|
||||
}
|
||||
|
||||
public Long CalculateTotalQA( long jobCardId ){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", jobCardId );
|
||||
Long count = namedParameterJdbcTemplate.queryForObject(COUNT_TOTAL_QA_ITEMS, params, Long.class);
|
||||
return count != null ? count : 0;
|
||||
}
|
||||
|
||||
public StitchingOfflineItem getLastStitchItemByCardIdAndTime(long jobCardId) {
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue("job_card_id", jobCardId);
|
||||
|
||||
return namedParameterJdbcTemplate.query(SELECT_BY_TIME_AND_CARD_ID, params,new StitchingOfflineItemRowMapper())
|
||||
.stream()
|
||||
.findFirst()
|
||||
.orElse( new StitchingOfflineItem() );
|
||||
}
|
||||
|
||||
public List<StitchingOfflineItem> findByJobCardIdAndDate(long jobCardId, String startDate, String endDate){
|
||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||
params.addValue( "job_card_id", jobCardId );
|
||||
params.addValue( "start_date", startDate );
|
||||
params.addValue( "end_date", endDate );
|
||||
return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD_AND_DATE , params, new StitchingOfflineItemRowMapper() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ public class SummaryInventoryReportDao {
|
|||
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||
|
||||
private final String TABLE_NAME = "cut_to_pack.inventory_transaction_leg ";
|
||||
String SELECT_QUERY = "SELECT item_id, account_id, parent_document_id, DATE(transaction_leg_datetime) AS transaction_date, "
|
||||
String SELECT_QUERY = "SELECT job_card_id, item_id, account_id, parent_document_id, DATE(transaction_leg_datetime) AS transaction_date, "
|
||||
+ "sku, parent_document_type, parent_document_piece_type, "
|
||||
+ "SUM(CASE WHEN type = 'IN' THEN 1 ELSE 0 END) AS total_in, "
|
||||
+ "SUM(CASE WHEN type = 'OUT' THEN 1 ELSE 0 END) AS total_out "
|
||||
|
|
|
@ -15,6 +15,7 @@ public class SummaryInventoryReportRowMapper implements RowMapper<SummaryInvento
|
|||
summaryInventoryReport.setAccountId(rs.getString("account_id"));
|
||||
summaryInventoryReport.setDate(rs.getString("transaction_date"));
|
||||
summaryInventoryReport.setTotalIn(rs.getLong("total_in"));
|
||||
summaryInventoryReport.setJobCardID(rs.getLong("job_card_id"));
|
||||
summaryInventoryReport.setTotalOut(rs.getLong("total_out"));
|
||||
summaryInventoryReport.setParentDocumentType(rs.getString("parent_document_type"));
|
||||
summaryInventoryReport.setParentDocumentPieceType(rs.getString("parent_document_piece_type"));
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
package com.utopiaindustries.model.ctp;
|
||||
|
||||
public class CuttingJobCardItemWrapper {
|
||||
private long jobCardId;
|
||||
private String poName;
|
||||
private String sku;
|
||||
private Long totalCutting;
|
||||
private String width;
|
||||
private String length;
|
||||
private String gsm;
|
||||
private String wtPly;
|
||||
private String ply;
|
||||
private String articleName;
|
||||
private boolean isComplete;
|
||||
private String jobCardCode;
|
||||
private String cuttingOperatorName;
|
||||
private long cuttingAccountId;
|
||||
|
||||
public long getJobCardId() {
|
||||
return jobCardId;
|
||||
}
|
||||
|
||||
public void setJobCardId(long jobCardId) {
|
||||
this.jobCardId = jobCardId;
|
||||
}
|
||||
|
||||
public String getPoName() {
|
||||
return poName;
|
||||
}
|
||||
|
||||
public void setPoName(String poName) {
|
||||
this.poName = poName;
|
||||
}
|
||||
|
||||
public String getSku() {
|
||||
return sku;
|
||||
}
|
||||
|
||||
public void setSku(String sku) {
|
||||
this.sku = sku;
|
||||
}
|
||||
|
||||
public Long getTotalCutting() {
|
||||
return totalCutting;
|
||||
}
|
||||
|
||||
public void setTotalCutting(Long totalCutting) {
|
||||
this.totalCutting = totalCutting;
|
||||
}
|
||||
|
||||
public String getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(String width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public String getGsm() {
|
||||
return gsm;
|
||||
}
|
||||
|
||||
public void setGsm(String gsm) {
|
||||
this.gsm = gsm;
|
||||
}
|
||||
|
||||
public String getWtPly() {
|
||||
return wtPly;
|
||||
}
|
||||
|
||||
public void setWtPly(String wtPly) {
|
||||
this.wtPly = wtPly;
|
||||
}
|
||||
|
||||
public String getPly() {
|
||||
return ply;
|
||||
}
|
||||
|
||||
public void setPly(String ply) {
|
||||
this.ply = ply;
|
||||
}
|
||||
|
||||
public String getArticleName() {
|
||||
return articleName;
|
||||
}
|
||||
|
||||
public void setArticleName(String articleName) {
|
||||
this.articleName = articleName;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return isComplete;
|
||||
}
|
||||
|
||||
public void setComplete(boolean complete) {
|
||||
isComplete = complete;
|
||||
}
|
||||
|
||||
public String getJobCardCode() {
|
||||
return jobCardCode;
|
||||
}
|
||||
|
||||
public void setJobCardCode(String jobCardCode) {
|
||||
this.jobCardCode = jobCardCode;
|
||||
}
|
||||
|
||||
public long getCuttingAccountId() {
|
||||
return cuttingAccountId;
|
||||
}
|
||||
|
||||
public void setCuttingAccountId(long cuttingAccountId) {
|
||||
this.cuttingAccountId = cuttingAccountId;
|
||||
}
|
||||
|
||||
public String getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(String length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public String getCuttingOperatorName() {
|
||||
return cuttingOperatorName;
|
||||
}
|
||||
|
||||
public void setCuttingOperatorName(String cuttingOperatorName) {
|
||||
this.cuttingOperatorName = cuttingOperatorName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CuttingJobCardItemWrapper{" +
|
||||
"cuttingAccountId=" + cuttingAccountId +
|
||||
", cuttingOperatorName='" + cuttingOperatorName + '\'' +
|
||||
", jobCardCode='" + jobCardCode + '\'' +
|
||||
", isComplete=" + isComplete +
|
||||
", articleName='" + articleName + '\'' +
|
||||
", ply='" + ply + '\'' +
|
||||
", wtPly='" + wtPly + '\'' +
|
||||
", gsm='" + gsm + '\'' +
|
||||
", length='" + length + '\'' +
|
||||
", width='" + width + '\'' +
|
||||
", totalCutting=" + totalCutting +
|
||||
", sku='" + sku + '\'' +
|
||||
", poName='" + poName + '\'' +
|
||||
", jobCardId=" + jobCardId +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ public class InventoryTransactionLeg {
|
|||
private String parentDocumentType;
|
||||
private long parentDocumentId;
|
||||
private String parentDocumentPieceType;
|
||||
|
||||
private long jobCardId;
|
||||
//wrapper
|
||||
private InventoryTransaction transaction;
|
||||
|
||||
|
@ -122,6 +122,14 @@ public class InventoryTransactionLeg {
|
|||
this.parentDocumentPieceType = parentDocumentPieceType;
|
||||
}
|
||||
|
||||
public long getJobCardId() {
|
||||
return jobCardId;
|
||||
}
|
||||
|
||||
public void setJobCardId(long jobCardId) {
|
||||
this.jobCardId = jobCardId;
|
||||
}
|
||||
|
||||
public InventoryTransaction getTransaction() {
|
||||
return transaction;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ public class JobCard {
|
|||
private String purchaseOrderId;
|
||||
private long locationSiteId;
|
||||
private String description;
|
||||
private String articleName;
|
||||
private int poQuantity;
|
||||
// wrapper
|
||||
private List<JobCardItem> items;
|
||||
private long toAccountId;
|
||||
|
@ -162,6 +164,22 @@ public class JobCard {
|
|||
this.locationTitle = locationTitle;
|
||||
}
|
||||
|
||||
public String getArticleName() {
|
||||
return articleName;
|
||||
}
|
||||
|
||||
public void setArticleName(String articleName) {
|
||||
this.articleName = articleName;
|
||||
}
|
||||
|
||||
public int getPoQuantity() {
|
||||
return poQuantity;
|
||||
}
|
||||
|
||||
public void setPoQuantity(int poQuantity) {
|
||||
this.poQuantity = poQuantity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JobCard{" +
|
||||
|
@ -174,9 +192,11 @@ public class JobCard {
|
|||
", inventoryStatus='" + inventoryStatus + '\'' +
|
||||
", customer='" + customer + '\'' +
|
||||
", lotNumber='" + lotNumber + '\'' +
|
||||
", purchaseOrderId=" + purchaseOrderId +
|
||||
", purchaseOrderId='" + purchaseOrderId + '\'' +
|
||||
", locationSiteId=" + locationSiteId +
|
||||
", description='" + description + '\'' +
|
||||
", articleName='" + articleName + '\'' +
|
||||
", poQuantity=" + poQuantity +
|
||||
", items=" + items +
|
||||
", toAccountId=" + toAccountId +
|
||||
", purchaseOrderTitle='" + purchaseOrderTitle + '\'' +
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
package com.utopiaindustries.model.ctp;
|
||||
|
||||
public class POsDetails {
|
||||
private String poNumber;
|
||||
private String articleTitle;
|
||||
private long poQuantity;
|
||||
private long totalCutting;
|
||||
private long remainingCutting;
|
||||
private long totalStitching;
|
||||
private long remainingStitching;
|
||||
private long totalEndLineQC;
|
||||
private long remainingEndLineQC;
|
||||
private long totalFinishing;
|
||||
private long remainingFinishing;
|
||||
private long totalAGradeItem;
|
||||
private long totalBGradeItem;
|
||||
private long totalCGradeItem;
|
||||
|
||||
public long getPoQuantity() {
|
||||
return poQuantity;
|
||||
}
|
||||
|
||||
public void setPoQuantity(long poQuantity) {
|
||||
this.poQuantity = poQuantity;
|
||||
}
|
||||
|
||||
public String getPoNumber() {
|
||||
return poNumber;
|
||||
}
|
||||
|
||||
public void setPoNumber(String poNumber) {
|
||||
this.poNumber = poNumber;
|
||||
}
|
||||
|
||||
public String getArticleTitle() {
|
||||
return articleTitle;
|
||||
}
|
||||
|
||||
public void setArticleTitle(String articleTitle) {
|
||||
this.articleTitle = articleTitle;
|
||||
}
|
||||
|
||||
public long getTotalCutting() {
|
||||
return totalCutting;
|
||||
}
|
||||
|
||||
public void setTotalCutting(long totalCutting) {
|
||||
this.totalCutting = totalCutting;
|
||||
}
|
||||
|
||||
public long getRemainingCutting() {
|
||||
return remainingCutting;
|
||||
}
|
||||
|
||||
public void setRemainingCutting(long remainingCutting) {
|
||||
this.remainingCutting = remainingCutting;
|
||||
}
|
||||
|
||||
public long getTotalStitching() {
|
||||
return totalStitching;
|
||||
}
|
||||
|
||||
public void setTotalStitching(long totalStitching) {
|
||||
this.totalStitching = totalStitching;
|
||||
}
|
||||
|
||||
public long getRemainingStitching() {
|
||||
return remainingStitching;
|
||||
}
|
||||
|
||||
public void setRemainingStitching(long remainingStitching) {
|
||||
this.remainingStitching = remainingStitching;
|
||||
}
|
||||
|
||||
public long getTotalEndLineQC() {
|
||||
return totalEndLineQC;
|
||||
}
|
||||
|
||||
public void setTotalEndLineQC(long totalEndLineQC) {
|
||||
this.totalEndLineQC = totalEndLineQC;
|
||||
}
|
||||
|
||||
public long getRemainingEndLineQC() {
|
||||
return remainingEndLineQC;
|
||||
}
|
||||
|
||||
public void setRemainingEndLineQC(long remainingEndLineQC) {
|
||||
this.remainingEndLineQC = remainingEndLineQC;
|
||||
}
|
||||
|
||||
public long getTotalFinishing() {
|
||||
return totalFinishing;
|
||||
}
|
||||
|
||||
public void setTotalFinishing(long totalFinishing) {
|
||||
this.totalFinishing = totalFinishing;
|
||||
}
|
||||
|
||||
public long getRemainingFinishing() {
|
||||
return remainingFinishing;
|
||||
}
|
||||
|
||||
public void setRemainingFinishing(long remainingFinishing) {
|
||||
this.remainingFinishing = remainingFinishing;
|
||||
}
|
||||
|
||||
public long getTotalAGradeItem() {
|
||||
return totalAGradeItem;
|
||||
}
|
||||
|
||||
public void setTotalAGradeItem(long totalAGradeItem) {
|
||||
this.totalAGradeItem = totalAGradeItem;
|
||||
}
|
||||
|
||||
public long getTotalBGradeItem() {
|
||||
return totalBGradeItem;
|
||||
}
|
||||
|
||||
public void setTotalBGradeItem(long totalBGradeItem) {
|
||||
this.totalBGradeItem = totalBGradeItem;
|
||||
}
|
||||
|
||||
public long getTotalCGradeItem() {
|
||||
return totalCGradeItem;
|
||||
}
|
||||
|
||||
public void setTotalCGradeItem(long totalCGradeItem) {
|
||||
this.totalCGradeItem = totalCGradeItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "POsDetails{" +
|
||||
"totalCutting=" + totalCutting +
|
||||
", remainingCutting=" + remainingCutting +
|
||||
", totalStitching=" + totalStitching +
|
||||
", remainingStitching=" + remainingStitching +
|
||||
", totalEndLineQC=" + totalEndLineQC +
|
||||
", remainingEndLineQC=" + remainingEndLineQC +
|
||||
", totalFinishing=" + totalFinishing +
|
||||
", remainingFinishing=" + remainingFinishing +
|
||||
", totalAGradeItem=" + totalAGradeItem +
|
||||
", totalBGradeItem=" + totalBGradeItem +
|
||||
", totalCGradeItem=" + totalCGradeItem +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ public class SummaryInventoryReport {
|
|||
private String Date;
|
||||
private long totalIn;
|
||||
private long totalOut;
|
||||
private long jobCardID;
|
||||
private String parentDocumentType;
|
||||
private String parentDocumentId;
|
||||
private String accountId;
|
||||
|
@ -91,4 +92,12 @@ public class SummaryInventoryReport {
|
|||
public void setAccountId(String accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public long getJobCardID() {
|
||||
return jobCardID;
|
||||
}
|
||||
|
||||
public void setJobCardID(long jobCardID) {
|
||||
this.jobCardID = jobCardID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,11 +62,33 @@ public class SummaryInventoryReportQueryBuilder {
|
|||
.bracketClose()
|
||||
.bracketClose()
|
||||
.and()
|
||||
.columnBetween("transaction_leg_date",startDate,endDate)
|
||||
.columnBetween("transaction_leg_datetime",startDate,endDate)
|
||||
.groupBy("DATE(transaction_leg_datetime), sku, parent_document_type, parent_document_piece_type")
|
||||
.orderBy("transaction_date,", "sku");
|
||||
|
||||
return qb.build();
|
||||
}
|
||||
|
||||
public static String cuttingQueryBuild(long jobCardId,
|
||||
List<Long> account,
|
||||
String startDate,
|
||||
String endDate,String type) {
|
||||
|
||||
QueryBuilder qb = new QueryBuilder()
|
||||
.setTable(TABLE_NAME)
|
||||
.setColumns("*")
|
||||
.where()
|
||||
.columnIn("account_id",account.toArray(new Long[0]))
|
||||
.and()
|
||||
.columnEqualToOrGreaterThan("transaction_leg_datetime",startDate)
|
||||
.and()
|
||||
.columnEqualToOrLessThan("transaction_leg_datetime",endDate)
|
||||
.and()
|
||||
.columnEquals("type",type);
|
||||
if (jobCardId != 0){
|
||||
qb.and()
|
||||
.columnEquals("job_card_id", jobCardId );
|
||||
}
|
||||
return qb.build();
|
||||
}
|
||||
}
|
|
@ -174,6 +174,7 @@ public class InventoryService {
|
|||
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( ));
|
||||
|
||||
|
|
|
@ -0,0 +1,714 @@
|
|||
package com.utopiaindustries.service;
|
||||
|
||||
|
||||
import com.utopiaindustries.dao.ctp.*;
|
||||
import com.utopiaindustries.model.ctp.*;
|
||||
import com.utopiaindustries.querybuilder.ctp.SummaryInventoryReportQueryBuilder;
|
||||
import com.utopiaindustries.util.CTPDateTimeFormat;
|
||||
import com.utopiaindustries.util.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class ReportingService {
|
||||
|
||||
private final JobCardItemDAO jobCardItemDAO;
|
||||
private final ProcessDAO processDAO;
|
||||
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 InventoryAccountDAO inventoryAccountDAO;
|
||||
|
||||
public ReportingService( JobCardItemDAO jobCardItemDAO, ProcessDAO processDAO, BundleDAO bundleDAO, InventoryTransactionLegDAO inventoryTransactionLegDAO, InventoryTransactionDAO inventoryTransactionDAO, JobCardDAO jobCardDAO, CryptographyService cryptographyService, MasterBundleDAO masterBundleDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO, InventoryAccountDAO inventoryAccountDAO) {
|
||||
this.jobCardItemDAO = jobCardItemDAO;
|
||||
this.processDAO = processDAO;
|
||||
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.inventoryAccountDAO = inventoryAccountDAO;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getJobCardProgress(String jobCardID) {
|
||||
if (jobCardID == null) {
|
||||
return new LinkedHashMap<>();
|
||||
} else {
|
||||
Map<String, Integer> totalProgress = new HashMap<>();
|
||||
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID));
|
||||
|
||||
BigDecimal totalProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
BigDecimal actualProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
BigDecimal expectedProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getExpectedProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
// Cutting Progress Calculation
|
||||
if (actualProduction.compareTo(BigDecimal.ZERO) == 0) {
|
||||
totalProgress.put("Cutting Progress", 0);
|
||||
} else if (actualProduction.compareTo(expectedProduction) < 0) {
|
||||
BigDecimal cuttingProgress = actualProduction
|
||||
.divide(expectedProduction, 4, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(100));
|
||||
totalProgress.put("Cutting Progress", cuttingProgress.intValue());
|
||||
} else {
|
||||
totalProgress.put("Cutting Progress", 100);
|
||||
}
|
||||
|
||||
// Stitching Progress Calculation
|
||||
if (totalProduction.compareTo(BigDecimal.ZERO) == 0) {
|
||||
totalProgress.put("Stitching Progress", 0);
|
||||
} else {
|
||||
BigDecimal stitchingProgress = totalProduction
|
||||
.divide(actualProduction, 4, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(100));
|
||||
totalProgress.put("Stitching Progress", stitchingProgress.intValue());
|
||||
}
|
||||
|
||||
// QA Progress Calculation
|
||||
Long qaProgressItems = stitchingOfflineItemDAO.CalculateTotalQA(Long.parseLong(jobCardID));
|
||||
if (qaProgressItems == 0) {
|
||||
totalProgress.put("QA Progress", 0);
|
||||
} else {
|
||||
BigDecimal qaProgress = BigDecimal.valueOf(qaProgressItems)
|
||||
.divide(actualProduction, 4, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(100));
|
||||
totalProgress.put("QA Progress", qaProgress.intValue());
|
||||
}
|
||||
|
||||
// Finishing Progress Calculation
|
||||
Long totalFinishItem = finishedItemDAO.calculateTotalFinishItem(Long.parseLong(jobCardID));
|
||||
if (totalFinishItem == 0) {
|
||||
totalProgress.put("Finishing Progress", 0);
|
||||
} else {
|
||||
BigDecimal finishItemProgress = BigDecimal.valueOf(totalFinishItem)
|
||||
.divide(actualProduction, 4, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(100));
|
||||
totalProgress.put("Finishing Progress", finishItemProgress.intValue());
|
||||
}
|
||||
|
||||
// Job Card Progress Calculation
|
||||
if (totalProduction.compareTo(BigDecimal.ZERO) == 0 && actualProduction.compareTo(BigDecimal.ZERO) == 0) {
|
||||
totalProgress.put("Job Card Progress", 0);
|
||||
} else {
|
||||
BigDecimal progressPercentage;
|
||||
if (actualProduction.compareTo(expectedProduction) > 0) {
|
||||
progressPercentage = actualProduction.add(totalProduction)
|
||||
.add(BigDecimal.valueOf(qaProgressItems))
|
||||
.add(BigDecimal.valueOf(totalFinishItem))
|
||||
.divide(actualProduction.multiply(BigDecimal.valueOf(4)), 4, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(100));
|
||||
} else {
|
||||
progressPercentage = actualProduction.add(totalProduction)
|
||||
.add(BigDecimal.valueOf(qaProgressItems))
|
||||
.add(BigDecimal.valueOf(totalFinishItem))
|
||||
.divide(expectedProduction.multiply(BigDecimal.valueOf(4)), 4, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(100));
|
||||
}
|
||||
totalProgress.put("Job Card Progress", progressPercentage.intValue());
|
||||
}
|
||||
|
||||
// Sorting Map based on Custom Order
|
||||
Map<String, Integer> indexMap = new HashMap<>();
|
||||
indexMap.put("Cutting Progress", 1);
|
||||
indexMap.put("Stitching Progress", 2);
|
||||
indexMap.put("QA Progress", 3);
|
||||
indexMap.put("Finishing Progress", 4);
|
||||
indexMap.put("Job Card Progress", 5);
|
||||
|
||||
return totalProgress.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(entry -> indexMap.get(entry.getKey())))
|
||||
.collect(LinkedHashMap::new, (m, v) -> m.put(v.getKey(), v.getValue()), Map::putAll);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Integer getTotalProduction(String jobCardID){
|
||||
if (jobCardID == null){
|
||||
return 0;
|
||||
}else {
|
||||
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID));
|
||||
BigDecimal actualProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
return actualProduction.intValue();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Integer> getCompleteProduction(String jobCardID) {
|
||||
if (jobCardID == null) {
|
||||
return new LinkedHashMap<>();
|
||||
} else {
|
||||
HashMap<String, Integer> totalProgress = new HashMap<>();
|
||||
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID));
|
||||
|
||||
BigDecimal totalProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
BigDecimal actualProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
Long qaProgressItems = stitchingOfflineItemDAO.CalculateTotalQA(Long.parseLong(jobCardID));
|
||||
Long totalFinishItem = finishedItemDAO.calculateTotalFinishItem(Long.parseLong(jobCardID));
|
||||
|
||||
// Get Job card Complete Items
|
||||
Map<String, Integer> jobCardCompleteItems = getSegregateItems(jobCardID);
|
||||
Integer segregateTotalItems = jobCardCompleteItems.values().stream().mapToInt(Integer::intValue).sum();
|
||||
|
||||
// Add values to totalProgress map
|
||||
totalProgress.put("Cutting Progress", actualProduction.intValue());
|
||||
totalProgress.put("Stitching Progress", totalProduction.intValue());
|
||||
totalProgress.put("QA Progress", qaProgressItems.intValue());
|
||||
totalProgress.put("Finishing Progress", totalFinishItem.intValue());
|
||||
totalProgress.put("Job Card Progress", segregateTotalItems);
|
||||
|
||||
//custom order
|
||||
Map<String, Integer> indexMap = new HashMap<>();
|
||||
indexMap.put("Job Card Progress", 1);
|
||||
indexMap.put("Cutting Progress", 2);
|
||||
indexMap.put("Stitching Progress", 3);
|
||||
indexMap.put("Finishing Progress", 4);
|
||||
indexMap.put("QA Progress", 5);
|
||||
|
||||
// Sort the keys based on custom order
|
||||
return totalProgress.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(entry -> indexMap.get(entry.getKey())))
|
||||
.collect(LinkedHashMap::new, (m, v) -> m.put(v.getKey(), v.getValue()), Map::putAll);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Map<String,Integer> getSegregateItems(String jobCardID){
|
||||
if (jobCardID == null){
|
||||
return new HashMap<>();
|
||||
}else {
|
||||
HashMap<String,Integer> gradingItems = new HashMap<>();
|
||||
List<InventoryAccount> inventoryAccounts = inventoryAccountDAO.getPackagingAccounts();
|
||||
List<FinishedItem> finishedItems = finishedItemDAO.findByJobCardId(Long.parseLong(jobCardID));
|
||||
List<Long> finishItemsIds = finishedItems.stream()
|
||||
.map(FinishedItem::getId).collect(Collectors.toList());
|
||||
if (finishItemsIds.isEmpty()){
|
||||
gradingItems.put("A GRADE",0);
|
||||
gradingItems.put("B GRADE",0);
|
||||
gradingItems.put("C GRADE",0);
|
||||
return gradingItems;
|
||||
}else {
|
||||
for (InventoryAccount inventoryAccount : inventoryAccounts){
|
||||
long totalGradingItems = inventoryTransactionLegDAO.CalculateTotalGradingItems(finishItemsIds,(int) inventoryAccount.getId());
|
||||
gradingItems.put(inventoryAccount.getTitle(), (int) totalGradingItems);
|
||||
}
|
||||
return gradingItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<String,String> getEachPhaseTotalTime(String jobCardID){
|
||||
if (jobCardID == null){
|
||||
return new HashMap<>();
|
||||
}else {
|
||||
HashMap<String,String> phasesTimes = new HashMap<>();
|
||||
JobCard jobCard = jobCardDAO.find(Long.parseLong(jobCardID));
|
||||
Bundle lastBundle = bundleDAO.findLastBundleByCardId(Long.parseLong(jobCardID));
|
||||
|
||||
//Cutting time
|
||||
StringBuilder cuttingTime = generateTime(jobCard.getCreatedAt(),lastBundle.getCreatedAt());
|
||||
phasesTimes.put("Cutting Total Time",cuttingTime.toString());
|
||||
|
||||
//Stitching time
|
||||
List<Long> bundlesIds = bundleDAO.findByCardId(Long.parseLong(jobCardID)).stream().map(Bundle::getId).collect(Collectors.toList());
|
||||
if (!bundlesIds.isEmpty()){
|
||||
InventoryTransactionLeg inventoryTransactionLeg = inventoryTransactionLegDAO.getFirstStitchBundleTime(bundlesIds,"STITCH_BUNDLE");
|
||||
StitchingOfflineItem lastStitchItem = stitchingOfflineItemDAO.getLastStitchItemByCardIdAndTime(Long.parseLong(jobCardID));
|
||||
StringBuilder stitchingTime = generateTime(inventoryTransactionLeg.getTransactionLegDateTime(),lastStitchItem.getCreatedAt());
|
||||
phasesTimes.put("Stitching Total Time",stitchingTime.toString());
|
||||
}else {
|
||||
phasesTimes.put("Stitching Total Time",null);
|
||||
|
||||
}
|
||||
|
||||
return phasesTimes;
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<String,String> countPendingItemsOnDifferentPhases(String jobCardID){
|
||||
if (jobCardID == null){
|
||||
return new HashMap<>();
|
||||
}else {
|
||||
HashMap<String,String> phasePending = new HashMap<String,String>();
|
||||
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID));
|
||||
BigDecimal totalProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
BigDecimal actualProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
BigDecimal expectedProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getExpectedProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
if(actualProduction.compareTo(totalProduction) == 0) {
|
||||
phasePending.put("Stitching Total Time", null);
|
||||
}else {
|
||||
phasePending.put("Stitching Total Time", "Pending");
|
||||
}
|
||||
return phasePending;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Map<String, Object>> getCuttingDetails(String jobCardID) {
|
||||
if (jobCardID == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<String, Map<String, Object>> cuttingDetails = new HashMap<>();
|
||||
Map<String, InventoryAccount> cuttingAccount = new HashMap<>();
|
||||
Map<String, String> cuttingPersonName = new HashMap<>();
|
||||
Map<String, LocalDate> cuttingDate = new HashMap<>();
|
||||
|
||||
List<Bundle> bundles = bundleDAO.findByCardId(Long.parseLong(jobCardID));
|
||||
if (bundles.isEmpty()) {
|
||||
return cuttingDetails;
|
||||
}
|
||||
|
||||
Map<Long, Bundle> bundleMap = bundles.stream()
|
||||
.collect(Collectors.toMap(Bundle::getId, Function.identity()));
|
||||
|
||||
List<Long> bundleIds = new ArrayList<>(bundleMap.keySet());
|
||||
List<InventoryTransactionLeg> inventoryTransactionLegs = inventoryTransactionLegDAO
|
||||
.getTransactionByParentIdAndType(bundleIds, "BUNDLE");
|
||||
|
||||
for (InventoryTransactionLeg inventoryTransactionLeg : inventoryTransactionLegs) {
|
||||
Integer accountId = inventoryTransactionLeg.getAccountId();
|
||||
InventoryAccount inventoryAccount = inventoryAccountDAO.find(accountId.longValue());
|
||||
if (inventoryAccount != null) {
|
||||
String accountTitle = inventoryAccount.getTitle();
|
||||
cuttingAccount.put(accountTitle, inventoryAccount);
|
||||
Bundle bundle = bundleMap.get(inventoryTransactionLeg.getParentDocumentId());
|
||||
cuttingPersonName.put(accountTitle, (bundle != null) ? bundle.getCreatedBy() : null);
|
||||
cuttingDate.put(accountTitle,(bundle != null) ? bundle.getCreatedAt().toLocalDate() : null);
|
||||
}
|
||||
}
|
||||
|
||||
cuttingDetails.put("accounts", new HashMap<>(cuttingAccount));
|
||||
cuttingDetails.put("personName", new HashMap<>(cuttingPersonName));
|
||||
cuttingDetails.put("date", new HashMap<>(cuttingDate));
|
||||
|
||||
return cuttingDetails;
|
||||
}
|
||||
|
||||
public Map<String, Map<String, Object>> getStitchingDetails(String jobCardID) {
|
||||
if (jobCardID == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<String, Map<String, Object>> stitchingDetails = new HashMap<>();
|
||||
Map<String, InventoryAccount> stitchingAccount = new HashMap<>();
|
||||
Map<String, String> stitchingPersonName = new HashMap<>();
|
||||
Map<String, LocalDate> stitchingDate = new HashMap<>();
|
||||
|
||||
List<StitchingOfflineItem> stitchingOfflineItems = stitchingOfflineItemDAO.findByJobCardId(Long.parseLong(jobCardID));
|
||||
if (stitchingOfflineItems.isEmpty()) {
|
||||
return stitchingDetails;
|
||||
}
|
||||
|
||||
Map<Long, StitchingOfflineItem> stitchingOfflineItemMap = stitchingOfflineItems.stream()
|
||||
.collect(Collectors.toMap(StitchingOfflineItem::getId, Function.identity()));
|
||||
|
||||
List<Long> stitchingItemsArray = new ArrayList<>(stitchingOfflineItemMap.keySet());
|
||||
List<InventoryTransactionLeg> inventoryTransactionLegs = inventoryTransactionLegDAO
|
||||
.getTransactionByParentIdAndType(stitchingItemsArray, "STITCHING_OFFLINE");
|
||||
|
||||
for (InventoryTransactionLeg inventoryTransactionLeg : inventoryTransactionLegs) {
|
||||
Integer accountId = inventoryTransactionLeg.getAccountId();
|
||||
InventoryAccount inventoryAccount = inventoryAccountDAO.find(accountId.longValue());
|
||||
if (inventoryAccount != null) {
|
||||
String accountTitle = inventoryAccount.getTitle();
|
||||
stitchingAccount.put(accountTitle, inventoryAccount);
|
||||
StitchingOfflineItem stitchingOfflineItem = stitchingOfflineItemMap.get(inventoryTransactionLeg.getParentDocumentId());
|
||||
stitchingPersonName.put(accountTitle, (stitchingOfflineItem != null) ? stitchingOfflineItem.getCreatedBy() : null);
|
||||
stitchingDate.put(accountTitle,(stitchingOfflineItem != null) ? stitchingOfflineItem.getCreatedAt().toLocalDate() : null);
|
||||
}
|
||||
}
|
||||
|
||||
stitchingDetails.put("accounts", new HashMap<>(stitchingAccount));
|
||||
stitchingDetails.put("personName", new HashMap<>(stitchingPersonName));
|
||||
stitchingDetails.put("date", new HashMap<>(stitchingDate));
|
||||
|
||||
return stitchingDetails;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, List<?>> getPhasesProgressDayWise(String jobCardID) {
|
||||
if (jobCardID == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID));
|
||||
BigDecimal actualProduction = jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
LocalDateTime startDate = jobCardDAO.find(Long.parseLong(jobCardID)).getCreatedAt();
|
||||
HashMap<String, List<?>> barChartData = new HashMap<>();
|
||||
|
||||
List<InventoryTransactionLeg> inventoryTransactionLegs = inventoryTransactionLegDAO
|
||||
.getTransactionByJobCardAndDatesAndType(Long.parseLong(jobCardID), startDate.toString(), LocalDateTime.now().toString(), "IN");
|
||||
|
||||
//remove quality multiple transaction entry approved/rejects
|
||||
List<InventoryTransactionLeg> filteredTransactions = inventoryTransactionLegs.stream()
|
||||
.collect(Collectors.toMap(
|
||||
leg -> leg.getAccountId() + "-" + leg.getParentDocumentType() + "-" + leg.getParentDocumentId(),
|
||||
leg -> leg, // Value
|
||||
(existing, replacement) -> existing.getTransactionLegDateTime().isBefore(replacement.getTransactionLegDateTime()) ? existing : replacement // Keep Oldest
|
||||
))
|
||||
.values()
|
||||
.stream()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
|
||||
List<String> uniqueDates = inventoryTransactionLegs.stream()
|
||||
.map(leg -> leg.getTransactionLegDateTime().toLocalDate().format(formatter))
|
||||
.distinct()
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<String, Integer> dateIndexMap = new HashMap<>();
|
||||
for (int i = 0; i < uniqueDates.size(); i++) {
|
||||
dateIndexMap.put(uniqueDates.get(i), i);
|
||||
}
|
||||
|
||||
List<Integer> cuttingList = new ArrayList<>(Collections.nCopies(uniqueDates.size(), 0));
|
||||
List<Integer> stitchingList = new ArrayList<>(Collections.nCopies(uniqueDates.size(), 0));
|
||||
List<Integer> qualityList = new ArrayList<>(Collections.nCopies(uniqueDates.size(), 0));
|
||||
List<Integer> finishItems = new ArrayList<>(Collections.nCopies(uniqueDates.size(), 0));
|
||||
|
||||
for (InventoryTransactionLeg leg : filteredTransactions) {
|
||||
String dateKey = leg.getTransactionLegDateTime().format(formatter);
|
||||
int index = dateIndexMap.get(dateKey);
|
||||
if ("BUNDLE".equals(leg.getParentDocumentType())) {
|
||||
Bundle bundle = bundleDAO.find(leg.getParentDocumentId());
|
||||
cuttingList.set(index, cuttingList.get(index) + bundle.getWrapQuantity().intValue());
|
||||
}
|
||||
else if ("STITCHING_OFFLINE".equals(leg.getParentDocumentType())) {
|
||||
stitchingList.set(index, stitchingList.get(index) + leg.getQuantity().intValue());
|
||||
}
|
||||
else if ("FINISHED_ITEM".equals(leg.getParentDocumentType()) && (leg.getAccountId().equals(7) || leg.getAccountId().equals(12))) {
|
||||
if (index == 0 || !dateIndexMap.containsKey(dateKey)) {
|
||||
qualityList.set(index, 0);
|
||||
}
|
||||
qualityList.set(index, qualityList.get(index) + leg.getQuantity().intValue());
|
||||
}else if ("FINISHED_ITEM".equals(leg.getParentDocumentType()) && (leg.getAccountId().equals(8) || leg.getAccountId().equals(9) || leg.getAccountId().equals(10))) {
|
||||
if (index == 0 || !dateIndexMap.containsKey(dateKey)) {
|
||||
finishItems.set(index, 0);
|
||||
}
|
||||
finishItems.set(index, finishItems.get(index) + leg.getQuantity().intValue());
|
||||
}
|
||||
}
|
||||
|
||||
barChartData.put("dates", uniqueDates);
|
||||
barChartData.put("cutting", cuttingList);
|
||||
barChartData.put("stitching", stitchingList);
|
||||
barChartData.put("quality", qualityList);
|
||||
barChartData.put("finishing", finishItems);
|
||||
|
||||
return barChartData;
|
||||
}
|
||||
|
||||
public List<POsDetails> getAllPOs(String poName) {
|
||||
List<POsDetails> pOsDetailsList = new ArrayList<>();
|
||||
List<JobCard> jobCards = jobCardDAO.findAll() ;
|
||||
HashMap<String, List<JobCard>> filterJobCardsByPos;
|
||||
if(poName != null && !poName.isEmpty()) {
|
||||
filterJobCardsByPos = jobCards.stream()
|
||||
.filter(jobCard -> jobCard.getPurchaseOrderId().equals(poName))
|
||||
.collect(Collectors.groupingBy(
|
||||
JobCard::getPurchaseOrderId,
|
||||
HashMap::new,
|
||||
Collectors.toList()
|
||||
));
|
||||
}else {
|
||||
filterJobCardsByPos = jobCards.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
JobCard::getPurchaseOrderId,
|
||||
HashMap::new,
|
||||
Collectors.toList()
|
||||
));
|
||||
}
|
||||
|
||||
Map<String,Integer> jobCardCompleteItems = new HashMap<>();
|
||||
for (String pos : filterJobCardsByPos.keySet()) {
|
||||
BigDecimal totalProduction = BigDecimal.ZERO;
|
||||
BigDecimal actualProduction = BigDecimal.ZERO;
|
||||
int poQuantity = 0;
|
||||
String articleName = "";
|
||||
Long qaProgressItems = 0L;
|
||||
Long totalFinishItem = 0L;
|
||||
POsDetails pOsDetails = new POsDetails();
|
||||
for (JobCard jobCard : filterJobCardsByPos.get(pos)) {
|
||||
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(jobCard.getId());
|
||||
totalProduction = totalProduction.add(jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
|
||||
actualProduction = actualProduction.add(jobCardItems.stream()
|
||||
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
poQuantity = jobCard.getPoQuantity();
|
||||
articleName = jobCard.getArticleName();
|
||||
qaProgressItems += Optional.ofNullable(stitchingOfflineItemDAO.CalculateTotalQA(jobCard.getId())).orElse(0L);
|
||||
totalFinishItem += Optional.ofNullable(finishedItemDAO.calculateTotalFinishItem(jobCard.getId())).orElse(0L);
|
||||
|
||||
jobCardCompleteItems = getSegregateItems(String.valueOf(jobCard.getId()));
|
||||
if (jobCardCompleteItems == null) {
|
||||
jobCardCompleteItems = new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
pOsDetails.setPoNumber(pos);
|
||||
pOsDetails.setArticleTitle(articleName);
|
||||
pOsDetails.setPoQuantity(poQuantity);
|
||||
pOsDetails.setTotalCutting(actualProduction.intValue());
|
||||
pOsDetails.setTotalStitching(totalProduction.intValue());
|
||||
pOsDetails.setTotalEndLineQC(qaProgressItems.intValue());
|
||||
pOsDetails.setTotalFinishing(totalFinishItem);
|
||||
|
||||
pOsDetails.setRemainingCutting(poQuantity - actualProduction.intValue());
|
||||
pOsDetails.setRemainingStitching(poQuantity - totalProduction.intValue());
|
||||
pOsDetails.setRemainingEndLineQC(poQuantity - qaProgressItems);
|
||||
pOsDetails.setRemainingFinishing(poQuantity - totalFinishItem);
|
||||
|
||||
pOsDetails.setTotalAGradeItem(jobCardCompleteItems.getOrDefault("A GRADE", 0));
|
||||
pOsDetails.setTotalBGradeItem(jobCardCompleteItems.getOrDefault("B GRADE", 0));
|
||||
pOsDetails.setTotalCGradeItem(jobCardCompleteItems.getOrDefault("C GRADE", 0));
|
||||
|
||||
pOsDetailsList.add(pOsDetails);
|
||||
}
|
||||
return pOsDetailsList;
|
||||
}
|
||||
|
||||
public HashMap<String, Map<String, Integer>> getAllPoJobCards(String PONumber, String selectDate) {
|
||||
String startDate = selectDate != null && !selectDate.isEmpty() ? selectDate + " 00:00:01": null;
|
||||
String endDate = selectDate != null && !selectDate.isEmpty() ? selectDate + " 23:59:59": null;
|
||||
|
||||
HashMap<String, Map<String, Integer>> poJobCardItemsProgress = new HashMap<>();
|
||||
List<JobCard> jobCards = jobCardDAO.findAll();
|
||||
// Filter JobCards by Purchase Order ID
|
||||
List<JobCard> filterJobCardsByPos = jobCards.stream()
|
||||
.filter(e -> e.getPurchaseOrderId().equals(PONumber))
|
||||
.collect(Collectors.toList());
|
||||
List<InventoryAccount> inventoryAccounts = inventoryAccountDAO.getPackagingAccounts();
|
||||
List<Integer> gradingAccounts = inventoryAccounts.stream().map(e-> (int)(e.getId())).collect(Collectors.toList());
|
||||
for (JobCard jobCard : filterJobCardsByPos) {
|
||||
List<Bundle> bundles = bundleDAO.findByCardIdAndDATE(jobCard.getId(),startDate,endDate);
|
||||
List<StitchingOfflineItem> stitchingOfflineItems = stitchingOfflineItemDAO.findByJobCardIdAndDate(jobCard.getId(),startDate,endDate);
|
||||
List<FinishedItem> finishedItems = finishedItemDAO.calculateTotalFinishItem(jobCard.getId(),startDate,endDate);
|
||||
List<InventoryTransactionLeg> inventoryTransactionLegs = inventoryTransactionLegDAO.getTransactionByJobCardAndDatesAndTypeAndAccountID(jobCard.getId(),startDate,endDate,"IN", gradingAccounts);
|
||||
|
||||
//cutting days wise
|
||||
BigDecimal cutting = bundles.stream()
|
||||
.map(bundle -> Optional.ofNullable(bundle.getWrapQuantity()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
//stitching day wise
|
||||
Integer stitching = stitchingOfflineItems.size();
|
||||
|
||||
//total qa
|
||||
Integer qa = finishedItems.size();
|
||||
Map<String, Integer> segregateItems = inventoryTransactionLegs.stream()
|
||||
.filter(leg -> inventoryAccounts.stream()
|
||||
.anyMatch(account -> (int) account.getId() == (leg.getAccountId())))
|
||||
.collect(Collectors.toMap(
|
||||
leg -> inventoryAccounts.stream()
|
||||
.filter(account -> (int) account.getId() == (leg.getAccountId()))
|
||||
.findFirst()
|
||||
.map(InventoryAccount::getTitle)
|
||||
.orElse("Unknown"),
|
||||
leg -> leg.getQuantity().intValue(),
|
||||
Integer::sum,
|
||||
HashMap::new
|
||||
));
|
||||
Map<String, Integer> items = getCompleteProduction(String.valueOf(jobCard.getId()));
|
||||
items.put("Cutting Progress",cutting.intValue());
|
||||
items.put("Stitching Progress",stitching);
|
||||
items.put("QA Progress",qa);
|
||||
items.put("A Grade",segregateItems.get("A GRADE") != null ? segregateItems.get("A GRADE") : 0);
|
||||
items.put("B Grade",segregateItems.get("B GRADE") != null ? segregateItems.get("B GRADE") : 0);
|
||||
items.put("C Grade",segregateItems.get("C GRADE") != null ? segregateItems.get("C GRADE") : 0);
|
||||
|
||||
// Define sorting order
|
||||
Map<String, Integer> indexMap = new HashMap<>();
|
||||
indexMap.put("Job Card Progress", 1);
|
||||
indexMap.put("Cutting Progress", 2);
|
||||
indexMap.put("Stitching Progress", 3);
|
||||
indexMap.put("QA Progress", 4);
|
||||
indexMap.put("Finishing Progress", 5);
|
||||
indexMap.put("A GRADE", 6);
|
||||
indexMap.put("B GRADE", 7);
|
||||
indexMap.put("C GRADE", 8);
|
||||
|
||||
// Sort items based on indexMap order
|
||||
Map<String, Integer> sortedItems = items.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(entry -> indexMap.getOrDefault(entry.getKey(), Integer.MAX_VALUE)))
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
Map.Entry::getValue,
|
||||
(oldValue, newValue) -> oldValue,
|
||||
LinkedHashMap::new
|
||||
));
|
||||
|
||||
// Add sorted items to the result map
|
||||
poJobCardItemsProgress.put(jobCard.getCode(), sortedItems);
|
||||
}
|
||||
|
||||
return poJobCardItemsProgress;
|
||||
}
|
||||
|
||||
public Map<String, Object> getCuttingTableDetails(String jobCardId, String cuttingTableId, String startDate, String endDate) {
|
||||
Map<String, Object> cuttingDetails = new HashMap<>();
|
||||
long jobCardIdTemp = 0L;
|
||||
String startDate1 = null;
|
||||
String endDate1 = null;
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(startDate)) {
|
||||
String formattedStart = CTPDateTimeFormat.getMySQLFormattedDateString(startDate, CTPDateTimeFormat.HTML5_DATE_INPUT_FORMAT);
|
||||
String formattedEnd = !StringUtils.isNullOrEmpty(endDate)
|
||||
? CTPDateTimeFormat.getMySQLFormattedDateString(endDate, CTPDateTimeFormat.HTML5_DATE_INPUT_FORMAT)
|
||||
: LocalDate.now().toString();
|
||||
|
||||
startDate1 = String.format("'%s 00:00:01'", formattedStart);
|
||||
endDate1 = String.format("'%s 23:59:59'", formattedEnd);
|
||||
}
|
||||
|
||||
List<InventoryAccount> inventoryAccounts = inventoryAccountDAO.findByParentEntityTypeAndParentId("PROCESS", 1L);
|
||||
List<Long> inventoryAccountIds = inventoryAccounts.stream().map(InventoryAccount::getId).collect(Collectors.toList());
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(jobCardId)) {
|
||||
jobCardIdTemp = Long.parseLong(jobCardId);
|
||||
} else if (!StringUtils.isNullOrEmpty(cuttingTableId)) {
|
||||
inventoryAccountIds = List.of(Long.parseLong(cuttingTableId));
|
||||
}
|
||||
|
||||
String query = SummaryInventoryReportQueryBuilder.cuttingQueryBuild(jobCardIdTemp, inventoryAccountIds, startDate1, endDate1, "IN");
|
||||
List<InventoryTransactionLeg> inventoryTransactionLegs = inventoryTransactionLegDAO.findByQuery(query);
|
||||
|
||||
Map<String, Integer> dateWiseProduction = new TreeMap<>();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
|
||||
|
||||
Map<LocalDate, List<Long>> dateWiseJobCardIds = inventoryTransactionLegs.stream()
|
||||
.filter(e -> e.getTransactionLegDateTime() != null && e.getJobCardId() != 0)
|
||||
.collect(Collectors.groupingBy(
|
||||
e -> e.getTransactionLegDateTime().toLocalDate(),
|
||||
Collectors.mapping(InventoryTransactionLeg::getJobCardId, Collectors.toList())
|
||||
));
|
||||
|
||||
for (Map.Entry<LocalDate, List<Long>> entry : dateWiseJobCardIds.entrySet()) {
|
||||
List<Long> jobCardIds = entry.getValue();
|
||||
if (!jobCardIds.isEmpty()) {
|
||||
List<JobCardItem> jobCardItems = jobCardItemDAO.findByJobCardIds(jobCardIds);
|
||||
int totalProduction = jobCardItems.stream()
|
||||
.filter(item -> item.getActualProduction() != null)
|
||||
.mapToInt(item -> item.getActualProduction().intValue())
|
||||
.sum();
|
||||
dateWiseProduction.put(entry.getKey().format(formatter), totalProduction);
|
||||
}
|
||||
}
|
||||
|
||||
List<Long> distinctJobCardIds = inventoryTransactionLegs.stream()
|
||||
.map(InventoryTransactionLeg::getJobCardId)
|
||||
.filter(id -> id != 0)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<Long, List<CuttingJobCardItemWrapper>> jobCardItemsCuttingDetailsMap = new HashMap<>();
|
||||
|
||||
for (long jobCardIdEntry : distinctJobCardIds) {
|
||||
Long accountId = inventoryTransactionLegs.stream()
|
||||
.filter(e -> e.getJobCardId() == jobCardIdEntry)
|
||||
.map(e -> e.getAccountId().longValue())
|
||||
.findFirst()
|
||||
.orElse(0L);
|
||||
|
||||
JobCard jobCard = jobCardDAO.find(jobCardIdEntry);
|
||||
Bundle bundle = bundleDAO.findByCardId(jobCardIdEntry).stream().findFirst().orElse(new Bundle());
|
||||
|
||||
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(jobCardIdEntry);
|
||||
|
||||
List<CuttingJobCardItemWrapper> wrappers = jobCardItems.stream().map(item -> {
|
||||
CuttingJobCardItemWrapper wrapper = new CuttingJobCardItemWrapper();
|
||||
wrapper.setArticleName(jobCard.getArticleName());
|
||||
wrapper.setJobCardCode(jobCard.getCode());
|
||||
wrapper.setGsm(item.getGsm());
|
||||
wrapper.setPly(item.getPly());
|
||||
wrapper.setSku(item.getSku());
|
||||
wrapper.setTotalCutting(item.getActualProduction().longValue());
|
||||
wrapper.setWidth(item.getWidth());
|
||||
wrapper.setWtPly(item.getWtPly());
|
||||
wrapper.setComplete(item.isComplete());
|
||||
wrapper.setPoName(jobCard.getPurchaseOrderId());
|
||||
wrapper.setCuttingOperatorName(bundle.getCreatedBy());
|
||||
wrapper.setJobCardId(item.getJobCardId());
|
||||
wrapper.setLength(item.getLength());
|
||||
wrapper.setCuttingAccountId(accountId);
|
||||
return wrapper;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
jobCardItemsCuttingDetailsMap.computeIfAbsent(accountId, k -> new ArrayList<>()).addAll(wrappers);
|
||||
}
|
||||
|
||||
cuttingDetails.put("Date Wise Cutting", dateWiseProduction);
|
||||
cuttingDetails.put("accountWiseCutting", jobCardItemsCuttingDetailsMap);
|
||||
cuttingDetails.put("cuttingAccount", inventoryAccounts);
|
||||
return cuttingDetails;
|
||||
}
|
||||
|
||||
|
||||
private StringBuilder generateTime(LocalDateTime startDate, LocalDateTime endDate){
|
||||
StringBuilder totalTime = new StringBuilder();
|
||||
if(startDate != null && endDate != null){
|
||||
Duration duration = Duration.between(startDate, endDate);
|
||||
if (duration.toDays() > 0) {
|
||||
totalTime.append(String.format("%d days, ", duration.toDays()));
|
||||
}
|
||||
|
||||
if (duration.toHours() % 24 > 0) {
|
||||
totalTime.append(String.format("%d hours, ", duration.toHours() % 24));
|
||||
}
|
||||
|
||||
if (duration.toMinutes() % 60 > 0) {
|
||||
totalTime.append(String.format("%d minutes ", duration.toMinutes() % 60));
|
||||
}
|
||||
return totalTime;
|
||||
}else return totalTime.append("");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
( async function(){
|
||||
|
||||
Vue.prototype.$types = window.ctp.types;
|
||||
Vue.prototype.$accounts = window.ctp.accounts;
|
||||
|
||||
let app = new Vue({
|
||||
el : '#dashboard',
|
||||
data :{
|
||||
jobCard : {}
|
||||
},
|
||||
computed: {
|
||||
getStatus: function() {
|
||||
return `badge-${this.jobCard.status}`;
|
||||
},
|
||||
getInvStatus: function() {
|
||||
return `badge-${this.jobCard.inventoryStatus}`;
|
||||
}
|
||||
},
|
||||
methods : {
|
||||
onCardSelect : function ( id, card ) {
|
||||
// $.ajax({
|
||||
// url: `/ctp/rest/job-cards/find/${id}`,
|
||||
// method: 'GET',
|
||||
// contentType: 'application/json',
|
||||
// dataType: 'json',
|
||||
// success: ( data ) => {
|
||||
// this.jobCard = data;
|
||||
// },
|
||||
// error : function ( err ){
|
||||
// alert( err );
|
||||
// }
|
||||
// })
|
||||
console.log("hello")
|
||||
|
||||
}
|
||||
},
|
||||
mounted : function () {
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
})(jQuery);
|
|
@ -0,0 +1,274 @@
|
|||
document.addEventListener("DOMContentLoaded", function () {
|
||||
if (typeof Highcharts === "undefined") {
|
||||
console.error("Highcharts library not loaded!");
|
||||
return;
|
||||
}
|
||||
|
||||
function createGaugeChart(progress, color, divId, title, height, width , fontSize, fontYAxis, fontXAxis, fontColor, total, actual, aGrade, bGrade, cGrade) {
|
||||
Highcharts.chart(divId, {
|
||||
chart: {
|
||||
type: 'solidgauge',
|
||||
width: width,
|
||||
height: height,
|
||||
backgroundColor: 'transparent',
|
||||
plotBackgroundColor: null,
|
||||
shadow: false
|
||||
},
|
||||
title: {
|
||||
text: title,
|
||||
y: 30
|
||||
},
|
||||
pane: {
|
||||
startAngle: 0,
|
||||
endAngle: 360,
|
||||
y: 0,
|
||||
background: [{
|
||||
backgroundColor: 'transparent',
|
||||
shape: "arc",
|
||||
borderWidth: 0,
|
||||
innerRadius: '60%',
|
||||
outerRadius: '100%'
|
||||
}]
|
||||
},
|
||||
yAxis: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
tickPositions: [],
|
||||
lineWidth: 0,
|
||||
minorTickLength: 0,
|
||||
tickWidth: 0,
|
||||
gridLineWidth: 0,
|
||||
stops: [
|
||||
[1, color]
|
||||
]
|
||||
},
|
||||
series: [{
|
||||
name: 'Percentage',
|
||||
data: [progress],
|
||||
dataLabels: {
|
||||
format: '{y}% ',
|
||||
y: fontYAxis,
|
||||
x: fontXAxis,
|
||||
borderWidth: 0,
|
||||
backgroundColor: 'none',
|
||||
style: {
|
||||
fontSize: fontSize + 'px',
|
||||
fontWeight: 'bold',
|
||||
color:fontColor
|
||||
},
|
||||
zIndex: 10
|
||||
},
|
||||
tooltip: {
|
||||
pointFormat: title == 'Finishing Progress' ? 'Percentage: ' + progress + '%<br>Total: ' + total + '<br>Completed: ' + actual + '<br>A Grade: ' + aGrade + '<br>B Grade: ' + bGrade + '<br>C Grade: ' + cGrade : 'Percentage: ' + progress + '%<br>Total: ' + total + '<br>Completed:'+actual
|
||||
},
|
||||
color: color,
|
||||
showInLegend: false
|
||||
}],
|
||||
credits: {
|
||||
enabled: false
|
||||
}
|
||||
});
|
||||
}
|
||||
function createBarChart(divId, height, width, title, aHeading, aData, bHeading, bData, cHeading, cData, dHeading, dData, dates, fontSize, maxValue) {
|
||||
if (!document.getElementById(divId)) {
|
||||
return;
|
||||
}
|
||||
Highcharts.chart(divId, {
|
||||
chart: {
|
||||
type: 'column',
|
||||
height: height,
|
||||
width: width,
|
||||
},
|
||||
title: {
|
||||
text: title,
|
||||
align: 'center',
|
||||
verticalAlign: 'top',
|
||||
y: 30,
|
||||
style: {
|
||||
fontSize: fontSize,
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
categories: dates,
|
||||
labels: {
|
||||
rotation: -45,
|
||||
style: {
|
||||
fontSize: 10-fontSize,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
min: 0,
|
||||
max: maxValue,
|
||||
softMax: maxValue,
|
||||
softMin: 0,
|
||||
startOnTick: true,
|
||||
endOnTick: true,
|
||||
title: {
|
||||
text: 'Total Progress',
|
||||
style: {
|
||||
fontSize: fontSize,
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
},
|
||||
labels: {
|
||||
format: '{value}%'
|
||||
}
|
||||
},
|
||||
|
||||
scrollbar: {
|
||||
enabled: true
|
||||
},
|
||||
series: [{
|
||||
name: aHeading,
|
||||
data: aData
|
||||
}, {
|
||||
name: bHeading,
|
||||
data: bData
|
||||
}, {
|
||||
name: cHeading,
|
||||
data: cData
|
||||
}, {
|
||||
name: dHeading,
|
||||
data: dData
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
function createSingleBarChart(divId, height, width, title,Heading, Data, dates, fontSize, maxValue) {
|
||||
if (!document.getElementById(divId)) {
|
||||
return;
|
||||
}
|
||||
Highcharts.chart(divId, {
|
||||
chart: {
|
||||
type: 'column',
|
||||
height: height,
|
||||
width: width,
|
||||
},
|
||||
title: {
|
||||
text: title,
|
||||
align: 'center',
|
||||
verticalAlign: 'top',
|
||||
y: 30,
|
||||
style: {
|
||||
fontSize: fontSize,
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
categories: dates,
|
||||
labels: {
|
||||
rotation: -45,
|
||||
style: {
|
||||
fontSize: 10-fontSize,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
min: 0,
|
||||
max: maxValue,
|
||||
softMax: maxValue,
|
||||
softMin: 0,
|
||||
startOnTick: true,
|
||||
endOnTick: true,
|
||||
title: {
|
||||
text: 'Total Progress',
|
||||
style: {
|
||||
fontSize: fontSize,
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
},
|
||||
labels: {
|
||||
format: '{value}%'
|
||||
}
|
||||
},
|
||||
|
||||
scrollbar: {
|
||||
enabled: true
|
||||
},
|
||||
series: [{
|
||||
name: Heading,
|
||||
data: Data
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
initializeGauges();
|
||||
function initializeGauges() {
|
||||
|
||||
const gaugeDivs2 = document.querySelectorAll('.gauge-chart2');
|
||||
gaugeDivs2.forEach(function (div) {
|
||||
const progress = div.getAttribute('data-progress');
|
||||
const color = div.getAttribute('data-color');
|
||||
const title = div.getAttribute('data-title');
|
||||
const height = div.getAttribute('data-height');
|
||||
const width = div.getAttribute('data-width');
|
||||
const fontSize = div.getAttribute('data-fontSize');
|
||||
const fontColor = div.getAttribute('data-fontColor');
|
||||
const total = div.getAttribute('data-totalProduction');
|
||||
const actual = div.getAttribute('data-actualProduction');
|
||||
const divId = div.id;
|
||||
console.log(actual)
|
||||
createGaugeChart(parseInt(progress), color, divId, title, height, width, fontSize, -20, 4, fontColor, total, actual);
|
||||
});
|
||||
|
||||
const gaugeDivs = document.querySelectorAll('.gauge-chart');
|
||||
gaugeDivs.forEach(function (div) {
|
||||
const progress = div.getAttribute('data-progress');
|
||||
const color = div.getAttribute('data-color');
|
||||
const title = div.getAttribute('data-title');
|
||||
const height = div.getAttribute('data-height');
|
||||
const width = div.getAttribute('data-width');
|
||||
const fontSize = div.getAttribute('data-fontSize');
|
||||
const fontColor = div.getAttribute('data-fontColor');
|
||||
const total = div.getAttribute('data-totalProduction');
|
||||
const actual = div.getAttribute('data-actualProduction');
|
||||
const aGrade = div.getAttribute('data-aGrade');
|
||||
const bGrade = div.getAttribute('data-bGrade');
|
||||
const cGrade = div.getAttribute('data-cGrade');
|
||||
const divId = div.id;
|
||||
createGaugeChart(parseInt(progress), color, divId, title, height, width, fontSize, -15, 2, fontColor, total, actual, aGrade, bGrade, cGrade);
|
||||
|
||||
});
|
||||
|
||||
const barChart = document.querySelectorAll('.barChart');
|
||||
barChart.forEach(function (div) {
|
||||
const title = div.getAttribute('data-title');
|
||||
const height = div.getAttribute('data-height');
|
||||
const width = div.getAttribute('data-width');
|
||||
const fontSize = div.getAttribute('data-fontSize');
|
||||
const maxValue = Number(div.getAttribute('data-totalProduction'));
|
||||
const aHeading = 'Cutting';
|
||||
const aData = JSON.parse(div.getAttribute('data-cutting'));
|
||||
const bHeading='Stitching';
|
||||
const bData =JSON.parse(div.getAttribute('data-stitching'));
|
||||
const cHeading='End Line Quality Checking';
|
||||
const cData =JSON.parse(div.getAttribute('data-quality'));
|
||||
const dHeading="Finish Items";
|
||||
const dData =JSON.parse(div.getAttribute('data-finishing'));
|
||||
const dates = div.getAttribute('data-dates');
|
||||
const datesArray = dates.split(',');
|
||||
const divId = div.id;
|
||||
createBarChart( divId, height, width, title, aHeading, aData, bHeading, bData, cHeading, cData, dHeading, dData, datesArray, fontSize, maxValue);
|
||||
});
|
||||
|
||||
const cuttingBarChart = document.querySelectorAll('.cuttingBarChart');
|
||||
cuttingBarChart.forEach(function (div) {
|
||||
const title = div.getAttribute('data-title');
|
||||
const height = div.getAttribute('data-height');
|
||||
const width = div.getAttribute('data-width');
|
||||
const fontSize = div.getAttribute('data-fontSize');
|
||||
const maxValue = Number(div.getAttribute('data-totalProduction'));
|
||||
const Heading = div.getAttribute('data-barHeading');
|
||||
const Data = JSON.parse(div.getAttribute('data-barData'));
|
||||
const dates = div.getAttribute('data-dates');
|
||||
const datesArray = dates.split(',');
|
||||
const divId = div.id;
|
||||
createSingleBarChart( divId, height, width, title, Heading, Data, datesArray, fontSize, maxValue);
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,91 @@
|
|||
(async function () {
|
||||
|
||||
Vue.component('bundle-table', {
|
||||
props: ['bundles'],
|
||||
methods: {
|
||||
removeBundle: function (idx) {
|
||||
this.$emit('bundle-remove', idx)
|
||||
},
|
||||
getFormattedDateTime: function (bundle) {
|
||||
if (!!bundle.createdAt) {
|
||||
return bundle.createdAt.split('T')[0] + ' ' + bundle.createdAt.split('T')[1];
|
||||
}
|
||||
return luxon.DateTime.now().toFormat('yyyy-MM-dd HH:mm:ss');
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<table class="table table-bordered bg-white col-sm-8">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Item ID</th>
|
||||
<th>Sku</th>
|
||||
<th>Job Card ID</th>
|
||||
<th>Wrap Quantity</th>
|
||||
<th>Type</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(bundle,index) in bundles">
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].id'" v-bind:value="bundle.id" >
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].itemId'" v-bind:value="bundle.itemId" >
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].sku'" v-bind:value="bundle.sku" >
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].masterBundleId'" v-bind:value="bundle.masterBundleId" >
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].jobCardId'" v-bind:value="bundle.jobCardId" >
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].wrapQuantity'" v-bind:value="bundle.wrapQuantity" >
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].type'" v-bind:value="bundle.type" >
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].barcode'" v-bind:value="bundle.barcode" >
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].createdAt'" v-bind:value="getFormattedDateTime(bundle.createdAt)" >
|
||||
<input hidden="hidden" v-bind:name="'bundles[' + index + '].createdBy'" v-bind:value="bundle.createdBy" >
|
||||
<td><span>{{bundle.id}}</span></td>
|
||||
<td><span>{{bundle.itemId}}</span></td>
|
||||
<td><span>{{bundle.sku}}</span></td>
|
||||
<td><span>{{bundle.jobCardId}}</span></td>
|
||||
<td><span>{{bundle.wrapQuantity}}</span></td>
|
||||
<td><span>{{bundle.type}}</span></td>
|
||||
<td>
|
||||
<button type="button" title="Remove" class="btn btn-light text-left" v-on:click="removeBundle(index)">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`
|
||||
|
||||
})
|
||||
|
||||
|
||||
let app = new Vue({
|
||||
el: "#jobcardsidebar",
|
||||
data: {
|
||||
bundles: [],
|
||||
},
|
||||
methods: {
|
||||
removeBundle: function (idx) {
|
||||
this.bundles.splice(idx, 1)
|
||||
},
|
||||
onBundleSelect: function (id, bundle) {
|
||||
this.bundles.push(
|
||||
bundle
|
||||
)
|
||||
},
|
||||
hasMultipleItemSelect : function () {
|
||||
const ids = this.bundles.map(item => item.itemId);
|
||||
const uniqueIds = new Set(ids);
|
||||
return uniqueIds.size > 1;
|
||||
},
|
||||
hasDuplicates: function () {
|
||||
const ids = this.bundles.map(item => item.id);
|
||||
const uniqueIds = new Set(ids);
|
||||
return ids.length !== uniqueIds.size;
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.bundles = window.ctp.wrapper.bundles;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
File diff suppressed because one or more lines are too long
|
@ -1050,6 +1050,35 @@ if ( typeof Vue !== 'undefined' ) {
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* location site search component
|
||||
*/
|
||||
Vue.component( 'search-job-card-dashBoard', {
|
||||
mixins: [searchComponentMixin],
|
||||
methods: {
|
||||
getSearchUrl: function() {
|
||||
return `/ctp/rest/locations/sites/search?term=${encodeURIComponent( this.list.term )}`;
|
||||
},
|
||||
getEmittedEventName: function() {
|
||||
return 'location-site-select';
|
||||
}
|
||||
},
|
||||
props: {
|
||||
labelText: {
|
||||
default: 'Search Site'
|
||||
},
|
||||
titleFieldName: {
|
||||
default: 'siteTitle'
|
||||
},
|
||||
idFieldName: {
|
||||
default: 'siteId'
|
||||
},
|
||||
codeFieldName: {
|
||||
default: ''
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* location site search component
|
||||
|
@ -3409,6 +3438,44 @@ if ( typeof Vue !== 'undefined' ) {
|
|||
})
|
||||
|
||||
|
||||
/*
|
||||
* job card search for reporting
|
||||
* */
|
||||
Vue.component('job-card-for-reporting',{
|
||||
mixins: [searchComponentMixin],
|
||||
methods : {
|
||||
getSearchUrl : function () {
|
||||
let url = `/ctp/rest/job-cards/search?term=${encodeURIComponent(this.list.term)}&filter=false`;
|
||||
if( ! this.filter ){
|
||||
url += '&filter=false'
|
||||
}
|
||||
return url;
|
||||
},
|
||||
getEmittedEventName: function() {
|
||||
return 'job-card-select';
|
||||
},
|
||||
getTitle: function( card ) {
|
||||
return `(${card.code}) - ${card.createdBy}`;
|
||||
}
|
||||
},
|
||||
props: {
|
||||
labelText: {
|
||||
default: 'Search Job Card'
|
||||
},
|
||||
titleFieldName: {
|
||||
default: 'cardTitle'
|
||||
},
|
||||
idFieldName: {
|
||||
default: 'jobCardId'
|
||||
},
|
||||
codeFieldName : {
|
||||
default : 'jobCardCode'
|
||||
},
|
||||
filter : {
|
||||
default : true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
<script th:src="@{/js/vendor/bignumber.min.js}"></script>
|
||||
<script th:src="@{/js/vue-components.js}"></script>
|
||||
<script th:src="@{/js/utils.js}"></script>
|
||||
<script src="https://code.highcharts.com/highcharts.js"></script>
|
||||
<script src="https://code.highcharts.com/highcharts-more.js"></script>
|
||||
<script src="https://code.highcharts.com/modules/solid-gauge.js"></script>
|
||||
<title th:text="${#strings.concat(title, ' - CTP')}"></title>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -125,6 +128,28 @@
|
|||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<!--Second level of reporting-->
|
||||
<nav class="navbar navbar-light bg-light navbar-expand-lg justify-content-between"
|
||||
th:if="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/reporting')}">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item"
|
||||
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/reporting/po-report') ? 'active' : ''}">
|
||||
<a th:href="@{/reporting/po-report}" class="nav-link">PO Report</a>
|
||||
</li>
|
||||
<li class="nav-item"
|
||||
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/reporting/job-card-report') ? 'active' : ''}">
|
||||
<a th:href="@{/reporting/job-card-report}" class="nav-link">Job Card Report</a>
|
||||
</li>
|
||||
<li class="nav-item"
|
||||
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/reporting/cutting-report') ? 'active' : ''}">
|
||||
<a th:href="@{/reporting/cutting-report}" class="nav-link">Cutting Tables Report</a>
|
||||
</li>
|
||||
<li class="nav-item"
|
||||
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/reporting/summary') ? 'active' : ''}">
|
||||
<a th:href="@{/reporting/summary}" class="nav-link">Summary</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<!-- second level stitching -->
|
||||
<nav class="navbar navbar-light bg-light navbar-expand-lg justify-content-between"
|
||||
th:if="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/stitching')}">
|
||||
|
|
|
@ -32,12 +32,20 @@
|
|||
<label>Lot Number</label>
|
||||
<input class="form-control" th:field="*{lotNumber}" required>
|
||||
</div>
|
||||
<div class="col-sm-3 form-group">
|
||||
<label>Article Name</label>
|
||||
<input class="form-control" th:field="*{articleName}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-sm-3 form-group">
|
||||
<label>Purchase Order</label>
|
||||
<input type="text" class="form-control" th:field="*{purchaseOrderId}" required>
|
||||
</div>
|
||||
<div class="col-sm-3 form-group">
|
||||
<label>PO Quantity</label>
|
||||
<input type="number" class="form-control" th:field="*{poQuantity}" required>
|
||||
</div>
|
||||
<div class="col-sm-3 form-group" th:with="title=*{locationTitle},id=*{locationSiteId}">
|
||||
<location-site-search th:attr="id=${id},title=${title}"
|
||||
v-bind:id-field-name="'locationSiteId'">
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml">
|
||||
<head th:replace="_fragments :: head('Home Page')"></head>
|
||||
<body>
|
||||
<!-- sidebar starts -->
|
||||
<aside class="col-sm-2" th:fragment="sidebar">
|
||||
<div class="page-filters-sidebar">
|
||||
<form th:action="@{${#strings.replace(#httpServletRequest.requestURI, #request.getContextPath(), '')}}">
|
||||
<h5 class="mb-4">Refine Your Search</h5>
|
||||
<div class="form-group" th:with="title=${param['jobCardCode']}" data-vue-app>
|
||||
<job-card-for-reporting th:attr="title=${title}"
|
||||
v-bind:id-field-name="'job-card-id'"
|
||||
v-bind:title-field-name="''"
|
||||
></job-card-for-reporting>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Start Date</label>
|
||||
<input type="date" class="form-control" name="start-date" th:value="${param['start-date'] ?: startDate}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>End Date</label>
|
||||
<input type="date" class="form-control" name="end-date" th:value="${param['end-date'] ?: endDate}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Cutting Account</label>
|
||||
<select class="form-control" name="accountId">
|
||||
<option value="">Please Select</option>
|
||||
<option th:each="account : ${accounts}"
|
||||
th:value="${account.id}"
|
||||
th:selected="${account.id == (param['accountId'] ?: accountId)}"
|
||||
th:text="${account.title}">
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-secondary btn-block" value="Search">
|
||||
<a th:href="@{${#strings.replace(#httpServletRequest.requestURI, #request.getContextPath(), '')}}"
|
||||
class="btn btn-secondary btn-block">Reset</a>
|
||||
</form>
|
||||
<div th:replace="_fragments :: page-footer-scripts"></div>
|
||||
</div>
|
||||
</aside>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,87 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ctp="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head th:replace="_fragments :: head('Cutting Report')"></head>
|
||||
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<header class="row page-header" th:replace="_fragments :: page-header"></header>
|
||||
<main class="row page-main">
|
||||
<aside class="col-sm-2" th:replace="/reporting/cutting-report-sidebar :: sidebar"></aside>
|
||||
<div class="col-sm">
|
||||
<table class="table table-striped" data-account-table data-order="[[ 0, "asc" ]]">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td th:if="${cutting.get('Date Wise Cutting') != null}" style="padding-left: 150px;">
|
||||
<div style="border: 2px solid #d5d8dc; padding-top: 10px; border-radius: 10px; height: 560px; width: 80%; overflow-x: auto;">
|
||||
<div id="cuttingBarChart" class="cuttingBarChart" style="height: 500px; width: 1600px;"
|
||||
th:data-width="1600"
|
||||
th:data-height="500"
|
||||
th:data-title="'Days Wise Progress'"
|
||||
th:data-dates="${cutting.get('Date Wise Cutting').keySet()}"
|
||||
th:data-barData="${cutting.get('Date Wise Cutting').values()}"
|
||||
th:data-barHeading="'Cutting'"
|
||||
th:data-stitching="''"
|
||||
th:data-quality="''"
|
||||
th:data-finishing="''"
|
||||
th:data-totalProduction="'30000'"
|
||||
th:data-fontSize="30"
|
||||
></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr th:if="${cutting.get('cuttingAccount') != null}" th:each="cuttingAccount, index : ${cutting.get('cuttingAccount')}">
|
||||
<td th:if="${cutting.get('accountWiseCutting').containsKey(cuttingAccount.id)}" class="p-0 text-center">
|
||||
<div class="bg-dark text-white py-2 px-3 fs-5 fw-bold text-center" th:text="${cuttingAccount.title}"></div>
|
||||
<table class="table table-bordered mt-2">
|
||||
<thead class="">
|
||||
<tr>
|
||||
<th>Job Card</th>
|
||||
<th>PO Number</th>
|
||||
<th>SKU</th>
|
||||
<th>Article Name</th>
|
||||
<th>Total Cutting</th>
|
||||
<th>Cutting Operator Name</th>
|
||||
<th>Width</th>
|
||||
<th>Length</th>
|
||||
<th>GSM</th>
|
||||
<th>WT PLY</th>
|
||||
<th>PLY</th>
|
||||
<th>Cutting Complete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="wrap, index : ${cutting.get('accountWiseCutting').get(cuttingAccount.id)}">
|
||||
<td th:text="${wrap.jobCardCode}"></td>
|
||||
<td th:text="${wrap.poName}"></td>
|
||||
<td th:text="${wrap.sku}"></td>
|
||||
<td th:text="${wrap.articleName}"></td>
|
||||
<td th:text="${wrap.totalCutting}"></td>
|
||||
<td th:text="${wrap.cuttingOperatorName}"></td>
|
||||
<td th:text="${wrap.width}"></td>
|
||||
<td th:text="${wrap.length}"></td>
|
||||
<td th:text="${wrap.gsm}"></td>
|
||||
<td th:text="${wrap.wtPly}"></td>
|
||||
<td th:text="${wrap.ply}"></td>
|
||||
<td>
|
||||
<span th:if="${!wrap.Complete}" class="badge badge-danger" >Not Complete</span>
|
||||
<div th:if="${wrap.Complete}">
|
||||
<span class="badge badge-APPROVED">Completed</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Load JavaScript file -->
|
||||
<script th:src="@{/js/charts.js}"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml">
|
||||
<head th:replace="_fragments :: head('Home Page')"></head>
|
||||
<body>
|
||||
<!-- sidebar starts -->
|
||||
<aside class="col-sm-2" th:fragment="sidebar">
|
||||
<div class="page-filters-sidebar">
|
||||
<form th:action="@{${#strings.replace(#httpServletRequest.requestURI, #request.getContextPath(), '')}}">
|
||||
<h5 class="mb-4">Refine Your Search</h5>
|
||||
<div class="form-group" th:with="id=${param['site-id']},title=${param['site-title']}" data-vue-app>
|
||||
<job-card-for-reporting th:attr="id=${id},title=${title}"
|
||||
v-bind:id-field-name="'job-card-id'"
|
||||
v-bind:title-field-name="'site-title'"
|
||||
></job-card-for-reporting>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-secondary btn-block" value="Search">
|
||||
<a th:href="@{${#strings.replace(#httpServletRequest.requestURI, #request.getContextPath(), '')}}"
|
||||
class="btn btn-secondary btn-block">Reset</a>
|
||||
</form>
|
||||
<div th:replace="_fragments :: page-footer-scripts"></div>
|
||||
</div>
|
||||
</aside>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,164 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ctp="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head th:replace="_fragments :: head('Job Card Report')"></head>
|
||||
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<header class="row page-header" th:replace="_fragments :: page-header"></header>
|
||||
<main class="row page-main">
|
||||
<aside class="col-sm-2" th:replace="/reporting/job-card-report-sidebar :: sidebar"></aside>
|
||||
<div class="col-sm">
|
||||
<table class="table " >
|
||||
<thead>
|
||||
<tr th:if="${jobCardProgress == null}">
|
||||
<th colspan="5" style="font-size:26px; text-align: center;">Please Select Job card</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr th:if="${jobCardProgress != null }">
|
||||
<td style="padding:0px;">
|
||||
<div style="border: 2px solid #d5d8dc; padding: 10px; border-radius: 10px; height: 370px;">
|
||||
<h1 style="text-align: center;">Job Card Report</h1>
|
||||
<div style="display: flex; align-items: center;">
|
||||
<div style="text-align: center;margin-top: -45px">
|
||||
<div style="width: 300px; height: 330px;"
|
||||
th:id="'gauge-chart2'"
|
||||
class="gauge-chart2"
|
||||
th:data-progress="${jobCardProgress.get('Job Card Progress')}"
|
||||
th:data-title="${'Job Card Progress'}"
|
||||
th:data-width="350"
|
||||
th:data-height="350"
|
||||
th:data-totalProduction="${totalProduction}"
|
||||
th:data-actualProduction="${completeProduction.get('Job Card Progress')}"
|
||||
th:data-fontSize="30"
|
||||
th:data-fontColor="'#17202a'"
|
||||
th:data-color="'#566573'"></div>
|
||||
</div>
|
||||
<div style="display: flex; ">
|
||||
<div th:each="title, index : ${jobCardProgress.keySet()}" style="text-align: center; margin-top: 40px;">
|
||||
<div th:if ="${ title != 'Job Card Progress' }"
|
||||
th:id="'gauge-chart-' + ${index}" class="gauge-chart" style="width: 200px; height: 230px;"
|
||||
th:data-progress="${jobCardProgress.get(title)}"
|
||||
th:data-totalProduction="${totalProduction}"
|
||||
th:data-actualProduction="${completeProduction.get(title)}"
|
||||
th:data-title="${title}"
|
||||
th:data-width="230"
|
||||
th:data-height="230"
|
||||
th:data-fontSize="20"
|
||||
th:data-aGrade="${segregateItems.get('A GRADE') == null ? 0 : segregateItems.get('A GRADE')}"
|
||||
th:data-bGrade="${segregateItems.get('B GRADE') == null ? 0 : segregateItems.get('B GRADE')}"
|
||||
th:data-cGrade="${segregateItems.get('C GRADE') == null ? 0 : segregateItems.get('C GRADE')}"
|
||||
th:data-fontColor="'#17202a'"
|
||||
th:data-color="'#95a5a6'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr th:if="${phasesTimes != null }">
|
||||
<td style="display: flex; flex-direction: column; align-items: center; border: none !important; outline: none;">
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<div th:each="phase, index : ${phasesTimes.keySet()}" style="border: 2px solid #d5d8dc; border-radius: 10px; text-align: center; padding:20px;">
|
||||
<H6 th:text="${phase}"></H6>
|
||||
<H6 th:text="${phasesTimes.get(phase)}"></H6>
|
||||
<H6 th:if="${pendingStatus.get(phase) != null}" th:text="${pendingStatus.get(phase)}"></H6>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<!-- Cutting Details Column -->
|
||||
<td th:if="${cuttingDetails != null && cuttingDetails.get('accounts') != null}" style="padding: 0px; text-align: center;">
|
||||
<div style="background-color: black; color: white; padding: 10px; font-size: 18px; font-weight: bold; text-align: center;">
|
||||
Cutting Detail
|
||||
</div>
|
||||
<table class="table" style="width: 100%; border-collapse: collapse;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Title</th>
|
||||
<th>Cutting</th>
|
||||
<th>Cutting Date</th>
|
||||
<th>Cutting Table Descriptions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:if="${cuttingDetails != null}" th:each="detail, index : ${cuttingDetails.get('accounts').keySet()}">
|
||||
<td th:text="${cuttingDetails.get('accounts').get(detail).id}"></td>
|
||||
<td th:text="${cuttingDetails.get('accounts').get(detail).title}"></td>
|
||||
<td th:text="${cuttingDetails.get('personName').get(detail)}"></td>
|
||||
<td>
|
||||
<span th:text="${#temporals.format(cuttingDetails.get('date').get(detail), 'E')}"></span>
|
||||
<span ctp:formatdate="${cuttingDetails.get('date').get(detail)}"></span>
|
||||
</td>
|
||||
<td th:text="${cuttingDetails.get('accounts').get(detail).notes}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
<!-- Stitching Details Column -->
|
||||
<td th:if="${stitchingDetails != null && stitchingDetails.get('accounts') != null}" style="padding: 0px; text-align: center;">
|
||||
<div style="background-color: black; color: white; padding: 10px; font-size: 18px; font-weight: bold; text-align: center;">
|
||||
Stitching Detail
|
||||
</div>
|
||||
<table class="table" style="width: 100%; border-collapse: collapse;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Title</th>
|
||||
<th>Stitching</th>
|
||||
<th>Stitching Day</th>
|
||||
<th>Stitching Table Descriptions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody th:if="${stitchingDetails != null and stitchingDetails.get('accounts') != null}">
|
||||
<tr th:each="detail : ${stitchingDetails.get('accounts').keySet()}">
|
||||
<td th:text="${stitchingDetails.get('accounts').get(detail).id}"></td>
|
||||
<td th:text="${stitchingDetails.get('accounts').get(detail).title}"></td>
|
||||
<td th:text="${stitchingDetails.get('personName') != null ? stitchingDetails.get('personName').get(detail) : ''}"></td>
|
||||
<td>
|
||||
<span th:if="${stitchingDetails.get('date') != null and stitchingDetails.get('date').get(detail) != null}" th:text="${#temporals.format(stitchingDetails.get('date').get(detail), 'E')}"></span>
|
||||
<span th:if="${stitchingDetails.get('date') != null and stitchingDetails.get('date').get(detail) != null}" ctp:formatdate="${stitchingDetails.get('date').get(detail)}"></span>
|
||||
</td>
|
||||
<td th:text="${stitchingDetails.get('accounts').get(detail).notes}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr th:if="${dailyProgress != null}">
|
||||
<td colspan="5" style="padding-left: 150px;">
|
||||
<div style="border: 2px solid #d5d8dc; padding-top: 10px; border-radius: 10px; height: 560px; width: 80%; overflow-x: auto;">
|
||||
<div id="barChart" class="barChart" style="height: 500px; width: 1600px;"
|
||||
th:data-width="1600"
|
||||
th:data-height="500"
|
||||
th:data-title="'Days Wise Progress'"
|
||||
th:data-dates="${dailyProgress.get('dates')}"
|
||||
th:data-cutting="${dailyProgress.get('cutting')}"
|
||||
th:data-stitching="${dailyProgress.get('stitching')}"
|
||||
th:data-quality="${dailyProgress.get('quality')}"
|
||||
th:data-finishing="${dailyProgress.get('finishing')}"
|
||||
th:data-totalProduction="${completeProduction.get('Cutting Progress')}"
|
||||
th:data-fontSize="30"
|
||||
></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Load JavaScript file -->
|
||||
<script th:src="@{/js/charts.js}"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml">
|
||||
<head th:replace="_fragments :: head('Home Page')"></head>
|
||||
<body>
|
||||
<!-- sidebar starts -->
|
||||
<aside class="col-sm-2" th:fragment="sidebar">
|
||||
<div class="page-filters-sidebar">
|
||||
<form th:action="@{${#strings.replace(#httpServletRequest.requestURI, #request.getContextPath(), '')}}">
|
||||
<h5 class="mb-4">Refine Your Search</h5>
|
||||
<div class="form-group">
|
||||
<label>Select Date</label>
|
||||
<input type="date" class="form-control" name="select-date" th:value="${param['select-date'] ?: selectDate}">
|
||||
</div>
|
||||
<input type="submit" class="btn btn-secondary btn-block" value="Search">
|
||||
<a th:href="@{${#strings.replace(#httpServletRequest.requestURI, #request.getContextPath(), '')}}"
|
||||
class="btn btn-secondary btn-block">Reset</a>
|
||||
</form>
|
||||
<div th:replace="_fragments :: page-footer-scripts"></div>
|
||||
</div>
|
||||
</aside>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:uind="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ctp="http://www.w3.org/1999/xhtml">
|
||||
<head th:replace="_fragments :: head('POs Job Card Details')"></head>
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<header class="row page-header" th:replace="_fragments :: page-header"></header>
|
||||
<main class="row page-main">
|
||||
<aside class="col-sm-2" th:replace="/reporting/po-job-card-report-sidebar :: sidebar"></aside>
|
||||
<div class="col-sm">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr th:if="${allJobCard != null}" th:each="jobCard : ${allJobCard.keySet()}" style="padding-bottom:10px">
|
||||
<td class="m-0 pb-3">
|
||||
<table class="table mb-0 table-bordered text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="10" class="text-center bg-dark text-white">
|
||||
<span th:text="${jobCard}"></span>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th th:each="headings : ${allJobCard.get(jobCard).keySet()}" th:text="${headings}"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td >
|
||||
<span style="font-size: 14px; font-weight: bold;" th:text="'Total : ' + ${allJobCard.get(jobCard).get('Cutting Progress')}"></span>
|
||||
<br>
|
||||
<span style="font-size: 14px; font-weight: bold;" th:text="'Complete Products : ' + ${allJobCard.get(jobCard).get('Job Card Progress')}"></span>
|
||||
</td>
|
||||
<td style="font-size: 14px;" th:if="${values != 'Job Card Progress'}" th:each="values : ${allJobCard.get(jobCard).keySet()}" th:text="${allJobCard.get(jobCard).get(values)}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div th:replace="_fragments :: page-footer-scripts"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml">
|
||||
<head th:replace="_fragments :: head('Home Page')"></head>
|
||||
<body>
|
||||
<!-- sidebar starts -->
|
||||
<aside class="col-sm-2" th:fragment="sidebar">
|
||||
<div class="page-filters-sidebar">
|
||||
<form th:action="@{${#strings.replace(#httpServletRequest.requestURI, #request.getContextPath(), '')}}">
|
||||
<h5 class="mb-4">Refine Your Search</h5>
|
||||
<div class="form-group">
|
||||
<label>PO Name</label>
|
||||
<input type="text" class="form-control" name="poName" th:value="${param['poName'] ?: poName}">
|
||||
</div>
|
||||
<input type="submit" class="btn btn-secondary btn-block" value="Search">
|
||||
<a th:href="@{${#strings.replace(#httpServletRequest.requestURI, #request.getContextPath(), '')}}"
|
||||
class="btn btn-secondary btn-block">Reset</a>
|
||||
</form>
|
||||
<div th:replace="_fragments :: page-footer-scripts"></div>
|
||||
</div>
|
||||
</aside>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ctp="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head th:replace="_fragments :: head('PO Report')"></head>
|
||||
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<header class="row page-header" th:replace="_fragments :: page-header"></header>
|
||||
<main class="row page-main">
|
||||
<aside class="col-sm-2" th:replace="/reporting/po-report-sidebar :: sidebar"></aside>
|
||||
<div class="col-sm">
|
||||
<h3>PO's Report</h3>
|
||||
<div th:replace="_notices :: page-notices"></div>
|
||||
<div th:replace="_fragments :: table-loading-skeleton"></div>
|
||||
<table class="table table-striped font-sm" data-table data-order="[[ 0, "asc" ]]">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>PO Number</th>
|
||||
<th>PO Article</th>
|
||||
<th>PO Quantity</th>
|
||||
<th>Cutting</th>
|
||||
<th>Cutting Balance</th>
|
||||
<th>Stitching</th>
|
||||
<th>Stitching Balance</th>
|
||||
<th>End Line QC</th>
|
||||
<th>End Line QC Balance</th>
|
||||
<th>Finishing Items</th>
|
||||
<th>Finishing Items Balance</th>
|
||||
<th>A Grade Items</th>
|
||||
<th>B Grade Items</th>
|
||||
<th>C Grade Items</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Dummy data for testing purposes -->
|
||||
<tr th:each="poDetail : ${allPOs}">
|
||||
<td><a class="text-reset" th:href="@{'/reporting/po-report-view/' + ${poDetail.poNumber}}" th:text="${poDetail.poNumber}"></a></td>
|
||||
<td th:text="${poDetail.articleTitle}"></td>
|
||||
<td th:text="${poDetail.poQuantity}"></td>
|
||||
<td th:text="${poDetail.totalCutting}"></td>
|
||||
<td th:text="${poDetail.remainingCutting}"></td>
|
||||
<td th:text="${poDetail.totalStitching}"></td>
|
||||
<td th:text="${poDetail.remainingStitching}"></td>
|
||||
<td th:text="${poDetail.totalEndLineQC}"></td>
|
||||
<td th:text="${poDetail.remainingEndLineQC}"></td>
|
||||
<td th:text="${poDetail.totalFinishing}"></td>
|
||||
<td th:text="${poDetail.remainingFinishing}"></td>
|
||||
<td th:text="${poDetail.totalAGradeItem}"></td>
|
||||
<td th:text="${poDetail.totalBGradeItem}"></td>
|
||||
<td th:text="${poDetail.totalCGradeItem}"></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
<!-- <h4 th:if="${#lists.size(cards) == 0 }">No cards found.</h4>-->
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div th:replace="_fragments :: page-footer-scripts"></div>
|
||||
<script th:src="@{/js/summary.js}"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue