diff --git a/pom.xml b/pom.xml index 0fe8ad5..35c9b13 100644 --- a/pom.xml +++ b/pom.xml @@ -10,12 +10,12 @@ dev.fyloz.trial.colorrecipesexplorer ColorRecipesExplorer - 1.1.3 + 1.2.0 Color Recipes Explorer UTF-8 - 1.8 + 11 @@ -41,11 +41,6 @@ spring-boot-starter-test test - - org.xhtmlrenderer - flying-saucer-pdf - 9.1.18 - org.apache.poi poi-ooxml @@ -56,16 +51,6 @@ h2 runtime - - commons-codec - commons-codec - 1.11 - - - com.itextpdf - itextpdf - 5.5.10 - org.apache.pdfbox pdfbox @@ -95,6 +80,12 @@ commonmark 0.13.1 + + commons-io + commons-io + 2.6 + + diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java index 2c2be3f..3947342 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/configuration/InitialDataLoader.java @@ -35,7 +35,7 @@ public class InitialDataLoader implements ApplicationListener optionalSavedMaterialType = materialTypeService.save(defaultMaterialType); - if (!optionalSavedMaterialType.isPresent()) { + if (optionalSavedMaterialType.isEmpty()) { ColorRecipesExplorerApplication.LOGGER.warn(String.format("Échec de la création du type de produit par défaut '%s'.", name)); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseCode.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseCode.java index 702eea5..d0f3855 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseCode.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/io/response/ResponseCode.java @@ -28,6 +28,13 @@ public enum ResponseCode { RECIPE_NOT_FOUND_NO_PARAMS(25, ResponseCodeType.ERROR, 0), MATERIAL_NOT_FOUND_BY_NAME(26, ResponseCodeType.ERROR, 1), SUCCESS_DELETING_COMPANY(27, ResponseCodeType.SUCCESS, 1), + SUCCESS_SAVING_MATERIAL(28, ResponseCodeType.SUCCESS, 1), + SUCCESS_SAVING_MATERIAL_TYPE(29, ResponseCodeType.SUCCESS, 1), + SUCCESS_SAVING_RECIPE(30, ResponseCodeType.SUCCESS, 1), + SUCCESS_DELETING_MATERIAL(31, ResponseCodeType.SUCCESS, 1), + SUCCESS_SAVING_COMPANY(32, ResponseCodeType.SUCCESS, 1), + SUCCESS_DELETING_RECIPE(33, ResponseCodeType.SUCCESS, 1), + SUCCESS_DELETING_MATERIAL_TYPE(34, ResponseCodeType.SUCCESS, 1), // HTTP Errors _500(100, ResponseCodeType.ERROR, 0), diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.java index 2289522..54f123b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Material.java @@ -11,9 +11,9 @@ import java.io.Serializable; @Entity @Table(name = "materials") @Data +@EqualsAndHashCode(callSuper = false) @RequiredArgsConstructor @NoArgsConstructor -@EqualsAndHashCode(callSuper = false) public class Material extends BeanModel implements Serializable { @Id diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MaterialType.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MaterialType.java index 8377236..8f913b9 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MaterialType.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/MaterialType.java @@ -20,7 +20,7 @@ public class MaterialType extends BeanModel implements Serializable { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) - private Integer materialTypeID; + private Integer materialTypeID = 0; @NonNull @NotNull diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java index eed7c52..34a68ec 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/model/Recipe.java @@ -57,27 +57,13 @@ public class Recipe extends BeanModel implements Serializable { return recipeID; } - public Material getBase() { - if (recipeMixes.isEmpty() || recipeMixes.stream().allMatch(m -> m.getMixQuantities().isEmpty())) return null; - - Material base = recipeMixes - .stream() - .map(mix -> mix - .getMixQuantities() - .stream() - .filter(mq -> mq.getMaterial().getMaterialType().getMaterialTypeName().equals(MaterialType.BASE_MATERIAL_TYPE_NAME)) - .findFirst().get() - ) - .findFirst().orElse(recipeMixes - .stream() - .filter(m -> !m.getMixQuantities().isEmpty()) - .findFirst() - .get() - .getMixQuantities() - .stream() - .findFirst() - .get()).getMaterial(); - - return base; - } +// public Material getBase() { +// for (Mix mix : recipeMixes) { +// for(MixQuantity mq : mix.getMixQuantities()) { +// if(mq.getMaterial().getMaterialType().getMaterialTypeName().equals(MaterialType.BASE_MATERIAL_TYPE_NAME)) return mq.getMaterial(); +// } +// } +// +// return null; +// } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.java index 6f4b3c5..ff66b00 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/InventoryService.java @@ -32,13 +32,13 @@ public class InventoryService { return null; } - public boolean useMix(Mix mix, Map quantities) { + public boolean useMix(Map quantities) { for (Map.Entry entry : quantities.entrySet()) { Material material = entry.getKey(); if (!material.isMixType()) { material.setInventoryQuantity(material.getInventoryQuantity() - entry.getValue()); - if (!materialService.update(material).isPresent()) return false; + if (materialService.update(material).isEmpty()) return false; } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java index 1085485..d547356 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialService.java @@ -72,9 +72,10 @@ public class MaterialService extends GenericService { if (material == null) return false; Optional materialByCode = dao.findByMaterialCode(material.getMaterialCode()); - return super.isValidForUpdate(material) && (!materialByCode.isPresent() || material.getMaterialID().equals(materialByCode.get().getMaterialID())); + return super.isValidForUpdate(material) && (materialByCode.isEmpty() || material.getMaterialID().equals(materialByCode.get().getMaterialID())); } + @Deprecated(since = "1.2.0") public List getAllBySearchString(String searchString) { return dao.findAllByMaterialCodeContainingIgnoreCase(searchString).stream().filter(m -> !m.isMixType()).collect(Collectors.toList()); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialTypeService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialTypeService.java index 99aa914..359c964 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialTypeService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MaterialTypeService.java @@ -46,13 +46,13 @@ public class MaterialTypeService extends GenericService materialTypeByName = dao.findByMaterialTypeName(materialType.getMaterialTypeName()); - return !materialTypeByName.isPresent() || materialType.getMaterialTypeID().equals(materialTypeByName.get().getMaterialTypeID()); + return materialTypeByName.isEmpty() || materialType.getMaterialTypeID().equals(materialTypeByName.get().getMaterialTypeID()); } public boolean isValidForUpdatePrefix(MaterialType materialType) { Optional materialTypeByPrefix = dao.findByPrefix(materialType.getPrefix()); - return !materialTypeByPrefix.isPresent() || materialType.getMaterialTypeID().equals(materialTypeByPrefix.get().getMaterialTypeID()); + return materialTypeByPrefix.isEmpty() || materialType.getMaterialTypeID().equals(materialTypeByPrefix.get().getMaterialTypeID()); } public Optional getByName(String name) { diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixService.java index 09e05f6..d1ed7e2 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/MixService.java @@ -11,9 +11,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; +import java.util.stream.Collectors; @Service public class MixService extends GenericService { @@ -32,6 +31,25 @@ public class MixService extends GenericService { this.recipeService = recipeService; } + public Collection getAvailableMaterialsForNewMix(Recipe recipe) { + Collection recipeMixTypes = recipeService.getAssociatedMixesTypes(recipe); + + return materialService + .getAll() + .stream() + .filter(m -> !m.isMixType() || recipeMixTypes.contains(mixTypeService.getByMaterial(m).get())) + .sorted(Comparator.comparing(Material::getMaterialCode)) + .sorted(Comparator.comparing(m -> m.getMaterialType().getMaterialTypeName())) + .collect(Collectors.toList()); + } + + public Collection getAvailableMaterialsForMix(Recipe recipe, Mix mix) { + return getAvailableMaterialsForNewMix(recipe) + .stream() + .filter(m -> !m.equals(mix.getMixType().getMaterial())) + .collect(Collectors.toList()); + } + @Transactional public ModelResponseBuilder create(MixCreationFormDto formDto, @NotNull Recipe recipe) { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); @@ -39,7 +57,7 @@ public class MixService extends GenericService { List materials = new ArrayList<>(); for (String materialCode : formDto.getMaterials()) { Optional found = materialService.getByMaterialCode(materialCode); - if (!found.isPresent()) { + if (found.isEmpty()) { return modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND_BY_NAME, materialCode); } @@ -47,7 +65,7 @@ public class MixService extends GenericService { } Optional optionalMixType = mixTypeService.createByName(formDto.getMixTypeName(), formDto.getMaterialType()); - if (!optionalMixType.isPresent()) return modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); + if (optionalMixType.isEmpty()) return modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); MixType mixType = optionalMixType.get(); if (recipeService.hasMixType(recipe, mixType)) @@ -80,7 +98,7 @@ public class MixService extends GenericService { List materials = new ArrayList<>(); for (String materialCode : formDto.getMaterials()) { Optional found = materialService.getByMaterialCode(materialCode); - if (!found.isPresent()) { + if (found.isEmpty()) { return modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND_BY_NAME, materialCode); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java index 37aaa80..d9dc400 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/RecipeService.java @@ -68,7 +68,7 @@ public class RecipeService extends GenericService { storedRecipe.setNote(newRecipe.getNote()); Optional optionalRecipe = convertAndCreateSteps(storedRecipe, form); - if (!optionalRecipe.isPresent()) { + if (optionalRecipe.isEmpty()) { return Optional.empty(); } @@ -126,6 +126,7 @@ public class RecipeService extends GenericService { .contains(mixType); } + @Deprecated(since = "1.2.0") public Map> getRecipesForSearchString(String searchString) { List recipes = dao.findAllByRecipeDescriptionContainsOrRecipeCodeContains(searchString.toUpperCase()); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/TouchUpKitService.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/TouchUpKitService.java new file mode 100644 index 0000000..92eafed --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/services/model/TouchUpKitService.java @@ -0,0 +1,32 @@ +package dev.fyloz.trial.colorrecipesexplorer.core.services.model; + +import dev.fyloz.trial.colorrecipesexplorer.core.utils.PdfBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ResourceLoader; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +@Service +public class TouchUpKitService { + + private static final String TOUCH_UP_FR = "KIT DE RETOUCHE"; + private static final String TOUCH_UP_EN = "TOUCH UP KIT"; + public static final int FONT_SIZE = 42; + + private ResourceLoader resourceLoader; + + @Autowired + public TouchUpKitService(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + public byte[] getPdfForJobNumber(String jobNumber) throws IOException { + return new PdfBuilder(resourceLoader, true, FONT_SIZE) + .addLine(TOUCH_UP_FR, true, 0) + .addLine(TOUCH_UP_EN, true, 0) + .addLine(jobNumber, false, 10) + .build(); + } + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/PdfBuilder.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/PdfBuilder.java new file mode 100644 index 0000000..42050a4 --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/core/utils/PdfBuilder.java @@ -0,0 +1,101 @@ +package dev.fyloz.trial.colorrecipesexplorer.core.utils; + +import dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDFont; +import org.apache.pdfbox.pdmodel.font.PDType0Font; +import org.springframework.core.io.ResourceLoader; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +public class PdfBuilder { + + private PDFont font; + private PDDocument document = new PDDocument(); + private PDPage page = new PDPage(); + private Collection lines = new ArrayList<>(); + private boolean duplicated; + private int fontSize; + private int fontSizeBold; + private int lineSpacing; + + public PdfBuilder(ResourceLoader resourceLoader, boolean duplicated, int fontSize) throws IOException { + this.duplicated = duplicated; + this.fontSize = fontSize; + this.fontSizeBold = this.fontSize + 12; + this.lineSpacing = (int) (this.fontSize * 1.5f); + + document.addPage(page); + font = PDType0Font.load(document, resourceLoader.getResource(WebsitePaths.FONT_ARIAL_BOLD).getFile()); + } + + public PdfBuilder addLine(String text, boolean bold, int marginTop) { + lines.add(new PdfLine(text, bold, marginTop)); + + return this; + } + + public byte[] build() throws IOException { + writeContent(); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + document.save(outputStream); + document.close(); + + return outputStream.toByteArray(); + } + + private void writeContent() throws IOException { + PDPageContentStream contentStream = new PDPageContentStream(document, page); + contentStream.beginText(); + + int marginTop = 30; + for (PdfLine line : lines) { + writeCenteredText(contentStream, line, marginTop); + marginTop += lineSpacing; + } + + if (duplicated) { + marginTop = (int) page.getMediaBox().getHeight() / 2; + for (PdfLine line : lines) { + writeCenteredText(contentStream, line, marginTop); + marginTop += lineSpacing; + } + } + + contentStream.endText(); + contentStream.close(); + } + + private void writeCenteredText(PDPageContentStream contentStream, PdfLine line, int marginTop) throws IOException { + float textWidth = font.getStringWidth(line.getText()) / 1000 * (line.isBold() ? fontSizeBold : fontSize); + float textHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * (line.isBold() ? fontSizeBold : fontSize); + float textX = (page.getMediaBox().getWidth() - textWidth) / 2f; + float textY = (page.getMediaBox().getHeight() - (marginTop + line.getMarginTop()) - textHeight); + + if (line.isBold()) contentStream.setFont(font, fontSizeBold); + else contentStream.setFont(font, fontSize); + + contentStream.newLineAtOffset(textX, textY); + contentStream.showText(line.getText()); + contentStream.newLineAtOffset(-textX, -textY); // Réinitialise la position pour la prochaine ligne + } + + @Data + @AllArgsConstructor + public static class PdfLine { + + private String text; + private boolean bold; + private int marginTop; + + } + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/PagesPaths.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/WebsitePaths.java similarity index 92% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/PagesPaths.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/WebsitePaths.java index 6000b93..1565f0b 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/PagesPaths.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/WebsitePaths.java @@ -1,19 +1,19 @@ package dev.fyloz.trial.colorrecipesexplorer.web; -public class PagesPaths { +public class WebsitePaths { // Autres public static final String INDEX = "index"; public static final String SEARCH = "search"; public static final String SEARCH_INVENTORY = "inventory/search"; public static final String SIMDUT_FILES = "simdut/{materialID}"; public static final String PASSWORD_VALIDATION = "password/valid"; - public static final String TOUCHUP = "touchup"; public static final String RECIPE_XLS = "recipe/xls/{recipeID}"; public static final String ALL_RECIPES_XLS = "recipe/xls"; public static final String ERROR = "error"; public static final String CLOSE_TAB = "closeTab"; public static final String UPDATES = "updates"; public static final String UPDATES_GET = "updates/get"; + public static final String FONT_ARIAL_BOLD = "classpath:fonts/arialbd.ttf"; // Images public static final String IMAGES_FILES = "images/{image}"; @@ -21,6 +21,12 @@ public class PagesPaths { public static final String ADD_IMAGE_SPECIFIC = "images/add/{recipeID}"; public static final String DELETE_IMAGE = "images/delete"; + // Touch up kits + public static final String TOUCHUP = "touchup"; + public static final String TOUCHUP_PDF = "touchup/pdf"; + public static final String TOUCHUP_PTOUCH = "touchup/ptouch"; + public static final String TOUCHUP_PTOUCH_PAGE = "touchupPtouch"; + // Inventaire public static final String INVENTORY = "inventory"; public static final String USE_INVENTORY = "inventory/use"; diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/CREErrorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/CREErrorController.java index 51716fb..b9ce072 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/CREErrorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/CREErrorController.java @@ -10,7 +10,7 @@ import org.springframework.web.servlet.ModelAndView; import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServletRequest; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.ERROR; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.ERROR; @Controller public class CREErrorController implements ErrorController { diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/IndexController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/IndexController.java index cc51792..69a061f 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/IndexController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/IndexController.java @@ -6,7 +6,6 @@ import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; import dev.fyloz.trial.colorrecipesexplorer.core.model.Company; import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; import dev.fyloz.trial.colorrecipesexplorer.core.services.PasswordService; -import dev.fyloz.trial.colorrecipesexplorer.core.services.model.CompanyService; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -19,17 +18,16 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INDEX; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.PASSWORD_VALIDATION; @Controller public class IndexController { - private CompanyService companyService; private RecipeService recipeService; @Autowired - public IndexController(CompanyService companyService, RecipeService recipeService) { - this.companyService = companyService; + public IndexController(RecipeService recipeService) { this.recipeService = recipeService; } @@ -39,21 +37,14 @@ public class IndexController { * @return La page à afficher. */ @GetMapping({INDEX, "/"}) - public ModelAndView showPage() { - List companies = companyService.getAll(); - Map> recipes = new HashMap<>(); - - for (Company company : companies) { - recipes.put(company, recipeService.getByCompany(company)); - } - + public ModelAndView getPage() { return new ModelResponseBuilder(INDEX) - .addResponseData(ResponseDataType.RECIPE_MAP, recipes) + .addResponseData(ResponseDataType.RECIPE_MAP, recipeService.getRecipesByCompany()) .build(); } - @GetMapping(value = SEARCH, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody + // @GetMapping(value = SEARCH, produces = MediaType.APPLICATION_JSON_VALUE) +// @ResponseBody public Map searchWord(@RequestParam String searchString) { Map> searchResult = recipeService.getRecipesForSearchString(searchString); Map> outputResult = new HashMap<>(); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/InventoryController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/InventoryController.java index 154be15..8980f8a 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/InventoryController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/InventoryController.java @@ -21,8 +21,9 @@ import org.springframework.web.servlet.ModelAndView; import java.util.*; import java.util.stream.Collectors; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; import static dev.fyloz.trial.colorrecipesexplorer.web.StringBank.RESPONSE_REASON; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INVENTORY; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.USE_INVENTORY; @Controller public class InventoryController { @@ -41,7 +42,7 @@ public class InventoryController { } @GetMapping(INVENTORY) - public ModelAndView getInventory(ModelAndView model) { + public ModelAndView getPage(ModelAndView model) { return new ModelResponseBuilder(model) .withView(INVENTORY) .addResponseData(ResponseDataType.MATERIALS, materialService.getAllOrdered().stream().filter(m -> !m.isMixType()).collect(Collectors.toList())) @@ -77,7 +78,8 @@ public class InventoryController { @ResponseBody @Transactional // TODO vers DTO - public Map consumeMaterials(@RequestBody Map form) { + // TODO + vers service + public Map consumeMaterials(@RequestBody Map> form) { JSONResponseBuilder responseBuilder = new JSONResponseBuilder(); List mixes = new ArrayList<>(); @@ -87,7 +89,7 @@ public class InventoryController { int mixID = Integer.parseInt(mixIDStr); Optional optionalMix = mixService.getByID(mixID); - if (!optionalMix.isPresent()) { + if (optionalMix.isEmpty()) { return responseBuilder .addResponseCode(ResponseCode.MIX_NOT_FOUND, mixID) .build(); @@ -96,14 +98,15 @@ public class InventoryController { Mix mix = optionalMix.get(); mixes.add(mix); - Map formMaterials = (Map) form.get(mixIDStr); + Map formMaterials = form.get(mixIDStr); Map mixQuantities = new HashMap<>(); for (Material material : mix.getMixQuantities().stream().map(MixQuantity::getMaterial).collect(Collectors.toList())) { String materialIDAsString = String.valueOf(material.getMaterialID()); if (formMaterials.containsKey(materialIDAsString)) { - mixQuantities.put(material, Float.parseFloat(formMaterials.get(materialIDAsString))); + Float quantityAsString = formMaterials.get(materialIDAsString); + mixQuantities.put(material, quantityAsString); } } @@ -123,7 +126,7 @@ public class InventoryController { } for (Mix mix : mixes) { - if (!inventoryService.useMix(mix, quantities.get(mix))) { + if (!inventoryService.useMix(quantities.get(mix))) { return responseBuilder .addResponseCode(ResponseCode.ERROR_SAVING) .build(); @@ -135,8 +138,8 @@ public class InventoryController { .build(); } - @GetMapping(value = SEARCH_INVENTORY, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseBody + // @GetMapping(value = SEARCH_INVENTORY, produces = MediaType.APPLICATION_JSON_VALUE) + // @ResponseBody public Map searchWordInventory(@RequestParam String searchString) { List searchResult = materialService.getAllBySearchString(searchString); List outputResult = searchResult.stream().map(Material::getMaterialID).collect(Collectors.toList()); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/OthersController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/OthersController.java index e675c88..3d4228a 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/OthersController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/OthersController.java @@ -1,23 +1,19 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller; -import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MaterialService; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixService; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.MixTypeService; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; import dev.fyloz.trial.colorrecipesexplorer.core.utils.FileUtils; -import dev.fyloz.trial.colorrecipesexplorer.xlsx.XlsxExporter; import org.commonmark.node.Node; import org.commonmark.parser.Parser; import org.commonmark.renderer.html.HtmlRenderer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ResourceLoader; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -27,19 +23,11 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; -import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.util.Collection; -import java.util.Comparator; -import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; import static dev.fyloz.trial.colorrecipesexplorer.web.StringBank.MATERIALS; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller public class OthersController { @@ -69,7 +57,7 @@ public class OthersController { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(MATERIAL_SELECTOR_FRAGMENT); Optional optionalRecipe = recipeService.getByID(recipeID); - if (!optionalRecipe.isPresent()) { + if (optionalRecipe.isEmpty()) { return modelResponseBuilder .withView("") .build(); @@ -78,77 +66,13 @@ public class OthersController { Optional optionalMix = mixService.getByID(mixID); boolean mixExist = optionalMix.isPresent(); - List associatedMixTypes = recipeService.getAssociatedMixesTypes(optionalRecipe.get()); - // Récupère seulement les produits qui ne sont pas des types de mélange OU que ce type existe dans la recette - List materials = materialService - .getAll() - .stream() - .filter(m -> !m.isMixType() || (!mixExist || !m.equals(optionalMix.get().getMixType().getMaterial())) && associatedMixTypes.contains(mixTypeService.getByMaterial(m).get())) - .sorted(Comparator.comparing(Material::getMaterialCode)) - .sorted(Comparator.comparing(m -> m.getMaterialType().getMaterialTypeName())) - .collect(Collectors.toList()); + Collection materials = mixExist ? mixService.getAvailableMaterialsForMix(optionalRecipe.get(), optionalMix.get()) : mixService.getAvailableMaterialsForNewMix(optionalRecipe.get()); return modelResponseBuilder .addAttribute(MATERIALS, materials) .build(); } - @GetMapping(TOUCHUP) - public ModelAndView getTouchUpPdf() { - return new ModelResponseBuilder().withRedirect("pdf/touchup.pdf").build(); - } - - @GetMapping(RECIPE_XLS) - public ResponseEntity getXlsForRecipe(HttpServletRequest request, @PathVariable int recipeID) { - HttpHeaders headers = new HttpHeaders(); - - Optional optionalRecipe = recipeService.getByID(recipeID); - if (!optionalRecipe.isPresent()) { - headers.add(HttpHeaders.LOCATION, request.getHeader("referer")); - return new ResponseEntity<>(headers, HttpStatus.FOUND); - } - - byte[] recipeXLS = new XlsxExporter().generate(optionalRecipe.get()); - if (recipeXLS.length <= 0) return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); - - return ResponseEntity.ok() - .headers(headers) - .contentLength(recipeXLS.length) - .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) - .body(recipeXLS); - } - - @GetMapping(value = ALL_RECIPES_XLS, produces = "application/zip") - public ResponseEntity getAllXls() throws IOException { - HttpHeaders headers = new HttpHeaders(); - - ColorRecipesExplorerApplication.LOGGER.info("Exportation de toutes les couleurs en XLS"); - - ByteArrayOutputStream byteOS = new ByteArrayOutputStream(); - ZipOutputStream out = new ZipOutputStream(byteOS); - - Collection recipes = recipeService.getAll(); - for (Recipe recipe : recipes) { - byte[] recipeXLS = new XlsxExporter().generate(recipe); - if (recipeXLS.length <= 0) return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); - - out.putNextEntry(new ZipEntry(String.format("%s_%s.xlsx", recipe.getCompany().getCompanyName(), recipe.getRecipeCode()))); - out.write(recipeXLS, 0, recipeXLS.length); - out.closeEntry(); - } - - out.close(); - - byte[] zipContent = byteOS.toByteArray(); - byteOS.close(); - - return ResponseEntity.ok() - .headers(headers) - .contentLength(zipContent.length) - .contentType(MediaType.parseMediaType("application/zip")) - .body(zipContent); - } - @GetMapping(value = UPDATES) public ModelAndView showUpdates() { return new ModelResponseBuilder(UPDATES).build(); @@ -156,7 +80,7 @@ public class OthersController { @GetMapping(value = UPDATES_GET, produces = MediaType.TEXT_HTML_VALUE) @ResponseBody - public ResponseEntity getUpdates() throws IOException { + public ResponseEntity getUpdates() { String fileContent = FileUtils.readClasspathFile(resourceLoader, "classpath:updates.md"); if (fileContent == null) return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/RecipeExplorerController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/RecipeExplorerController.java index 5902c18..7f13b81 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/RecipeExplorerController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/RecipeExplorerController.java @@ -16,7 +16,7 @@ import org.springframework.web.servlet.ModelAndView; import java.util.*; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller public class RecipeExplorerController { @@ -44,11 +44,11 @@ public class RecipeExplorerController { * @return La page à afficher. */ @GetMapping(EXPLORER_RECIPE_SPECIFIC) - public ModelAndView showRecipe(@PathVariable int recipeID) { + public ModelAndView getPage(@PathVariable int recipeID) { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(EXPLORER_RECIPE); Optional optionalRecipe = recipeService.getByID(recipeID); - if (!optionalRecipe.isPresent()) { + if (optionalRecipe.isEmpty()) { return modelResponseBuilder .withView(INDEX) .addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeID) @@ -78,7 +78,7 @@ public class RecipeExplorerController { String note = form.get("note").toString(); Optional optionalRecipe = recipeService.getByID(recipeID); - if (!optionalRecipe.isPresent()) { + if (optionalRecipe.isEmpty()) { responseBuilder.addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeID); } else { Recipe recipe = optionalRecipe.get(); @@ -91,7 +91,7 @@ public class RecipeExplorerController { int mixID = Integer.parseInt(mixIDStr); Optional optionalMix = mixService.getByID(mixID); - if (!optionalMix.isPresent()) { + if (optionalMix.isEmpty()) { responseBuilder.addResponseCode(ResponseCode.MIX_NOT_FOUND, mixID); } else { Mix mix = optionalMix.get(); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/CompanyCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/CompanyCreatorController.java index 15a29ca..73351ea 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/CompanyCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/CompanyCreatorController.java @@ -16,8 +16,8 @@ import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.CREATOR_COMPANY; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.INDEX; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_COMPANY; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INDEX; @Controller public class CompanyCreatorController { @@ -33,7 +33,7 @@ public class CompanyCreatorController { public ModelAndView showCreationPage(ModelAndView model, Company company) { return new ModelResponseBuilder(model) .withView(CREATOR_COMPANY) - .addResponseData(ResponseDataType.COMPANY, company) + .addResponseData(ResponseDataType.COMPANY, company == null ? new Company() : company) .build(); } @@ -62,9 +62,9 @@ public class CompanyCreatorController { Optional savedCompany = companyService.save(company); if (savedCompany.isPresent()) { - return modelResponseBuilder - .addResponseData(ResponseDataType.COMPANY_NAME, savedCompany.get().getCompanyName()) - .build(); + return showCreationPage(modelResponseBuilder + .addResponseCode(ResponseCode.SUCCESS_SAVING_COMPANY, savedCompany.get().getCompanyName()) + .build(), null); } else { modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MaterialCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MaterialCreatorController.java index 556ed6d..58edc21 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MaterialCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MaterialCreatorController.java @@ -17,7 +17,7 @@ import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.CREATOR_MATERIAL; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_MATERIAL; @Controller public class MaterialCreatorController { @@ -68,7 +68,7 @@ public class MaterialCreatorController { if (savedMaterial.isPresent()) { material = savedMaterial.get(); - modelResponseBuilder.addResponseData(ResponseDataType.MATERIAL_CODE, material.getMaterialCode()); + modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL, material.getMaterialCode()); if (simdut.getSize() > 0 && !materialService.addSimdut(simdut, material)) { modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING_SIMDUT); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MaterialTypeCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MaterialTypeCreatorController.java index 3ffa255..cf43e65 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MaterialTypeCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MaterialTypeCreatorController.java @@ -13,9 +13,10 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid; +import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.CREATOR_MATERIAL_TYPE; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.INDEX; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_MATERIAL_TYPE; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INDEX; @Controller public class MaterialTypeCreatorController { @@ -28,7 +29,7 @@ public class MaterialTypeCreatorController { } @GetMapping(CREATOR_MATERIAL_TYPE) - public ModelAndView showPage(ModelAndView model, MaterialType materialType) { + public ModelAndView getPage(ModelAndView model, MaterialType materialType) { return new ModelResponseBuilder(model) .withView(CREATOR_MATERIAL_TYPE) .addResponseData(ResponseDataType.MATERIAL_TYPE, materialType == null ? new MaterialType() : materialType) @@ -40,8 +41,11 @@ public class MaterialTypeCreatorController { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(ControllerUtils.redirect(INDEX)); if (materialTypeService.isValidForCreation(materialType)) { - if (materialTypeService.save(materialType) != null) { - return modelResponseBuilder.build(); + Optional optionalMaterialType = materialTypeService.save(materialType); + if (optionalMaterialType.isPresent()) { + return getPage(modelResponseBuilder + .addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL_TYPE, optionalMaterialType.get().getMaterialTypeName()) + .build(), null); } else { modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); } @@ -49,6 +53,6 @@ public class MaterialTypeCreatorController { modelResponseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST, materialType.getMaterialTypeName()); } - return showPage(modelResponseBuilder.build(), materialType); + return getPage(modelResponseBuilder.build(), materialType); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MixCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MixCreatorController.java index b62498a..061e2e2 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MixCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/MixCreatorController.java @@ -3,8 +3,6 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.creators; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MixCreationFormDto; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.*; @@ -19,12 +17,9 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid; -import java.util.Comparator; -import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller public class MixCreatorController { @@ -58,7 +53,7 @@ public class MixCreatorController { .withView(CREATOR_MIX); Optional optionalRecipe = recipeService.getByID(recipeID); - if (!optionalRecipe.isPresent()) { + if (optionalRecipe.isEmpty()) { return modelResponseBuilder .withView(ControllerUtils.redirect(EDITOR_RECIPE)) .build(); @@ -66,20 +61,10 @@ public class MixCreatorController { Recipe recipe = optionalRecipe.get(); - List associatedMixTypes = recipeService.getAssociatedMixesTypes(recipe); - // Récupère seulement les produits qui ne sont pas des types de mélange OU que ce type existe dans la recette - List materials = materialService - .getAll() - .stream() - .filter(m -> !m.isMixType() || associatedMixTypes.contains(mixTypeService.getByMaterial(m).get())) - .sorted(Comparator.comparing(Material::getMaterialCode)) - .sorted(Comparator.comparing(m -> m.getMaterialType().getMaterialTypeName())) - .collect(Collectors.toList()); - ModelResponseBuilder responseBuilder = modelResponseBuilder .addResponseData(ResponseDataType.RECIPE, recipe) .addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll()) - .addAttribute("materialsJson", materialService.asJson(materials)); + .addAttribute("materialsJson", materialService.asJson(mixService.getAvailableMaterialsForNewMix(recipe))); if (materialService.getAll().isEmpty()) { responseBuilder.addResponseCode(ResponseCode.NO_MATERIAL) diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/RecipeCreatorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/RecipeCreatorController.java index 750a237..6ac4184 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/RecipeCreatorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/creators/RecipeCreatorController.java @@ -15,8 +15,8 @@ import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.CREATOR_RECIPE; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.CREATOR_RECIPE_SUCCESS; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CREATOR_RECIPE; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.EDITOR_RECIPE_SPECIFIC; @Controller public class RecipeCreatorController { @@ -62,12 +62,12 @@ public class RecipeCreatorController { */ @PostMapping(value = CREATOR_RECIPE) public ModelAndView createRecipe(@Valid Recipe recipe) { - ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(CREATOR_RECIPE_SUCCESS); + ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); Optional savedRecipe = recipeService.save(recipe); if (savedRecipe.isPresent()) { return modelResponseBuilder - .addResponseData(ResponseDataType.RECIPE, savedRecipe.get()) + .withRedirect(EDITOR_RECIPE_SPECIFIC, savedRecipe.get().getRecipeID()) .build(); } modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MaterialEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MaterialEditorController.java index 17ca51f..cc0d8d5 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MaterialEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MaterialEditorController.java @@ -19,7 +19,7 @@ import org.springframework.web.servlet.ModelAndView; import java.util.Optional; import java.util.stream.Collectors; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller public class MaterialEditorController { @@ -58,7 +58,7 @@ public class MaterialEditorController { if (material.getMaterialCode() == null) { Optional optionalMaterial = materialService.getByID(materialID); - if (!optionalMaterial.isPresent()) { + if (optionalMaterial.isEmpty()) { return listMaterials( responseBuilder .addResponseCode(ResponseCode.MATERIAL_NOT_FOUND, materialID) @@ -110,7 +110,8 @@ public class MaterialEditorController { } else { Optional updatedMaterial = materialService.update(material); if (updatedMaterial.isPresent()) { - responseBuilder.addResponseData(ResponseDataType.MATERIAL_CODE, updatedMaterial.get().getMaterialCode()); + responseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL, updatedMaterial.get().getMaterialCode()); +// responseBuilder.addResponseData(ResponseDataType.MATERIAL_CODE, updatedMaterial.get().getMaterialCode()); } else { return showEditPage( responseBuilder @@ -159,7 +160,7 @@ public class MaterialEditorController { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(ControllerUtils.redirect("material/editor/" + materialID)); Optional optionalMaterial = materialService.getByID(materialID); - if (!optionalMaterial.isPresent()) { + if (optionalMaterial.isEmpty()) { return chooseSIMDUTFile(modelResponseBuilder .addResponseCode(ResponseCode.MATERIAL_NOT_FOUND, materialID) .build(), diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MaterialTypeEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MaterialTypeEditorController.java index 60e572d..7de1750 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MaterialTypeEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MaterialTypeEditorController.java @@ -15,7 +15,7 @@ import org.springframework.web.servlet.ModelAndView; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller public class MaterialTypeEditorController { @@ -43,7 +43,7 @@ public class MaterialTypeEditorController { if (materialType.getMaterialTypeName() == null) { Optional optionalMaterialType = materialTypeService.getByID(materialTypeID); - if (!optionalMaterialType.isPresent()) { + if (optionalMaterialType.isEmpty()) { return listMaterialTypes( responseBuilder .addResponseCode(ResponseCode.MATERIAL_TYPE_NOT_FOUND, materialTypeID) @@ -62,32 +62,38 @@ public class MaterialTypeEditorController { @PostMapping(value = EDITOR_MATERIAL_TYPE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) public ModelAndView saveEditedMaterialType(MaterialType materialType) { ModelResponseBuilder responseBuilder = new ModelResponseBuilder(""); - int materialTypeID = materialType.getMaterialTypeID(); - if (!materialTypeService.getByID(materialTypeID).isPresent()) { - responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_NOT_FOUND, materialTypeID); - } else if (!materialTypeService.isValidForUpdateName(materialType)) { - return showEditPage( - responseBuilder - .addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST, materialType.getMaterialTypeName()) - .build(), - materialTypeID, materialType); - } else if (!materialTypeService.isValidForUpdatePrefix(materialType)) { - return showEditPage( - responseBuilder - .addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST_PREFIX, materialType.getPrefix()) - .build(), - materialTypeID, materialType); + // L'ID est 0 lors de la désérialisation, il faut utiliser le nom unique + String materialTypeName = materialType.getMaterialTypeName(); + Optional optionalMaterialType = materialTypeService.getByName(materialTypeName); + + if (optionalMaterialType.isEmpty()) { + responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_NOT_FOUND, materialTypeName); } else { - Optional updatedMaterialType = materialTypeService.update(materialType); - if (updatedMaterialType.isPresent()) { - responseBuilder.addResponseData(ResponseDataType.MATERIAL_TYPE_NAME, updatedMaterialType.get().getMaterialTypeName()); - } else { + materialType = optionalMaterialType.get(); + if (!materialTypeService.isValidForUpdateName(materialType)) { return showEditPage( responseBuilder - .addResponseCode(ResponseCode.ERROR_SAVING) + .addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST, materialType.getMaterialTypeName()) .build(), - materialTypeID, null); + materialType.getMaterialTypeID(), materialType); + } else if (!materialTypeService.isValidForUpdatePrefix(materialType)) { + return showEditPage( + responseBuilder + .addResponseCode(ResponseCode.MATERIAL_TYPE_ALREADY_EXIST_PREFIX, materialType.getPrefix()) + .build(), + materialType.getMaterialTypeID(), materialType); + } else { + Optional updatedMaterialType = materialTypeService.update(materialType); + if (updatedMaterialType.isPresent()) { + responseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_MATERIAL_TYPE, updatedMaterialType.get().getMaterialTypeName()); + } else { + return showEditPage( + responseBuilder + .addResponseCode(ResponseCode.ERROR_SAVING) + .build(), + materialType.getMaterialTypeID(), materialType); + } } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MixEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MixEditorController.java index ce347a2..cfdd9d5 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MixEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/MixEditorController.java @@ -3,9 +3,7 @@ package dev.fyloz.trial.colorrecipesexplorer.web.controller.editors; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseCode; import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; -import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; import dev.fyloz.trial.colorrecipesexplorer.core.model.Mix; -import dev.fyloz.trial.colorrecipesexplorer.core.model.MixType; import dev.fyloz.trial.colorrecipesexplorer.core.model.dto.MixCreationFormDto; import dev.fyloz.trial.colorrecipesexplorer.core.services.model.*; import dev.fyloz.trial.colorrecipesexplorer.core.utils.ControllerUtils; @@ -19,13 +17,10 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.servlet.ModelAndView; import javax.validation.Valid; -import java.util.Comparator; -import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; import static dev.fyloz.trial.colorrecipesexplorer.web.StringBank.*; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller public class MixEditorController { @@ -54,27 +49,18 @@ public class MixEditorController { * @return La page à afficher. */ @GetMapping(EDITOR_MIX_SPECIFIC) - public ModelAndView showPage(ModelAndView model, @PathVariable int mixID) { + public ModelAndView getPage(ModelAndView model, @PathVariable int mixID) { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(model) .withView(EDITOR_MIX_SPECIFIC.replaceAll("/\\{" + MIX_ID + "}", "")); Optional optionalMix = mixService.getByID(mixID); - if (!optionalMix.isPresent()) { + if (optionalMix.isEmpty()) { return modelResponseBuilder .withView(ControllerUtils.redirect(EDITOR_RECIPE)) .build(); } Mix mix = optionalMix.get(); - List associatedMixTypes = recipeService.getAssociatedMixesTypes(mix.getRecipe()); - // Récupère seulement les produits qui ne sont pas des types de mélange OU que ce type existe dans la recette - List materials = materialService - .getAll() - .stream() - .filter(m -> !m.isMixType() || (!m.equals(mix.getMixType().getMaterial()) && associatedMixTypes.contains(mixTypeService.getByMaterial(m).get()))) - .sorted(Comparator.comparing(Material::getMaterialCode)) - .sorted(Comparator.comparing(m -> m.getMaterialType().getMaterialTypeName())) - .collect(Collectors.toList()); return modelResponseBuilder .addResponseData(ResponseDataType.MIX, mix) @@ -82,7 +68,7 @@ public class MixEditorController { .addAttribute(MATERIAL_TYPE, mix.getMixType().getMaterial().getMaterialType()) .addAttribute(MATERIAL_TYPES, materialTypeService.getAll()) .addAttribute("mixJson", materialService.asJson(mix)) - .addAttribute("materialsJson", materialService.asJson(materials)) + .addAttribute("materialsJson", mixService.asJson(mixService.getAvailableMaterialsForMix(mix.getRecipe(), mix))) .build(); } @@ -108,10 +94,10 @@ public class MixEditorController { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(); Optional optionalMix = mixService.getByID(mixID); - if (!optionalMix.isPresent()) { + if (optionalMix.isEmpty()) { modelResponseBuilder.addResponseCode(ResponseCode.MIX_NOT_FOUND, mixID); - return showPage(modelResponseBuilder.build(), mixID); + return getPage(modelResponseBuilder.build(), mixID); } Mix mix = optionalMix.get(); @@ -119,7 +105,7 @@ public class MixEditorController { ModelResponseBuilder editResult = mixService.edit(mix, formDto); if (editResult != null) { - return showPage( + return getPage( modelResponseBuilder .addResponseCode(ResponseCode.ERROR_SAVING) .build(), @@ -134,8 +120,8 @@ public class MixEditorController { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(""); Optional optionalMix = mixService.getByID(mixID); - if (!optionalMix.isPresent()) { - return showPage(modelResponseBuilder + if (optionalMix.isEmpty()) { + return getPage(modelResponseBuilder .addResponseCode(ResponseCode.MIX_NOT_FOUND, mixID) .build(), mixID); @@ -147,7 +133,7 @@ public class MixEditorController { if (!mixService.deleteMix(mix)) { modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING); - return showPage(modelResponseBuilder.build(), mixID); + return getPage(modelResponseBuilder.build(), mixID); } return modelResponseBuilder.build(); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/RecipeEditorController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/RecipeEditorController.java index d26afc9..07ae314 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/RecipeEditorController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/editors/RecipeEditorController.java @@ -20,7 +20,7 @@ import org.springframework.web.servlet.ModelAndView; import java.util.ArrayList; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller public class RecipeEditorController { @@ -59,7 +59,7 @@ public class RecipeEditorController { if (recipe.getRecipeCode() == null || recipe.getCompany() == null) { Optional optionalRecipe = recipeService.getByID(recipeID); - if (!optionalRecipe.isPresent()) { + if (optionalRecipe.isEmpty()) { return listRecipes( modelResponseBuilder .addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeID) @@ -104,7 +104,7 @@ public class RecipeEditorController { int recipeID = recipe.getRecipeID(); Optional optionalStoredRecipe = recipeService.getByID(recipeID); - if (!optionalStoredRecipe.isPresent()) { + if (optionalStoredRecipe.isEmpty()) { return listRecipes( modelResponseBuilder .addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeID) @@ -113,7 +113,7 @@ public class RecipeEditorController { Optional optionalRecipe = recipeService.updateRecipe(recipe, optionalStoredRecipe.get(), form); if (optionalRecipe.isPresent()) { - modelResponseBuilder.addResponseData(ResponseDataType.RECIPE_CODE, optionalRecipe.get().getRecipeCode()); + modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_SAVING_RECIPE, optionalRecipe.get().getRecipeCode()); return listRecipes(modelResponseBuilder.build()); } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/ImageFilesController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java similarity index 93% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/ImageFilesController.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java index 9cef050..c6be16a 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/ImageFilesController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/ImageFilesController.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.web.controller; +package dev.fyloz.trial.colorrecipesexplorer.web.controller.files; import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; import dev.fyloz.trial.colorrecipesexplorer.core.io.file.ImageHandler; @@ -25,7 +25,7 @@ import java.io.IOException; import java.util.Map; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.*; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; @Controller public class ImageFilesController { @@ -67,7 +67,7 @@ public class ImageFilesController { * @return La page à afficher. */ @GetMapping(ADD_IMAGE_SPECIFIC) - public ModelAndView showPage(ModelAndView model, @PathVariable int recipeID) { + public ModelAndView getPage(ModelAndView model, @PathVariable int recipeID) { return new ModelResponseBuilder(model) .withView(ADD_IMAGE) .addResponseData(ResponseDataType.RECIPE_ID, recipeID) @@ -100,14 +100,14 @@ public class ImageFilesController { // Vérifie que le fichier est bien une image if (ImageIO.read(image.getInputStream()) == null) { - return showPage(modelResponseBuilder + return getPage(modelResponseBuilder .addResponseCode(ResponseCode.FILE_NOT_IMAGE) .build(), recipeID); } Optional optionalRecipe = recipeService.getByID(recipeID); - if (!optionalRecipe.isPresent()) { - return showPage(modelResponseBuilder + if (optionalRecipe.isEmpty()) { + return getPage(modelResponseBuilder .addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeID) .build(), recipeID); } @@ -115,7 +115,7 @@ public class ImageFilesController { Recipe recipe = optionalRecipe.get(); ImageHandler imageHandler = new ImageHandler(recipe, recipeService); if (!imageHandler.createFile()) { - return showPage(modelResponseBuilder + return getPage(modelResponseBuilder .addResponseCode(ResponseCode.ERROR_SAVING_IMAGE) .build(), recipeID); } @@ -133,7 +133,7 @@ public class ImageFilesController { ColorRecipesExplorerApplication.LOGGER.error("Erreur inconnue lors de la création d'une image", e); modelResponseBuilder.addResponseCode(ResponseCode.ERROR_SAVING_IMAGE); - return showPage(modelResponseBuilder.build(), recipeID); + return getPage(modelResponseBuilder.build(), recipeID); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/SIMDUTFilesController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/SIMDUTFilesController.java similarity index 87% rename from src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/SIMDUTFilesController.java rename to src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/SIMDUTFilesController.java index 0c2f046..f458681 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/SIMDUTFilesController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/SIMDUTFilesController.java @@ -1,4 +1,4 @@ -package dev.fyloz.trial.colorrecipesexplorer.web.controller; +package dev.fyloz.trial.colorrecipesexplorer.web.controller.files; import dev.fyloz.trial.colorrecipesexplorer.core.io.file.FileHandler; import dev.fyloz.trial.colorrecipesexplorer.core.model.Material; @@ -16,8 +16,8 @@ import org.springframework.web.bind.annotation.PostMapping; import javax.servlet.http.HttpServletRequest; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.CLOSE_TAB; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.SIMDUT_FILES; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.CLOSE_TAB; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.SIMDUT_FILES; @Controller public class SIMDUTFilesController { @@ -34,7 +34,7 @@ public class SIMDUTFilesController { Optional optionalMaterial = materialService.getByID(materialID); HttpHeaders headers = new HttpHeaders(); - if (!optionalMaterial.isPresent()) { + if (optionalMaterial.isEmpty()) { headers.add("Location", request.getHeader("referer")); return new ResponseEntity<>(headers, HttpStatus.FOUND); } @@ -53,7 +53,7 @@ public class SIMDUTFilesController { @PostMapping(SIMDUT_FILES) public ResponseEntity getFile(@PathVariable int materialID) { Optional optionalMaterial = materialService.getByID(materialID); - if (!optionalMaterial.isPresent()) return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); + if (optionalMaterial.isEmpty()) return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); FileHandler fileHandler = new FileHandler(String.format("%s_%s", materialID, optionalMaterial.get().getMaterialCode()), FileHandler.FileContext.SIMDUT, FileHandler.FileExtension.PDF); if (!fileHandler.isValid()) return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/TouchUpKitController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/TouchUpKitController.java new file mode 100644 index 0000000..581dd90 --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/TouchUpKitController.java @@ -0,0 +1,53 @@ +package dev.fyloz.trial.colorrecipesexplorer.web.controller.files; + +import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ModelResponseBuilder; +import dev.fyloz.trial.colorrecipesexplorer.core.io.response.ResponseDataType; +import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +import dev.fyloz.trial.colorrecipesexplorer.core.services.model.TouchUpKitService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.servlet.ModelAndView; + +import java.io.IOException; + +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.*; + +@Controller +public class TouchUpKitController { + + private TouchUpKitService touchUpKitService; + private RecipeService recipeService; + + @Autowired + public TouchUpKitController(TouchUpKitService touchUpKitService, RecipeService recipeService) { + this.touchUpKitService = touchUpKitService; + this.recipeService = recipeService; + } + + @GetMapping(TOUCHUP) + public ModelAndView getPage(ModelAndView model) { + return new ModelResponseBuilder(model) + .withView(TOUCHUP) + .addResponseData(ResponseDataType.RECIPE_MAP, recipeService.getRecipesByCompany()) + .build(); + } + + @PostMapping(value = TOUCHUP_PDF, produces = MediaType.APPLICATION_PDF_VALUE) + public ResponseEntity getTouchUpKitPdf(@RequestBody String jobNumber) throws IOException { + return new ResponseEntity<>(touchUpKitService.getPdfForJobNumber(jobNumber.replace("jobNumber=", "")), HttpStatus.FOUND); + } + + @PostMapping(value = TOUCHUP_PTOUCH) + public ModelAndView getTouchUpKitPtouch(@RequestBody String jobNumber) { + return new ModelResponseBuilder(TOUCHUP_PTOUCH_PAGE) + .addAttribute("jobNumber", jobNumber.replace("jobNumber=", "")) + .build(); + } + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/XlsExporterController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/XlsExporterController.java new file mode 100644 index 0000000..dabe9c9 --- /dev/null +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/files/XlsExporterController.java @@ -0,0 +1,89 @@ +package dev.fyloz.trial.colorrecipesexplorer.web.controller.files; + +import dev.fyloz.trial.colorrecipesexplorer.ColorRecipesExplorerApplication; +import dev.fyloz.trial.colorrecipesexplorer.core.model.Recipe; +import dev.fyloz.trial.colorrecipesexplorer.core.services.model.RecipeService; +import dev.fyloz.trial.colorrecipesexplorer.xlsx.XlsxExporter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +import javax.servlet.http.HttpServletRequest; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.Optional; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.ALL_RECIPES_XLS; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.RECIPE_XLS; + +// TODO Une grande partie du code de ce controlleur devrait se trouver dans un service +@Controller +public class XlsExporterController { + + private RecipeService recipeService; + + @Autowired + public XlsExporterController(RecipeService recipeService) { + this.recipeService = recipeService; + } + + @GetMapping(RECIPE_XLS) + public ResponseEntity getXlsForRecipe(HttpServletRequest request, @PathVariable int recipeID) { + HttpHeaders headers = new HttpHeaders(); + + Optional optionalRecipe = recipeService.getByID(recipeID); + if (optionalRecipe.isEmpty()) { + headers.add(HttpHeaders.LOCATION, request.getHeader("referer")); + return new ResponseEntity<>(headers, HttpStatus.FOUND); + } + + byte[] recipeXLS = new XlsxExporter().generate(optionalRecipe.get()); + if (recipeXLS.length <= 0) return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + + return ResponseEntity.ok() + .headers(headers) + .contentLength(recipeXLS.length) + .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) + .body(recipeXLS); + } + + @GetMapping(value = ALL_RECIPES_XLS, produces = "application/zip") + public ResponseEntity getAllXls() throws IOException { + HttpHeaders headers = new HttpHeaders(); + + ColorRecipesExplorerApplication.LOGGER.info("Exportation de toutes les couleurs en XLS"); + + ByteArrayOutputStream byteOS = new ByteArrayOutputStream(); + ZipOutputStream out = new ZipOutputStream(byteOS); + + Collection recipes = recipeService.getAll(); + for (Recipe recipe : recipes) { + byte[] recipeXLS = new XlsxExporter().generate(recipe); + if (recipeXLS.length <= 0) return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + + out.putNextEntry(new ZipEntry(String.format("%s_%s.xlsx", recipe.getCompany().getCompanyName(), recipe.getRecipeCode()))); + out.write(recipeXLS, 0, recipeXLS.length); + out.closeEntry(); + } + + out.close(); + + byte[] zipContent = byteOS.toByteArray(); + byteOS.close(); + + return ResponseEntity.ok() + .headers(headers) + .contentLength(zipContent.length) + .contentType(MediaType.parseMediaType("application/zip")) + .body(zipContent); + } + +} diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/CompanyRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/CompanyRemoverController.java index 09bef80..e8f01ba 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/CompanyRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/CompanyRemoverController.java @@ -14,8 +14,8 @@ import org.springframework.web.servlet.ModelAndView; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.REMOVER_COMPANY; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.REMOVER_COMPANY_SPECIFIC; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_COMPANY; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_COMPANY_SPECIFIC; @Controller public class CompanyRemoverController { @@ -37,7 +37,7 @@ public class CompanyRemoverController { * @return La page à afficher */ @GetMapping(REMOVER_COMPANY) - public ModelAndView showPage(ModelAndView model) { + public ModelAndView getPage(ModelAndView model) { return new ModelResponseBuilder(model) .withView(REMOVER_COMPANY) .addResponseData(ResponseDataType.COMPANIES, companyService.getAll()) @@ -78,6 +78,6 @@ public class CompanyRemoverController { modelResponseBuilder.addResponseCode(ResponseCode.COMPANY_NOT_FOUND, companyID); } - return showPage(modelResponseBuilder.build()); + return getPage(modelResponseBuilder.build()); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialRemoverController.java index 8e8f581..0541b0e 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialRemoverController.java @@ -15,8 +15,8 @@ import org.springframework.web.servlet.ModelAndView; import java.util.Optional; import java.util.stream.Collectors; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.REMOVER_MATERIAL; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.REMOVER_MATERIAL_SPECIFIC; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATERIAL; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATERIAL_SPECIFIC; @Controller public class MaterialRemoverController { @@ -35,7 +35,7 @@ public class MaterialRemoverController { * @return La page à afficher. */ @GetMapping(REMOVER_MATERIAL) - public ModelAndView showPage(ModelAndView model) { + public ModelAndView getPage(ModelAndView model) { return new ModelResponseBuilder(model) .withView(REMOVER_MATERIAL) .addResponseData(ResponseDataType.MATERIALS, materialService.getAll().stream().filter(m -> !m.isMixType()).collect(Collectors.toList())) @@ -65,13 +65,13 @@ public class MaterialRemoverController { ModelResponseBuilder responseBuilder = new ModelResponseBuilder(""); Optional optionalMaterial = materialService.getByID(materialID); - if (!optionalMaterial.isPresent()) { + if (optionalMaterial.isEmpty()) { responseBuilder.addResponseCode(ResponseCode.MATERIAL_NOT_FOUND, materialID); } else { Material material = optionalMaterial.get(); if (materialService.deleteIfNotLinked(material)) { - responseBuilder.addResponseData(ResponseDataType.MATERIAL_CODE, material.getMaterialCode()); + responseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_MATERIAL, material.getMaterialCode()); if (!materialService.removeSimdut(material)) { responseBuilder.addResponseCode(ResponseCode.ERROR_SAVING_SIMDUT); @@ -81,6 +81,6 @@ public class MaterialRemoverController { } } - return showPage(responseBuilder.build()); + return getPage(responseBuilder.build()); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialTypeRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialTypeRemoverController.java index facf9eb..720bfbc 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialTypeRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/MaterialTypeRemoverController.java @@ -14,8 +14,8 @@ import org.springframework.web.servlet.ModelAndView; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.REMOVER_MATERIAL_TYPE; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.REMOVER_MATERIAL_TYPE_SPECIFIC; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATERIAL_TYPE; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_MATERIAL_TYPE_SPECIFIC; @Controller public class MaterialTypeRemoverController { @@ -29,7 +29,7 @@ public class MaterialTypeRemoverController { } @GetMapping(REMOVER_MATERIAL_TYPE) - public ModelAndView showPage(ModelAndView model) { + public ModelAndView getPage(ModelAndView model) { return new ModelResponseBuilder(model) .withView(REMOVER_MATERIAL_TYPE) .addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll()) @@ -41,18 +41,18 @@ public class MaterialTypeRemoverController { ModelResponseBuilder responseBuilder = new ModelResponseBuilder(""); Optional optionalMaterialType = materialTypeService.getByID(materialTypeID); - if (!optionalMaterialType.isPresent()) { + if (optionalMaterialType.isEmpty()) { responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_NOT_FOUND, materialTypeID); } else { MaterialType materialType = optionalMaterialType.get(); if (materialTypeService.deleteIfNotLinked(materialType)) { - responseBuilder.addResponseData(ResponseDataType.MATERIAL_TYPE_NAME, materialType.getMaterialTypeName()); + responseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_MATERIAL_TYPE, materialType.getMaterialTypeName()); } else { responseBuilder.addResponseCode(ResponseCode.MATERIAL_TYPE_LINKED, materialType.getMaterialTypeName()); } } - return showPage(responseBuilder.build()); + return getPage(responseBuilder.build()); } } diff --git a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/RecipeRemoverController.java b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/RecipeRemoverController.java index 2bbc64c..91f020c 100644 --- a/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/RecipeRemoverController.java +++ b/src/main/java/dev/fyloz/trial/colorrecipesexplorer/web/controller/removers/RecipeRemoverController.java @@ -13,8 +13,8 @@ import org.springframework.web.servlet.ModelAndView; import java.util.Optional; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.REMOVER_RECIPE; -import static dev.fyloz.trial.colorrecipesexplorer.web.PagesPaths.REMOVER_RECIPE_SPECIFIC; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_RECIPE; +import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.REMOVER_RECIPE_SPECIFIC; @Controller public class RecipeRemoverController { @@ -62,7 +62,7 @@ public class RecipeRemoverController { ModelResponseBuilder modelResponseBuilder = new ModelResponseBuilder(""); Optional optionalRecipe = recipeService.getByID(recipeID); - if (!optionalRecipe.isPresent()) { + if (optionalRecipe.isEmpty()) { return listRecipes( modelResponseBuilder .addResponseCode(ResponseCode.RECIPE_NOT_FOUND, recipeID) @@ -77,7 +77,7 @@ public class RecipeRemoverController { .build()); } - modelResponseBuilder.addResponseData(ResponseDataType.RECIPE_CODE, recipe.getRecipeCode()); + modelResponseBuilder.addResponseCode(ResponseCode.SUCCESS_DELETING_RECIPE, recipe.getRecipeCode()); return listRecipes(modelResponseBuilder.build()); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 05c2ad6..f7385a0 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -24,6 +24,8 @@ spring: web-allow-others: true server: port: 9090 + http2: + enabled: true error: whitelabel: enabled: false diff --git a/src/main/resources/fonts/arialbd.ttf b/src/main/resources/fonts/arialbd.ttf new file mode 100644 index 0000000..d0d857e Binary files /dev/null and b/src/main/resources/fonts/arialbd.ttf differ diff --git a/src/main/resources/lang/messages_en.properties b/src/main/resources/lang/messages_en.properties index 5aa7c36..7e6c412 100644 --- a/src/main/resources/lang/messages_en.properties +++ b/src/main/resources/lang/messages_en.properties @@ -1,105 +1,118 @@ -company.form.companyName=Banner name -menu.explore=Explore -menu.add=Add -menu.edit=Edit -menu.delete=Delete -menu.inventory=Inventory -menu.others=Others -recipe.color=Color -recipe.description=Description -recipe.sample=Sample -recipe.approbationDate=Approbation date -recipe.remark=Remark -recipe.notice=Notice -recipe.steps=Steps -keyword.company=Banner -keyword.material=Material -keyword.recipe=Recipe -keyword.touchUpKitPDF=Touch Up Kit PDF -keyword.quantity=Quantity -keyword.type=Type -keyword.units=Units -keyword.edit=Edit -keyword.use=Use -keyword.save=Save -keyword.back=Back -mix.location=Location -material.code=Code -material.inventoryQuantity=Inventory quantity -material.type=Material type -material.simdutFile=SIMDUT File -units.milliliters=Milliliters -units.liters=Liters -units.gallons=Gallons -inventory.lowQuantity=Low quantity -inventory.hideOthers=Hide other materials -inventory.showOnly=Show only -material.error.anyFound=No materials were found. app.title=Color recipes explorer -footer.lang=Voir en français -company.add.title=Adding a banner -company.success.created=The banner {0} has been saved. -keyword.see=See -company.error.anyFound=No banners were found. -recipe.warning.notApproved=This recipe is not approved +company.add.title=Add a banner company.delete.title=Delete banners +company.error.anyFound=No banners were found. +company.form.companyName=Banner name +company.success.created=The banner {0} has been saved. company.success.deleted=The banner {0} has been deleted. -keyword.delete=Delete -material.add.title=Adding a material -material.success.created=The material {0} has been saved. -material.editing.title=Editing {0} -material.delete.title=Delete materials -material.success.deleted=The material {0} has been deleted. -material.success.saved=The material {0} has been saved. -material.edit.title=Edit materials -material.simdut.choose=Choose material's SIMDUT file -materialType.add.title=Add a material type -materialType.name=Name -materialType.prefix=Prefix -keyword.characters=characters -materialType.usePercents=Use percentages -image.add.title=Add an image -mix.add.title=Adding a banner -mix.add.subtitle=Adding a mix for the recipe {0} -mix.mixType=Mix type -keyword.remove=Remove -mix.edit.title=Editing a mix -mix.edit.subtitle=Editing a mix for the recipe {0} ({1}) -password.ask=What is your password? -password.notValid=Your password is not valid error.serverError=An error occurred while sending data to the server. -recipe.add.title=Add a recipe -recipe.sucess.saved=The recipe {0} has been saved. You can now add ingredients. -keyword.continue=Continue -recipe.editing.title=Editing {0} -recipe.edit.addMix=Add a mix -recipe.edit.addImage=Add an image -recipe.success.edit=The recipe {0} has been saved. -recipe.edit.title=Edit a recipe -recipe.explore.title={0} color -recipe.warning.notApproved.short=Not approved -recipe.image.corrupted=Image deleted or corrupted -recipe.delete.title=Delete recipes -recipe.success.deleted=The recipe {0} has been deleted. -keyword.search=Search -materialType.editor.title=Edit material types -materialType.editing.title=Editing {0} -keyword.id=ID -materialType.success.saved=The material type {0} has been saved. -materialType.delete.title=Delete material types -materialType.success.deleted=The material type {0} has been deleted. -materialType.error.anyFound=Any material type has been found. -keyword.calculation=Calculation -recipe.error.anyFound=No recipes were found. -recipe.exportAllXLS=Export all colors (XLSX) -recipe.xlsVersion=XLSX version -keyword.updates=Updates history -material.simdutFile.notFound=No SIMDUT file found -recipe.warning.changesNotSaved=Changes are not saved -recipe.warning.exportAll=Do you really want to export all the colors? This can take some times and slow down the application. -warning.noResult=Nothing corresponding the the research was found +footer.lang=Voir en français +image.add.title=Add an image inventory.askUseMix=Do you really want to deduct this mix from the inventory? inventory.askUseRecipe=Do you really want to deduct this recipe from the inventory? +inventory.hideOthers=Hide other materials +inventory.lowQuantity=Low quantity +inventory.showOnly=Show only +keyword.back=Back +keyword.calculation=Calculation +keyword.cancel=Cancel +keyword.characters=characters +keyword.company=Banner +keyword.continue=Continue +keyword.delete=Delete +keyword.edit=Edit +keyword.id=ID keyword.images=Images -warning.askChangePage=Are you sure you want to continue? Unsaved changes will be lost. +keyword.material=Material +keyword.pdf=PDF keyword.print=Print +keyword.ptouch=P-touch +keyword.ptouchTemplate=P-touch templates +keyword.quantity=Quantity +keyword.recipe=Recipe +keyword.remove=Remove +keyword.save=Save +keyword.search=Search +keyword.see=See +keyword.type=Type +keyword.units=Units +keyword.updates=Updates history +keyword.use=Use +material.add.title=Add a material +material.code=Code +material.delete.title=Delete materials +material.edit.title=Edit materials +material.editing.title=Editing {0} +material.error.anyFound=No materials were found. +material.inventoryQuantity=Inventory quantity +material.simdut.choose=Choose material's SIMDUT file +material.simdut.error.notFound=No SIMDUT file found +material.simdut=SIMDUT File +material.success.created=The material {0} has been saved. +material.success.deleted=The material {0} has been deleted. +material.success.saved=The material {0} has been saved. +material.type=Material type +materialType.add.title=Add a material type +materialType.delete.title=Delete material types +materialType.editing.title=Editing {0} +materialType.editor.title=Edit material types +materialType.error.anyFound=Any material type has been found. +materialType.name=Name +materialType.prefix=Prefix +materialType.success.deleted=The material type {0} has been deleted. +materialType.success.saved=The material type {0} has been saved. +materialType.usePercents=Use percentages +menu.add=Add +menu.delete=Delete +menu.edit=Edit +menu.explore=Explore +menu.inventory=Inventory +menu.others=Others +mix.add.subtitle=Add a mix for the recipe {0} +mix.add.title=Add a banner +mix.edit.subtitle=Editing a mix for the recipe {0} ({1}) +mix.edit.title=Editing a mix +mix.location=Location +mix.mixType=Mix type +password.ask=What is your password? +password.notValid=Your password is not valid +recipe.add.title=Add a recipe +recipe.approbationDate=Approbation date +recipe.color=Color +recipe.delete.title=Delete recipes +recipe.description=Description +recipe.edit.addImage=Add an image +recipe.edit.addMix=Add a mix +recipe.edit.title=Edit a recipe +recipe.editing.title=Editing {0} +recipe.error.anyFound=No recipes were found. +recipe.explore.title={0} color +recipe.exportAllXLS=Export all colors (XLSX) +recipe.image.corrupted=Image deleted or corrupted +recipe.notice=Notice +recipe.print.confirm=Are you sure you want to print this mix? +recipe.print.error.bpacNotInstalled=BPac is not installed +recipe.print.error.noBase=There is no base in this mix +recipe.print.error=An error occurred while printing +recipe.print.printing=Printing in progress. This may take a few seconds. +recipe.print.status.error=The b-Pac extension is not installed +recipe.print.status.ok=The b-Pac extension is installed +recipe.remark=Remark +recipe.sample=Sample +recipe.steps=Steps +recipe.success.deleted=The recipe {0} has been deleted. +recipe.success.edit=The recipe {0} has been saved. +recipe.sucess.saved=The recipe {0} has been saved. You can now add ingredients. +recipe.touchup.title=Touch-up kit labels +recipe.touchup=Touch-up kit labels +recipe.warning.changesNotSaved=Changes are not saved +recipe.warning.exportAll=Do you really want to export all the colors? This can take some times and slow down the application. +recipe.warning.notApproved.short=Not approved +recipe.warning.notApproved=This recipe is not approved +recipe.xlsVersion=XLSX version +units.gallons=Gallons +units.liters=Liters +units.milliliters=Milliliters +warning.askChangePage=Are you sure you want to continue? Unsaved changes will be lost. +warning.noResult=Search returned no results +keyword.jobNumber=Job number diff --git a/src/main/resources/lang/messages_fr.properties b/src/main/resources/lang/messages_fr.properties index 57f87e0..48680ef 100644 --- a/src/main/resources/lang/messages_fr.properties +++ b/src/main/resources/lang/messages_fr.properties @@ -1,106 +1,118 @@ -menu.explore=Explorer -menu.add=Ajouter -menu.edit=Modifier -menu.delete=Supprimer -menu.inventory=Inventaire -menu.others=Autres -recipe.color=Couleur -recipe.description=Description -recipe.sample=Échantillon -recipe.approbationDate=Date d'approbation -recipe.remark=Remarque -recipe.notice=Note -recipe.steps=Étapes -keyword.company=Bannière -keyword.material=Produit -keyword.recipe=Recette -keyword.touchUpKitPDF=PDF Kits de retouche -keyword.quantity=Quantité -keyword.type=Type -keyword.units=Unités -keyword.edit=Modifier -keyword.use=Utiliser -keyword.save=Enregistrer -keyword.back=Retour -keyword.delete=Supprimer -mix.location=Position -material.code=Code -material.inventoryQuantity=Quantité en inventaire -material.type=Type de produit -material.simdutFile=Fichier SIMDUT -units.milliliters=Millilitres -units.liters=Litres -units.gallons=Gallons -inventory.lowQuantity=Quantité faible -inventory.hideOthers=Cacher les autres produits -inventory.showOnly=Voir seulement -material.error.anyFound=Aucun produit n'a été trouvé. app.title=Explorateur de recettes de couleur -footer.lang=See in english company.add.title=Ajout d'une bannière -company.success.created=La bannière {0} à été enregistrée. -company.form.companyName=Nom de la bannière -keyword.see=Voir -company.error.anyFound=Aucune bannière n'a été trouvée. -recipe.warning.notApproved=Cette recette n'est pas approuvée company.delete.title=Supprimer des bannières +company.error.anyFound=Aucune bannière n'a été trouvée. +company.form.companyName=Nom de la bannière +company.success.created=La bannière {0} à été enregistrée. company.success.deleted=La bannière {0} a bien été supprimée. -material.add.title=Ajout d'un produit -material.success.created=Le produit {0} a été enregistré. -material.editing.title=Modification de {0} -material.delete.title=Supprimer des produits -material.success.deleted=Le produit {0} a bien été supprimée. -material.success.saved=Le produit {0} a bien été sauvegardé. -material.edit.title=Modifer des produits -material.simdut.choose=Choisissez le fichier SIMDUT du produit -materialType.add.title=Ajout d'un type de produit -materialType.name=Nom -materialType.prefix=Préfix -keyword.characters=caractères -materialType.usePercents=Utiliser les pourcentages -image.add.title=Ajout une image -mix.add.title=Ajout d'un mélange -mix.add.subtitle=Ajout d''un mélange pour la recette {0} -mix.mixType=Type de mélange -keyword.remove=Retirer -mix.edit.title=Modifier un mélange -mix.edit.subtitle=Modifier un mélange pour la recette {0} ({1}) -password.ask=Quel est votre mot de passe? -password.notValid=Votre mot de passe n'est pas valide error.serverError=Une erreur est survenue lors de l'envoie des informations vers le serveur. -recipe.add.title=Ajout d'une recette -recipe.sucess.saved=La recette {0} à été enregistrée. Vous pouvez maintenant ajouter les ingrédients. -keyword.continue=Continuer -recipe.editing.title=Modification de {0} -recipe.edit.addMix=Ajouter un mélange -recipe.edit.addImage=Ajouter une image -recipe.success.edit=La recette {0} a bien été sauvegardée. -recipe.edit.title=Modifier une recette -recipe.explore.title=Couleur {0} -recipe.warning.notApproved.short=Non approuvée -recipe.image.corrupted=Image supprimée ou corrompue -recipe.delete.title=Supprimer des recettes -recipe.success.deleted=La recette {0} a bien été supprimée. -keyword.search=Rechercher -materialType.editor.title=Modifier un type de produit -materialType.editing.title=Modification de {0} -keyword.id=Identifiant -materialType.success.saved=Le type de produit {0} a bien été sauvegardé. -materialType.delete.title=Supprimer des types de produit -materialType.success.deleted=Le type de produit {0} a bien été supprimé. -materialType.error.anyFound=Aucun type de produit n'a été trouvé. -keyword.calculation=Calcul -recipe.error.anyFound=Aucune recette n'a été trouvée. -recipe.exportAllXLS=Exporter toutes les couleurs (XLSX) -recipe.xlsVersion=Version XLSX -keyword.updates=Historique des mises à jour -material.simdutFile.notFound=Aucun fichier SIMDUT trouvé -recipe.warning.changesNotSaved=Des modifications ne sont pas sauvegardées -recipe.warning.exportAll=Voulez-vous vraiment exporter toutes les couleurs? Cela peut prendre un certain temps et ralentir l'application. -warning.noResult=Rien correspondant à la recherche n'a été trouvé +footer.lang=See in english +image.add.title=Ajout une image inventory.askUseMix=Êtes-vous certain de vouloir déduire ce mélange de l'inventaire? inventory.askUseRecipe=Êtes-vous certain de vouloir déduire cette recette de l'inventaire? +inventory.hideOthers=Cacher les autres produits +inventory.lowQuantity=Quantité faible +inventory.showOnly=Voir seulement +keyword.back=Retour +keyword.calculation=Calcul +keyword.cancel=Annuler +keyword.characters=caractères +keyword.company=Bannière +keyword.continue=Continuer +keyword.delete=Supprimer +keyword.edit=Modifier +keyword.id=Identifiant keyword.images=Images -warning.askChangePage=Êtes-vous sûr de vouloir continuer? Les modifications non enregistrées seront perdues. +keyword.material=Produit +keyword.pdf=PDF keyword.print=Imprimer - +keyword.ptouch=P-touch +keyword.ptouchTemplate=Modèles P-touch +keyword.quantity=Quantité +keyword.recipe=Recette +keyword.remove=Retirer +keyword.save=Enregistrer +keyword.search=Rechercher +keyword.see=Voir +keyword.type=Type +keyword.units=Unités +keyword.updates=Historique des mises à jour +keyword.use=Utiliser +material.add.title=Ajout d'un produit +material.code=Code +material.delete.title=Supprimer des produits +material.edit.title=Modifer des produits +material.editing.title=Modification de {0} +material.error.anyFound=Aucun produit n'a été trouvé. +material.inventoryQuantity=Quantité en inventaire +material.simdut.choose=Choisissez le fichier SIMDUT du produit +material.simdut.error.notFound=Aucun fichier SIMDUT trouvé +material.simdut=Fichier SIMDUT +material.success.created=Le produit {0} a été enregistré. +material.success.deleted=Le produit {0} a bien été supprimée. +material.success.saved=Le produit {0} a bien été sauvegardé. +material.type=Type de produit +materialType.add.title=Ajout d'un type de produit +materialType.delete.title=Supprimer des types de produit +materialType.editing.title=Modification de {0} +materialType.editor.title=Modifier un type de produit +materialType.error.anyFound=Aucun type de produit n'a été trouvé. +materialType.name=Nom +materialType.prefix=Préfix +materialType.success.deleted=Le type de produit {0} a bien été supprimé. +materialType.success.saved=Le type de produit {0} a bien été sauvegardé. +materialType.usePercents=Utiliser les pourcentages +menu.add=Ajouter +menu.delete=Supprimer +menu.edit=Modifier +menu.explore=Explorer +menu.inventory=Inventaire +menu.others=Autres +mix.add.subtitle=Ajout d''un mélange pour la recette {0} +mix.add.title=Ajout d'un mélange +mix.edit.subtitle=Modifier un mélange pour la recette {0} ({1}) +mix.edit.title=Modifier un mélange +mix.location=Position +mix.mixType=Type de mélange +password.ask=Quel est votre mot de passe? +password.notValid=Votre mot de passe n'est pas valide +recipe.add.title=Ajout d'une recette +recipe.approbationDate=Date d'approbation +recipe.color=Couleur +recipe.delete.title=Supprimer des recettes +recipe.description=Description +recipe.edit.addImage=Ajouter une image +recipe.edit.addMix=Ajouter un mélange +recipe.edit.title=Modifier une recette +recipe.editing.title=Modification de {0} +recipe.error.anyFound=Aucune recette n'a été trouvée. +recipe.explore.title=Couleur {0} +recipe.exportAllXLS=Exporter toutes les couleurs (XLSX) +recipe.image.corrupted=Image supprimée ou corrompue +recipe.notice=Note +recipe.print.confirm=Voulez-vous vraiment imprimer ce mélange? +recipe.print.error.bpacNotInstalled=BPac n'est pas installé +recipe.print.error.noBase=Il n'y a pas de base dans ce mélange +recipe.print.error=Une erreur est survenue pendant l'impression +recipe.print.printing=Impression en cours. Cette opération peut prendre quelques secondes. +recipe.print.status.error=L'extension b-Pac n'est pas installée +recipe.print.status.ok=L'extension b-Pac est installée +recipe.remark=Remarque +recipe.sample=Échantillon +recipe.steps=Étapes +recipe.success.deleted=La recette {0} a bien été supprimée. +recipe.success.edit=La recette {0} a bien été sauvegardée. +recipe.sucess.saved=La recette {0} à été enregistrée. Vous pouvez maintenant ajouter les ingrédients. +recipe.touchup.title=Étiquettes de kit de retouche +recipe.touchup=Étiquettes de kit de retouche +recipe.warning.changesNotSaved=Des modifications ne sont pas sauvegardées +recipe.warning.exportAll=Voulez-vous vraiment exporter toutes les couleurs? Cela peut prendre un certain temps et ralentir l'application. +recipe.warning.notApproved.short=Non approuvée +recipe.warning.notApproved=Cette recette n'est pas approuvée +recipe.xlsVersion=Version XLSX +units.gallons=Gallons +units.liters=Litres +units.milliliters=Millilitres +warning.askChangePage=Êtes-vous sûr de vouloir continuer? Les modifications non enregistrées seront perdues. +warning.noResult=La recherche n'a donné aucun résultat +keyword.jobNumber=Numéro de job diff --git a/src/main/resources/lang/responses_en.properties b/src/main/resources/lang/responses_en.properties index a3188aa..41f63b1 100644 --- a/src/main/resources/lang/responses_en.properties +++ b/src/main/resources/lang/responses_en.properties @@ -1,22 +1,22 @@ -response.1=The quantities of each material used have been deducted from the inventory +response.1=The quantities of used materials have been deducted from the inventory response.10=There is already a material with the code {0} response.11=There is already a material type named {0} -response.12=Any banner with the ID {0} has been found +response.12=No banner with the ID {0} has been found response.13=There is already a banner named {0} response.14=The material {0} is linked to one or more recipes, edit them first response.15=The banner {0} is linked to one or more recipes, delete them first response.16=The mix with the ID {0} is not linked to the recipe with the ID {1} response.17=There is not enough {0} in inventory for this recipe response.18=This recipe already contains a mix of the type {0} -response.19=Any material type with the ID {0} has been found +response.19=No material type with the name {0} has been found response.2=The recipe's informations have been saved response.3=An error has occurred while saving response.4=An error has occurred while saving the image response.5=An error has occurred while saving the SIMDUT file response.6=Your password is not valid -response.7=Any recipe with the ID {0} has been found -response.8=Any mix with the ID {0} has been found -response.9=Any material with the ID {0} has been found +response.7=No recipe with the ID {0} has been found +response.8=No mix with the ID {0} has been found +response.9=No material with the ID {0} has been found response.20=There is already a material type with the prefix {0} response.21=The material type {0} is linked to one or more materials, delete them first. response.101=The requested page could not be found @@ -28,3 +28,10 @@ response.24=This file need to be an image response.25=The recipe was not found response.26=The material with the code {0} was not found response.27=The banner {0} has been delete +response.28=The material {0} has been saved +response.29=The material type {0} has been saved +response.30=The recipe for the color {0} has been saved +response.31=The material {0} has been deleted +response.32=The banner {0} has been saved +response.33=The recipe {0} has been deleted +response.34=The material type {0} has been deleted diff --git a/src/main/resources/lang/responses_fr.properties b/src/main/resources/lang/responses_fr.properties index dfa5e68..e0e061f 100644 --- a/src/main/resources/lang/responses_fr.properties +++ b/src/main/resources/lang/responses_fr.properties @@ -1,4 +1,4 @@ -response.1=Les quantités de chaque produits utilisés ont été déduites de l'inventaire +response.1=Les quantités des produits utilisés ont été déduites de l'inventaire response.10=Il y a déjà un produit ayant le code {0} response.11=Il y a déjà un type de produit s''appellant {0} response.12=Aucune bannière ayant l''identifiant {0} n''a été trouvée @@ -8,7 +8,7 @@ response.15=La bannière {0} est liée à une ou plusieurs recettes, veuillez le response.16=Le mélange ayant l''identifiant {0} n''est pas associé à la recette ayant l''identifiant {1} response.17=Il n''y a pas assez de {0} en inventaire pour cette recette response.18=Cette recette contient déjà un mélange du type {0} -response.19=Aucun type de produit ayant l''identifiant {0} n''a été trouvée +response.19=Aucun type de produit ayant le nom {0} n''a été trouvée response.2=Les informations de la recette ont été sauvegardées response.3=Une erreur est survenue lors de l''enregistrement response.4=Une erreur est survenue lors de l'enregistrement de l'image @@ -28,3 +28,10 @@ response.24=Ce fichier doit être une image response.25=La recette n'a pas été trouvée response.26=Le produit ayant le code {0} n''a pas été trouvé response.27=La bannière {0} a bien été supprimée +response.28=Le produit {0} a bien été sauvegardé +response.29=Le type de produit {0} a bien été sauvegardé +response.30=La recette pour la couleur {0} a bien été sauvegardée +response.31=Le produit {0} a bien été supprimée +response.32=La bannière {0} a bien été sauvegardée +response.33=La recette {0} a bien été supprimée +response.34=Le type de produit {0} a bien été supprimé diff --git a/src/main/resources/static/bpac.xpi b/src/main/resources/static/bpac.xpi new file mode 100644 index 0000000..1941857 Binary files /dev/null and b/src/main/resources/static/bpac.xpi differ diff --git a/src/main/resources/static/css/main.css b/src/main/resources/static/css/main.css index 3b6f84c..049e1a7 100644 --- a/src/main/resources/static/css/main.css +++ b/src/main/resources/static/css/main.css @@ -4,6 +4,10 @@ body { overflow-x: hidden; } +* { + transition: all .1s; +} + h1 { text-decoration: underline; } @@ -73,18 +77,6 @@ textarea { padding: 10px; } -/*.error {*/ -/* color: red;*/ -/*}*/ - -/*.success {*/ -/* color: green;*/ -/*}*/ - -/*.error, .success {*/ -/* font-weight: bold;*/ -/*}*/ - table { border-collapse: collapse; } @@ -129,49 +121,82 @@ table:not(.noStyle) tr:nth-child(odd) { width: 150px; } -.errorBox { - background-color: #ef9a9a; - color: #e53935; - font-weight: bold; -} - -.successBox { - background-color: #a5d6a7; - color: #4caf50; - font-weight: bold; -} - -.warningBox { - background-color: #fff59d; - color: #fdd835; - font-weight: bold; -} - .messageBox { - display: inline-block; - margin: 20px auto auto; + display: none; + position: fixed; + top: -20px; + left: 50%; + transform: translateX(-50%); } .messageBox .messageBoxContainer { display: inline-block; - height: 24px; padding: 16px; - text-align: left; } -.messageBox .messageBoxInnerBox { - display: inline-block; - height: 24px; +.messageBox .messageBoxMessageContainer { + display: flex; + flex-direction: row; + position: relative; + vertical-align: center; + align-items: center; + text-align: center; } .messageBox img { - float: left; + width: 24px; + height: 24px; } .messageBox p { - display: inline-block; - margin: 0 0 0 16px; - line-height: 24px; + font-weight: bold; + margin: 0 0 0 20px; + width: 100%; +} + +#errorBox { + background-color: #ef9a9a; + color: #e53935; +} + +#successBox { + background-color: #a5d6a7; + color: #4caf50; +} + +#warningBox { + background-color: #fff59d; + color: #fdd835; +} + +#confirmBox, #promptBox { + background-color: #90caf9; + color: #1e88e5; + height: 75px; + z-index: 60; +} + +#promptBox { + height: 110px; +} + +.confirmButtonsContainer button { + margin: 0 60px; +} + +.confirmButtonsContainer { + display: flex; + flex-direction: row; + margin: 5px 0; + justify-content: center; +} + +.confirmInputContainer input { + width: 90%; + background-color: white; + padding: 2px 0; + margin: 10px 5% 2px; + text-align: left !important; } .subtitle { @@ -205,3 +230,14 @@ table:not(.noStyle) tr:nth-child(odd) { .submitButton { float: right; } + +#filter { + display: none; + background-color: black; + width: 100%; + height: 100%; + position: fixed; + top: 0; + opacity: 0; + z-index: 50; +} diff --git a/src/main/resources/static/css/menu.css b/src/main/resources/static/css/menu.css index c330a6d..6845286 100644 --- a/src/main/resources/static/css/menu.css +++ b/src/main/resources/static/css/menu.css @@ -4,24 +4,46 @@ header, footer { text-align: center; width: 100%; color: white; + position: fixed; + z-index: 99; +} + +header { + top: 0; + display: flex; + background-color: black; +} + +header .spacer { + width: 100%; +} + +header a:hover, .dropdown:hover .dropbtn { + background-color: #0d0d0d; +} + +header .header-right { + display: flex; + flex-direction: row; +} + +header #printStatusIcon { + margin-right: 20px; +} + +nav { + display: flex; + flex-direction: row; } footer { - position: fixed; height: 5%; bottom: 0; padding-top: 10px; } -nav img { - margin-left: auto; -} - -nav { - display: flex; - flex-wrap: wrap; - overflow: visible; - background-color: inherit; +section { + margin-top: 100px; } nav a { @@ -50,10 +72,6 @@ nav a { margin: 0; } -nav a:hover, .dropdown:hover .dropbtn { - background-color: #0d0d0d; -} - .dropdown-content { display: none; position: absolute; @@ -81,7 +99,7 @@ nav a:hover, .dropdown:hover .dropbtn { } @media only screen and (max-width: 702px) { - nav img { + header img { display: none; } } diff --git a/src/main/resources/static/icons/confirm.svg b/src/main/resources/static/icons/confirm.svg new file mode 100644 index 0000000..4afca3c --- /dev/null +++ b/src/main/resources/static/icons/confirm.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/src/main/resources/static/icons/error.svg b/src/main/resources/static/icons/error.svg index 3eaebfb..2047e73 100644 --- a/src/main/resources/static/icons/error.svg +++ b/src/main/resources/static/icons/error.svg @@ -2,5 +2,5 @@ + d="M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z"/> diff --git a/src/main/resources/static/icons/printer.svg b/src/main/resources/static/icons/printer.svg new file mode 100644 index 0000000..438787e --- /dev/null +++ b/src/main/resources/static/icons/printer.svg @@ -0,0 +1,6 @@ + + + + + diff --git a/src/main/resources/static/icons/printerError.svg b/src/main/resources/static/icons/printerError.svg new file mode 100644 index 0000000..3d4c025 --- /dev/null +++ b/src/main/resources/static/icons/printerError.svg @@ -0,0 +1,6 @@ + + + + + diff --git a/src/main/resources/static/js/bpac.js b/src/main/resources/static/js/bpac.js new file mode 100644 index 0000000..8d2cbd7 --- /dev/null +++ b/src/main/resources/static/js/bpac.js @@ -0,0 +1,1182 @@ +var n = n || {}; +n.appendMessage = n => { + const t = new CustomEvent("bpac_send", {detail: n}); + document.dispatchEvent(t) +}; +const t = "Can't connect to b-PAC"; + +export class IObject { + constructor(n) { + this.p_ = n + } + + GetAttribute(i) { + const r = "IObject::GetAttribute", u = {method: r, p: this.p_, kind: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : f.detail.ret == !1 ? n() : n(f.detail.attribute) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + GetData(i) { + const r = "IObject::GetData", u = {method: r, p: this.p_, kind: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : f.detail.ret == !1 ? n() : n(f.detail.data) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + GetFontBold() { + const i = "IObject::GetFontBold", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.connect == !1 ? r(t) : n(f.detail.ret) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetFontEffect() { + const i = "IObject::GetFontEffect", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.effect) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetFontItalics() { + const i = "IObject::GetFontItalics", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.connect == !1 ? r(t) : n(f.detail.ret) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetFontMaxPoint() { + const i = "IObject::GetFontMaxPoint", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.point) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetFontName() { + const i = "IObject::GetFontName", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.name) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetFontStrikeout() { + const i = "IObject::GetFontStrikeout", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.connect == !1 ? r(t) : n(f.detail.ret) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetFontUnderline() { + const i = "IObject::GetFontUnderline", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.connect == !1 ? r(t) : n(f.detail.ret) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + SetAlign(i, r) { + const u = "IObject::SetAlign", f = {method: u, p: this.p_, horizontal: i, vertical: r}, + e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + SetAttribute(i, r) { + const u = "IObject::SetAttribute", f = {method: u, p: this.p_, kind: i, attribute: r}, + e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + SetData(i, r, u) { + let e; + const o = Object.prototype.toString.call(r).slice(8, -1); + e = o === "Date" ? r.getTime() / 1e3 : r; + const f = "IObject::SetData", s = {method: f, p: this.p_, kind: i, data: e, param: u}, + h = new Promise((n, i) => { + const r = u => { + document.removeEventListener(f, r), u.detail.connect == !1 ? i(t) : n(u.detail.ret) + }; + document.addEventListener(f, r) + }); + return n.appendMessage(s), h + } + + SetFontBold(i) { + const r = "IObject::SetFontBold", u = {method: r, p: this.p_, bold: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + SetFontEffect(i) { + const r = "IObject::SetFontEffect", u = {method: r, p: this.p_, effect: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + SetFontItalics(i) { + const r = "IObject::SetFontItalics", u = {method: r, p: this.p_, italics: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + SetFontMaxPoint(i) { + const r = "IObject::SetFontMaxPoint", u = {method: r, p: this.p_, point: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + SetFontName(i) { + const r = "IObject::SetFontName", u = {method: r, p: this.p_, name: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + SetFontStrikeout(i) { + const r = "IObject::SetFontStrikeout", u = {method: r, p: this.p_, strikeout: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + SetFontUnderline(i) { + const r = "IObject::SetFontUnderline", u = {method: r, p: this.p_, underline: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + SetPosition(i, r, u, f) { + const e = "IObject::SetPosition", o = {method: e, p: this.p_, x: i, y: r, width: u, height: f}, + s = new Promise((n, i) => { + const r = u => { + document.removeEventListener(e, r), u.detail.connect == !1 ? i(t) : n(u.detail.ret) + }; + document.addEventListener(e, r) + }); + return n.appendMessage(o), s + } + + SetSelection(i, r) { + const u = "IObject::SetPosition", f = {method: u, p: this.p_, start: i, end: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + get Height() { + const i = "IObject::GetHeight", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.height) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set Height(t) { + const i = {method: "IObject::SetHeight", p: this.p_, height: t}; + n.appendMessage(i) + } + + get HorizontalAlign() { + const i = "IObject::GetHorizontalAlign", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.align) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set HorizontalAlign(t) { + const i = {method: "IObject::SetHorizontalAlign", p: this.p_, align: t}; + n.appendMessage(i) + } + + get Name() { + const i = "IObject::GetName", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.name) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set Name(t) { + const i = {method: "IObject::SetName", p: this.p_, name: t}; + n.appendMessage(i) + } + + get Orientation() { + const i = "IObject::GetOrientation", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.orientation) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set Orientation(t) { + const i = {method: "IObject::SetOrientation", p: this.p_, orientation: t}; + n.appendMessage(i) + } + + get SelectionEnd() { + const i = "IObject::GetSelectionEnd", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.selection) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set SelectionEnd(t) { + const i = {method: "IObject::SetSelectionEnd", p: this.p_, selection: t}; + n.appendMessage(i) + } + + get SelectionStart() { + const i = "IObject::GetSelectionStart", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.selection) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set SelectionStart(t) { + const i = {method: "IObject::SetSelectionStart", p: this.p_, selection: t}; + n.appendMessage(i) + } + + get Text() { + const i = "IObject::GetText", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.text) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set Text(t) { + const i = {method: "IObject::SetText", p: this.p_, text: t}; + n.appendMessage(i) + } + + get Type() { + const i = "IObject::GetType", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.type) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + get VerticalAlign() { + const i = "IObject::GetVerticalAlign", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.align) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set VerticalAlign(t) { + const i = {method: "IObject::SetVerticalAlign", p: this.p_, align: t}; + n.appendMessage(i) + } + + get Width() { + const i = "IObject::GetWidth", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.width) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set Width(t) { + const i = {method: "IObject::SetWidth", p: this.p_, width: t}; + n.appendMessage(i) + } + + get X() { + const i = "IObject::GetX", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.X) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set X(t) { + const i = {method: "IObject::SetX", p: this.p_, X: t}; + n.appendMessage(i) + } + + get Y() { + const i = "IObject::GetY", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.Y) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + set Y(t) { + const i = {method: "IObject::SetY", p: this.p_, Y: t}; + n.appendMessage(i) + } +} + +export class IObjects { + constructor(n) { + this.p_ = n + } + + GetItem(i) { + const r = "IObjects::GetItem", u = {method: r, p: this.p_, index: i}, f = new Promise((n, i) => { + const u = f => { + if (document.removeEventListener(r, u), f.detail.connect == !1) i(t); else if (f.detail.ret == !1) n(); else if (f.detail.p >= 0) { + const t = new IObject(f.detail.p); + n(t) + } else i() + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + GetCount() { + const i = "IObjects::GetCount", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.count) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetIndex(i) { + const r = "IObjects::GetIndex", u = {method: r, p: this.p_, obj: i.p_}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : f.detail.ret == !1 ? n() : n(f.detail.index) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + GetIndexByName(i, r) { + const u = "IObjects::GetIndexByName", f = {method: u, p: this.p_, name: i, indexBgn: r}, + e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : f.detail.ret == !1 ? n() : n(f.detail.index) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + Insert(i, r, u, f, e, o, s) { + const h = "IObjects::Insert", + c = {method: h, p: this.p_, index: i, type: r, X: u, Y: f, width: e, height: o, option: s}, + l = new Promise((n, i) => { + const r = u => { + if (document.removeEventListener(h, r), u.detail.connect == !1) i(t); else if (u.detail.ret == !1) n(); else if (u.detail.p >= 0) { + const t = new IObject(u.detail.p); + n(t) + } else i() + }; + document.addEventListener(h, r) + }); + return n.appendMessage(c), l + } + + Remove(i) { + const r = "IObjects::Remove", u = {method: r, p: this.p_, index: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + get Count() { + return this.GetCount() + } +} + +export class IPrinter { + constructor(n) { + this.p_ = n + } + + GetInstalledPrinters() { + const i = "IPrinter::GetInstalledPrinters", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.printers) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetMediaId() { + const i = "IPrinter::GetMediaId", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.id) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetMediaName() { + const i = "IPrinter::GetMediaName", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.name) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetPrintedTapeLength() { + const i = "IPrinter::GetPrintedTapeLength", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.length) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetSupportedMediaIds() { + const i = "IPrinter::GetSupportedMediaIds", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.mediaIds) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + GetSupportedMediaNames() { + const i = "IPrinter::GetSupportedMediaNames", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.mediaNames) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + IsMediaIdSupported(i) { + const r = "IPrinter::IsMediaIdSupported", u = {method: r, p: this.p_, id: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + IsMediaNameSupported(i) { + const r = "IPrinter::IsMediaNameSupported", u = {method: r, p: this.p_, name: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + IsPrinterOnline(i) { + const r = "IPrinter::IsPrinterOnline", u = {method: r, p: this.p_, name: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + IsPrinterSupported(i) { + const r = "IPrinter::IsPrinterSupported", u = {method: r, p: this.p_, name: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + get ErrorCode() { + const i = "IPrinter::GetErrorCode", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.errorCode) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + get ErrorString() { + const i = "IPrinter::GetErrorString", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.errorString) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + get Name() { + const i = "IPrinter::GetName", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.name) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + get PortName() { + const i = "IPrinter::GetPortName", r = {method: i, p: this.p_}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.port) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } +} + +export class IDocument { + static get Width() { + return IDocument.GetWidth() + } + + static get Length() { + return IDocument.GetLength() + } + + static set Length(n) { + IDocument.SetLength(n) + } + + static get CurrentSheet() { + return IDocument.GetCurrentSheet() + } + + static set CurrentSheet(n) { + IDocument.SetCurrentSheet(n) + } + + static get CutLineCount() { + return IDocument.GetCutLineCount() + } + + static get CutLines() { + return IDocument.GetCutLines() + } + + static get ErrorCode() { + return IDocument.GetErrorCode() + } + + static get MarginBottom() { + return IDocument.GetMarginBottom() + } + + static set MarginBottom(n) { + return IDocument.SetMarginBottom(n) + } + + static get MarginLeft() { + return IDocument.GetMarginLeft() + } + + static set MarginLeft(n) { + return IDocument.SetMarginLeft(n) + } + + static get MarginRight() { + return IDocument.GetMarginRight() + } + + static set MarginRight(n) { + return IDocument.SetMarginRight(n) + } + + static get MarginTop() { + return IDocument.GetMarginTop() + } + + static set MarginTop(n) { + return IDocument.SetMarginTop(n) + } + + static get Objects() { + return IDocument.GetObjects() + } + + static get Orientation() { + return IDocument.GetOrientation() + } + + static get Printer() { + return IDocument.GetPrinter() + } + + static get SheetNames() { + return IDocument.GetSheetNames() + } + + static Open(i) { + const r = "IDocument::Open", u = {method: r, filePath: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static DoPrint(i, r) { + const u = "IDocument::DoPrint", f = {method: u, dwOption: i, szOption: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static StartPrint(i, r) { + const u = "IDocument::StartPrint", f = {method: u, docName: i, option: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static PrintOut(i, r) { + const u = "IDocument::PrintOut", f = {method: u, copyCount: i, option: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static EndPrint() { + const i = "IDocument::EndPrint", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.connect == !1 ? r(t) : n(f.detail.ret) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetImageData(i, r, u) { + const f = "IDocument::GetImageData", e = {method: f, type: i, width: r, height: u}, o = new Promise((n, i) => { + const r = u => { + document.removeEventListener(f, r), u.detail.ret == !0 && u.detail.connect == !0 ? n(u.detail.image) : i(t) + }; + document.addEventListener(f, r) + }); + return n.appendMessage(e), o + } + + static GetObjectsCount() { + const i = "IDocument::GetObjectsCount", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !0 && f.detail.connect == !0 ? n(f.detail.count) : r(t) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetIndexByName(i, r) { + const u = "IDocument::GetIndexByName", f = {method: u, name: i, indexBgn: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : f.detail.ret == !0 ? n(f.detail.index) : n() + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static GetObject(i) { + const r = "IDocument::GetObject", u = {method: r, name: i}, f = new Promise((n, i) => { + const u = f => { + if (document.removeEventListener(r, u), f.detail.connect == !1) i(t); else if (f.detail.ret == !1) n(); else if (f.detail.p >= 0) { + const t = new IObject(f.detail.p); + n(t) + } else i() + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetObjects(i) { + const r = "IDocument::GetObjects", u = {method: r, name: i}, f = new Promise((n, i) => { + const u = f => { + if (document.removeEventListener(r, u), f.detail.ret == !1 || f.detail.connect == !1) i(t); else if (f.detail.p >= 0) { + const t = new IObjects(f.detail.p); + n(t) + } else i() + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetBarcodeIndex(i) { + const r = "IDocument::GetBarcodeIndex", u = {method: r, name: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : f.detail.ret == !1 ? n() : n(f.detail.index) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetMediaId() { + const i = "IDocument::GetMediaId", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.id) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetMediaName() { + const i = "IDocument::GetMediaName", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.name) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetPrinterName() { + const i = "IDocument::GetPrinterName", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.name) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetText(i) { + const r = "IDocument::GetText", u = {method: r, index: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.ret == !1 || f.detail.connect == !1 ? i(t) : n(f.detail.text) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetTextCount() { + const i = "IDocument::GetTextCount", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.count) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetTextIndex(i) { + const r = "IDocument::GetTextIndex", u = {method: r, name: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : f.detail.ret == !1 ? n() : n(f.detail.index) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetPrinter() { + const i = "IDocument::GetPrinter", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + if (document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1) r(t); else if (f.detail.p >= 0) { + const t = new IPrinter(f.detail.p); + n(t) + } else r() + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static SetText(i, r) { + const u = "IDocument::SetText", f = {method: u, index: i, text: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static SetBarcodeData(i, r) { + const u = "IDocument::SetBarcodeData", f = {method: u, index: i, text: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static SetMarginLeftRight(i, r) { + const u = "IDocument::SetMarginLeftRight", f = {method: u, left: i, right: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static SetMediaById(i, r) { + const u = "IDocument::SetMediaById", f = {method: u, id: i, fit: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static SetMediaByName(i, r) { + const u = "IDocument::SetMediaByName", f = {method: u, name: i, fit: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static SetPrinter(i, r) { + const u = "IDocument::SetPrinter", f = {method: u, name: i, fit: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static GetCurrentSheet() { + const i = "IDocument::GetCurrentSheet", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.name) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static SetCurrentSheet(i) { + const r = "IDocument::SetCurrentSheet", u = {method: r, name: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetCutLineCount() { + const i = "IDocument::GetCutLineCount", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.count) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetCutLines() { + const i = "IDocument::GetCutLines", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.connect == !1 ? r(t) : f.detail.ret == !1 ? n() : n(f.detail.cutlines) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetErrorCode() { + const i = "IDocument::GetErrorCode", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.errorCode) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetMarginBottom() { + const i = "IDocument::GetMarginBottom", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.margin) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static SetMarginBottom(i) { + const r = "IDocument::SetMarginBottom", u = {method: r, margin: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetMarginLeft() { + const i = "IDocument::GetMarginLeft", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.margin) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static SetMarginLeft(i) { + const r = "IDocument::SetMarginLeft", u = {method: r, margin: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetMarginRight() { + const i = "IDocument::GetMarginRight", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.margin) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static SetMarginRight(i) { + const r = "IDocument::SetMarginRight", u = {method: r, margin: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetMarginTop() { + const i = "IDocument::GetMarginTop", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.margin) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static SetMarginTop(i) { + const r = "IDocument::SetMarginTop", u = {method: r, margin: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 || f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static GetOrientation() { + const i = "IDocument::GetOrientation", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.orientation) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetSheetNames() { + const i = "IDocument::GetSheetNames", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.names) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetWidth() { + const i = "IDocument::GetWidth", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.width) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static GetLength() { + const i = "IDocument::GetLength", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.ret == !1 || f.detail.connect == !1 ? r(t) : n(f.detail.length) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static SetLength(i) { + const r = "IDocument::SetLength", u = {method: r, length: i}, f = new Promise((n, i) => { + const u = f => { + document.removeEventListener(r, u), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(r, u) + }); + return n.appendMessage(u), f + } + + static Save() { + const i = "IDocument::Save", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.connect == !1 ? r(t) : n(f.detail.ret) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } + + static SaveAs(i, r) { + const u = "IDocument::SaveAs", f = {method: u, type: i, filePath: r}, e = new Promise((n, i) => { + const r = f => { + document.removeEventListener(u, r), f.detail.connect == !1 ? i(t) : n(f.detail.ret) + }; + document.addEventListener(u, r) + }); + return n.appendMessage(f), e + } + + static Export(i, r, u) { + const f = "IDocument::Export", e = {method: f, type: i, filePath: r, dpi: u}, o = new Promise((n, i) => { + const r = u => { + document.removeEventListener(f, r), u.detail.connect == !1 ? i(t) : n(u.detail.ret) + }; + document.addEventListener(f, r) + }); + return n.appendMessage(e), o + } + + static Close() { + const i = "IDocument::Close", r = {method: i}, u = new Promise((n, r) => { + const u = f => { + document.removeEventListener(i, u), f.detail.connect == !1 ? r(t) : n(f.detail.ret) + }; + document.addEventListener(i, u) + }); + return n.appendMessage(r), u + } +} + +export const IsExtensionInstalled = () => document.body.classList.contains("bpac-extension-installed") ? !0 : !1 diff --git a/src/main/resources/static/js/main.js b/src/main/resources/static/js/main.js index 990feeb..2dd8cde 100644 --- a/src/main/resources/static/js/main.js +++ b/src/main/resources/static/js/main.js @@ -1,16 +1,19 @@ -const body = document.querySelector("body"); -const errorMsgBox = document.querySelector(".errorBox"); -const errorMsgBoxText = errorMsgBox.querySelector("p"); -const warningMsgBox = document.querySelector(".warningBox"); -const warningMsgBoxText = warningMsgBox.querySelector("p"); -const successMsgBox = document.querySelector(".successBox"); -const successMsgBoxText = successMsgBox.querySelector("p"); +const body = $("body"); +const errorMsg = $("#errorBox"); +const warningMsg = $("#warningBox"); +const successMsg = $("#successBox"); +const confirmMsg = $("#confirmBox"); +const promptMsg = $("#promptBox"); + +const messageBoxesAnimationTime = 200; +const messageBoxesFunctionsDelay = 300; $(() => { $('.materialCode').each(function () { const row = $(this); const materialID = row.data("materialid"); + // SIMDUT axios.post(`/simdut/${materialID}`) .catch(function (err) { if (err.response.status === 404) { @@ -19,127 +22,203 @@ $(() => { } }); }); - $(".messageBox").each(function () { checkMessageBoxesDisplay($(this)[0]) }); -}); - -window.addEventListener("load", () => { - - document.querySelectorAll(".returnButton").forEach((e) => { - e.addEventListener("click", () => { - document.location.href = referer; - }); + $(".toSave").on({ + keyup: function () { + showMessage(warningMsg, changesNotSavedText, false); + } + }); + $(".returnButton").on({click: () => window.location.href = referer}); + $(".materialCode").on({ + click: function () { + window.open(`/simdut/${$(this).data("materialid")}`, "_blank"); + } + }); + $("img").on({ + click: function () { + if ($(this).attr("id") === "logo") return; + window.open($(this).attr("src"), "_blank"); + } + }); + $('input[type="text"], input[type="number"], input[type="date"], textarea').each(function () { + $(this).addClass("rawInput"); + }); + $(".rawInput:not(.noPlaceholder)").each(function () { + $(this).attr({placeholder: "N/A"}); }); - document.querySelectorAll(".materialCode").forEach((e) => { - const materialID = e.getAttribute("data-materialID"); - e.addEventListener("click", () => { - window.open("/simdut/" + materialID, "_blank"); - }); + // Formulaires protégés + $(".requireAuth").on({ + submit: function () { + return checkPassword(this); + } }); - - document.querySelectorAll("img").forEach((e) => { - if (e.id !== "logo") { - e.addEventListener("click", () => { - window.open(e.src, "_blank"); + const removerForm = $(".requireAuth-remover"); + removerForm.find(".remover").on({ + click: function () { + console.log($(this)); + removerForm.attr({ + action: removerForm.attr("action") + $(this).data("entityid") }); + + checkPassword(removerForm); } }); - document.querySelectorAll(".requireAuth").forEach((e) => { - e.onsubmit = () => { - return checkPassword(e); - }; + // Favicon + $("head").append($("").attr({ + rel: "icon", + href: "/favicon.png" + })); + + // Imprimante + let src = `${baseUrl}/icons/printerError.svg`; + let title = printErrorTitle; + if ($(".bpac-extension-installed").length) { + src = `${baseUrl}/icons/printer.svg`; + title = printOkTitle; + } + $("#printStatusIcon").attr({ + src: src, + title: title }); - - document.querySelectorAll(".requireAuth-remover").forEach((e) => { - e.querySelectorAll(".remover").forEach(elem => { - elem.addEventListener("click", () => { - e.action += elem.getAttribute("data-entityID"); - checkPassword(e); - }); - }); - }); - - document.querySelectorAll(".companyTabTitle").forEach(e => { - e.addEventListener("click", () => { - const companyName = e.getAttribute("data-companyName"); - const table = document.getElementById("recipes_" + companyName); - - if (table.style.display === "none") { - table.style.display = "table"; - } else { - table.style.display = "none"; - } - }); - }); - - document.querySelectorAll('input[type="text"], input[type="number"], input[type="date"], textarea').forEach(e => e.classList.add("rawInput")) - - document.querySelectorAll(".rawInput").forEach(e => e.placeholder = "N/A"); - - window.addEventListener("keyup", e => { - if (e.target) { - if (e.target.classList.contains("toSave")) { - warningMsgBoxText.innerText = changesNotSavedText; - showElement(warningMsgBox); - } - } - }); - - // Ajoute le favicon - let faviconElement = document.createElement("link"); - faviconElement.rel = "icon"; - faviconElement.href = "/favicon.png"; - document.querySelector("head").appendChild(faviconElement); }); -function askDatabaseExport() { - return confirm(exportAllWarningText); +function confirmDatabaseExport() { + showConfirm(exportAllWarningText, false, () => { + window.location.href = "./recipe/xls"; + }); } -function checkPassword(form, callback) { - hideElement(errorMsgBox); +function checkPassword(form, callback = () => { +}) { + let shouldContinue = false; - const password = prompt(askPasswordText); - if (!password) return false; + promptMsg.find("input").attr({type: "password"}); + showConfirm(askPasswordText, true, async pwd => { + let data = {}; + data.password = pwd; - let data = {}; - data.password = password; + await axios.post("/password/valid", data) + .then(r => { + if (r.data === true) { + if (form != null) form.submit(); + callback(); + shouldContinue = true; + } else { + showMessage(errorMsg, invalidPasswordText); + } + }) + .catch(e => { + showMessage(errorMsg, generalErrorText); + console.log(e); + }); - axios.post("/password/valid", data) - .then(r => { - if (r.data === true) { - if (form != null) form.submit(); - if (callback != null) callback(); - return true; - } else { - errorMsgBoxText.innerText = invalidPasswordText; - showElement(errorMsgBox); - } - }) - .catch(e => { - errorMsgBoxText.innerText = generalErrorText; - showElement(errorMsgBox); - console.log(e); - }); + promptMsg.find("input").attr({type: "text"}); + }, () => promptMsg.find("input").attr({type: "text"})); - return false; + return shouldContinue; } +const messageBoxesY = -20; +const headerY = 70; + function checkMessageBoxesDisplay(element) { - if (!element.querySelector("p").textContent) hideElement(element); - else showElement(element); + const node = $(element); + + if (!node.find("p").text()) hideMessage(element); + else showMessage(element); } -function hideElement(element) { - element.style.display = "none"; +function isMessageVisible(type) { + return $(type).is(":visible"); } -function showElement(element) { - element.style.display = ""; +function showMessage(type, value, autoHide = true, hideTimeout = 2000) { + const node = $(type); + const message = node.find("p"); + + // Cache les autres boîtes de message sauf si une boîte de confirmation est active + if (!$("#filter").is(":visible")) { + $(`.messageBox:not(#${$(type).attr("id")}`).each(function () { + hideMessage(this); + }); + } else { + return; + } + + if (!isMessageVisible(type)) { + message.text(value); + node.show(); + node.animate({top: `${headerY}px`}, messageBoxesAnimationTime); + + if (autoHide) { + setTimeout(() => { + hideMessage(node); + }, hideTimeout); + } + } else { + if (message.text() !== value) hideMessage(type, () => showMessage(type, value, autoHide, hideTimeout)); + } +} + +function hideMessage(type, callback = () => { +}) { + const node = $(type); + + if (isMessageVisible(type)) { + node.animate({top: `${messageBoxesY}px`}, messageBoxesAnimationTime, "swing", () => { + node.hide(); + callback(); + }); + } +} + +function showConfirm(value, prompt = false, continueCallback = () => { +}, cancelCallback = () => { +}) { + const filter = $("#filter"); + const node = prompt ? $(promptMsg) : $(confirmMsg); + + if (prompt) node.find("#confirmInput").val(""); + + showMessage(node, value, false); + filter.show(); + filter.animate({opacity: 0.5}, messageBoxesAnimationTime); + + node.find(".confirmContinue").one({ + click: function () { + hideConfirm(node); + + setTimeout(function () { + if (!prompt) continueCallback(); + else continueCallback(node.find("#confirmInput").val()); + }, messageBoxesFunctionsDelay); + } + }); + node.find(".confirmCancel").one({ + click: function () { + hideConfirm(node); + + setTimeout(function () { + cancelCallback(); + }, messageBoxesFunctionsDelay); + } + }); +} + +function hideConfirm(node) { + hideMessage(node); + + const filter = $("#filter"); + filter.animate({opacity: 0}, messageBoxesAnimationTime + 100, "swing", () => { + filter.hide(); + // Retire les callbacks des anciennes confirmations + $(confirmMsg).find(".confirmContinue").unbind(); + $(confirmMsg).find(".confirmCancel").unbind(); + }); } const lTomL = 1000; @@ -151,15 +230,14 @@ let currentUnit = "mL"; function changeUnits(unitSelect, quantitiesSelector, unitsDisplay) { currentUnit = unitSelect.value; - document.querySelectorAll(unitsDisplay).forEach(e => { - e.innerText = currentUnit; + $(unitsDisplay).each(function () { + $(this).text(currentUnit); - // Modifie la quantitée - const quantityElem = e.parentElement.parentElement.querySelector(quantitiesSelector); + const quantityElem = $(this).parents(".materialRow").find(quantitiesSelector); + console.log(quantityElem); if (quantityElem) { - const originalQuantity = parseInt(quantityElem.dataset.quantityml); - - quantityElem.innerText = convertMlToUnit(originalQuantity); + const originalQuantity = parseInt(quantityElem.data("quantityml")); + quantityElem.text(convertMlToUnit(originalQuantity)); } }); } @@ -187,3 +265,7 @@ function percentageOf(percentage, number) { function searchIn(searchString, str) { return str.toUpperCase().indexOf(searchString.toUpperCase()) > -1; } + +function formatMessage(message) { + return message.replace(/'/g, "'"); +} diff --git a/src/main/resources/static/js/mix.js b/src/main/resources/static/js/mix.js index 8aca781..90fce8d 100644 --- a/src/main/resources/static/js/mix.js +++ b/src/main/resources/static/js/mix.js @@ -8,19 +8,22 @@ let materialSelectorHtml; let recipeID; $(() => { - recipeID = document.querySelector("#recipeID").value; + recipeID = $("#recipeID").val(); - axios.get(`/mix/selector/${recipeID}/-1`) + const mixIDInput = $("#mixID"); + const mixID = mixIDInput ? mixIDInput.val() : -1; + + axios.get(`/mix/selector/${recipeID}/${mixID}`) .then(r => { materialSelectorHtml = r.data; init(); }) .catch(e => { - console.log(e.status); - errorMsgBoxText.innerText = generalErrorText; - showElement(errorMsgBox); + showMessage(errorMsg, generalErrorText); console.log(e); }); + + onRowPositionChanged(); }); $(document).on("click", function () { @@ -32,165 +35,204 @@ $(document).on("click", ".materialSelector", function (event) { showMaterialList($(this)[0]); }); +// $(document).on("click", ".materialList p", function () { +// $(this).parents(".materialSelector").find("input").val($(this).data("materialcode")); +// }); + $(document).on("click", ".removeMaterial", function () { const id = $(this).data("removerow"); if ($(".materialListRow").length > 1) $(`#${id}`).remove(); }); $(document).on("click", ".upRow", function () { - const row = $(this).parent().parent(); + const row = $(this).parents(".materialListRow"); row.insertBefore(row.prev()); + + onRowPositionChanged(); }); $(document).on("click", ".downRow", function () { - const row = $(this).parent().parent(); - row.insertBefore(row.next()); + const row = $(this).parents(".materialListRow"); + row.insertAfter(row.next()); + + onRowPositionChanged() }); -document.querySelector(".mixMaterialListTitle button").addEventListener("click", () => { - addMaterial(null, null); +$(".mixMaterialListTitle button").on({ + click: function () { + addMaterial(null, null); + } }); +function onRowPositionChanged() { + $(".materialListRow").each(function () { + const node = $(this); + const upRow = node.find(".upRow"); + const downRow = node.find(".downRow"); + + let upRowHidden = false; + let downRowHidden = false; + + if (node.is(":first-child")) { + upRowHidden = true; + } else if (node.is(":last-child")) { + downRowHidden = true; + } + + if (upRowHidden) upRow.css({opacity: 0}); + else upRow.css({opacity: 1}); + + if (downRowHidden) downRow.css({opacity: 0}); + else downRow.css({opacity: 1}); + }); +} + function addMaterial(materialCode, quantity) { const row = addRow(materialNbr); - const positionColumn = addColumn("positionButtons", row); - const materialColumn = addColumn("material", row); - const quantityColumn = addColumn("quantity", row); - const unitsColumn = addColumn("units", row); - const removeButtonColumn = addColumn("removeButton", row); + const positionColumn = $(addColumn("positionButtons", row)); + const materialColumn = $(addColumn("material", row)); + const quantityColumn = $(addColumn("quantity", row)); + const unitsColumn = $(addColumn("units", row)); + const removeButtonColumn = $(addColumn("removeButton", row)); addPositionButtons(positionColumn); addQuantityInput(quantity, quantityColumn); addUnits(unitsColumn); addRemoveButton(materialNbr, removeButtonColumn); - materialColumn.innerHTML = materialSelectorHtml; - const materialSelector = materialColumn.querySelector("input"); + materialColumn.html(materialSelectorHtml); + const materialSelector = materialColumn.find("input"); if (materialCode) { - const material = materialColumn.querySelector(`.materialList p[data-materialcode="${materialCode}"]`); + const material = materialColumn.find(`.materialList p[data-materialcode="${materialCode}"]`); if (material) { - materialSelector.value = material.dataset.materialcode; - materialSelector.dataset.usepercentages = material.dataset.usepercentages; + materialSelector.val(material.data("materialcode")); + materialSelector.data({ + usepercentages: material.data("usepercentages") + }); } } - row.appendChild(materialColumn); - row.appendChild(quantityColumn); - row.appendChild(unitsColumn); - row.appendChild(removeButtonColumn); - - document.querySelector(".mixMaterialList").appendChild(row); + $(".mixMaterialList").append(row); checkUnits(materialSelector, row); + onRowPositionChanged(); materialNbr++; } function addRow(index) { - const row = document.createElement("div"); - row.classList.add("materialListRow"); - row.id = `material_${index}`; - return row; + return $("
") + .attr({ + class: "materialListRow", + id: `material_${index}` + }); } function addColumn(type, parent) { - const column = document.createElement("div"); - column.classList.add(type); + const column = $("
") + .attr({class: type}); - parent.appendChild(column); + $(parent).append(column); return column; } function addUnits(parent) { - const units = document.createElement("p"); - units.classList.add("quantityUnits"); - units.textContent = "mL"; + const units = $("

") + .attr({class: "quantityUnits"}) + .text("mL"); - parent.appendChild(units); + $(parent).append(units); return units; } function addRemoveButton(index, parent) { - const button = document.createElement("button"); - button.type = "button"; - button.textContent = removeText; - button.dataset.removerow = `material_${index}`; - button.classList.add("removeMaterial"); + const button = $("") + .attr({ + type: "button", + class: "removeMaterial" + }) + .data({removerow: `material_${index}`}) + .text(removeText); - parent.appendChild(button); + $(parent).append(button); return button; } function addQuantityInput(quantity, parent) { - let input = document.createElement("input"); - if (quantity === undefined || quantity === null) quantity = 1; - input.type = "number"; - input.name = "quantities"; - input.value = quantity; - input.step = 0.001; - input.min = 0.001; - input.required = true; + const input = $("") + .attr({ + type: "number", + name: "quantities", + value: quantity, + step: 0.001, + min: 0.001, + required: true + }); - parent.appendChild(input); + $(parent).append(input); return input; } function addPositionButtons(parent) { - const up = document.createElement("button"); - up.classList.add("upRow"); - up.type = "button"; - up.textContent = "↑"; - parent.appendChild(up); + $(parent).append($("") + .attr({ + class: "upRow", + type: "button" + }) + .text("↑")); - const down = document.createElement("button"); - down.classList.add("downRow"); - down.type = "button"; - down.textContent = "↓"; - parent.appendChild(down); + $(parent).append($("") + .attr({ + class: "downRow", + type: "button" + }) + .text("↓")); } function showMaterialList(input) { hideMaterialList(); - input.parentElement.querySelector(".materialSelector .materialList").classList.add("show"); + $(input).parent().find(".materialSelector .materialList").addClass("show"); } function hideMaterialList() { - const list = document.querySelector(".materialSelector .materialList.show"); - - if (list != null) list.classList.remove("show"); + const list = $(".materialSelector .materialList.show"); + if (list) list.removeClass("show"); } function selectMaterial(material) { - const materialName = material.dataset.materialcode; - const input = material.parentElement.parentElement.querySelector("input"); + const materialName = $(material).data("materialcode"); + const input = $(material).parents(".materialSelector").find("input"); - input.value = materialName; + input.val(materialName); - hideMaterialList(); - checkUnits(material, input.parentElement.parentElement.parentElement) + checkUnits(material, input.parents(".materialListRow")); } function searchMaterial(input) { - let filter, filterUpper, materials; + const filter = input.val(); + const materials = input.parent().find(".materialList p"); - filter = input.value; - materials = input.parentElement.querySelectorAll(".materialList p"); - - materials.forEach(e => { - if (searchIn(filter, e.textContent) || searchIn(filter, e.dataset.materialtype)) e.style.display = ""; - else e.style.display = "none"; + materials.each(function () { + const node = $(this); + if (searchIn(filter, node.text()) || searchIn(filter, node.data("materialtype"))) node.hide(); + else node.show(); }); - const found = input.parentElement.querySelector(`.materialList p[data-materialcode="${filter}"]`); - if (found) input.dataset.usepercentages = found.dataset.usepercentages; + const found = input.parent().find(`.materialList p[data-materialcode="${filter}"]`); + if (found) { + input.data({ + usepercentages: found.data("usepercentages") + }); + } - checkUnits(input, input.parentElement.parentElement.parentElement); + checkUnits(input, input.parents(".materialListRow")); } -function checkUnits(materialSelector, row) { - const quantityUnits = row.querySelector(".quantityUnits"); - if (materialSelector.dataset.usepercentages === "true") quantityUnits.innerText = "%"; - else quantityUnits.innerText = "mL"; +function checkUnits(materialSelector) { + const quantityUnits = $(materialSelector).parents(".materialListRow").find(".quantityUnits"); + console.log($(quantityUnits)); + if ($(materialSelector).data("usepercentages")) quantityUnits.text("%"); + else quantityUnits.text("mL"); } diff --git a/src/main/resources/static/js/ptouchPrint.js b/src/main/resources/static/js/ptouchPrint.js new file mode 100644 index 0000000..f978ac3 --- /dev/null +++ b/src/main/resources/static/js/ptouchPrint.js @@ -0,0 +1,47 @@ +import * as bpac from "/js/bpac.js"; + +export class PtouchPrinter { + constructor(object) { + this.object = object; + this.pdocument = bpac.IDocument; + } + + async print() { + if (!bpac.IsExtensionInstalled()) { + console.error("L'extension b-Pac n'est pas installée"); + return -1; + } + + try { + await this.openDoc(); + await this.fillDoc(); + this.printDoc(); + this.pdocument.Close(); + + return 1; + } catch (e) { + console.log(e); + return 99; + } + }; + + async openDoc() { + const docUrl = `${baseUrl}/lbx/${this.object.template}.lbx`; + console.log("Ouverture du modèle: " + docUrl); + await this.pdocument.Open(docUrl); + } + + async fillDoc() { + for (let i = 0; i < this.object.lines.length; i++) { + const line = this.object.lines[i]; + const label = await this.pdocument.GetObject(line.name); + label.Text = line.value; + } + } + + printDoc() { + this.pdocument.StartPrint("", 0); + this.pdocument.PrintOut(1, 0); + this.pdocument.EndPrint(); + } +} diff --git a/src/main/resources/static/js/recipeList.js b/src/main/resources/static/js/recipeList.js new file mode 100644 index 0000000..d98e0c0 --- /dev/null +++ b/src/main/resources/static/js/recipeList.js @@ -0,0 +1,8 @@ +$(() => { + $(".companyTabTitle").on({ + click: function () { + const companyID = $(this).parent().data("companyid"); + $(`#recipes_${companyID}`).toggle(); + } + }); +}); diff --git a/src/main/resources/static/js/recipeResearch.js b/src/main/resources/static/js/recipeResearch.js index 5bb866b..6d7f11f 100644 --- a/src/main/resources/static/js/recipeResearch.js +++ b/src/main/resources/static/js/recipeResearch.js @@ -33,8 +33,6 @@ function performSearch(searchString) { companyRows.forEach(c => { const recipeRows = c.querySelectorAll(".recipeRow"); - hideElement(warningMsgBox); - if (!searchString || !searchString.replace(/\s/g, '').length) { c.classList.add("researchResult"); @@ -44,7 +42,7 @@ function performSearch(searchString) { found = true; emptySearch = true; - } else if (searchIn(searchString, c.querySelector("h2").dataset.companyname)) { + } else if (searchIn(searchString, c.querySelector("h2").textContent)) { c.classList.add("researchResult"); recipeRows.forEach(r => r.classList.add("researchResult")); found = true; @@ -59,14 +57,12 @@ function performSearch(searchString) { }); }); } - - if (!found) { - warningMsgBoxText.innerText = researchNotFound; - showElement(warningMsgBox); - } - - if (emptySearch) closeTabs(); - else openTabs(); } ); + + if (!found) showMessage(warningMsg, researchNotFound, false); + else hideMessage(warningMsg); + + if (emptySearch) closeTabs(); + else openTabs(); } diff --git a/src/main/resources/static/lbx/Couleur.lbx b/src/main/resources/static/lbx/Couleur.lbx new file mode 100644 index 0000000..2eb2468 Binary files /dev/null and b/src/main/resources/static/lbx/Couleur.lbx differ diff --git a/src/main/resources/static/lbx/Templates.zip b/src/main/resources/static/lbx/Templates.zip new file mode 100644 index 0000000..f85fdd0 Binary files /dev/null and b/src/main/resources/static/lbx/Templates.zip differ diff --git a/src/main/resources/static/lbx/Touchup.lbx b/src/main/resources/static/lbx/Touchup.lbx new file mode 100644 index 0000000..ae8c520 Binary files /dev/null and b/src/main/resources/static/lbx/Touchup.lbx differ diff --git a/src/main/resources/static/pdf/touchup.old.pdf b/src/main/resources/static/pdf/touchup.old.pdf new file mode 100644 index 0000000..4f47c99 Binary files /dev/null and b/src/main/resources/static/pdf/touchup.old.pdf differ diff --git a/src/main/resources/static/pdf/touchup.pdf b/src/main/resources/static/pdf/touchup.pdf index 4f47c99..3a84182 100644 Binary files a/src/main/resources/static/pdf/touchup.pdf and b/src/main/resources/static/pdf/touchup.pdf differ diff --git a/src/main/resources/templates/company/creator.html b/src/main/resources/templates/company/creator.html index 0c0a50f..ca1cfb6 100644 --- a/src/main/resources/templates/company/creator.html +++ b/src/main/resources/templates/company/creator.html @@ -6,7 +6,7 @@ -
+
diff --git a/src/main/resources/templates/company/remover.html b/src/main/resources/templates/company/remover.html index ef05ef3..39957d1 100644 --- a/src/main/resources/templates/company/remover.html +++ b/src/main/resources/templates/company/remover.html @@ -20,7 +20,7 @@ -
+
diff --git a/src/main/resources/templates/error.html b/src/main/resources/templates/error.html index f11a558..d27d3d9 100644 --- a/src/main/resources/templates/error.html +++ b/src/main/resources/templates/error.html @@ -5,7 +5,7 @@ -
+
diff --git a/src/main/resources/templates/fragments.html b/src/main/resources/templates/fragments.html index 0bb89d4..528f483 100644 --- a/src/main/resources/templates/fragments.html +++ b/src/main/resources/templates/fragments.html @@ -11,10 +11,10 @@ -
+
- +
+
+ print status + +
+
+
+
-
+
- error icon -

-

+
+ error icon +

+

+
-
+
- success icon -

-

+
+ success icon +

+

+
-
+
- warning icon -

-

+
+ warning icon +

+

+
+
+
+
+
+ confirm icon +

+

+
+
+ + +
+
+
+
+ +
+
+
+
+ confirm icon +

+

+
+
+ +
+
+ + +
+
+
+
+ +
+
+
+

@@ -116,17 +173,20 @@
@@ -147,5 +207,13 @@
+ + diff --git a/src/main/resources/templates/images/add.html b/src/main/resources/templates/images/add.html index 2819e2b..e1477f3 100644 --- a/src/main/resources/templates/images/add.html +++ b/src/main/resources/templates/images/add.html @@ -6,7 +6,7 @@ -
+
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 40958e0..1ff7122 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -5,7 +5,7 @@ -
+
@@ -20,10 +20,9 @@
-

+

- @@ -51,16 +50,15 @@
+ diff --git a/src/main/resources/templates/inventory.html b/src/main/resources/templates/inventory.html index 07ca00a..8390bc1 100644 --- a/src/main/resources/templates/inventory.html +++ b/src/main/resources/templates/inventory.html @@ -57,7 +57,7 @@ -
+
{ e.addEventListener("click", () => { - document.location.href = `/material/editor/${e.dataset.materialid}`; + window.location.href = `/material/editor/${e.dataset.materialid}`; }); }); @@ -213,8 +213,6 @@ const materialRows = document.querySelectorAll(".materialRow"); function performSearch(searchString) { - hideElement(warningMsgBox); - let found = false; const recipesContainer = document.querySelector(".materialsContainer:not(.researchEnabled)"); @@ -242,10 +240,8 @@ } }); - if (!found) { - warningMsgBoxText.innerText = researchNotFound; - showElement(warningMsgBox); - } + if (!found) showMessage(warningMsg, researchNotFound, false); + else hideMessage(warningMsg); } /*]]>*/ diff --git a/src/main/resources/templates/material/created.html b/src/main/resources/templates/material/created.html index 03ab0d0..48d4d08 100644 --- a/src/main/resources/templates/material/created.html +++ b/src/main/resources/templates/material/created.html @@ -8,7 +8,7 @@ -
+

