Merge branch 'feature/GestioneMissioniMag' into feature/RefactoringGestioneColli

This commit is contained in:
2025-10-21 09:49:53 +02:00
24 changed files with 1577 additions and 34 deletions

View File

@@ -0,0 +1,55 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20250925103840 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
String sqlCreateMaster = "CREATE TABLE dbo.mtb_missione_mag_auto\n" +
"(\n" +
" id BIGINT IDENTITY\n" +
" CONSTRAINT mtb_missione_mag_auto_pk\n" +
" PRIMARY KEY,\n" +
" cod_mdep VARCHAR(5) NOT NULL,\n" +
" cod_area VARCHAR(15) NOT NULL,\n" +
" CONSTRAINT table_name_mtb_depo_area_cod_area_cod_mdep_fk\n" +
" FOREIGN KEY (cod_mdep, cod_area) REFERENCES dbo.mtb_depo_area (cod_mdep, cod_area),\n" +
" created_by VARCHAR(40) NOT NULL\n" +
" CONSTRAINT mtb_missione_mag_auto_stb_user_user_name_fk\n" +
" REFERENCES dbo.stb_user,\n" +
" created_at DATETIME DEFAULT GETDATE() NOT NULL\n" +
")";
String sqlCreateDetail = "CREATE TABLE dbo.mtb_missione_mag_auto_det\n" +
"(\n" +
" id BIGINT IDENTITY\n" +
" CONSTRAINT mtb_missione_mag_auto_det_pk\n" +
" PRIMARY KEY,\n" +
" parent_id BIGINT NOT NULL\n" +
" CONSTRAINT mtb_missione_mag_auto_det_mtb_missione_mag_auto_id_fk\n" +
" REFERENCES dbo.mtb_missione_mag_auto (id),\n" +
" sscc VARCHAR(18),\n" +
" posizione_in VARCHAR(40),\n" +
" posizione_out VARCHAR(40),\n" +
" error_message VARCHAR(MAX),\n" +
" completed BIT DEFAULT 0 NOT NULL,\n" +
" skipped BIT DEFAULT 0 NOT NULL,\n" +
" started_at DATETIME,\n" +
" ended_at DATETIME,\n" +
" created_at DATETIME DEFAULT GETDATE(),\n" +
" updated_at DATETIME DEFAULT GETDATE() NOT NULL\n" +
")";
executeStatement(sqlCreateMaster, sqlCreateDetail);
}
@Override
public void down() throws Exception {
}
}

View File

