Merge pull request 'qa-report' (#24) from qa-report into main

Reviewed-on: #24
add-store
usama.jameel 2025-05-23 04:07:34 +00:00
commit 0a43acbcbe
14 changed files with 309 additions and 140 deletions

View File

@ -0,0 +1,14 @@
package com.utopiaindustries.auth;
import org.springframework.security.access.prepost.PreAuthorize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@PreAuthorize("hasAnyRole('ROLE_INVENTORY_ACCOUNT','ROLE_ADMIN')")
public @interface InventoryAccountRole {
}

View File

@ -1,16 +1,15 @@
package com.utopiaindustries.controller; package com.utopiaindustries.controller;
import com.utopiaindustries.auth.AdminRole; import com.utopiaindustries.auth.InventoryAccountRole;
import com.utopiaindustries.model.ctp.InventoryAccount; import com.utopiaindustries.model.ctp.InventoryAccount;
import com.utopiaindustries.service.InventoryAccountService; import com.utopiaindustries.service.InventoryAccountService;
import com.utopiaindustries.util.StringUtils;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller @Controller
@AdminRole @InventoryAccountRole
@RequestMapping( "/inventory-accounts" ) @RequestMapping( "/inventory-accounts" )
public class InventoryAccountController { public class InventoryAccountController {

View File

@ -196,7 +196,7 @@ public class FinishedItemDAO {
return namedParameterJdbcTemplate.query(SELECT_BY_JOB_CARD_AND_DATE, params, new FinishedItemRowMapper()); return namedParameterJdbcTemplate.query(SELECT_BY_JOB_CARD_AND_DATE, params, new FinishedItemRowMapper());
} }
public Long findByOperationDoneDate(String startDate, String endDate, String qaStatus, List<Long> ids){ public Long findByOperationDateAndIdsAndQaStatus(String startDate, String endDate, String qaStatus, List<Long> ids){
MapSqlParameterSource params = new MapSqlParameterSource(); MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue( "start_date", startDate ); params.addValue( "start_date", startDate );
params.addValue( "end_date", endDate ); params.addValue( "end_date", endDate );

View File

@ -20,7 +20,26 @@ public class InventoryAccountDAO {
private final String SELECT_QUERY = String.format( "SELECT * FROM %s WHERE id = :id", TABLE_NAME ); 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 title DESC", TABLE_NAME ); private final String SELECT_ALL_QUERY = String.format( "SELECT * FROM %s ORDER BY title DESC", TABLE_NAME );
private final String DELETE_QUERY = String.format( "DELETE FROM %s WHERE id = :id", TABLE_NAME ); private final String DELETE_QUERY = String.format( "DELETE FROM %s WHERE id = :id", TABLE_NAME );
private final String INSERT_QUERY = String.format( "INSERT INTO %s (id, title, parent_entity_type, parent_entity_id, active, created_by, created_at, location_site_id, notes, is_packaging) VALUES (:id, :title, :parent_entity_type, :parent_entity_id, :active, :created_by, :created_at, :location_site_id, :notes, :is_packaging) ON DUPLICATE KEY UPDATE title = VALUES(title), parent_entity_type = VALUES(parent_entity_type), parent_entity_id = VALUES(parent_entity_id), active = VALUES(active), created_by = VALUES(created_by), created_at = VALUES(created_at), location_site_id = VALUES(location_site_id), notes = VALUES(notes), is_packaging = VALUES(is_packaging)", TABLE_NAME ); private final String INSERT_QUERY = String.format(
"INSERT INTO %s (id, title, parent_entity_type, parent_entity_id, active, created_by, created_at, location_site_id, notes, is_packaging, article_name, shift_minutes, total_machines, efficiency, sam) " +
"VALUES (:id, :title, :parent_entity_type, :parent_entity_id, :active, :created_by, :created_at, :location_site_id, :notes, :is_packaging, :article_name, :shift_minutes, :total_machines, :efficiency, :sam) " +
"ON DUPLICATE KEY UPDATE " +
"title = VALUES(title), " +
"parent_entity_type = VALUES(parent_entity_type), " +
"parent_entity_id = VALUES(parent_entity_id), " +
"active = VALUES(active), " +
"created_by = VALUES(created_by), " +
"created_at = VALUES(created_at), " +
"location_site_id = VALUES(location_site_id), " +
"notes = VALUES(notes), " +
"is_packaging = VALUES(is_packaging), " +
"article_name = VALUES(article_name), " +
"shift_minutes = VALUES(shift_minutes), " +
"efficiency = VALUES(efficiency), " +
"sam = VALUES(sam), " +
"total_machines = VALUES(total_machines)",
TABLE_NAME
);
private final String SELECT_BY_IDS = String.format( "SELECT * FROM %s WHERE id IN (:ids)", TABLE_NAME ); private final String SELECT_BY_IDS = String.format( "SELECT * FROM %s WHERE id IN (:ids)", TABLE_NAME );
private final String SELECT_BY_IDS_AND_PARENT_ID = String.format( "SELECT * FROM %s WHERE active = TRUE AND id IN (:ids) AND parent_entity_id = :parent_entity_id", TABLE_NAME ); private final String SELECT_BY_IDS_AND_PARENT_ID = String.format( "SELECT * FROM %s WHERE active = TRUE AND id IN (:ids) AND parent_entity_id = :parent_entity_id", TABLE_NAME );
private final String SELECT_BY_IDS_AND_PARENT_IDS = String.format( "SELECT * FROM %s WHERE active = TRUE AND id IN (:ids) AND parent_entity_id IN (:parent_entity_ids)", TABLE_NAME ); private final String SELECT_BY_IDS_AND_PARENT_IDS = String.format( "SELECT * FROM %s WHERE active = TRUE AND id IN (:ids) AND parent_entity_id IN (:parent_entity_ids)", TABLE_NAME );
@ -45,6 +64,11 @@ public class InventoryAccountDAO {
.addValue( "created_at", inventoryAccount.getCreatedAt() ) .addValue( "created_at", inventoryAccount.getCreatedAt() )
.addValue( "location_site_id", inventoryAccount.getLocationSiteId() ) .addValue( "location_site_id", inventoryAccount.getLocationSiteId() )
.addValue( "notes", inventoryAccount.getNotes() ) .addValue( "notes", inventoryAccount.getNotes() )
.addValue( "article_name", inventoryAccount.getArticleName() )
.addValue( "total_machines", inventoryAccount.getTotalMachines() )
.addValue( "shift_minutes", inventoryAccount.getShiftMinutes() )
.addValue( "efficiency", inventoryAccount.getEfficiency() )
.addValue( "sam", inventoryAccount.getSam() )
.addValue("is_packaging", inventoryAccount.getIsPackaging() ); .addValue("is_packaging", inventoryAccount.getIsPackaging() );
return params; return params;
} }

View File

@ -20,6 +20,11 @@ public class InventoryAccountRowMapper implements RowMapper<InventoryAccount> {
} }
inventoryAccount.setLocationSiteId( rs.getInt( "location_site_id" ) ); inventoryAccount.setLocationSiteId( rs.getInt( "location_site_id" ) );
inventoryAccount.setNotes( rs.getString( "notes" ) ); inventoryAccount.setNotes( rs.getString( "notes" ) );
inventoryAccount.setArticleName( rs.getString( "article_name" ) );
inventoryAccount.setShiftMinutes( rs.getLong( "shift_minutes" ) );
inventoryAccount.setTotalMachines( rs.getLong( "total_machines" ) );
inventoryAccount.setEfficiency( rs.getBigDecimal( "efficiency" ) );
inventoryAccount.setSam( rs.getBigDecimal( "sam" ) );
inventoryAccount.setIsPackaging( rs.getBoolean("is_packaging" ) ); inventoryAccount.setIsPackaging( rs.getBoolean("is_packaging" ) );
return inventoryAccount; return inventoryAccount;
} }

View File

@ -221,7 +221,7 @@ public class InventoryTransactionLegDAO {
return namedParameterJdbcTemplate.query( SELECT_JOB_CARD_And_Date_Type_Account_Id , params, new InventoryTransactionLegRowMapper() ); return namedParameterJdbcTemplate.query( SELECT_JOB_CARD_And_Date_Type_Account_Id , params, new InventoryTransactionLegRowMapper() );
} }
public List<Long> getParentIDsOFRemainingINVENTORY(String parentType, Integer accountId){ public List<Long> findRemainingByParentTypeAndAccountID(String parentType, Integer accountId){
MapSqlParameterSource params = new MapSqlParameterSource(); MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("account_id", accountId ); params.addValue("account_id", accountId );
params.addValue("parent_document_type", parentType ); params.addValue("parent_document_type", parentType );

View File

@ -98,7 +98,7 @@ public class PackagingItemsDAO {
return namedParameterJdbcTemplate.query(SELECT_BY_JOB_CARD_ID, params, new PackagingItemsRowMapper()); return namedParameterJdbcTemplate.query(SELECT_BY_JOB_CARD_ID, params, new PackagingItemsRowMapper());
} }
public Long findByDateANDIDs(String startDate, String endDate,List<Long> ids){ public Long findByDateAndIds(String startDate, String endDate,List<Long> ids){
MapSqlParameterSource params = new MapSqlParameterSource(); MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue( "start_date", startDate ); params.addValue( "start_date", startDate );
params.addValue( "end_date", endDate ); params.addValue( "end_date", endDate );

View File

@ -174,7 +174,7 @@ public class StitchingOfflineItemDAO {
return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD_AND_DATE , params, new StitchingOfflineItemRowMapper() ); return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD_AND_DATE , params, new StitchingOfflineItemRowMapper() );
} }
public Long findByQCDoneDate(String startDate, String endDate, String qaStatus, List<Long> ids){ public Long findByQCOperationDateAndIds(String startDate, String endDate, String qaStatus, List<Long> ids){
MapSqlParameterSource params = new MapSqlParameterSource(); MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue( "start_date", startDate ); params.addValue( "start_date", startDate );
params.addValue( "end_date", endDate ); params.addValue( "end_date", endDate );
@ -183,7 +183,7 @@ public class StitchingOfflineItemDAO {
Long count = namedParameterJdbcTemplate.queryForObject(SELECT_BY_DATE_QA_STATUS, params, Long.class); Long count = namedParameterJdbcTemplate.queryForObject(SELECT_BY_DATE_QA_STATUS, params, Long.class);
return count != null ? count : 0; return count != null ? count : 0;
} }
public Long findByQCDoneDateApproved(String startDate, String endDate, String qaStatus){ public Long findByQCOperationDateAndApproved(String startDate, String endDate, String qaStatus){
MapSqlParameterSource params = new MapSqlParameterSource(); MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue( "start_date", startDate ); params.addValue( "start_date", startDate );
params.addValue( "end_date", endDate ); params.addValue( "end_date", endDate );

View File

@ -10,5 +10,6 @@ public enum Roles {
ROLE_FINISHING, ROLE_FINISHING,
ROLE_PACKAGING, ROLE_PACKAGING,
ROLE_REPORTING, ROLE_REPORTING,
ROLE_PURCHASE_ORDER ROLE_PURCHASE_ORDER,
ROLE_INVENTORY_ACCOUNT
} }

View File

@ -1,5 +1,6 @@
package com.utopiaindustries.model.ctp; package com.utopiaindustries.model.ctp;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
public class InventoryAccount { public class InventoryAccount {
@ -14,6 +15,12 @@ public class InventoryAccount {
private Integer locationSiteId; private Integer locationSiteId;
private String notes; private String notes;
private Boolean isPackaging; private Boolean isPackaging;
private String articleName;
private long shiftMinutes;
private long totalMachines;
private BigDecimal efficiency;
private BigDecimal sam;
//wrapper //wrapper
private String locationTitle; private String locationTitle;
@ -105,6 +112,45 @@ public class InventoryAccount {
this.locationTitle = locationTitle; this.locationTitle = locationTitle;
} }
public String getArticleName() {
return articleName;
}
public void setArticleName(String articleName) {
this.articleName = articleName;
}
public long getShiftMinutes() {
return shiftMinutes;
}
public void setShiftMinutes(long shiftMinutes) {
this.shiftMinutes = shiftMinutes;
}
public long getTotalMachines() {
return totalMachines;
}
public void setTotalMachines(long totalMachines) {
this.totalMachines = totalMachines;
}
public BigDecimal getEfficiency() {
return efficiency;
}
public void setEfficiency(BigDecimal efficiency) {
this.efficiency = efficiency;
}
public BigDecimal getSam() {
return sam;
}
public void setSam(BigDecimal sam) {
this.sam = sam;
}
@Override @Override
public String toString() { public String toString() {
@ -119,6 +165,10 @@ public class InventoryAccount {
", locationSiteId=" + locationSiteId + ", locationSiteId=" + locationSiteId +
", notes='" + notes + '\'' + ", notes='" + notes + '\'' +
", isPackaging=" + isPackaging + ", isPackaging=" + isPackaging +
", articleName='" + articleName + '\'' +
", shiftMinutes=" + shiftMinutes +
", totalMachines=" + totalMachines +
", efficiency=" + efficiency +
", locationTitle='" + locationTitle + '\'' + ", locationTitle='" + locationTitle + '\'' +
'}'; '}';
} }

View File

@ -4,7 +4,11 @@ import com.utopiaindustries.dao.ctp.*;
import com.utopiaindustries.model.ctp.*; import com.utopiaindustries.model.ctp.*;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -37,7 +41,9 @@ public class DashboardService {
String finishingAccount = "FINISHING ACCOUNT " + lineNo; String finishingAccount = "FINISHING ACCOUNT " + lineNo;
String packagingAccount = "A GRADE ACCOUNT " + lineNo; String packagingAccount = "A GRADE ACCOUNT " + lineNo;
String startDate1 = LocalDateTime.now().withHour(0).withMinute(0).withSecond(1).format(formatter); LocalDateTime today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(1);
String startDate1 = today.format(formatter);
String endDate1 = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).format(formatter); String endDate1 = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).format(formatter);
String startDateWithHour = LocalDateTime.now().minusHours(1).format(formatter); String startDateWithHour = LocalDateTime.now().minusHours(1).format(formatter);
String endDateWithHour = LocalDateTime.now().format(formatter); String endDateWithHour = LocalDateTime.now().format(formatter);
@ -47,6 +53,9 @@ public class DashboardService {
List<InventoryAccount> inventoryAccounts = inventoryAccountDAO.findAll(); List<InventoryAccount> inventoryAccounts = inventoryAccountDAO.findAll();
InventoryAccount inventoryAccount = inventoryAccounts.stream()
.filter(e -> cuttingAccount.equals(e.getTitle())).findFirst().orElse(new InventoryAccount());
Map<String, Integer> inventoryAccountMap = inventoryAccounts.stream() Map<String, Integer> inventoryAccountMap = inventoryAccounts.stream()
.filter(e -> cuttingAccount.equals(e.getTitle()) || .filter(e -> cuttingAccount.equals(e.getTitle()) ||
stitchingAccount.equals(e.getTitle()) || stitchingAccount.equals(e.getTitle()) ||
@ -55,16 +64,17 @@ public class DashboardService {
.collect(Collectors.toMap(InventoryAccount::getTitle, e -> (int) e.getId())); .collect(Collectors.toMap(InventoryAccount::getTitle, e -> (int) e.getId()));
List<Long> stitchingItemIds = inventoryTransactionLegDAO.getParentIDsOFRemainingINVENTORY("STITCHING_OFFLINE", inventoryAccountMap.get(stitchingAccount)); List<Long> stitchingItemIds = inventoryTransactionLegDAO.findRemainingByParentTypeAndAccountID("STITCHING_OFFLINE", inventoryAccountMap.get(stitchingAccount));
List<Long> finishing = inventoryTransactionLegDAO.getInParentIdIdByDate("FINISHED_ITEM", inventoryAccountMap.get(finishingAccount)); List<Long> finishing = inventoryTransactionLegDAO.getInParentIdIdByDate("FINISHED_ITEM", inventoryAccountMap.get(finishingAccount));
List<Long> packagingItemIDs = inventoryTransactionLegDAO.getParentIDsOFRemainingINVENTORY("PACKAGING", inventoryAccountMap.get(packagingAccount)); List<Long> packagingItemIDs = inventoryTransactionLegDAO.findRemainingByParentTypeAndAccountID("PACKAGING", inventoryAccountMap.get(packagingAccount));
Long approvedStitchingOfflineItems = 0L; Long approvedStitchingOfflineItems = 0L;
Long qcReject = 0L; long qcReject = 0L;
if (stitchingItemIds != null && !stitchingItemIds.isEmpty()) { if (stitchingItemIds != null && !stitchingItemIds.isEmpty()) {
approvedStitchingOfflineItems = stitchingOfflineItemDAO.findByQCDoneDateApproved(startDate1, endDate1, "APPROVED"); approvedStitchingOfflineItems = stitchingOfflineItemDAO.findByQCOperationDateAndApproved(startDate1, endDate1, "APPROVED");
qcReject = stitchingOfflineItemDAO.findByQCDoneDate(null, endDate1, "REJECT", stitchingItemIds); qcReject = stitchingOfflineItemDAO.findByQCOperationDateAndIds(null, endDate1, "REJECT", stitchingItemIds);
} }
Long alterationPieceFinish = 0L; Long alterationPieceFinish = 0L;
@ -74,21 +84,35 @@ public class DashboardService {
Long operationNotPerformed = 0L; Long operationNotPerformed = 0L;
if (finishing != null && !finishing.isEmpty()) { if (finishing != null && !finishing.isEmpty()) {
approved = finishedItemDAO.findByOperationDoneDate(startDate1, endDate1, "APPROVED", finishing); approved = finishedItemDAO.findByOperationDateAndIdsAndQaStatus(startDate1, endDate1, "APPROVED", finishing);
operationNotPerformed = finishedItemDAO.findByOperationDoneDate(null, endDate1, "-", finishing); operationNotPerformed = finishedItemDAO.findByOperationDateAndIdsAndQaStatus(null, endDate1, "-", finishing);
rejectFinishedItem = finishedItemDAO.findByOperationDoneDate(null, endDate1, "REJECT", finishing); rejectFinishedItem = finishedItemDAO.findByOperationDateAndIdsAndQaStatus(null, endDate1, "REJECT", finishing);
washFinishedItem = finishedItemDAO.findByOperationDoneDate(startDate1, endDate1, "WASHED", finishing); washFinishedItem = finishedItemDAO.findByOperationDateAndIdsAndQaStatus(startDate1, endDate1, "WASHED", finishing);
alterationPieceFinish = finishedItemDAO.findByOperationDoneDate(null, endDate1, "ALTER", finishing); alterationPieceFinish = finishedItemDAO.findByOperationDateAndIdsAndQaStatus(null, endDate1, "ALTER", finishing);
} }
Long packagingItems = 0L; Long packagingItems = 0L;
Long packagingItemsHourly = 0L;
if (packagingItemIDs != null && !packagingItemIDs.isEmpty()) { if (packagingItemIDs != null && !packagingItemIDs.isEmpty()) {
packagingItems = packagingItemsDAO.findByDateANDIDs(startDate1, endDate1, packagingItemIDs); packagingItems = packagingItemsDAO.findByDateAndIds(startDate1, endDate1, packagingItemIDs);
packagingItemsHourly = packagingItemsDAO.findByDateANDIDs(startDateWithHour, endDateWithHour, packagingItemIDs);
} }
LocalDateTime statTime = LocalDateTime.now().withHour(9).withMinute(0).withSecond(0).withNano(0);
LocalDateTime endTime = statTime.plusMinutes(inventoryAccount.getShiftMinutes());
long minutesPassed = 0;
if (statTime.isBefore(LocalDateTime.now()) && LocalDateTime.now().isBefore(endTime)) {
minutesPassed = Duration.between(statTime, LocalDateTime.now()).toMinutes();
}
long shiftTargetMinutesWise = getTargetShiftWiseOrHourlyWise(Math.max(0, minutesPassed), inventoryAccount);
float efficiency;
if (shiftTargetMinutesWise == 0) {
efficiency = 0f;
} else {
efficiency = (float) approvedStitchingOfflineItems / shiftTargetMinutesWise;
}
progress.put("Stitching", (float) approvedStitchingOfflineItems + qcReject); progress.put("Stitching", (float) approvedStitchingOfflineItems + qcReject);
progress.put("totalWips", (float) stitchingItemIds.size() - qcReject); progress.put("totalWips", (float) stitchingItemIds.size() - qcReject);
progress.put("Alteration", (float) qcReject); progress.put("Alteration", (float) qcReject);
@ -97,32 +121,50 @@ public class DashboardService {
progress.put("ALTER", (float) alterationPieceFinish); progress.put("ALTER", (float) alterationPieceFinish);
progress.put("Reject", (float) rejectFinishedItem); progress.put("Reject", (float) rejectFinishedItem);
progress.put("wash", (float) washFinishedItem); progress.put("wash", (float) washFinishedItem);
progress.put("packaging", (float) packagingItems); progress.put("packaging", (float) packagingItems);
progress.put("Shift Achieved", (float) packagingItems); progress.put("Efficiency",efficiency);
progress.put("Efficiency", (float) packagingItems / 1000 * 100);
progress.put("Hourly Achieved", Float.valueOf(packagingItemsHourly));
return progress; return progress;
} }
public Map<String, String> getLineDetails(String lineNo) { public Map<String, String> getLineDetails(String lineNo) {
String cuttingAccount = "CUTTING ACCOUNT " + lineNo; String cuttingAccount = "CUTTING ACCOUNT " + lineNo;
List<InventoryAccount> inventoryAccounts = inventoryAccountDAO.findAll(); List<InventoryAccount> inventoryAccounts = inventoryAccountDAO.findAll();
String articleNote = inventoryAccounts.stream() InventoryAccount inventoryAccount = inventoryAccounts.stream()
.filter(e -> cuttingAccount.equals(e.getTitle())) .filter(e -> cuttingAccount.equals(e.getTitle())).findFirst().orElse(new InventoryAccount());
.map(InventoryAccount::getNotes).findFirst().orElse(null);
int shiftTarget = getTargetShiftWiseOrHourlyWise(inventoryAccount.getShiftMinutes(), inventoryAccount);
int shiftHourlyTarget = getTargetShiftWiseOrHourlyWise(60, inventoryAccount);
HashMap<String, String> details = new HashMap<>(); HashMap<String, String> details = new HashMap<>();
List<JobCard> jobCards = jobCardDAO.findAll(); details.put("Shift Target", shiftTarget + " Pcs");
details.put("Shift Target", 1000 + " Pcs"); details.put("articleName", inventoryAccount.getArticleName());
details.put("articleNote", articleNote); details.put("Hourly Target", shiftHourlyTarget + " Pcs");
details.put("Hourly Target", 1000 / 24 + " Pcs"); details.put("Total Machine", String.valueOf(inventoryAccount.getTotalMachines()));
details.put("Total Induction", String.valueOf(jobCards.size()));
details.put("Total Machine", String.valueOf(30));
details.put("Total Worker", String.valueOf(30)); details.put("Total Worker", String.valueOf(30));
details.put("line", "Line " + lineNo); details.put("line", "Line " + lineNo);
return details; return details;
} }
//formula for calculating targets --> machine * shiftTime * Efficiency / SAM
private int getTargetShiftWiseOrHourlyWise(long minutes, InventoryAccount inventoryAccount) {
if (inventoryAccount == null ||
inventoryAccount.getTotalMachines() == 0 ||
inventoryAccount.getEfficiency() == null ||
inventoryAccount.getSam() == null) {
return 0;
}
BigDecimal totalMachines = BigDecimal.valueOf(inventoryAccount.getTotalMachines());
BigDecimal efficiency = inventoryAccount.getEfficiency();
BigDecimal sam = inventoryAccount.getSam();
BigDecimal totalShiftProductiveTime = totalMachines
.multiply(BigDecimal.valueOf(minutes))
.multiply(efficiency);
if (sam.longValue() != 0) {
return totalShiftProductiveTime.divide(sam, 0, RoundingMode.HALF_UP).intValueExact();
}
return 0;
}
} }

View File

@ -94,6 +94,15 @@
class="dropdown-item">User And Roles</a> class="dropdown-item">User And Roles</a>
</div> </div>
</li> </li>
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_INVENTORY_ACCOUNT')">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#">Inventory Accounts</a>
<div class="dropdown-menu">
<!-- Add Inventory Accounts-->
<a th:href="@{/inventory-accounts}"
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/inventory-accounts') ? 'active' : ''}"
class="dropdown-item">Inventory Accounts</a>
</div>
</li>
</ul> </ul>
<div class="dropdown page-header__user-menu"> <div class="dropdown page-header__user-menu">
<a href="#" class="dropdown-toggle btn btn-sm btn-outline-light" data-toggle="dropdown"> <a href="#" class="dropdown-toggle btn btn-sm btn-outline-light" data-toggle="dropdown">

View File

@ -1,106 +1,132 @@
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml" <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml"
xmlns:uind="http://www.w3.org/1999/xhtml" xmlns:ctp="http://www.w3.org/1999/xhtml"> xmlns:uind="http://www.w3.org/1999/xhtml" xmlns:ctp="http://www.w3.org/1999/xhtml">
<head th:replace="_fragments :: head('Home Page')"></head> <head th:replace="_fragments :: head('Home Page')"></head>
<body> <body>
<div class="container-fluid"> <div class="container-fluid">
<header class="row page-header" th:replace="_fragments :: page-header"></header> <header class="row page-header" th:replace="_fragments :: page-header"></header>
<main class="row page-main"> <main class="row page-main">
<div class="col-sm" th:fragment="inventoryAccountForm"> <div class="col-sm" th:fragment="inventoryAccountForm">
<form th:action="@{ ${account.id} ? ('/inventory-accounts/edit/' + ${account.id}) : '/inventory-accounts/edit' }" <form th:action="@{ ${account.id} ? ('/inventory-accounts/edit/' + ${account.id}) : '/inventory-accounts/edit' }"
method="POST" th:object="${account}" method="POST" th:object="${account}"
id="accountApp"> id="accountApp">
<input type="hidden" th:field="*{id}"> <input type="hidden" th:field="*{id}">
<input type="hidden" th:field="*{createdAt}"> <input type="hidden" th:field="*{createdAt}">
<input type="hidden" th:field="*{createdBy}"> <input type="hidden" th:field="*{createdBy}">
<div class="bg-light p-3 mb-3"> <div class="bg-light p-3 mb-3">
<h6 class="mb-3">Account </h6> <h6 class="mb-3">Account </h6>
<div class="form-row"> <div class="form-row">
<div class="col-sm-3 form-group"> <div class="col-sm-3 form-group">
<label>Title</label> <label>Title</label>
<input class="form-control" th:field="*{title}" required> <input class="form-control" th:field="*{title}" required>
</div>
<div class="col-sm-6 form-group">
<label>Notes</label>
<input class="form-control" th:field="*{notes}" required>
</div>
</div>
</div> </div>
<div class="bg-light p-3 mb-3"> <div class="col-sm-3 form-group">
<h6 class="mb-3">Misc </h6> <label>Article Name</label>
<div class="form-row"> <input class="form-control" th:field="*{articleName}">
<div class="col-sm-3 form-group">
<label>Parent Type</label>
<select class="form-control" th:field="*{parentEntityType}">
<option value="">Please Select</option>
<option value="PROCESS">PROCESS</option>
</select>
</div>
<div class="col-sm-3 form-group">
<label>Process</label>
<select class="form-control" th:field="*{parentEntityId}">
<option value="0">Please Select</option>
<option th:each="process:${processes}"
th:value="${process.id}"
th:text="${process.title}"
></option>
</select>
</div>
<div class="col-sm-3 form-group" data-vue-app th:with="id=*{locationSiteId},title=*{locationTitle}">
<location-site-search th:attr="id=${id},title=${title}"
v-bind:label-text="'Location Site'"
v-bind:id-field-name="'locationSiteId'"
v-bind:required="true">
</location-site-search>
</div>
</div>
<div class="form-row">
<div class="col-sm-3 form-group">
<label>Created By</label>
<span th:text="*{createdBy}" class="form-control" readonly></span>
</div>
<div class="col-sm-3 form-group">
<label>Created At</label>
<span class="form-control" ctp:formatdatetime="*{createdAt}" readonly></span>
</div>
<div class="col-sm-1 form-group">
<label for="active">Active</label>
<div class="form-check">
<input class="custom-control-label:" type="checkbox" id="active" th:field="*{active}" />
</div>
</div>
<div class="col-sm-1 form-group">
<label for="is-grading">Is Grading Account</label>
<div class="form-check">
<input class="custom-control-label:" type="checkbox" id="is-grading" th:field="*{isPackaging}" />
</div>
</div>
</div>
</div> </div>
<div> <div class="col-sm-3 form-group">
<button class="btn btn-primary" type="submit">Submit</button> <label>Shift Minutes</label>
<a th:href="@{/inventory-accounts}" class="btn btn-light">Cancel</a> <input type="number" class="form-control" th:field="*{shiftMinutes}">
</div> </div>
</form> <div class="col-sm-3 form-group">
<label>Efficiency</label>
<input type="number" class="form-control" th:field="*{efficiency}" step="0.01"
inputmode="decimal" min="0">
</div>
<div class="col-sm-3 form-group">
<label>SAM</label>
<input type="number" class="form-control no-spinner" th:field="*{sam}" step="0.01"
inputmode="decimal" min="0"></div>
<div class="col-sm-3 form-group">
<label>Total Machine</label>
<input type="number" class="form-control" th:field="*{totalMachines}">
</div>
<div class="col-sm-6 form-group">
<label>Notes</label>
<input class="form-control" th:field="*{notes}" required>
</div>
</div>
</div> </div>
</main> <div class="bg-light p-3 mb-3">
<h6 class="mb-3">Misc </h6>
<div class="form-row">
<div class="col-sm-3 form-group">
<label>Parent Type</label>
<select class="form-control" th:field="*{parentEntityType}">
<option value="">Please Select</option>
<option value="PROCESS">PROCESS</option>
</select>
</div>
<div class="col-sm-3 form-group">
<label>Process</label>
<select class="form-control" th:field="*{parentEntityId}">
<option value="0">Please Select</option>
<option th:each="process:${processes}"
th:value="${process.id}"
th:text="${process.title}"
></option>
</select>
</div>
<div class="col-sm-3 form-group" data-vue-app
th:with="id=*{locationSiteId},title=*{locationTitle}">
<location-site-search th:attr="id=${id},title=${title}"
v-bind:label-text="'Location Site'"
v-bind:id-field-name="'locationSiteId'"
v-bind:required="true">
</location-site-search>
</div>
</div>
<div class="form-row">
<div class="col-sm-3 form-group">
<label>Created By</label>
<span th:text="*{createdBy}" class="form-control" readonly></span>
</div>
<div class="col-sm-3 form-group">
<label>Created At</label>
<span class="form-control" ctp:formatdatetime="*{createdAt}" readonly></span>
</div>
<div class="col-sm-1 form-group">
<label for="active">Active</label>
<div class="form-check">
<input class="custom-control-label:" type="checkbox" id="active" th:field="*{active}"/>
</div>
</div>
<div class="col-sm-1 form-group">
<label for="is-grading">Is Grading Account</label>
<div class="form-check">
<input class="custom-control-label:" type="checkbox" id="is-grading"
th:field="*{isPackaging}"/>
</div>
</div>
</div>
</div>
<div>
<button class="btn btn-primary" type="submit">Submit</button>
<a th:href="@{/inventory-accounts}" class="btn btn-light">Cancel</a>
</div>
</form>
</div> </div>
</body> </main>
<style> </div>
/* Custom CSS to increase the size of the checkbox */ </body>
.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before { <style>
border-color: #007bff; /* Custom CSS to increase the size of the checkbox */
background-color: #007bff; .custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {
} border-color: #007bff;
.custom-checkbox .custom-control-input ~ .custom-control-label::before { background-color: #007bff;
width: 1.5em; }
height: 1.5em;
} .custom-checkbox .custom-control-input ~ .custom-control-label::before {
.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { width: 1.5em;
font-size: 1em; height: 1.5em;
} }
.custom-checkbox .custom-control-input {
width: 1.5em; .custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {
height: 1.5em; font-size: 1em;
} }
</style>
.custom-checkbox .custom-control-input {
width: 1.5em;
height: 1.5em;
}
</style>
</html> </html>

View File

@ -28,7 +28,7 @@
<div class="text-end"> <div class="text-end">
<h3 class="fw-bold m-0 text-end " <h3 class="fw-bold m-0 text-end "
th:text=" 'Total Machines: '+ ${detail.get('Total Machine')} ">0</h3> th:text=" 'Total Machines: '+ ${detail.get('Total Machine')} ">0</h3>
<h3 class="fw-bold m-0 text-end" th:text="'Article: ' + ${detail.get('articleNote')}"> <h3 class="fw-bold m-0 text-end" th:text="'Article: ' + ${detail.get('articleName')}">
0</h3> 0</h3>
</div> </div>
</div> </div>
@ -44,7 +44,7 @@
<div class="col-lg-6 border border-black-50 d-flex flex-column align-items-center justify-content-center text-center text-white rounded" <div class="col-lg-6 border border-black-50 d-flex flex-column align-items-center justify-content-center text-center text-white rounded"
style="background-color: #72788a;"> style="background-color: #72788a;">
<h1 class="fw-bold pt-5 pb-2" style="font-size: 6rem;" <h1 class="fw-bold pt-5 pb-2" style="font-size: 6rem;"
th:text="${(phases.get('Shift Achieved') != null ? phases.get('Shift Achieved').intValue() : 0) + ' Pcs'}"></h1> th:text="${phases.get('packaging')?.intValue() ?: 0}"></h1>
<h1 class="fw-bold m-0 text-start pb-5 pt-2" style="font-size: 4rem;">Achieved</h1> <h1 class="fw-bold m-0 text-start pb-5 pt-2" style="font-size: 4rem;">Achieved</h1>
</div> </div>
</div> </div>
@ -87,7 +87,7 @@
<div class="col-lg-6 border border-black-50 p-5 d-flex flex-column align-items-center justify-content-center text-center text-white rounded" <div class="col-lg-6 border border-black-50 p-5 d-flex flex-column align-items-center justify-content-center text-center text-white rounded"
style="background-color: #516ec4; height: 100%; "> style="background-color: #516ec4; height: 100%; ">
<h1 class="fw-bold pl-3 pr-3 pt-5 pb-2" style="font-size: 6rem;" <h1 class="fw-bold pl-3 pr-3 pt-5 pb-2" style="font-size: 6rem;"
th:text="${phases.get('Efficiency') + ' %'}">0%</h1> th:text="${#numbers.formatDecimal(phases.get('Efficiency'), 1, 2) + ' %'}">0%</h1>
<h1 class="fw-bold m-0 text-start pl-3 pr-3 pb-5 pt-2" style="font-size: 5rem;">Efficiency</h1> <h1 class="fw-bold m-0 text-start pl-3 pr-3 pb-5 pt-2" style="font-size: 5rem;">Efficiency</h1>
</div> </div>
@ -100,7 +100,6 @@
</div> </div>
</div> </div>
<!-- Card 3: Finishing --> <!-- Card 3: Finishing -->
<div class="col-lg-3 d-flex"> <div class="col-lg-3 d-flex">
<div class="card w-100 h-100"> <div class="card w-100 h-100">