diff --git a/src/main/resources/templates/material/creator.html b/src/main/resources/templates/material/creator.html index e759a45..707577b 100644 --- a/src/main/resources/templates/material/creator.html +++ b/src/main/resources/templates/material/creator.html @@ -6,10 +6,9 @@ -
+
-

@@ -29,7 +28,7 @@
- +
diff --git a/src/main/resources/templates/material/edit.html b/src/main/resources/templates/material/edit.html index ae04b3b..2197b31 100644 --- a/src/main/resources/templates/material/edit.html +++ b/src/main/resources/templates/material/edit.html @@ -9,7 +9,7 @@ -
+
@@ -34,6 +34,9 @@
+
+ +
@@ -71,6 +74,10 @@ th:value="${mType.materialTypeID}">
+
+ + +
@@ -90,7 +97,7 @@ }); document.querySelector("#editSIMDUT").addEventListener("click", () => { - document.location.href = `/material/simdut/${materialID}`; + window.location.href = `/material/simdut/${materialID}`; }); })(); diff --git a/src/main/resources/templates/material/editor.html b/src/main/resources/templates/material/editor.html index b8678bd..59d2f35 100644 --- a/src/main/resources/templates/material/editor.html +++ b/src/main/resources/templates/material/editor.html @@ -17,13 +17,10 @@ -
+
-