@@ -8,7 +8,10 @@ public enum IntegryApplicationEnum {
TASK("478f3a4c51824ad23cb50c1c60670c0f"),
SALESBOOK("f0484398-1f8b-42f5-ab79-5282c164e1d8"),
CONSEGNA("c012124f-4f11-471c-ae12-81bd4a97626c"),
WINCLOCK("54ceebf0-494f-49f1-850b-b15c57666146");
WINCLOCK("54ceebf0-494f-49f1-850b-b15c57666146"),
//Service Applications
SERVICE_EUROFORK_CONNECTOR("eadadd1c-13bb-4aae-87fd-4672573f8088");
private final String text;

View File

@@ -7,6 +7,7 @@ import java.util.HashMap;
public class ForeignKeyDTO {
public static HashMap<String, String> tableConstraintBindings = new HashMap<String, String>() {{
put(CtbAmac.ENTITY, "Codice macchina inesistente");
put(MtbAart.ENTITY, "Codice articolo inesistente");
put(MtbPartitaMag.ENTITY, "Partita di magazzino inesistente");
put(DtbDoct.ENTITY, "Documento inesistente");

View File

@@ -51,7 +51,7 @@ public class MtbDepoPosizioni extends EntityBase {
private Long idPosizione;
@SqlField(value = "tipo_magaz_automatico", maxLength = 40)
private String tipoMagazAutomatico;
private TipoMagazzinoAutomaticoEnum tipoMagazAutomatico;
@SqlField(value = "posti_pallet", nullable = false, defaultObjectValue = "0")
private Integer postiPallet;
@@ -145,10 +145,15 @@ public class MtbDepoPosizioni extends EntityBase {
return this;
}
public String getTipoMagazAutomatico() {
public TipoMagazzinoAutomaticoEnum getTipoMagazAutomatico() {
return tipoMagazAutomatico;
}
public MtbDepoPosizioni setTipoMagazAutomatico(TipoMagazzinoAutomaticoEnum tipoMagazAutomatico) {
this.tipoMagazAutomatico = tipoMagazAutomatico;
return this;
}
public Integer getPostiPallet() {
return postiPallet;
}
@@ -157,11 +162,6 @@ public class MtbDepoPosizioni extends EntityBase {
this.postiPallet = postiPallet;
}
public MtbDepoPosizioni setTipoMagazAutomatico(String tipoMagazAutomatico) {
this.tipoMagazAutomatico = tipoMagazAutomatico;
return this;
}
public String getCodArea() {
return codArea;
}
@@ -230,4 +230,40 @@ public class MtbDepoPosizioni extends EntityBase {
return from(val);
}
}
public enum TipoMagazzinoAutomaticoEnum implements IBaseEnum<TipoMagazzinoAutomaticoEnum> {
SILO2("SILO2"),
EUROFORK("EUROFORK");
private final String value;
TipoMagazzinoAutomaticoEnum(String value) {
this.value = value;
}
public static TipoMagazzinoAutomaticoEnum from(Object value) {
String castValue = (String) value;
for (TipoMagazzinoAutomaticoEnum b : TipoMagazzinoAutomaticoEnum.values()) {
if (b.value.equalsIgnoreCase(castValue))
return b;
}
return null;
}
@JsonValue
public String getValue() {
return this.value;
}
@Override
public Object get() {
return this.value;
}
@Override
public TipoMagazzinoAutomaticoEnum fromInternal(Object val) {
return from(val);
}
}
}

View File

@@ -0,0 +1,112 @@
package it.integry.ems_model.entity;
import com.fasterxml.jackson.annotation.JsonTypeName;
import it.integry.common.var.CommonConstants;
import it.integry.ems_model.annotation.*;
import it.integry.ems_model.base.EntityBase;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.kie.api.definition.type.PropertyReactive;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Master()
@PropertyReactive()
@Table(value = MtbMissioneMagAuto.ENTITY)
@JsonTypeName(value = MtbMissioneMagAuto.ENTITY)
public class MtbMissioneMagAuto extends EntityBase {
public final static String ENTITY = "mtb_missione_mag_auto";
private final static Long serialVersionUID = 1L;
private final static Logger logger = LogManager.getLogger();
public MtbMissioneMagAuto() {
super(logger);
}
@PK()
@Identity()
@SqlField(value = "id", nullable = false)
private Long id;
@SqlField(value = "cod_mdep", maxLength = 5, nullable = false)
@FK(tableName = MtbDepoArea.ENTITY, columnName = "cod_mdep")
private String codMdep;
@SqlField(value = "cod_area", maxLength = 15, nullable = false)
@FK(tableName = MtbDepoArea.ENTITY, columnName = "cod_area")
private String codArea;
@SqlField(value = "created_by", maxLength = 40, nullable = false)
@FK(tableName = StbUser.ENTITY, columnName = "user_name")
private String createdBy;
@SqlField(value = "created_at", nullable = false, defaultObjectValue = CommonConstants.TIMESTAMP)
private LocalDateTime createdAt;
@EntityChild()
private List<MtbMissioneMagAutoDet> mtbMissioneMagAutoDet = new ArrayList<>();
public Long getId() {
return id;
}
public MtbMissioneMagAuto setId(Long id) {
this.id = id;
return this;
}
public String getCodMdep() {
return codMdep;
}
public MtbMissioneMagAuto setCodMdep(String codMdep) {
this.codMdep = codMdep;
return this;
}
public String getCodArea() {
return codArea;
}
public MtbMissioneMagAuto setCodArea(String codArea) {
this.codArea = codArea;
return this;
}
public String getCreatedBy() {
return createdBy;
}
public MtbMissioneMagAuto setCreatedBy(String createdBy) {
this.createdBy = createdBy;
return this;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public MtbMissioneMagAuto setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
return this;
}
public List<MtbMissioneMagAutoDet> getMtbMissioneMagAutoDet() {
return mtbMissioneMagAutoDet;
}
public MtbMissioneMagAuto setMtbMissioneMagAutoDet(List<MtbMissioneMagAutoDet> mtbMissioneMagAutoDet) {
this.mtbMissioneMagAutoDet = mtbMissioneMagAutoDet;
return this;
}
protected void deleteChilds() throws Exception {
MtbMissioneMagAutoDet mtbMissioneMagAutoDet = new MtbMissioneMagAutoDet();
mtbMissioneMagAutoDet.deleteAllEntities(connection, this);
}
}

View File

@@ -0,0 +1,175 @@
package it.integry.ems_model.entity;
import com.fasterxml.jackson.annotation.JsonTypeName;
import it.integry.common.var.CommonConstants;
import it.integry.ems_model.annotation.*;
import it.integry.ems_model.base.EntityBase;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.kie.api.definition.type.PropertyReactive;
import java.time.LocalDateTime;
@PropertyReactive()
@Table(value = MtbMissioneMagAutoDet.ENTITY)
@JsonTypeName(value = MtbMissioneMagAutoDet.ENTITY)
public class MtbMissioneMagAutoDet extends EntityBase {
public final static String ENTITY = "mtb_missione_mag_auto_det";
private final static Long serialVersionUID = 1L;
private final static Logger logger = LogManager.getLogger();
public MtbMissioneMagAutoDet() {
super(logger);
}
@PK()
@Identity()
@SqlField(value = "id", nullable = false)
private Long id;
@SqlField(value = "parent_id", nullable = false)
@ImportFromParent(value = "id")
@FK(tableName = MtbMissioneMagAuto.ENTITY, columnName = "id")
private Long parentId;
@SqlField(value = "sscc", maxLength = 18, nullable = true)
private String sscc;
@SqlField(value = "posizione_in", maxLength = 40, nullable = true)
private String posizioneIn;
@SqlField(value = "posizione_out", maxLength = 40, nullable = true)
private String posizioneOut;
@SqlField(value = "error_message", maxLength = -1, nullable = true)
private String errorMessage;
@SqlField(value = "completed", nullable = false)
private boolean completed;
@SqlField(value = "skipped", nullable = false)
private boolean skipped;
@SqlField(value = "started_at", nullable = true)
private LocalDateTime startedAt;
@SqlField(value = "ended_at", nullable = true)
private LocalDateTime endedAt;
@SqlField(value = "created_at", nullable = false, defaultObjectValue = CommonConstants.TIMESTAMP)
private LocalDateTime createdAt;
@SqlField(value = "updated_at", nullable = false, defaultObjectValue = CommonConstants.TIMESTAMP)
private LocalDateTime updatedAt;
public Long getId() {
return id;
}
public MtbMissioneMagAutoDet setId(Long id) {
this.id = id;
return this;
}
public Long getParentId() {
return parentId;
}
public MtbMissioneMagAutoDet setParentId(Long parentId) {
this.parentId = parentId;
return this;
}
public String getSscc() {
return sscc;
}
public MtbMissioneMagAutoDet setSscc(String sscc) {
this.sscc = sscc;
return this;
}
public String getPosizioneIn() {
return posizioneIn;
}
public MtbMissioneMagAutoDet setPosizioneIn(String posizioneIn) {
this.posizioneIn = posizioneIn;
return this;
}
public String getPosizioneOut() {
return posizioneOut;
}
public MtbMissioneMagAutoDet setPosizioneOut(String posizioneOut) {
this.posizioneOut = posizioneOut;
return this;
}
public String getErrorMessage() {
return errorMessage;
}
public MtbMissioneMagAutoDet setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
return this;
}
public boolean isCompleted() {
return completed;
}
public MtbMissioneMagAutoDet setCompleted(boolean completed) {
this.completed = completed;
return this;
}
public boolean isSkipped() {
return skipped;
}
public MtbMissioneMagAutoDet setSkipped(boolean skipped) {
this.skipped = skipped;
return this;
}
public LocalDateTime getStartedAt() {
return startedAt;
}
public MtbMissioneMagAutoDet setStartedAt(LocalDateTime startedAt) {
this.startedAt = startedAt;
return this;
}
public LocalDateTime getEndedAt() {
return endedAt;
}
public MtbMissioneMagAutoDet setEndedAt(LocalDateTime endedAt) {
this.endedAt = endedAt;
return this;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public MtbMissioneMagAutoDet setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
return this;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public MtbMissioneMagAutoDet setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
return this;
}
}

View File

@@ -2,6 +2,7 @@ package it.integry.ems_model.utility;
import it.integry.ems_model.annotation.SqlField;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.lang.reflect.Field;
@@ -34,6 +35,7 @@ public class UtilityHashMap {
}
@Nonnull
public static <T> List<T> mapListToObjects(List<HashMap<String, Object>> dataList, Class<T> clazz) {
List<T> result = new ArrayList<>();
try {

View File

@@ -17,7 +17,6 @@ import javax.servlet.http.HttpServletRequest;
@RestController
@Scope("request")
public class InventarioController {
private final Logger logger = LogManager.getLogger();
@Autowired

View File

@@ -0,0 +1,155 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.controller;
import it.integry.common.var.CommonConstants;
import it.integry.ems.javabeans.RequestDataDTO;
import it.integry.ems.logistic.missioni.magazzino_automatico.dto.CreateMissioneMagazzinoAutomaticoRequestDTO;
import it.integry.ems.logistic.missioni.magazzino_automatico.dto.CreateMissioneMagazzinoAutomaticoResponseDTO;
import it.integry.ems.logistic.missioni.magazzino_automatico.dto.LogErrorMissioneMagazzinoAutomaticoRequestDTO;
import it.integry.ems.logistic.missioni.magazzino_automatico.service.MissioniMagazzinoAutomaticoService;
import it.integry.ems.response.ServiceRestResponse;
import it.integry.ems.retail.wms.generic.service.WMSGiacenzaULService;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems.user.UserSession;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;
@RestController
@Scope("request")
@RequestMapping("missioni/magazzino-automatico")
public class MissioniMagazzinoAutomaticoController {
private final Logger logger = LogManager.getLogger();
private final MissioniMagazzinoAutomaticoService missioniMagazzinoAutomaticoService;
private final MultiDBTransactionManager multiDBTransactionManager;
private final RequestDataDTO requestDataDTO;
private final UserSession userSession;
private final WMSGiacenzaULService wmsGiacenzaULService;
public MissioniMagazzinoAutomaticoController(MissioniMagazzinoAutomaticoService missioniMagazzinoAutomaticoService, MultiDBTransactionManager multiDBTransactionManager, RequestDataDTO requestDataDTO, UserSession userSession, WMSGiacenzaULService wmsGiacenzaULService) {
this.missioniMagazzinoAutomaticoService = missioniMagazzinoAutomaticoService;
this.multiDBTransactionManager = multiDBTransactionManager;
this.requestDataDTO = requestDataDTO;
this.userSession = userSession;
this.wmsGiacenzaULService = wmsGiacenzaULService;
}
@GetMapping(value = "retrieve-all")
public @ResponseBody
ServiceRestResponse retrieveAll(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@RequestParam(required = false, defaultValue = "true") boolean onlyPending,
@RequestParam(required = false, defaultValue = "-1") int limit) throws Exception {
return ServiceRestResponse.createPositiveResponse(missioniMagazzinoAutomaticoService.retrieveAll(multiDBTransactionManager, onlyPending, limit));
}
@GetMapping(value = "retrieve")
public @ResponseBody
ServiceRestResponse retrieve(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@RequestParam long id) throws Exception {
return ServiceRestResponse.createPositiveResponse(missioniMagazzinoAutomaticoService.retrieveItem(multiDBTransactionManager, id));
}
@PostMapping(value = "create")
public @ResponseBody
ServiceRestResponse create(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@RequestBody CreateMissioneMagazzinoAutomaticoRequestDTO requestBody) throws Exception {
userSession.checkUser();
if (requestBody.getData() == null)
throw new IllegalArgumentException("Request body data is null");
long missioneId = missioniMagazzinoAutomaticoService.createMissione(multiDBTransactionManager,
requestDataDTO.getUsername(),
requestBody.getData());
return ServiceRestResponse.createPositiveResponse(
new CreateMissioneMagazzinoAutomaticoResponseDTO(missioneId));
}
@GetMapping(value = "set-as-started")
public @ResponseBody
ServiceRestResponse abort(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@RequestParam long missionId,
@RequestParam long missionRowId) throws Exception {
userSession.checkUser();
missioniMagazzinoAutomaticoService.setMissionAsStarted(multiDBTransactionManager,
missionId,
missionRowId);
return ServiceRestResponse.createPositiveResponse();
}
@GetMapping(value = "abort")
public @ResponseBody
ServiceRestResponse abort(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@RequestParam long missionId) throws Exception {
userSession.checkUser();
missioniMagazzinoAutomaticoService.abortMission(multiDBTransactionManager,
missionId);
return ServiceRestResponse.createPositiveResponse();
}
@PostMapping(value = "log-error")
public @ResponseBody
ServiceRestResponse logError(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@RequestBody LogErrorMissioneMagazzinoAutomaticoRequestDTO requestBody) throws Exception {
userSession.checkUser();
missioniMagazzinoAutomaticoService.logMissionError(multiDBTransactionManager,
requestBody.getMissionId(),
requestBody.getMissionRowId(),
requestBody.getErrorMessage());
return ServiceRestResponse.createPositiveResponse();
}
// @PostMapping(value = "move-lu")
// public @ResponseBody
// ServiceRestResponse moveLu(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
// @RequestBody MoveLuRequestDTO requestBody) throws Exception {
// userSession.checkUser();
//
// final List<MvwSitArtUdcDetInventarioDTO> giacenzaItems = wmsGiacenzaULService.retrieveArtsInGiacenzaByBarcodeUl(multiDBTransactionManager.getPrimaryConnection(), requestBody.getBarcodeUl());
// if(giacenzaItems == null || giacenzaItems.isEmpty())
// throw new IllegalArgumentException("Unità logistica non trovata: " + requestBody.getBarcodeUl());
//
// final MvwSitArtUdcDetInventarioDTO giacenzaItem = giacenzaItems.get(0);
//
// final MtbDepoPosizioni posizione = WMSUtility.getPosizioneFromName(multiDBTransactionManager.getPrimaryConnection(), giacenzaItem.getPosizione());
// if(posizione == null)
// throw new IllegalArgumentException("Posizione non trovata: " + giacenzaItem.getPosizione());
//
// long missioneId = missioniMagazzinoAutomaticoService.createMissione(multiDBTransactionManager,
// requestDataDTO.getUsername(),
// new MissioneMagazzinoAutomaticoDTO(){{
//// setCodCmac(requestBody.getCodCmac());
//// setRows(requestBody.getRows());
// }});
//
//
// return ServiceRestResponse.createPositiveResponse(
// new CreateMissioneMagazzinoAutomaticoResponseDTO(missioneId));
//
// return ServiceRestResponse.createPositiveResponse();
// }
}

View File

@@ -0,0 +1,15 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.dto;
public class CreateMissioneMagazzinoAutomaticoRequestDTO {
private MissioneMagazzinoAutomaticoDTO data;
public MissioneMagazzinoAutomaticoDTO getData() {
return data;
}
public CreateMissioneMagazzinoAutomaticoRequestDTO setData(MissioneMagazzinoAutomaticoDTO data) {
this.data = data;
return this;
}
}

View File

@@ -0,0 +1,14 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.dto;
public class CreateMissioneMagazzinoAutomaticoResponseDTO {
private final long id;
public CreateMissioneMagazzinoAutomaticoResponseDTO(long id) {
this.id = id;
}
public long getId() {
return id;
}
}

View File

@@ -0,0 +1,35 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.dto;
public class LogErrorMissioneMagazzinoAutomaticoRequestDTO {
private long missionId;
private long missionRowId;
private String errorMessage;
public long getMissionId() {
return missionId;
}
public LogErrorMissioneMagazzinoAutomaticoRequestDTO setMissionId(long missionId) {
this.missionId = missionId;
return this;
}
public long getMissionRowId() {
return missionRowId;
}
public LogErrorMissioneMagazzinoAutomaticoRequestDTO setMissionRowId(long missionRowId) {
this.missionRowId = missionRowId;
return this;
}
public String getErrorMessage() {
return errorMessage;
}
public LogErrorMissioneMagazzinoAutomaticoRequestDTO setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
return this;
}
}

View File

@@ -0,0 +1,85 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.LocalDateTime;
import java.util.List;
public class MissioneMagazzinoAutomaticoDTO {
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Long id;
private String codMdep;
private String codArea;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private String createdBy;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private LocalDateTime createdAt;
private List<MissioneMagazzinoAutomaticoRowDTO> rows;
public MissioneMagazzinoAutomaticoDTO() {
}
public MissioneMagazzinoAutomaticoDTO(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
private MissioneMagazzinoAutomaticoDTO setId(Long id) {
this.id = id;
return this;
}
public String getCodMdep() {
return codMdep;
}
public MissioneMagazzinoAutomaticoDTO setCodMdep(String codMdep) {
this.codMdep = codMdep;
return this;
}
public String getCodArea() {
return codArea;
}
public MissioneMagazzinoAutomaticoDTO setCodArea(String codArea) {
this.codArea = codArea;
return this;
}
public String getCreatedBy() {
return createdBy;
}
public MissioneMagazzinoAutomaticoDTO setCreatedBy(String createdBy) {
this.createdBy = createdBy;
return this;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public MissioneMagazzinoAutomaticoDTO setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
return this;
}
public List<MissioneMagazzinoAutomaticoRowDTO> getRows() {
return rows;
}
public MissioneMagazzinoAutomaticoDTO setRows(List<MissioneMagazzinoAutomaticoRowDTO> rows) {
this.rows = rows;
return this;
}
}

View File

@@ -0,0 +1,150 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.LocalDateTime;
public class MissioneMagazzinoAutomaticoRowDTO {
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private Long id;
private String sscc;
private String posizioneIn;
private String posizioneOut;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private String errorMessage;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private boolean completed;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private boolean skipped;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private LocalDateTime startedAt;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private LocalDateTime endedAt;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private LocalDateTime createdAt;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private LocalDateTime updatedAt;
public MissioneMagazzinoAutomaticoRowDTO() {
}
public MissioneMagazzinoAutomaticoRowDTO(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
private MissioneMagazzinoAutomaticoRowDTO setId(Long id) {
this.id = id;
return this;
}
public String getSscc() {
return sscc;
}
public MissioneMagazzinoAutomaticoRowDTO setSscc(String sscc) {
this.sscc = sscc;
return this;
}
public String getPosizioneIn() {
return posizioneIn;
}
public MissioneMagazzinoAutomaticoRowDTO setPosizioneIn(String posizioneIn) {
this.posizioneIn = posizioneIn;
return this;
}
public String getPosizioneOut() {
return posizioneOut;
}
public MissioneMagazzinoAutomaticoRowDTO setPosizioneOut(String posizioneOut) {
this.posizioneOut = posizioneOut;
return this;
}
public String getErrorMessage() {
return errorMessage;
}
public MissioneMagazzinoAutomaticoRowDTO setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
return this;
}
public boolean isCompleted() {
return completed;
}
public MissioneMagazzinoAutomaticoRowDTO setCompleted(boolean completed) {
this.completed = completed;
return this;
}
public boolean isSkipped() {
return skipped;
}
public MissioneMagazzinoAutomaticoRowDTO setSkipped(boolean skipped) {
this.skipped = skipped;
return this;
}
public LocalDateTime getStartedAt() {
return startedAt;
}
public MissioneMagazzinoAutomaticoRowDTO setStartedAt(LocalDateTime startedAt) {
this.startedAt = startedAt;
return this;
}
public LocalDateTime getEndedAt() {
return endedAt;
}
public MissioneMagazzinoAutomaticoRowDTO setEndedAt(LocalDateTime endedAt) {
this.endedAt = endedAt;
return this;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public MissioneMagazzinoAutomaticoRowDTO setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
return this;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public MissioneMagazzinoAutomaticoRowDTO setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
return this;
}
public boolean isError() {
return errorMessage != null && !errorMessage.isEmpty() && !completed && !skipped;
}
public boolean isRunning() {
return startedAt != null && endedAt == null;
}
}

View File

@@ -0,0 +1,25 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.dto;
public class MoveLuRequestDTO {
private String barcodeUl;
private String posizioneDestinazione;
public String getBarcodeUl() {
return barcodeUl;
}
public MoveLuRequestDTO setBarcodeUl(String barcodeUl) {
this.barcodeUl = barcodeUl;
return this;
}
public String getPosizioneDestinazione() {
return posizioneDestinazione;
}
public MoveLuRequestDTO setPosizioneDestinazione(String posizioneDestinazione) {
this.posizioneDestinazione = posizioneDestinazione;
return this;
}
}

View File

@@ -0,0 +1,140 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.service;
import groovy.lang.Tuple2;
import it.integry.annotations.CustomerService;
import it.integry.ems.javabeans.RequestDataDTO;
import it.integry.ems.migration._base.IntegryCustomer;
import it.integry.ems.retail.wms.Utility.WMSUtility;
import it.integry.ems.service.EntityProcessor;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems_model.config.EmsRestConstants;
import it.integry.ems_model.entity.MtbColr;
import it.integry.ems_model.entity.MtbColt;
import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityHashMap;
import it.integry.ems_model.utility.UtilityQuery;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@CustomerService(IntegryCustomer.Biolevante)
public class EuroforkDataSyncronizerService {
private final Logger logger = LogManager.getLogger();
private final EntityProcessor entityProcessor;
public EuroforkDataSyncronizerService(EntityProcessor entityProcessor) {
this.entityProcessor = entityProcessor;
}
@PostConstruct
public void init() {
logger.info("EuroforkDataSyncronizerService initialized for Biolevante");
}
@Scheduled(fixedDelay = 1, timeUnit = TimeUnit.MINUTES)
private void syncLuScheduled() {
if (true) //Da abilitare al momento del bisogno
return;
String sqlRetrieveEuroforkStatus = "SELECT LU.[Number] AS SSCC,\n" +
" ISNULL(\n" +
" IIF(LEN(Cells.[Note]) > 0, CONCAT('WH1', Cells.[Note]), NULL),\n" +
" CONCAT('WH1',\n" +
" FORMAT(Cells.[Level], '00'),\n" +
" Cells.[ColumnSide],\n" +
" FORMAT(Cells.[Column], '000'))) AS posizione\n" +
"FROM LU\n" +
" INNER JOIN Cells ON LU.Cells_ID = Cells.ID\n" +
"WHERE Element IN ('Bay', 'Cell')\n" +
" AND LU.[State] = 'Warehouse'";
try (MultiDBTransactionManager mdbEurofork = new MultiDBTransactionManager("EUROFORK");
MultiDBTransactionManager mdbInternal = new MultiDBTransactionManager("BIOLEVANTE")) {
final List<HashMap<String, Object>> internalAssignedPositions = UtilityDB.executeSimpleQuery(mdbInternal.getPrimaryConnection(),
"SELECT DISTINCT barcode_ul, mvw.posizione\n" +
"FROM mvw_sitart_udc_det_inventario mvw\n" +
" INNER JOIN mtb_depo_posizioni ON mvw.posizione = mtb_depo_posizioni.posizione\n" +
"WHERE mtb_depo_posizioni.cod_area = 'WH1'");
final HashMap<String, String> internalAssignedPositionsMap = new HashMap<>();
for (HashMap<String, Object> row : internalAssignedPositions) {
String barcodeUl = UtilityHashMap.getValueIfExists(row, "barcode_ul");
String posizione = UtilityHashMap.getValueIfExists(row, "posizione");
internalAssignedPositionsMap.put(barcodeUl, posizione);
}
final List<HashMap<String, Object>> euroforkAssignedPositions = UtilityDB.executeSimpleQuery(mdbEurofork.getPrimaryConnection(), sqlRetrieveEuroforkStatus);
final HashMap<String, String> euroforkAssignedPositionsMap = new HashMap<>();
for (HashMap<String, Object> row : euroforkAssignedPositions) {
String barcodeUl = UtilityHashMap.getValueIfExists(row, "SSCC");
String posizione = UtilityHashMap.getValueIfExists(row, "posizione");
euroforkAssignedPositionsMap.put(barcodeUl, posizione);
}
// Mappa delle posizioni da aggiornare (barcodeUl, (oldPosizione, newPosizione))
HashMap<String, Tuple2<String, String>> updateMap = new HashMap<>();
//Rimuovo le posizioni che non sono più presenti in Eurofork
for (String barcodeUl : internalAssignedPositionsMap.keySet()) {
String newPosizione = euroforkAssignedPositionsMap.getOrDefault(barcodeUl, null);
updateMap.put(barcodeUl, new Tuple2<>(internalAssignedPositionsMap.get(barcodeUl), newPosizione));
}
//Aggiungo le nuove posizioni presenti in Eurofork
for (String barcodeUl : euroforkAssignedPositionsMap.keySet()) {
if (!internalAssignedPositionsMap.containsKey(barcodeUl)) {
String newPosizione = euroforkAssignedPositionsMap.get(barcodeUl);
updateMap.put(barcodeUl, new Tuple2<>(null, newPosizione));
}
}
//Aggiorno solo le posizioni che sono cambiate
final Map<String, Tuple2<String, String>> dataToStore = updateMap.entrySet()
.stream().filter(x -> !Objects.equals(x.getValue().getV1(), x.getValue().getV2()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
//Controllo la correttezza degli SSCC
String sql = "SELECT barcode_ul FROM mvw_sitart_udc_det_inventario\n" +
"WHERE barcode_ul IN (" + UtilityQuery.concatStringFieldsWithSeparator(new ArrayList<>(dataToStore.keySet()), ",") + ")";
final List<String> existantsUl = UtilityDB.executeSimpleQueryOnlyFirstColumn(mdbInternal.getPrimaryConnection(), sql);
//Aggiorno solo gli SSCC esistenti
final Map<String, Tuple2<String, String>> dataToStore2 = dataToStore.entrySet()
.stream().filter(x -> existantsUl.contains(x.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
RequestDataDTO requestDataDTO = RequestDataDTO.systemMockupData();
for (Map.Entry<String, Tuple2<String, String>> ulRow : dataToStore2.entrySet()) {
MtbColt internalMovement = WMSUtility.createInternalMovement(mdbInternal.getPrimaryConnection(), "01", requestDataDTO.getUsername());
final List<MtbColr> cambiaPosizioneUlMovement =
WMSUtility.createCambiaPosizioneUlMovement(
mdbInternal.getPrimaryConnection(),
ulRow.getKey(),
false,
"01",
ulRow.getValue().getV2() == null ? EmsRestConstants.NULL : ulRow.getValue().getV2());
internalMovement.setMtbColr(cambiaPosizioneUlMovement);
entityProcessor.processEntity(internalMovement, false, false, requestDataDTO.getUsername(), mdbInternal, requestDataDTO);
}
String tmp = "";
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,224 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.service;
import it.integry.ems.exception.PrimaryDatabaseNotPresentException;
import it.integry.ems.logistic.missioni.magazzino_automatico.dto.MissioneMagazzinoAutomaticoDTO;
import it.integry.ems.logistic.missioni.magazzino_automatico.utils.MissioniMagazzinoAutomaticoUtils;
import it.integry.ems.service.EntityProcessor;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems_model.config.EmsRestConstants;
import it.integry.ems_model.entity.MtbMissioneMagAuto;
import it.integry.ems_model.entity.MtbMissioneMagAutoDet;
import it.integry.ems_model.entity.StbUser;
import it.integry.ems_model.exception.DataConverterNotFoundException;
import it.integry.ems_model.types.OperationType;
import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityHashMap;
import it.integry.ems_model.utility.UtilityQuery;
import it.integry.ems_model.utility.UtilityString;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import javax.validation.constraints.NotNull;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class MissioniMagazzinoAutomaticoService {
private final EntityProcessor entityProcessor;
public MissioniMagazzinoAutomaticoService(EntityProcessor entityProcessor) {
this.entityProcessor = entityProcessor;
}
public List<MissioneMagazzinoAutomaticoDTO> retrieveAll(MultiDBTransactionManager multiDBTransactionManager, boolean onlyPending) throws PrimaryDatabaseNotPresentException, DataConverterNotFoundException, SQLException, InstantiationException, IllegalAccessException {
return retrieveAll(multiDBTransactionManager, onlyPending, -1);
}
public List<MissioneMagazzinoAutomaticoDTO> retrieveAll(MultiDBTransactionManager multiDBTransactionManager, boolean onlyPending, int limit) throws PrimaryDatabaseNotPresentException, DataConverterNotFoundException, SQLException, InstantiationException, IllegalAccessException {
String sql = "SELECT mmma.id,\n" +
" mmma.cod_mdep,\n" +
" mmma.cod_area,\n" +
" mmma.created_at,\n" +
" su.full_name AS created_by\n" +
"FROM " + MtbMissioneMagAuto.ENTITY + " mmma \n" +
"INNER JOIN " + StbUser.ENTITY + " su ON su.user_name = mmma.created_by \n";
if (onlyPending) {
sql += "INNER JOIN (SELECT DISTINCT parent_id,\n" +
" IIF(COUNT(*) OVER (PARTITION BY parent_id) = SUM(IIF(CAST(completed AS SMALLINT) = 1, 1, CAST(skipped AS SMALLINT))) OVER (PARTITION BY parent_id), 1, 0) AS completed\n" +
"FROM " + MtbMissioneMagAutoDet.ENTITY + " mmma_det) mmma_det ON\n" +
"mmma.id = mmma_det.parent_id \n";
sql += "WHERE mmma_det.completed = 0";
}
sql += " ORDER BY mmma.created_at DESC";
List<MtbMissioneMagAuto> missioni = UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sql, MtbMissioneMagAuto.class);
if (missioni == null || missioni.isEmpty()) {
return null;
}
String sqlRows = "SELECT * FROM " + MtbMissioneMagAutoDet.ENTITY + " WHERE parent_id IN (" +
UtilityQuery.concatLongFieldsWithSeparator(missioni.stream().map(MtbMissioneMagAuto::getId).collect(Collectors.toList()), ",")
+ ")";
if (onlyPending) {
sqlRows += " AND completed = 0 AND skipped = 0";
}
final List<MtbMissioneMagAutoDet> missioniRows = UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sqlRows, MtbMissioneMagAutoDet.class);
missioni.forEach(missione -> {
final List<MtbMissioneMagAutoDet> rows = missioniRows.stream()
.filter(x -> x.getParentId().equals(missione.getId()))
.collect(Collectors.toList());
missione.setMtbMissioneMagAutoDet(rows);
});
if (limit > 0 && missioni.size() > limit) {
missioni = missioni.subList(0, limit);
}
return MissioniMagazzinoAutomaticoUtils.convertEntityListToDto(missioni);
}
public MissioneMagazzinoAutomaticoDTO retrieveItem(MultiDBTransactionManager multiDBTransactionManager, long missionId) throws PrimaryDatabaseNotPresentException, DataConverterNotFoundException, SQLException, InstantiationException, IllegalAccessException {
String sql = "SELECT mmma.*\n" +
"FROM " + MtbMissioneMagAuto.ENTITY + " mmma \n" +
"WHERE mmma.id = " + UtilityDB.valueToString(missionId);
final MtbMissioneMagAuto missione = UtilityDB.executeSimpleQueryOnlyFirstRowDTO(multiDBTransactionManager.getPrimaryConnection(), sql, MtbMissioneMagAuto.class);
if (missione == null) {
return null;
}
String sqlRows = "SELECT * FROM " + MtbMissioneMagAutoDet.ENTITY + " WHERE parent_id = " + UtilityDB.valueToString(missionId);
final List<MtbMissioneMagAutoDet> missioniRows = UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sqlRows, MtbMissioneMagAutoDet.class);
final List<MtbMissioneMagAutoDet> rows = missioniRows.stream()
.filter(x -> x.getParentId().equals(missione.getId()))
.collect(Collectors.toList());
missione.setMtbMissioneMagAutoDet(rows);
return MissioniMagazzinoAutomaticoUtils.convertEntityToDto(missione);
}
public long createMissione(MultiDBTransactionManager multiDBTransactionManager, String username, MissioneMagazzinoAutomaticoDTO missione) throws Exception {
if (UtilityString.isNullOrEmpty(username))
throw new UsernameNotFoundException("Username is null or empty");
final MtbMissioneMagAuto mtbMissioneMagAuto = MissioniMagazzinoAutomaticoUtils.convertDtoToEntity(missione)
.setCreatedAt(LocalDateTime.now())
.setCreatedBy(username);
mtbMissioneMagAuto.setOperation(OperationType.INSERT);
mtbMissioneMagAuto.getMtbMissioneMagAutoDet().forEach(x -> x.setOperation(OperationType.INSERT));
entityProcessor.processEntity(mtbMissioneMagAuto, multiDBTransactionManager);
return mtbMissioneMagAuto.getId();
}
public void setMissionAsStarted(MultiDBTransactionManager multiDBTransactionManager, long missionId, long missionRowId) throws Exception {
String sqlMissione = "SELECT * \n" +
" FROM " + MtbMissioneMagAutoDet.ENTITY + " mmma_det\n" +
" WHERE mmma_det.id = " + UtilityDB.valueToString(missionRowId);
MtbMissioneMagAutoDet missioneRow = UtilityDB.executeSimpleQueryOnlyFirstRowDTO(multiDBTransactionManager.getPrimaryConnection(), sqlMissione, MtbMissioneMagAutoDet.class);
missioneRow.setOperation(OperationType.UPDATE);
missioneRow.setStartedAt(LocalDateTime.now());
missioneRow.setCompleted(false);
missioneRow.setEndedAt(EmsRestConstants.LOCAL_DATE_TIME_NULL);
missioneRow.setUpdatedAt(LocalDateTime.now());
MtbMissioneMagAuto missione = new MtbMissioneMagAuto()
.setId(missionId);
missione.setOperation(OperationType.UPDATE);
missione.getMtbMissioneMagAutoDet().add(missioneRow);
entityProcessor.processEntity(missione, multiDBTransactionManager);
}
public void abortMission(MultiDBTransactionManager multiDBTransactionManager, long missionId) throws Exception {
MtbMissioneMagAuto mtbMissioneMagAuto = new MtbMissioneMagAuto();
mtbMissioneMagAuto.setId(missionId);
String sqlRows = "SELECT * FROM " + MtbMissioneMagAutoDet.ENTITY +
" WHERE parent_id = " + UtilityDB.valueToString(missionId) +
" AND completed = 0 AND skipped = 0";
final List<MtbMissioneMagAutoDet> mtbMissioneMagAutoDets = UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sqlRows, MtbMissioneMagAutoDet.class);
if (mtbMissioneMagAutoDets == null) return;
mtbMissioneMagAutoDets.forEach(x ->
x.setSkipped(true)
.setOperation(OperationType.UPDATE));
mtbMissioneMagAuto.setMtbMissioneMagAutoDet(mtbMissioneMagAutoDets);
entityProcessor.processEntity(mtbMissioneMagAuto, multiDBTransactionManager);
}
public void logMissionError(MultiDBTransactionManager multiDBTransactionManager, long missionId, long missionRowId, String errorMessage) throws Exception {
String sqlMissione = "SELECT * \n" +
" FROM " + MtbMissioneMagAutoDet.ENTITY + " mmma_det\n" +
" WHERE mmma_det.id = " + UtilityDB.valueToString(missionRowId);
MtbMissioneMagAutoDet missioneRow = UtilityDB.executeSimpleQueryOnlyFirstRowDTO(multiDBTransactionManager.getPrimaryConnection(), sqlMissione, MtbMissioneMagAutoDet.class);
missioneRow.setOperation(OperationType.UPDATE);
missioneRow.setErrorMessage(errorMessage);
missioneRow.setUpdatedAt(LocalDateTime.now());
MtbMissioneMagAuto missione = new MtbMissioneMagAuto()
.setId(missionId);
missione.setOperation(OperationType.UPDATE);
missione.getMtbMissioneMagAutoDet().add(missioneRow);
entityProcessor.processEntity(missione, multiDBTransactionManager);
}
public @NotNull HashMap<String, Boolean> checkIfPendingMissionExists(Connection connection, List<String> ssccToCheck) throws PrimaryDatabaseNotPresentException, SQLException {
if (ssccToCheck == null || ssccToCheck.isEmpty())
return new HashMap<>();
String sql = "SELECT mmma_det.sscc, \n" +
" CAST(COUNT(*) AS BIT) AS exists_missione\n" +
"FROM " + MtbMissioneMagAutoDet.ENTITY + " mmma_det\n" +
"WHERE mmma_det.completed = 0\n" +
" AND mmma_det.skipped = 0\n" +
" AND mmma_det.sscc IN (" + UtilityQuery.concatStringFieldsWithSeparator(ssccToCheck, ",") + ")\n" +
"GROUP BY mmma_det.sscc";
List<HashMap<String, Object>> total = UtilityDB.executeSimpleQuery(connection, sql);
if (total.isEmpty())
return new HashMap<>();
final HashMap<String, Boolean> result = new HashMap<>();
total.forEach(x -> {
String sscc = UtilityHashMap.getValueIfExists(x, "sscc");
Boolean existsMissione = UtilityHashMap.getValueIfExists(x, "exists_missione");
if (existsMissione)
result.put(sscc, existsMissione);
});
return result;
}
}

View File

@@ -0,0 +1,91 @@
package it.integry.ems.logistic.missioni.magazzino_automatico.utils;
import it.integry.ems.logistic.missioni.magazzino_automatico.dto.MissioneMagazzinoAutomaticoDTO;
import it.integry.ems.logistic.missioni.magazzino_automatico.dto.MissioneMagazzinoAutomaticoRowDTO;
import it.integry.ems_model.entity.MtbMissioneMagAuto;
import it.integry.ems_model.entity.MtbMissioneMagAutoDet;
import java.util.List;
import java.util.stream.Collectors;
public class MissioniMagazzinoAutomaticoUtils {
public static List<MtbMissioneMagAuto> convertDtoListToEntity(List<MissioneMagazzinoAutomaticoDTO> inputData) {
return inputData.stream()
.map(MissioniMagazzinoAutomaticoUtils::convertDtoToEntity)
.collect(Collectors.toList());
}
public static MtbMissioneMagAuto convertDtoToEntity(MissioneMagazzinoAutomaticoDTO inputData) {
return new MtbMissioneMagAuto()
.setId(inputData.getId())
.setCreatedAt(inputData.getCreatedAt())
.setCodMdep(inputData.getCodMdep())
.setCodArea(inputData.getCodArea())
.setMtbMissioneMagAutoDet(inputData.getRows().stream()
.map(x -> convertDtoRowToEntity(x, inputData.getId()))
.collect(Collectors.toList()));
}
public static MtbMissioneMagAutoDet convertDtoRowToEntity(MissioneMagazzinoAutomaticoRowDTO inputData, Long parentId) {
return new MtbMissioneMagAutoDet()
.setId(inputData.getId())
.setParentId(parentId)
.setSscc(inputData.getSscc())
.setPosizioneIn(inputData.getPosizioneIn())
.setPosizioneOut(inputData.getPosizioneOut())
.setErrorMessage(inputData.getErrorMessage())
.setCompleted(inputData.isCompleted())
.setSkipped(inputData.isSkipped())
.setStartedAt(inputData.getStartedAt())
.setEndedAt(inputData.getEndedAt())
.setCreatedAt(inputData.getCreatedAt())
.setUpdatedAt(inputData.getUpdatedAt());
}
public static List<MissioneMagazzinoAutomaticoDTO> convertEntityListToDto(List<MtbMissioneMagAuto> inputData) {
return inputData.stream()
.map(MissioniMagazzinoAutomaticoUtils::convertEntityToDto)
.collect(Collectors.toList());
}
public static MissioneMagazzinoAutomaticoDTO convertEntityToDto(MtbMissioneMagAuto inputData) {
return new MissioneMagazzinoAutomaticoDTO(inputData.getId())
.setCreatedBy(inputData.getCreatedBy())
.setCreatedAt(inputData.getCreatedAt())
.setCodMdep(inputData.getCodMdep())
.setCodArea(inputData.getCodArea())
.setRows(convertEntityRowListToDto(inputData.getMtbMissioneMagAutoDet()));
}
public static List<MissioneMagazzinoAutomaticoRowDTO> convertEntityRowListToDto(List<MtbMissioneMagAutoDet> inputData) {
if (inputData == null)
return null;
return inputData.stream()
.map(MissioniMagazzinoAutomaticoUtils::convertEntityRowToDto)
.collect(Collectors.toList());
}
public static MissioneMagazzinoAutomaticoRowDTO convertEntityRowToDto(MtbMissioneMagAutoDet inputData) {
return new MissioneMagazzinoAutomaticoRowDTO(inputData.getId())
.setSscc(inputData.getSscc())
.setPosizioneIn(inputData.getPosizioneIn())
.setPosizioneOut(inputData.getPosizioneOut())
.setErrorMessage(inputData.getErrorMessage())
.setCompleted(inputData.isCompleted())
.setSkipped(inputData.isSkipped())
.setStartedAt(inputData.getStartedAt())
.setEndedAt(inputData.getEndedAt())
.setCreatedAt(inputData.getCreatedAt())
.setUpdatedAt(inputData.getUpdatedAt());
}
}

View File

@@ -167,6 +167,9 @@ public class WMSUtility {
final List<MvwSitArtUdcDetInventarioDTO> mvwSitArtUdcDetInventarioDTOS =
wmsGiacenzaULService.retrieveArtsInGiacenzaByBarcodeUls(connection, ssccList, true);
if (mvwSitArtUdcDetInventarioDTOS == null)
throw new Exception("Errore nel recupero degli articoli per il barcode: " + StringUtils.join(ssccList, ", "));
if (mvwSitArtUdcDetInventarioDTOS.isEmpty())
throw new Exception("Nessun articolo trovato per il barcode: " + ssccList);
@@ -755,7 +758,14 @@ public class WMSUtility {
public static MtbDepoPosizioni getPosizioneFromName(Connection conn, String posizione) throws Exception {
MtbDepoPosizioni mtbDepoPosizioni = UtilityDB.executeSimpleQueryOnlyFirstRowDTO(conn, Query.format("SELECT * from " + MtbDepoPosizioni.ENTITY + " where posizione = {}", posizione), MtbDepoPosizioni.class);
List<MtbDepoPosizioni> mtbDepoPosizioni = getPosizioniFromName(conn, Collections.singletonList(posizione));
return mtbDepoPosizioni == null || mtbDepoPosizioni.isEmpty() ? null : mtbDepoPosizioni.get(0);
}
public static List<MtbDepoPosizioni> getPosizioniFromName(Connection conn, List<String> inputData) throws Exception {
List<MtbDepoPosizioni> mtbDepoPosizioni = UtilityDB.executeSimpleQueryDTO(conn,
"SELECT * from " + MtbDepoPosizioni.ENTITY + "\n" +
"WHERE posizione IN (" + UtilityQuery.concatStringFieldsWithSeparator(inputData, ", ") + ")", MtbDepoPosizioni.class);
return mtbDepoPosizioni;
}

View File

@@ -0,0 +1,37 @@
package it.integry.ems.retail.wms.dto;
import java.util.List;
public class MagazzinoAutomaticoMoveItemsRequestDTO {
private List<String> barcodeUl;
private String posizioneDestinazione;
private String annotazioni;
public List<String> getBarcodeUl() {
return barcodeUl;
}
public MagazzinoAutomaticoMoveItemsRequestDTO setBarcodeUl(List<String> barcodeUl) {
this.barcodeUl = barcodeUl;
return this;
}
public String getPosizioneDestinazione() {
return posizioneDestinazione;
}
public MagazzinoAutomaticoMoveItemsRequestDTO setPosizioneDestinazione(String posizioneDestinazione) {
this.posizioneDestinazione = posizioneDestinazione;
return this;
}
public String getAnnotazioni() {
return annotazioni;
}
public MagazzinoAutomaticoMoveItemsRequestDTO setAnnotazioni(String annotazioni) {
this.annotazioni = annotazioni;
return this;
}
}

View File

@@ -1,10 +1,14 @@
package it.integry.ems.retail.wms.generic.controller;
import it.integry.common.var.CommonConstants;
import it.integry.ems.javabeans.RequestDataDTO;
import it.integry.ems.response.ServiceRestResponse;
import it.integry.ems.retail.wms.dto.MagazzinoAutomaticoMoveItemsRequestDTO;
import it.integry.ems.retail.wms.generic.dto.MagazzinoAutomaticoPickItemsRequestDTO;
import it.integry.ems.retail.wms.generic.dto.MagazzinoAutomaticoPutItemsRequestDTO;
import it.integry.ems.retail.wms.generic.service.WMSMagazzinoAutomaticoService;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems.user.UserSession;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
@@ -21,24 +25,46 @@ public class WMSMagazzinoAutomaticoController {
@Autowired
private WMSMagazzinoAutomaticoService wmsMagazzinoAutomaticoService;
@Autowired
private MultiDBTransactionManager multiDBTransactionManager;
@RequestMapping(value = "{posizione}/pickItems", method = RequestMethod.POST)
@Autowired
private RequestDataDTO requestDataDTO;
@Autowired
private UserSession userSession;
@PostMapping(value = "{posizione}/pickItems")
public @ResponseBody
ServiceRestResponse pickItems(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@PathVariable String posizione,
@RequestBody MagazzinoAutomaticoPickItemsRequestDTO magazzinoAutomaticoPickItemsRequestDTO) throws Exception {
wmsMagazzinoAutomaticoService.pickItems(magazzinoAutomaticoPickItemsRequestDTO);
userSession.checkUser();
wmsMagazzinoAutomaticoService.pickItems(multiDBTransactionManager, magazzinoAutomaticoPickItemsRequestDTO);
return ServiceRestResponse.createPositiveResponse();
}
@RequestMapping(value = "{posizione}/putItems", method = RequestMethod.POST)
@PostMapping(value = "{posizione}/putItems")
public @ResponseBody
ServiceRestResponse putItems(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@PathVariable String posizione,
@RequestBody MagazzinoAutomaticoPutItemsRequestDTO magazzinoAutomaticoPutItemsRequestDTO) throws Exception {
wmsMagazzinoAutomaticoService.putItems(magazzinoAutomaticoPutItemsRequestDTO);
userSession.checkUser();
wmsMagazzinoAutomaticoService.putItems(multiDBTransactionManager, requestDataDTO.getUsername(), posizione, magazzinoAutomaticoPutItemsRequestDTO);
return ServiceRestResponse.createPositiveResponse();
}
@PostMapping(value = "moveItems")
public @ResponseBody
ServiceRestResponse moveItems(@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@RequestBody MagazzinoAutomaticoMoveItemsRequestDTO requestBody) throws Exception {
userSession.checkUser();
wmsMagazzinoAutomaticoService.moveItems(multiDBTransactionManager, requestDataDTO.getUsername(), requestBody);
return ServiceRestResponse.createPositiveResponse();
}

View File

@@ -7,7 +7,6 @@ import it.integry.ems.retail.wms.generic.dto.RetrieveArtsInGiacenzaByArtRequestD
import it.integry.ems.retail.wms.generic.dto.StatoArtInventarioDTO;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems_model.config.EmsRestConstants;
import it.integry.ems_model.entity.MtbColt;
import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityHashMap;
import it.integry.ems_model.utility.UtilityQuery;
@@ -356,15 +355,49 @@ public class WMSGiacenzaULService {
return UtilityDB.executeSimpleQueryDTO(connection, sql, MvwSitArtUdcDetInventarioDTO.class);
}
public List<MvwSitArtUdcDetInventarioDTO> retrieveArtByMtbColt(Connection connection, MtbColt mtbColt) throws Exception {
return retrieveArtsByUL(connection,
mtbColt.getGestione(),
mtbColt.getDataCollo(),
mtbColt.getSerCollo(),
mtbColt.getNumCollo(),
mtbColt.getSegno(),
null, null);
public HashMap<String, Boolean> checkIfUlsAreInGiacenza(Connection connection, List<String> barcodeUls) throws Exception {
if (barcodeUls == null || barcodeUls.isEmpty())
return new HashMap<>();
String sql = "SELECT DISTINCT barcode_ul FROM mvw_sitart_udc_det_inventario " +
"WHERE barcode_ul IN (" + UtilityQuery.concatStringFieldsWithSeparator(barcodeUls, ", ") + ")";
List<HashMap<String, Object>> results = UtilityDB.executeSimpleQuery(connection, sql);
HashMap<String, Boolean> resultMap = new HashMap<>();
for (String ul : barcodeUls)
resultMap.put(ul, false);
for (HashMap<String, Object> row : results) {
String ul = UtilityHashMap.getValueIfExists(row, "barcode_ul");
if (!UtilityString.isNullOrEmpty(ul))
resultMap.put(ul, true);
}
return resultMap;
}
public HashMap<String, String> retrieveBarcodeUlsCurrentPosition(Connection connection, List<String> barcodeUls) throws Exception {
if (barcodeUls == null || barcodeUls.isEmpty())
return new HashMap<>();
String sql = "SELECT DISTINCT barcode_ul, posizione FROM mvw_sitart_udc_det_inventario " +
"WHERE barcode_ul IN (" + UtilityQuery.concatStringFieldsWithSeparator(barcodeUls, ", ") + ")";
List<HashMap<String, Object>> results = UtilityDB.executeSimpleQuery(connection, sql);
HashMap<String, String> resultMap = new HashMap<>();
for (String ul : barcodeUls)
resultMap.put(ul, null);
for (HashMap<String, Object> row : results) {
String ul = UtilityHashMap.getValueIfExists(row, "barcode_ul");
if (!UtilityString.isNullOrEmpty(ul))
resultMap.put(ul, UtilityHashMap.getValueIfExists(row, "posizione"));
}
return resultMap;
}
}

View File

@@ -5,8 +5,13 @@ import it.integry.ems.export.enums.EntityExportType;
import it.integry.ems.javabeans.RequestDataDTO;
import it.integry.ems.json.ResponseJSONObjectMapper;
import it.integry.ems.logistic.Export.ColliExporter;
import it.integry.ems.logistic.missioni.magazzino_automatico.dto.MissioneMagazzinoAutomaticoDTO;
import it.integry.ems.logistic.missioni.magazzino_automatico.dto.MissioneMagazzinoAutomaticoRowDTO;
import it.integry.ems.logistic.missioni.magazzino_automatico.service.MissioniMagazzinoAutomaticoService;
import it.integry.ems.retail.wms.Utility.WMSUtility;
import it.integry.ems.retail.wms.dto.CreateUDSRequestDTO;
import it.integry.ems.retail.wms.dto.CreateUDSRequestOrderDTO;
import it.integry.ems.retail.wms.dto.MagazzinoAutomaticoMoveItemsRequestDTO;
import it.integry.ems.retail.wms.generic.dto.*;
import it.integry.ems.retail.wms.lavorazione.service.WMSLavorazioneService;
import it.integry.ems.retail.wms.vendita.service.WMSSpedizioneService;
@@ -16,13 +21,17 @@ import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems.user.UserSession;
import it.integry.ems_model.entity.DtbOrdr;
import it.integry.ems_model.entity.MtbColt;
import it.integry.ems_model.entity.MtbDepoPosizioni;
import it.integry.ems_model.types.OperationType;
import it.integry.ems_model.utility.UtilityLocalDate;
import org.apache.commons.lang3.NotImplementedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@@ -46,16 +55,20 @@ public class WMSMagazzinoAutomaticoService {
@Autowired
private WMSSpedizioneService wmsSpedizioneService;
@Autowired
private MultiDBTransactionManager multiDBTransactionManager;
@Autowired
private UserSession userSession;
@Autowired
private RequestDataDTO requestDataDTO;
public void pickItems(MagazzinoAutomaticoPickItemsRequestDTO magazzinoAutomaticoPickItemsRequestDTO) throws Exception {
@Autowired
private WMSGiacenzaULService wmsGiacenzaULService;
@Autowired
private MissioniMagazzinoAutomaticoService missioniMagazzinoAutomaticoService;
public void pickItems(MultiDBTransactionManager multiDBTransactionManager, MagazzinoAutomaticoPickItemsRequestDTO magazzinoAutomaticoPickItemsRequestDTO) throws Exception {
MtbColt refMtbColt = null;
if (magazzinoAutomaticoPickItemsRequestDTO.isShouldCreateUDS()) {
@@ -113,13 +126,119 @@ public class WMSMagazzinoAutomaticoService {
}
public void putItems(MagazzinoAutomaticoPutItemsRequestDTO magazzinoAutomaticoPutItemsRequestDTO) throws Exception {
public void putItems(MultiDBTransactionManager multiDBTransactionManager, String username, String posizione, MagazzinoAutomaticoPutItemsRequestDTO magazzinoAutomaticoPutItemsRequestDTO) throws Exception {
MtbColt mtbColtToPut = magazzinoAutomaticoPutItemsRequestDTO.getInputMtbColt();
JsonNode node = jsonObjectMapper.valueToTree(mtbColtToPut);
final MtbDepoPosizioni mtbDepoPosizione = WMSUtility.getPosizioneFromName(multiDBTransactionManager.getPrimaryConnection(), posizione);
if (mtbDepoPosizione == null)
return;
switch (mtbDepoPosizione.getTipoMagazAutomatico()) {
case SILO2:
emsServices.export(multiDBTransactionManager, requestDataDTO,
EntityExportType.COLLI.getText(),
ColliExporter.Format.ICON_ACCETTAZIONE.getText(),
node, false);
break;
case EUROFORK:
//TODO: Ricavare la posizione di destinazione. Se l'UL proviene da L7 allora va ricavata dallo step dell'ordine
// String posizioneDest = "WH101L002";
final MissioneMagazzinoAutomaticoRowDTO missionRow = new MissioneMagazzinoAutomaticoRowDTO()
.setSscc(mtbColtToPut.getBarcodeUl())
.setPosizioneOut(mtbColtToPut.getPosizione())
.setPosizioneIn(mtbDepoPosizione.getPosizione());
final MissioneMagazzinoAutomaticoDTO missioneRequest = new MissioneMagazzinoAutomaticoDTO()
.setCodMdep(mtbDepoPosizione.getCodMdep())
.setCodArea(mtbDepoPosizione.getCodArea())
.setRows(Collections.singletonList(missionRow));
missioniMagazzinoAutomaticoService.createMissione(multiDBTransactionManager, username, missioneRequest);
break;
default:
throw new NotImplementedException("Tipo magazzino automatico non gestito: " + mtbDepoPosizione.getTipoMagazAutomatico().getValue());
}
}
public void moveItems(MultiDBTransactionManager multiDBTransactionManager, String username, MagazzinoAutomaticoMoveItemsRequestDTO inputData) throws Exception {
final HashMap<String, Boolean> existingMissions =
missioniMagazzinoAutomaticoService.checkIfPendingMissionExists(multiDBTransactionManager.getPrimaryConnection(), inputData.getBarcodeUl());
if (!existingMissions.isEmpty())
throw new IllegalArgumentException("Esistono missioni in corso per le unità logistiche: " + String.join(", ", existingMissions.keySet()));
final HashMap<String, String> giacenzaItems =
wmsGiacenzaULService.retrieveBarcodeUlsCurrentPosition(multiDBTransactionManager.getPrimaryConnection(), inputData.getBarcodeUl());
if (giacenzaItems == null || giacenzaItems.isEmpty())
throw new IllegalArgumentException("Unità logistica non trovata: " + inputData.getBarcodeUl());
//Controlli base per correttezza dei barcode ricevuti
List<String> barcodeNonTrovati = inputData.getBarcodeUl().stream()
.filter(barcode -> !giacenzaItems.containsKey(barcode))
.collect(Collectors.toList());
if (!barcodeNonTrovati.isEmpty())
throw new IllegalArgumentException("Unità logistica non in giacenza: " + barcodeNonTrovati.stream()
.findFirst()
.get());
//Carico anagrafica posizioni
List<String> posizioniPartenza = giacenzaItems.values().stream()
.filter(x -> x != null && !x.isEmpty())
.distinct()
.collect(Collectors.toList());
final List<MtbDepoPosizioni> posizioniAnag = WMSUtility.getPosizioniFromName(multiDBTransactionManager.getPrimaryConnection(), posizioniPartenza);
final List<MtbDepoPosizioni.TipoMagazzinoAutomaticoEnum> foundTipiMagAuto = posizioniAnag.stream()
.map(MtbDepoPosizioni::getTipoMagazAutomatico)
.distinct()
.collect(Collectors.toList());
if (foundTipiMagAuto.size() > 1)
throw new IllegalArgumentException("Le unità logistiche appartengono a magazzini automatici differenti: " + new HashMap<String, Integer>() {{
for (MtbDepoPosizioni.TipoMagazzinoAutomaticoEnum tipoMagAuto : foundTipiMagAuto)
put(tipoMagAuto.getValue(), (int) posizioniAnag.stream().filter(x -> x.getTipoMagazAutomatico() == tipoMagAuto).count());
}});
String codMdep = posizioniAnag.get(0).getCodMdep();
String codArea = posizioniAnag.get(0).getCodArea();
switch (foundTipiMagAuto.get(0)) {
case EUROFORK:
//Controllare che le pedane possono essere prelevate (non sono bloccate da altre pedane)
final List<MissioneMagazzinoAutomaticoRowDTO> missionRows = giacenzaItems.entrySet().stream()
.map(x -> new MissioneMagazzinoAutomaticoRowDTO()
.setSscc(x.getKey())
.setPosizioneOut(x.getValue())
.setPosizioneIn(inputData.getPosizioneDestinazione()))
.collect(Collectors.toList());
final MissioneMagazzinoAutomaticoDTO missioneRequest = new MissioneMagazzinoAutomaticoDTO()
.setCodMdep(codMdep)
.setCodArea(codArea)
.setRows(missionRows);
missioniMagazzinoAutomaticoService.createMissione(multiDBTransactionManager, username, missioneRequest);
break;
default:
throw new NotImplementedException("Tipo magazzino automatico non gestito: " + foundTipiMagAuto.get(0).getValue());
}
}
}

View File

@@ -128,6 +128,7 @@ public class RestLoggerBodyFilter extends AbstractRequestLoggingFilter {
!serviceName.contains("system/ok") &&
!serviceName.contains("system/login") &&
!serviceName.contains("auth/login") &&
!serviceName.contains("magazzino-automatico/retrieve-all") &&
!serviceName.contains("logs") &&
!serviceName.contains("getCurrentMachinesStatus") &&
!serviceName.contains("getOrdiniLavorazione") &&