-

@@ -55,7 +52,7 @@ e.addEventListener("click", () => { const materialID = e.getAttribute("data-materialID"); - document.location.href = "/material/editor/" + materialID; + window.location.href = "/material/editor/" + materialID; }); }); })(); diff --git a/src/main/resources/templates/material/remover.html b/src/main/resources/templates/material/remover.html index e11ab14..5284282 100644 --- a/src/main/resources/templates/material/remover.html +++ b/src/main/resources/templates/material/remover.html @@ -17,12 +17,10 @@ -
+
-

diff --git a/src/main/resources/templates/material/simdut.html b/src/main/resources/templates/material/simdut.html index 1621bbd..f3658ab 100644 --- a/src/main/resources/templates/material/simdut.html +++ b/src/main/resources/templates/material/simdut.html @@ -6,7 +6,7 @@ -
+
diff --git a/src/main/resources/templates/materialType/creator.html b/src/main/resources/templates/materialType/creator.html index 2bde6e4..6f33095 100644 --- a/src/main/resources/templates/materialType/creator.html +++ b/src/main/resources/templates/materialType/creator.html @@ -8,7 +8,7 @@ -
+
diff --git a/src/main/resources/templates/materialType/edit.html b/src/main/resources/templates/materialType/edit.html index 6b1d404..b952098 100644 --- a/src/main/resources/templates/materialType/edit.html +++ b/src/main/resources/templates/materialType/edit.html @@ -7,7 +7,7 @@ -
+
@@ -19,7 +19,7 @@
- +
diff --git a/src/main/resources/templates/materialType/editor.html b/src/main/resources/templates/materialType/editor.html index 100a225..c9afc10 100644 --- a/src/main/resources/templates/materialType/editor.html +++ b/src/main/resources/templates/materialType/editor.html @@ -17,13 +17,10 @@ -
+
-

-

@@ -53,7 +50,7 @@ e.addEventListener("click", () => { const materialTypeID = e.getAttribute("data-materialTypeID"); - document.location.href = "/materialType/editor/" + materialTypeID; + window.location.href = "/materialType/editor/" + materialTypeID; }); }); })(); diff --git a/src/main/resources/templates/materialType/remover.html b/src/main/resources/templates/materialType/remover.html index 4d00754..2db047c 100644 --- a/src/main/resources/templates/materialType/remover.html +++ b/src/main/resources/templates/materialType/remover.html @@ -17,7 +17,7 @@ -
+
diff --git a/src/main/resources/templates/mix/creator.html b/src/main/resources/templates/mix/creator.html index 65a59bb..2213f23 100644 --- a/src/main/resources/templates/mix/creator.html +++ b/src/main/resources/templates/mix/creator.html @@ -8,7 +8,7 @@ -
+
diff --git a/src/main/resources/templates/mix/editor.html b/src/main/resources/templates/mix/editor.html index 89bcc0e..62fb4ed 100644 --- a/src/main/resources/templates/mix/editor.html +++ b/src/main/resources/templates/mix/editor.html @@ -7,7 +7,7 @@ -
+
@@ -85,9 +85,9 @@ removeText = "[[#{keyword.remove}]]"; document.querySelector("#removeMix").addEventListener("click", () => { - showElement(errorMsgBox); + showMessage(errorMsg); - checkPassword(null, () => document.location.href = `/mix/remover/[[${mix.mixID}]]`); + checkPassword(null, () => window.location.href = `/mix/remover/[[${mix.mixID}]]`); }); })(); diff --git a/src/main/resources/templates/mix/selector.html b/src/main/resources/templates/mix/selector.html index 64b5e19..c59b7a1 100644 --- a/src/main/resources/templates/mix/selector.html +++ b/src/main/resources/templates/mix/selector.html @@ -19,7 +19,8 @@ th:text="${material.materialType.materialTypeName == 'Aucun' ? '' : '[' + material.materialType.prefix + ']'} + ' ' + ${material.materialCode}" th:data-materialcode="${material.materialCode}" th:data-materialtype="${material.materialType.materialTypeName}" - th:data-usepercentages="${material.materialType.usePercentages}">

+ th:data-usepercentages="${material.materialType.usePercentages}" + onclick="selectMaterial(this)">

diff --git a/src/main/resources/templates/recipe/bak.html b/src/main/resources/templates/recipe/bak.html deleted file mode 100644 index e09f147..0000000 --- a/src/main/resources/templates/recipe/bak.html +++ /dev/null @@ -1,155 +0,0 @@ -
- - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
-
- -
-
- - - - - - - - - - - -
- -
- -
- - - -
-
- - - - - - - - - - - - -
-

-
-
-
-
- - - - - - -
- Image supprimée ou corrompue - - -
-
- - - - - - - - - - -
-

-
- -
- - -
-
-
- -
- -
diff --git a/src/main/resources/templates/recipe/created.html b/src/main/resources/templates/recipe/created.html index d57f084..1601bbf 100644 --- a/src/main/resources/templates/recipe/created.html +++ b/src/main/resources/templates/recipe/created.html @@ -6,14 +6,14 @@ -
+

-
diff --git a/src/main/resources/templates/recipe/creator.html b/src/main/resources/templates/recipe/creator.html index 63df2a9..9dc29e7 100644 --- a/src/main/resources/templates/recipe/creator.html +++ b/src/main/resources/templates/recipe/creator.html @@ -5,7 +5,7 @@ -
+
diff --git a/src/main/resources/templates/recipe/edit.html b/src/main/resources/templates/recipe/edit.html index 7fa684f..be2ba4f 100644 --- a/src/main/resources/templates/recipe/edit.html +++ b/src/main/resources/templates/recipe/edit.html @@ -6,29 +6,6 @@ -
+
@@ -171,16 +148,13 @@
-
- -
-

- +

+
@@ -224,50 +198,44 @@ e.addEventListener("click", () => { const mixID = e.getAttribute("data-mixID"); - document.location.href = "/mix/editor/" + mixID; + window.location.href = "/mix/editor/" + mixID; }); }); document.querySelector("#newMix").addEventListener("click", () => { const recipeID = "[[${recipe.recipeID}]]"; - document.location.href = "/mix/creator/" + recipeID; + window.location.href = "/mix/creator/" + recipeID; }); document.querySelectorAll(".deleteImg").forEach(e => { e.addEventListener("click", async () => { - if (confirm(askChangePage)) { + showConfirm(askChangePage, false, () => { checkPassword(null, () => { let data = {}; - data['image'] = e.getAttribute("data-image"); - hideElement(errorMsgBox); axios.post("/images/delete", data) .then(r => { const data = r.data; if (data['error'] !== undefined) { - errorMsgBoxText.innerText = data['error']; - showElement(errorMsgBox); + showMessage(errorMsg, data['error']); } else { - document.location.reload(); + window.location.reload(); } }) .catch(e => { console.log(e); - errorMsgBoxText.innerText = "[[#{error.serverError}]]"; - showElement(errorMsgBox); + showMessage(errorMsg, generalErrorText); }); }); - } + }); }); }); document.querySelector("#addImage").addEventListener("click", () => { - if (confirm(askChangePage)) { - document.location.href = "/images/add/[[${recipe.recipeID}]]"; - } + showConfirm(askChangePage, false, () => window.location.href = "/images/add/[[${recipe.recipeID}]]"); }); const recipeText = "[[${recipeJSON}]]"; @@ -288,7 +256,7 @@ let input = document.createElement("input"); input.type = "text"; input.id = `step_${stepNbr}`; - input.classList.add("step", "rawInput"); + input.classList.add("step", "rawInput", "toSave"); input.name = "step"; input.autocomplete = "off"; if (value != null) input.value = value; diff --git a/src/main/resources/templates/recipe/editor.html b/src/main/resources/templates/recipe/editor.html index c3806cc..19710e5 100644 --- a/src/main/resources/templates/recipe/editor.html +++ b/src/main/resources/templates/recipe/editor.html @@ -6,7 +6,7 @@ -
+
@@ -21,10 +21,8 @@
-

- - + @@ -52,16 +50,15 @@
+ diff --git a/src/main/resources/templates/recipe/explore.html b/src/main/resources/templates/recipe/explore.html index 5fa3c79..7882eae 100644 --- a/src/main/resources/templates/recipe/explore.html +++ b/src/main/resources/templates/recipe/explore.html @@ -8,7 +8,7 @@ -
+
@@ -117,6 +117,8 @@
@@ -170,7 +173,7 @@
- +
@@ -207,210 +210,160 @@ + diff --git a/src/main/resources/templates/recipe/remover.html b/src/main/resources/templates/recipe/remover.html index ab4432e..6179519 100644 --- a/src/main/resources/templates/recipe/remover.html +++ b/src/main/resources/templates/recipe/remover.html @@ -6,7 +6,7 @@ -
+
@@ -22,10 +22,8 @@
-

- -
+ @@ -55,5 +53,6 @@
+ diff --git a/src/main/resources/templates/touchup.html b/src/main/resources/templates/touchup.html new file mode 100644 index 0000000..8ecf825 --- /dev/null +++ b/src/main/resources/templates/touchup.html @@ -0,0 +1,69 @@ + + + + + + + + + +
+ +
+
+ +

+ + +
+
+
+ + +
+
+ + +
+
+
+ +
+ +
+ + + + diff --git a/src/main/resources/templates/touchupPtouch.html b/src/main/resources/templates/touchupPtouch.html new file mode 100644 index 0000000..eb8284c --- /dev/null +++ b/src/main/resources/templates/touchupPtouch.html @@ -0,0 +1,52 @@ + + + + + + + +
+ +
+
+
+ +
+ + + + diff --git a/src/main/resources/templates/updates.html b/src/main/resources/templates/updates.html index bb6f0f9..1621aff 100644 --- a/src/main/resources/templates/updates.html +++ b/src/main/resources/templates/updates.html @@ -14,7 +14,7 @@ -
+
@@ -34,8 +34,7 @@ document.querySelector("#markdown").innerHTML = r.data; }) .catch(e => { - errorMsgBoxText.innerText = generalErrorText; - showElement(errorMsgBox); + showMessage(errorMsg, generalErrorText); console.log(e); }); }); diff --git a/src/main/resources/updates.md b/src/main/resources/updates.md index e8625ad..4f71f51 100644 --- a/src/main/resources/updates.md +++ b/src/main/resources/updates.md @@ -3,16 +3,28 @@ * Correction d'un bug qui empêchait la suppression des mélanges. * Correction d'un bug qui empêche les boutons supprimer de fonctionner. * Correction d'un bug qui permettait d'envoyer les formulaires demandant des mots de passe sans donner un mot de passe valide. -* Correction d'une désynchronisation entre le nom des mélanges et leurs produits internes. -* Amélioration du style du site. -* Transition des modèles vers Lombok. +* Correction d'une désynchronisation entre le nom des mélanges et leur produit interne. +* Amélioration du style. +* Amélioration de la fluidité de la navigation. +* Transition complète des modèles vers Lombok. ### Ajouts -* +++ Ajout du support pour l'imprimante P-touch. -* Les produits dans l'inventaire sont maintenant ordonnés alphabétiquement. -* Changement de l'ordre d'un mélange. +* Ajout du support pour l'imprimante P-touch de Brother. + * L'extension b-Pac doit être installée sur le navigateur des clients. + * [Firefox](https://cre.fyloz.dev/bpac.xpi) + * [Chrome](https://chrome.google.com/webstore/detail/brother-b-pac-extension/ilpghlfadkjifilabejhhijpfphfcfhb) + * Le logiciel b-Pac doit être installé sur l'ordinateur des clients. + * [Windows](https://download.brother.com/welcome/dlfp100614/bcciw32031.msi) +* Ajout de la possibilité d'imprimer les mélanges avec P-Touch +* Ajout de la possibilité d'imprimer les étiquettes de kit de retouche avec P-Touch +* Ajout des boîtes de confirmation. * Ajout d'un type de produit aux mélanges. +* Ajout du changement d'ordre des produits d'un mélange. +* Les produits dans l'inventaire sont maintenant ordonnés alphabétiquement. + +### Dépendances * Ajout de jQuery, début de la transition. +* Migration vers Java 11 # v1.1.3 ### Corrections