Added Associate model, invoice fileupload, changes by feedback
authorelgekko <vasary@elgekko.net>
Mon, 24 Apr 2023 15:08:09 +0000 (17:08 +0200)
committerelgekko <vasary@elgekko.net>
Mon, 24 Apr 2023 15:08:09 +0000 (17:08 +0200)
29 files changed:
TODO.txt [new file with mode: 0644]
lis-app/pom.xml
lis-db/src/main/java/hu/user/lis/db/Associate.java [new file with mode: 0644]
lis-db/src/main/java/hu/user/lis/db/Currency.java
lis-db/src/main/java/hu/user/lis/db/Invoice.java
lis-services/src/main/java/hu/user/lis/services/data/AssociateService.java [new file with mode: 0644]
lis-services/src/main/java/hu/user/lis/services/data/AssociateServiceImpl.java [new file with mode: 0644]
lis-services/src/main/java/hu/user/lis/services/data/InvoiceService.java
lis-services/src/main/java/hu/user/lis/services/data/InvoiceServiceImpl.java
lis-services/src/main/java/hu/user/lis/services/data/PartnerServiceImpl.java
lis-services/src/main/java/hu/user/lis/services/data/ProjectService.java
lis-services/src/main/java/hu/user/lis/services/data/ProjectServiceImpl.java
lis-ui/src/main/java/hu/user/lis/ui/Constants.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/converter/ByteArrayToAMediaConverter.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/event/EventBus.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/view/AsyncBaseModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/IndexViewModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/InvoiceEditorModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/PartnersViewModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/ProjectEditorModel.java
lis-ui/src/main/java/hu/user/lis/ui/view/ProjectsViewModel.java
lis-ui/src/main/resources/web/incoming-invoice-editor.zul [new file with mode: 0644]
lis-ui/src/main/resources/web/index.zul
lis-ui/src/main/resources/web/outgoing-invoice-editor.zul [moved from lis-ui/src/main/resources/web/invoice.zul with 80% similarity]
lis-ui/src/main/resources/web/partner-editor.zul [moved from lis-ui/src/main/resources/web/partner.zul with 100% similarity]
lis-ui/src/main/resources/web/project-editor.zul [new file with mode: 0644]
lis-ui/src/main/resources/web/project.zul
lis-ui/src/main/resources/web/projects.zul
pom.xml

diff --git a/TODO.txt b/TODO.txt
new file mode 100644 (file)
index 0000000..00757be
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,21 @@
+* Projektek táblázat oszlopok sorrendje: Azonosító, Partner (inkább ügyfél), Név (inkább megnevezés), Kapcsolattartó. Értelemszerűen a projekt részletezésben s ügyfél és megnevezés legyen.
+* A projekt részletek képernyőn össze lehetne csukni a be és a kimenő számla táblázatokat?
+* Számla táblázatban oszlopok:
+       Bejövő számlák: Szállító (ez most a partner), megnevezés (ez most a leírás), nettó összeg, Pénznem (ez most nincs), Fizetési határidő nem kell.
+       Kimenő számlák: Vevő (ez most a partner), megnevezés (ez most a leírás), nettó összeg, pénznem (ez most nincs), fizetési határidő nem kell.
+* a be és kimenő számlák felviteli képernyőjén be lehessen állítani, hogy ez egy tervezett számla-e.
+* számlakép feltöltés/törlés: pdf csatolás
+-a dátumformátum: 2023. 04. 23. Nincs hónapnév és értelemszerűen nincs idő sem.
+-Összegek: két tizedesre igazítva, magyar számformátum: pl: 100,23   1.543.234,00   2800,05
+-Tervezett szamla esetén a határidők nem ismertek, nem kötelező;  áfa deviza esetén nem ismert, nem kötelező
+-munkatárs lista és szerkesztő: név, óradíj?
+-munkatárs hozzárendelése a projekthez (vagy fordítva)
+-munkalap: külön lista xy hány órát (mindenki önköltség) dolgozott melyik projekten
+
+
+- authentikáció: hitelesítés-AD és helyi
+- authorizáció: sap s3 autorazition objects leírás!!!      -pl. számla: szla szám + művelet : megjelenítésnél elérhető e?
+- munkalap rögzítés úgy, hogy raktáron lévő alkatrészt is fel lehessen vinni a munkalapra.
+- Kell keresnünk egy nevet a rendszernek, mert szerintem a Leader Information System nem helyes angolul: SLY-CRM
+- plugin: gondolnunk kell arra, hogy minden ügyfélnél lehet egyedi testreszabási igény, de ennek valahogy el kell teljesen különülnie a "core" forráskódtól. Pl. javascript motort be lehetne építeni, a szkriptek pedig meghatározott pontokon lehetnének becsatolva a logikába. számla részletezés volt a példa (10000EUR számla 3 részletben forintban, kérdés mennyi pl. az utsó számla összege); 10 custom mező, javascripttel futna a custom mezők módosítására
+
index e270057d78b3df1fefa15ece6763ba70a54d5935..fe740f36634d80eda1c225844c0ddb0bbce43ddf 100644 (file)
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>hu.user</groupId>
     <artifactId>lis-app</artifactId>
-    <version>0.0.4-SNAPSHOT</version>
+    <version>0.0.5-SNAPSHOT</version>
     <parent>
         <groupId>hu.user</groupId>
         <artifactId>lis</artifactId>
diff --git a/lis-db/src/main/java/hu/user/lis/db/Associate.java b/lis-db/src/main/java/hu/user/lis/db/Associate.java
new file mode 100644 (file)
index 0000000..a7b66e8
--- /dev/null
@@ -0,0 +1,15 @@
+package hu.user.lis.db;
+
+import lombok.*;
+
+@Getter
+@Setter
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class Associate {
+    String id;
+    String name;
+    double hourlyRate;
+    boolean active;
+}
index 33ff0e3d92205dbafffd51d716cb2c9f89c851dd..1b30c931e3cfedc8013a149f2547e5afdea453e4 100644 (file)
@@ -5,7 +5,7 @@ import lombok.Getter;
 
 @Getter
 public enum Currency {
-    HUF(0), USD(1), EURO(2);
+    HUF(0), USD(1), EUR(2);
     final int val;
 
     Currency(int val) {
index 8bf00e1064bba02f005185ff239177f7f85531de..ba9f72361cb839dcc3f98b7f21a90ade117dba42 100644 (file)
@@ -22,4 +22,6 @@ public class Invoice {
     Date completionDate;
     Date createDate;
     Date paymentDeadline;
+    boolean planned;
+    byte[] file;
 }
diff --git a/lis-services/src/main/java/hu/user/lis/services/data/AssociateService.java b/lis-services/src/main/java/hu/user/lis/services/data/AssociateService.java
new file mode 100644 (file)
index 0000000..8c82603
--- /dev/null
@@ -0,0 +1,23 @@
+package hu.user.lis.services.data;
+
+import hu.user.lis.db.Associate;
+
+import java.util.List;
+
+public interface AssociateService {
+    List<Associate> getAll();
+
+    Associate createNew();
+
+    void add(Associate entity);
+
+    Associate getRandom();
+
+    Associate copy(Associate sourceEntity);
+
+    void replace(Associate targetEntity, Associate replacementEntity);
+
+    String toString(Associate sourceEntity);
+
+    Associate copy(Associate sourceEntity, String property, Object value);
+}
diff --git a/lis-services/src/main/java/hu/user/lis/services/data/AssociateServiceImpl.java b/lis-services/src/main/java/hu/user/lis/services/data/AssociateServiceImpl.java
new file mode 100644 (file)
index 0000000..e112dcd
--- /dev/null
@@ -0,0 +1,105 @@
+package hu.user.lis.services.data;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import hu.user.lis.db.Associate;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.RandomUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+@Log4j2
+public class AssociateServiceImpl implements AssociateService {
+    @Autowired
+    ObjectMapper mapper;
+    @Autowired
+    DataGeneratorService dataGeneratorService;
+    private List<Associate> entities;
+
+    @Override
+    public List<Associate> getAll() {
+        if (entities == null) {
+            entities = generate();
+        }
+        return entities;
+    }
+
+    @Override
+    public Associate createNew() {
+        String id = RandomStringUtils.random(8, "0123456789abcdef");
+        return Associate.builder().id(id).active(true).build();
+    }
+
+    @Override
+    public void add(Associate entity) {
+        entities.add(entity);
+    }
+
+    @Override
+    public void replace(Associate targetEntity, Associate replacementEntity) {
+        Associate listEntity = entities.stream().filter(p -> p.getId().equals(targetEntity.getId())).findFirst().get();
+        entities.remove(listEntity);
+        entities.add(replacementEntity);
+    }
+
+    @Override
+    public Associate getRandom() {
+        return getAll().get(RandomUtils.nextInt(0, entities.size()));
+    }
+
+    private List<Associate> generate() {
+        List<Associate> result = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            String id = RandomStringUtils.random(8, "0123456789abcdef");
+            String name = dataGeneratorService.faker().name().fullName();
+
+            Associate entity = Associate.builder().active(true).id(id).name(name).build();
+            result.add(entity);
+        }
+        return result;
+    }
+
+    @Override
+    public Associate copy(Associate sourceEntity) {
+        Associate result = null;
+        try {
+            String json = toString(sourceEntity);
+            result = mapper.readValue(json, Associate.class);
+        } catch (JsonProcessingException e) {
+            log.catching(e);
+        }
+        return result;
+    }
+
+    @Override
+    public String toString(Associate sourceEntity) {
+        String result = null;
+        try {
+            result = mapper.writeValueAsString(sourceEntity);
+        } catch (JsonProcessingException e) {
+            log.catching(e);
+        }
+        return result;
+    }
+
+    @Override
+    public Associate copy(Associate sourceEntity, String property, Object value) {
+        Associate result = copy(sourceEntity);
+        Field field = null;
+        try {
+            field = result.getClass().getDeclaredField(property);
+            field.setAccessible(true);
+            field.set(result, value);
+        } catch (Exception e) {
+            log.catching(e);
+        }
+        return result;
+    }
+
+}
index a51a57143f1e8b67c325fc8ea8f127acffddd619..973b79ebe3a84d0e70b44f8af16097f50ff12f29 100644 (file)
@@ -1,6 +1,5 @@
 package hu.user.lis.services.data;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
 import hu.user.lis.db.Invoice;
 
 import java.util.List;
@@ -12,11 +11,11 @@ public interface InvoiceService {
 
     void add(Invoice entity);
 
-    Invoice copy(Invoice sourceEntity) throws JsonProcessingException;
+    Invoice copy(Invoice sourceEntity);
 
-    String toString(Invoice sourceEntity) throws JsonProcessingException;
+    String toString(Invoice sourceEntity);
 
-    Invoice copy(Invoice sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException;
+    Invoice copy(Invoice sourceEntity, String property, Object value);
 
     void replace(Invoice targetEntity, Invoice replacementEntity);
 
index e2c18c0cbd296db1dbe7702130d0f0401e658869..36816383b52251dfdd77a05a3a60753dc6b3dbb5 100644 (file)
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import hu.user.lis.db.Currency;
 import hu.user.lis.db.Invoice;
 import hu.user.lis.db.Partner;
+import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.RandomUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -20,16 +21,17 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 @Service
+@Log4j2
 public class InvoiceServiceImpl implements InvoiceService {
     int GENERATE_COUNT = 1000;
-    private List<Invoice> incomingEntities;
-    private List<Invoice> outgoingEntities;
     @Autowired
     DataGeneratorService dataGeneratorService;
     @Autowired
     PartnerService partnerService;
     @Autowired
     ObjectMapper mapper;
+    private List<Invoice> incomingEntities;
+    private List<Invoice> outgoingEntities;
 
     @Override
     public List<Invoice> getAll() {
@@ -55,7 +57,7 @@ public class InvoiceServiceImpl implements InvoiceService {
     @Override
     public Invoice createNew() {
         String id = RandomStringUtils.random(8, "0123456789abcdef");
-        return Invoice.builder().id(id).build();
+        return Invoice.builder().id(id).planned(true).build();
     }
 
     @Override
@@ -119,22 +121,40 @@ public class InvoiceServiceImpl implements InvoiceService {
     }
 
     @Override
-    public Invoice copy(Invoice sourceEntity) throws JsonProcessingException {
-        String json = toString(sourceEntity);
-        return mapper.readValue(json, Invoice.class);
+    public Invoice copy(Invoice sourceEntity) {
+        Invoice result = null;
+        try {
+            String json = toString(sourceEntity);
+            result = mapper.readValue(json, Invoice.class);
+        } catch (JsonProcessingException e) {
+            log.catching(e);
+        }
+        return result;
     }
 
     @Override
-    public String toString(Invoice sourceEntity) throws JsonProcessingException {
-        return mapper.writeValueAsString(sourceEntity);
+    public String toString(Invoice sourceEntity) {
+        String result = null;
+        try {
+            result = mapper.writeValueAsString(sourceEntity);
+        } catch (JsonProcessingException e) {
+            log.catching(e);
+        }
+        return result;
     }
 
     @Override
-    public Invoice copy(Invoice sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException {
+    public Invoice copy(Invoice sourceEntity, String property, Object value) {
         Invoice result = copy(sourceEntity);
-        Field field = result.getClass().getDeclaredField(property);
-        field.setAccessible(true);
-        field.set(result, value);
+        Field field = null;
+        try {
+            field = result.getClass().getDeclaredField(property);
+            field.setAccessible(true);
+            field.set(result, value);
+        } catch (Exception e) {
+            log.catching(e);
+        }
         return result;
     }
+
 }
index ea4ac67c3f9367d0e345e0166298b0753f832189..adfba1cf1cb040e83d35a824a6ea4cadb9353445 100644 (file)
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.github.javafaker.Address;
 import hu.user.lis.db.Partner;
+import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.RandomUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -14,13 +15,13 @@ import java.util.ArrayList;
 import java.util.List;
 
 @Service
+@Log4j2
 public class PartnerServiceImpl implements PartnerService {
-    private List<Partner> entities;
-
     @Autowired
     ObjectMapper mapper;
     @Autowired
     DataGeneratorService dataGeneratorService;
+    private List<Partner> entities;
 
     @Override
     public List<Partner> getAll() {
@@ -72,22 +73,40 @@ public class PartnerServiceImpl implements PartnerService {
     }
 
     @Override
-    public Partner copy(Partner sourceEntity) throws JsonProcessingException {
-        String json = toString(sourceEntity);
-        return mapper.readValue(json, Partner.class);
+    public Partner copy(Partner sourceEntity) {
+        Partner result = null;
+        try {
+            String json = toString(sourceEntity);
+            result = mapper.readValue(json, Partner.class);
+        } catch (JsonProcessingException e) {
+            log.catching(e);
+        }
+        return result;
     }
 
     @Override
-    public String toString(Partner sourceEntity) throws JsonProcessingException {
-        return mapper.writeValueAsString(sourceEntity);
+    public String toString(Partner sourceEntity) {
+        String result = null;
+        try {
+            result = mapper.writeValueAsString(sourceEntity);
+        } catch (JsonProcessingException e) {
+            log.catching(e);
+        }
+        return result;
     }
 
     @Override
-    public Partner copy(Partner sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException {
+    public Partner copy(Partner sourceEntity, String property, Object value) {
         Partner result = copy(sourceEntity);
-        Field field = result.getClass().getDeclaredField(property);
-        field.setAccessible(true);
-        field.set(result, value);
+        Field field = null;
+        try {
+            field = result.getClass().getDeclaredField(property);
+            field.setAccessible(true);
+            field.set(result, value);
+        } catch (Exception e) {
+            log.catching(e);
+        }
         return result;
     }
+
 }
index 5f5b5acd92fb965b650f12f8c94b220e1b664962..d5f1e649b1d9f59f8198dc41ba33f48d47b284c3 100644 (file)
@@ -1,6 +1,5 @@
 package hu.user.lis.services.data;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
 import hu.user.lis.db.Project;
 
 import java.util.List;
@@ -12,13 +11,13 @@ public interface ProjectService {
 
     void add(Project entity);
 
-    Project copy(Project sourceEntity) throws JsonProcessingException;
+    Project copy(Project sourceEntity);
 
     void replace(Project targetEntity, Project replacementEntity);
 
     boolean isInvalid(Project entity);
 
-    String toString(Project sourceEntity) throws JsonProcessingException;
+    String toString(Project sourceEntity);
 
-    Project copy(Project sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException;
+    Project copy(Project sourceEntity, String property, Object value);
 }
index 41b6f4181d226f49ce07473ab978e1878b88d732..b450774e290ef2bb338da6d5a1c86950df971758 100644 (file)
@@ -100,22 +100,39 @@ public class ProjectServiceImpl implements ProjectService {
     }
 
     @Override
-    public Project copy(Project sourceEntity) throws JsonProcessingException {
-        String json = toString(sourceEntity);
-        return mapper.readValue(json, Project.class);
+    public Project copy(Project sourceEntity) {
+        Project result = null;
+        try {
+            String json = toString(sourceEntity);
+            result = mapper.readValue(json, Project.class);
+        } catch (JsonProcessingException e) {
+            log.catching(e);
+        }
+        return result;
     }
 
     @Override
-    public String toString(Project sourceEntity) throws JsonProcessingException {
-        return mapper.writeValueAsString(sourceEntity);
+    public String toString(Project sourceEntity) {
+        String result = null;
+        try {
+            result = mapper.writeValueAsString(sourceEntity);
+        } catch (JsonProcessingException e) {
+            log.catching(e);
+        }
+        return result;
     }
 
     @Override
-    public Project copy(Project sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException {
+    public Project copy(Project sourceEntity, String property, Object value) {
         Project result = copy(sourceEntity);
-        Field field = result.getClass().getDeclaredField(property);
-        field.setAccessible(true);
-        field.set(result, value);
+        Field field = null;
+        try {
+            field = result.getClass().getDeclaredField(property);
+            field.setAccessible(true);
+            field.set(result, value);
+        } catch (Exception e) {
+            log.catching(e);
+        }
         return result;
     }
 }
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/Constants.java b/lis-ui/src/main/java/hu/user/lis/ui/Constants.java
new file mode 100644 (file)
index 0000000..4294b18
--- /dev/null
@@ -0,0 +1,9 @@
+package hu.user.lis.ui;
+
+public class Constants {
+    public static final String SHOW_PROJECT_EDITOR = "SHOW_PROJECT_EDITOR";
+    public static final String SHOW_PROJECTS_LIST = "SHOW_PROJECTS_LIST";
+    public static final String SET_PROJECT_EDITOR_DATA = "SET_PROJECT_EDITOR_DATA";
+    public static final String SET_PROJECTS_LIST_DATA = "SET_PROJECTS_LIST_DATA";
+    public static final String PROJECT_EDITOR_QUEUE = "PROJECT_EDITOR_QUEUE";
+}
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/converter/ByteArrayToAMediaConverter.java b/lis-ui/src/main/java/hu/user/lis/ui/converter/ByteArrayToAMediaConverter.java
new file mode 100644 (file)
index 0000000..9d600c9
--- /dev/null
@@ -0,0 +1,24 @@
+package hu.user.lis.ui.converter;
+
+import org.zkoss.bind.BindContext;
+import org.zkoss.bind.Converter;
+import org.zkoss.util.media.AMedia;
+import org.zkoss.zul.Iframe;
+
+import java.util.Objects;
+
+public class ByteArrayToAMediaConverter implements Converter<AMedia, byte[], Iframe> {
+
+    @Override
+    public AMedia coerceToUi(byte[] data, Iframe iframe, BindContext bindContext) {
+        if (Objects.isNull(data)) {
+            return null;
+        }
+        return new AMedia("Számlakép", "pdf", "application/pdf", data);
+    }
+
+    @Override
+    public byte[] coerceToBean(AMedia media, Iframe iframe, BindContext bindContext) {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/event/EventBus.java b/lis-ui/src/main/java/hu/user/lis/ui/event/EventBus.java
new file mode 100644 (file)
index 0000000..52b22d2
--- /dev/null
@@ -0,0 +1,41 @@
+package hu.user.lis.ui.event;
+
+import hu.user.lis.ui.Constants;
+import org.springframework.stereotype.Service;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.EventQueue;
+import org.zkoss.zk.ui.event.EventQueues;
+
+@Service
+public class EventBus {
+    private EventQueue<Event> queue;
+
+    public EventBus() {
+        queue = EventQueues.lookup(Constants.PROJECT_EDITOR_QUEUE, EventQueues.APPLICATION, true);
+    }
+
+    public void register(EventListener listener) {
+        queue.subscribe(listener);
+    }
+
+    public void unregister(EventListener listener) {
+        queue.unsubscribe(listener);
+    }
+
+    public void showProjectsList(Object data) {
+        queue.publish(new Event(Constants.SHOW_PROJECTS_LIST, null, data));
+    }
+
+    public void showProjectEditor(Object data) {
+        queue.publish(new Event(Constants.SHOW_PROJECT_EDITOR, null, data));
+    }
+
+    public void setProjectEditorData(Object data) {
+        queue.publish(new Event(Constants.SET_PROJECT_EDITOR_DATA, null, data));
+    }
+
+    public void setProjectsListData(Object data) {
+        queue.publish(new Event(Constants.SET_PROJECTS_LIST_DATA, null, data));
+    }
+}
index 051ea26e736bc0b1ebddcd487d1996cb213995d3..5dd56961906b8e323c796c790dabb8b56fd7b5ec 100644 (file)
@@ -1,7 +1,5 @@
 package hu.user.lis.ui.view;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 import org.zkoss.bind.BindUtils;
 import org.zkoss.bind.annotation.Command;
 
@@ -10,7 +8,6 @@ import java.util.Arrays;
 import java.util.List;
 
 public class AsyncBaseModel {
-    private static final Logger logger = LogManager.getLogger();
     private List<UITask> uiTasks = new ArrayList<>();
 
     protected void doKeepAlive() {
@@ -39,5 +36,4 @@ public class AsyncBaseModel {
             uiTasks.clear();
         }
     }
-
 }
index a98106857342ee50bc65dab6af83f991eeb2e504..35b3686c50fbb748ac6d4ae7a33a1a41f245fca5 100644 (file)
@@ -1,38 +1,81 @@
 package hu.user.lis.ui.view;
 
+import com.google.common.collect.ImmutableMap;
+import hu.user.lis.ui.Constants;
+import hu.user.lis.ui.event.EventBus;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
 import org.springframework.boot.info.BuildProperties;
+import org.zkoss.bind.BindUtils;
+import org.zkoss.bind.annotation.BindingParam;
+import org.zkoss.bind.annotation.Command;
+import org.zkoss.bind.annotation.Destroy;
 import org.zkoss.bind.annotation.Init;
 import org.zkoss.zk.ui.Executions;
 import org.zkoss.zk.ui.event.Event;
-import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zk.ui.event.EventListener;
 import org.zkoss.zk.ui.select.annotation.VariableResolver;
 import org.zkoss.zk.ui.select.annotation.WireVariable;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
 
 @Log4j2
 @VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
 @Getter
 @Setter
-public class IndexViewModel {
+public class IndexViewModel implements EventListener {
+    public static final String PROJECT_EDITOR_PAGE = "~./project-editor.zul";
+    private static final String PARTNERS_LIST = "~./partners.zul";
+    private static final String PROJECTS_LIST = "~./projects.zul";
     @WireVariable
     BuildProperties buildProperties;
+    @WireVariable
+    EventBus eventBus;
     String searchPhrase;
-    int selectedPage;
-
+    String page;
+    private Map<String, String> navigation = ImmutableMap.of(
+            "/projects", PROJECTS_LIST
+    );
 
     @Init
     public void init() {
         HttpServletRequest nativeRequest = (HttpServletRequest) Executions.getCurrent().getNativeRequest();
         String path = (String) Executions.getCurrent().getAttribute("javax.servlet.forward.servlet_path");
-        if ("/projects".equals(path)) {
-            Events.postEvent(new Event("onFulFillProjectsTab"));
+        if (navigation.containsKey(path)) {
+            setPage(navigation.get(path));
+        } else {
+            setPage(PARTNERS_LIST);
         }
+        eventBus.register(this);
         log.info("Init {}", path);
     }
 
 
+    @Command
+    public void selectPage(@BindingParam("page") String page) {
+        setPage(page);
+        BindUtils.postNotifyChange(this, "page");
+    }
+
+    @Override
+    public void onEvent(Event event) {
+        if (Constants.SHOW_PROJECT_EDITOR.equals(event.getName())) {
+            selectPage(PROJECT_EDITOR_PAGE);
+            eventBus.setProjectEditorData(event.getData());
+        }
+        if (Constants.SHOW_PROJECTS_LIST.equals(event.getName())) {
+            selectPage(PROJECTS_LIST);
+            if (event.getData() != null) {
+                eventBus.setProjectsListData(event.getData());
+            }
+        }
+    }
+
+    @Destroy
+    public void onDestroy() {
+        log.info("Destroy {}");
+        eventBus.unregister(this);
+    }
 }
index c98ce1264d2f7e1cb62ff0c27cd8f9e70548de14..5d54d109b454f93669365b214695052d0f22dd9b 100644 (file)
@@ -15,10 +15,7 @@ import org.zkoss.bind.annotation.*;
 import org.zkoss.bind.validator.AbstractValidator;
 import org.zkoss.zk.ui.Component;
 import org.zkoss.zk.ui.Executions;
-import org.zkoss.zk.ui.event.Event;
-import org.zkoss.zk.ui.event.Events;
-import org.zkoss.zk.ui.event.InputEvent;
-import org.zkoss.zk.ui.event.OpenEvent;
+import org.zkoss.zk.ui.event.*;
 import org.zkoss.zk.ui.select.annotation.VariableResolver;
 import org.zkoss.zk.ui.select.annotation.WireVariable;
 import org.zkoss.zkplus.spring.DelegatingVariableResolver;
@@ -86,37 +83,56 @@ public class InvoiceEditorModel extends AbstractValidator {
         String property = ctx.getProperty().getProperty();
         Object value = ctx.getProperty().getValue();
         log.info("Validating caused by {} {} {}", target.getId(), property, value);
-        updateFormInvalid(false);
         try {
             Invoice newData = invoiceServiceImpl.copy(formDocument, property, value);
-            if (!Objects.isNull(origDocument) && invoiceServiceImpl.toString(origDocument).equals(invoiceServiceImpl.toString(newData))) {
-                log.info("Document not changed");
-                updateFormInvalid(true);
-                return;
-            }
-
-            if (newData.getNetAmount() <= 0 ||
-                    newData.getGrossAmount() <= 0 ||
-                    newData.getVatAmount() <= 0 ||
-                    StringUtils.isBlank(newData.getTitle()) ||
-                    Objects.isNull(newData.getPartner()) ||
-                    Objects.isNull(newData.getCompletionDate()) ||
-                    Objects.isNull(newData.getCreateDate()) ||
-                    Objects.isNull(newData.getPaymentDeadline()) ||
-                    newData.getCreateDate().after(newData.getCompletionDate()) ||
-                    newData.getCompletionDate().after(newData.getPaymentDeadline())
-            ) {
-                log.info("Document is not valid");
-                updateFormInvalid(true);
-            }
+            validate(newData);
         } catch (Exception e) {
             log.catching(e);
         }
 
     }
 
+    private void validate(Invoice newData) {
+        updateFormInvalid(false);
+        if (!Objects.isNull(origDocument) && invoiceServiceImpl.toString(origDocument).equals(invoiceServiceImpl.toString(newData))) {
+            log.info("Document not changed");
+            updateFormInvalid(true);
+            return;
+        }
+
+        if (newData.getNetAmount() <= 0 ||
+                newData.getGrossAmount() <= 0 ||
+                newData.getVatAmount() <= 0 ||
+                StringUtils.isBlank(newData.getTitle()) ||
+                Objects.isNull(newData.getPartner()) ||
+                Objects.isNull(newData.getCompletionDate()) ||
+                Objects.isNull(newData.getCreateDate()) ||
+                Objects.isNull(newData.getPaymentDeadline()) ||
+                newData.getCreateDate().after(newData.getCompletionDate()) ||
+                newData.getCompletionDate().after(newData.getPaymentDeadline())
+        ) {
+            log.info("Document is not valid");
+            updateFormInvalid(true);
+        }
+    }
+
     private void updateFormInvalid(boolean invalid) {
         setFormInvalid(invalid);
         BindUtils.postNotifyChange(this, "formInvalid");
     }
+
+    @Command
+    public void onUploadFile(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
+        UploadEvent evt = (UploadEvent) ctx.getTriggerEvent();
+        formDocument.setFile(evt.getMedia().getByteData());
+        BindUtils.postNotifyChange(this.formDocument, "file");
+        validate(invoiceServiceImpl.copy(formDocument));
+    }
+
+    @Command
+    public void onRemoveFile() {
+        formDocument.setFile(null);
+        BindUtils.postNotifyChange(this.formDocument, "file");
+        validate(invoiceServiceImpl.copy(formDocument));
+    }
 }
index 347ae0ec454f138d070cfee568bd3d5a396c4124..0ad8556dc466abe6cb2d3044b507b125c5c2ee12 100644 (file)
@@ -24,18 +24,17 @@ import java.util.Set;
 @Log4j2
 @VariableResolver(DelegatingVariableResolver.class)
 public class PartnersViewModel extends AsyncBaseModel {
-    @Getter
-    private Partner selectedPartner;
     @WireVariable
     @Getter
     PartnersDataModel partnersDataModel;
+    @Wire
+    Listbox partnersList;
+    @Getter
+    private Partner selectedPartner;
     private boolean filterShowInActive;
     private boolean filterShowActive;
     private boolean filterShowBoth;
 
-    @Wire
-    Listbox partnersList;
-
     @AfterCompose
     public void onAfterCompose(@ContextParam(ContextType.VIEW) Component view) {
         Selectors.wireComponents(view, this, false);
@@ -80,7 +79,7 @@ public class PartnersViewModel extends AsyncBaseModel {
 
     @Command
     public void onAdd() {
-        String page = "~./partner.zul";
+        String page = "~./partner-editor.zul";
         Partner newEntity = partnersDataModel.getPartnerService().createNew();
         Window editorWindow = (Window) Executions.createComponents(page, null,
                 Collections.singletonMap("formDocument", newEntity));
@@ -108,7 +107,7 @@ public class PartnersViewModel extends AsyncBaseModel {
 
     @Command
     public void onEdit() throws JsonProcessingException {
-        String page = "~./partner.zul";
+        String page = "~./partner-editor.zul";
         Partner editEntity = partnersDataModel.getPartnerService().copy(selectedPartner);
         Map<String, Object> arg = new HashMap<>();
         arg.put("origDocument", selectedPartner);
index ffa02f14976755497a6d9fc5602f8652708ee949..d303f7cfd05db3f0a7bb97b2c59f6ee831a61242 100644 (file)
@@ -1,11 +1,14 @@
 package hu.user.lis.ui.view;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.collect.ImmutableMap;
 import hu.user.lis.db.Invoice;
 import hu.user.lis.db.Project;
 import hu.user.lis.services.data.InvoiceService;
 import hu.user.lis.services.data.ProjectService;
+import hu.user.lis.ui.Constants;
 import hu.user.lis.ui.data.PartnerSelectorDataModel;
+import hu.user.lis.ui.event.EventBus;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
@@ -18,12 +21,14 @@ import org.zkoss.bind.validator.AbstractValidator;
 import org.zkoss.zk.ui.Component;
 import org.zkoss.zk.ui.Executions;
 import org.zkoss.zk.ui.event.Event;
-import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zk.ui.event.EventListener;
 import org.zkoss.zk.ui.event.InputEvent;
 import org.zkoss.zk.ui.event.OpenEvent;
 import org.zkoss.zk.ui.select.annotation.VariableResolver;
 import org.zkoss.zk.ui.select.annotation.WireVariable;
 import org.zkoss.zkplus.spring.DelegatingVariableResolver;
+import org.zkoss.zul.Center;
+import org.zkoss.zul.Panel;
 import org.zkoss.zul.Window;
 
 import java.util.*;
@@ -32,7 +37,7 @@ import java.util.*;
 @Getter
 @Setter
 @VariableResolver(DelegatingVariableResolver.class)
-public class ProjectEditorModel extends AbstractValidator {
+public class ProjectEditorModel extends AbstractValidator implements EventListener {
     private Project formDocument;
     private Project origDocument;
     @WireVariable
@@ -41,25 +46,37 @@ public class ProjectEditorModel extends AbstractValidator {
     private InvoiceService invoiceServiceImpl;
     @WireVariable
     private ProjectService projectServiceImpl;
+    @WireVariable
+    private EventBus eventBus;
     private boolean formInvalid = true;
     private Invoice selectedIncomingInvoice;
     private Invoice selectedOutgoingInvoice;
 
+    public ProjectEditorModel() {
+
+    }
+
     @Init
     public void init() {
+        eventBus.register(this);
         log.info("Initialized");
-        origDocument = (Project) Executions.getCurrent().getArg().get("origDocument");
-        formDocument = (Project) Executions.getCurrent().getArg().get("formDocument");
-        partnerSelectorDataModel.clearSelection();
     }
 
+
     @Command
-    public void onCloseWindow(@BindingParam("target") Window target, @BindingParam("select") boolean select) {
+    public void onEndEdit(@BindingParam("target") Window target, @BindingParam("select") boolean select) {
         if (select && formInvalid) {
             return;
         }
-        Event closeEvent = new Event("onClose", target, select ? formDocument : null);
-        Events.postEvent(closeEvent);
+        Map<String, Project> args = null;
+        if (select) {
+            if (Objects.isNull(origDocument)) {
+                args = ImmutableMap.of("formDocument", formDocument);
+            } else {
+                args = ImmutableMap.of("origDocument", origDocument, "formDocument", formDocument);
+            }
+        }
+        eventBus.showProjectsList(args);
     }
 
     @Command
@@ -106,7 +123,7 @@ public class ProjectEditorModel extends AbstractValidator {
         }
     }
 
-    private void validate(Project newData) throws JsonProcessingException {
+    private void validate(Project newData) {
         updateFormInvalid(false);
         if (!Objects.isNull(origDocument) && projectServiceImpl.toString(origDocument).equals(projectServiceImpl.toString(newData))) {
             log.info("Document not changed");
@@ -125,7 +142,7 @@ public class ProjectEditorModel extends AbstractValidator {
 
     @Command
     public void onAddIncoming() {
-        String page = "~./invoice.zul";
+        String page = "~./incoming-invoice-editor.zul";
         Invoice editEntity = invoiceServiceImpl.createNew();
         editEntity.setIncome(true);
         Window editorWindow = (Window) Executions.createComponents(page, null,
@@ -136,8 +153,7 @@ public class ProjectEditorModel extends AbstractValidator {
                 selectedIncomingInvoice = editEntity;
                 BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
                 BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
-                Project newData = projectServiceImpl.copy(formDocument);
-                validate(newData);
+                validate(projectServiceImpl.copy(formDocument));
             }
         });
         editorWindow.doModal();
@@ -145,7 +161,7 @@ public class ProjectEditorModel extends AbstractValidator {
 
     @Command
     public void onEditIncoming() throws JsonProcessingException {
-        String page = "~./invoice.zul";
+        String page = "~./incoming-invoice-editor.zul";
         Invoice editEntity = invoiceServiceImpl.copy(selectedIncomingInvoice);
         Map<String, Object> arg = new HashMap<>();
         arg.put("origDocument", selectedIncomingInvoice);
@@ -161,8 +177,7 @@ public class ProjectEditorModel extends AbstractValidator {
                 selectedIncomingInvoice = modifiedEntity;
                 BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
                 BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
-                Project newData = projectServiceImpl.copy(formDocument);
-                validate(newData);
+                validate(projectServiceImpl.copy(formDocument));
             }
         });
         editorWindow.doModal();
@@ -177,11 +192,12 @@ public class ProjectEditorModel extends AbstractValidator {
         selectedIncomingInvoice = null;
         BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
         BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
+        validate(projectServiceImpl.copy(formDocument));
     }
 
     @Command
     public void onAddOutgoing() {
-        String page = "~./invoice.zul";
+        String page = "~./outgoing-invoice-editor.zul";
         Invoice editEntity = invoiceServiceImpl.createNew();
         Window editorWindow = (Window) Executions.createComponents(page, null,
                 Collections.singletonMap("formDocument", editEntity));
@@ -191,8 +207,7 @@ public class ProjectEditorModel extends AbstractValidator {
                 selectedOutgoingInvoice = editEntity;
                 BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
                 BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
-                Project newData = projectServiceImpl.copy(formDocument);
-                validate(newData);
+                validate(projectServiceImpl.copy(formDocument));
             }
         });
         editorWindow.doModal();
@@ -200,7 +215,7 @@ public class ProjectEditorModel extends AbstractValidator {
 
     @Command
     public void onEditOutgoing() throws JsonProcessingException {
-        String page = "~./invoice.zul";
+        String page = "~./outgoing-invoice-editor.zul";
         Invoice editEntity = invoiceServiceImpl.copy(selectedOutgoingInvoice);
         Map<String, Object> arg = new HashMap<>();
         arg.put("origDocument", selectedOutgoingInvoice);
@@ -216,8 +231,7 @@ public class ProjectEditorModel extends AbstractValidator {
                 selectedOutgoingInvoice = modifiedEntity;
                 BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
                 BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
-                Project newData = projectServiceImpl.copy(formDocument);
-                validate(newData);
+                validate(projectServiceImpl.copy(formDocument));
             }
         });
         editorWindow.doModal();
@@ -232,10 +246,40 @@ public class ProjectEditorModel extends AbstractValidator {
         selectedOutgoingInvoice = null;
         BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
         BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
+        validate(projectServiceImpl.copy(formDocument));
     }
 
     private void updateFormInvalid(boolean invalid) {
         setFormInvalid(invalid);
         BindUtils.postNotifyChange(this, "formInvalid");
     }
+
+    @Override
+    public void onEvent(Event evt) {
+        if (Constants.SET_PROJECT_EDITOR_DATA.equals(evt.getName())) {
+            Map<String, Object> data = (Map<String, Object>) evt.getData();
+            origDocument = (Project) data.get("origDocument");
+            formDocument = (Project) data.get("formDocument");
+            BindUtils.postNotifyChange(this, "formDocument");
+        }
+    }
+
+    @Destroy
+    public void onDestroy() {
+        log.info("Destroy {}");
+        eventBus.unregister(this);
+    }
+
+    @Command
+    public void onOpenInvoicePanel(@BindingParam("parentPanel") Center parentPanel) {
+        log.info("Invoice panel open/close");
+        parentPanel.invalidate();
+    }
+
+    @Command
+    public void onClickInvoicePanel(@BindingParam("parentPanel") Center parentPanel, @BindingParam("panel") Panel panel) {
+        log.info("Invoice panel click");
+        panel.setOpen(!panel.isOpen());
+        parentPanel.invalidate();
+    }
 }
index ba355e36f1e85a2051b7d3c82b9dc81d6814b866..6c27919f79bf59da3eba3c10ad0ea275fb32a775 100644 (file)
@@ -1,32 +1,35 @@
 package hu.user.lis.ui.view;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.collect.ImmutableMap;
 import hu.user.lis.db.Project;
+import hu.user.lis.ui.Constants;
 import hu.user.lis.ui.data.ProjectsDataModel;
+import hu.user.lis.ui.event.EventBus;
 import lombok.Getter;
 import lombok.extern.log4j.Log4j2;
 import org.zkoss.bind.annotation.*;
 import org.zkoss.zk.ui.Component;
-import org.zkoss.zk.ui.Executions;
+import org.zkoss.zk.ui.event.Event;
+import org.zkoss.zk.ui.event.EventListener;
 import org.zkoss.zk.ui.select.Selectors;
 import org.zkoss.zk.ui.select.annotation.VariableResolver;
 import org.zkoss.zk.ui.select.annotation.WireVariable;
 import org.zkoss.zkplus.spring.DelegatingVariableResolver;
-import org.zkoss.zul.Window;
 
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
+
 @Log4j2
 @VariableResolver(DelegatingVariableResolver.class)
-public class ProjectsViewModel extends AsyncBaseModel {
-    @Getter
-    private Project selectedProject;
+public class ProjectsViewModel extends AsyncBaseModel implements EventListener {
     @WireVariable
     @Getter
     ProjectsDataModel projectsDataModel;
+    @WireVariable
+    EventBus eventBus;
+    @Getter
+    private Project selectedProject;
     private boolean filterShowInActive;
     private boolean filterShowActive;
     private boolean filterShowBoth;
@@ -39,8 +42,9 @@ public class ProjectsViewModel extends AsyncBaseModel {
 
     @Init
     public void init() {
-        log.info("Initialized");
         setFilterShowActive(true);
+        eventBus.register(this);
+        log.info("Initialized");
     }
 
     private void refresh() {
@@ -73,53 +77,15 @@ public class ProjectsViewModel extends AsyncBaseModel {
     public void onAdd() {
         String page = "~./project.zul";
         Project newEntity = projectsDataModel.getProjectService().createNew();
-        Window partnerWindow = (Window) Executions.createComponents(page, null,
-                Collections.singletonMap("formDocument", newEntity));
-        partnerWindow.addEventListener("onClose", e -> {
-            if (e.getData() != null) {
-                log.info("Partner popup result {}", e.getData());
-                projectsDataModel.getProjectService().add(newEntity);
-                projectsDataModel.clearSelection();
-                refresh();
-                projectsDataModel.addToSelection(newEntity);
-                selectedProject = newEntity;
-//                Optional<Listitem> listItem = partnersList.getItems().stream()
-//                        .filter(li -> ((Partner) li.getValue()).getId().equals(editPartner.getId()))
-//                        .findFirst();
-//                if (listItem.isPresent()) {
-//                    Clients.scrollIntoView(listItem.get());
-//                }
-//                registerTask(() -> {
-//                });
-            }
-        });
-        partnerWindow.doModal();
+        eventBus.showProjectEditor(ImmutableMap.of("formDocument", newEntity));
     }
 
     @Command
-    public void onEdit() throws JsonProcessingException {
-        String page = "~./project.zul";
+    public void onEdit() {
         Project editEntity = projectsDataModel.getProjectService().copy(selectedProject);
-        Map<String, Object> arg = new HashMap<>();
-        arg.put("origDocument", selectedProject);
-        arg.put("formDocument", editEntity);
-
-        Window partnerWindow = (Window) Executions.createComponents(page, null, arg);
-        partnerWindow.addEventListener("onClose", e -> {
-            if (e.getData() != null) {
-                log.info("Project popup result {}", e.getData());
-                Project modifiedEntity = (Project) e.getData();
-                projectsDataModel.clearSelection();
-                projectsDataModel.getProjectService().replace(selectedProject, modifiedEntity);
-                refresh();
-                projectsDataModel.addToSelection(modifiedEntity);
-                selectedProject = modifiedEntity;
-            }
-        });
-        partnerWindow.doModal();
+        eventBus.showProjectEditor(ImmutableMap.of("origDocument", selectedProject, "formDocument", editEntity));
     }
 
-
     public boolean isFilterShowInActive() {
         return filterShowInActive;
     }
@@ -155,4 +121,30 @@ public class ProjectsViewModel extends AsyncBaseModel {
         this.filterShowBoth = filterShowBoth;
         refresh();
     }
+
+    @Override
+    public void onEvent(Event event) {
+        if (Constants.SET_PROJECTS_LIST_DATA.equals(event.getName())) {
+            log.info("Apply Project edit result");
+            projectsDataModel.clearSelection();
+            Map<String, Project> args = (Map<String, Project>) event.getData();
+            Project formDocument = args.get("formDocument");
+            if (args.containsKey("origDocument")) {
+                Project origDocument = args.get("origDocument");
+                projectsDataModel.getProjectService().replace(origDocument, formDocument);
+            } else {
+                projectsDataModel.getProjectService().add(formDocument);
+            }
+            refresh();
+            projectsDataModel.addToSelection(formDocument);
+            selectedProject = formDocument;
+        }
+    }
+
+    @Destroy
+    public void onDestroy() {
+        log.info("Destroy {}");
+        eventBus.unregister(this);
+    }
+
 }
diff --git a/lis-ui/src/main/resources/web/incoming-invoice-editor.zul b/lis-ui/src/main/resources/web/incoming-invoice-editor.zul
new file mode 100644 (file)
index 0000000..7a66daa
--- /dev/null
@@ -0,0 +1,118 @@
+<?link rel="stylesheet" type="text/css" href="~./static/css/skeleton.css" ?>
+<?link rel="stylesheet" type="text/css" href="~./static/css/webclient.css" ?>
+<?component name="partner-selector" inline="true" macroURI="~./partner-selector.zul"?>
+<zk>
+    <zscript>
+        import hu.user.lis.db.Currency;
+        ListModelList currencies = new ListModelList(Currency.values());
+    </zscript>
+    <window id="invoicePopup" title="Bejövő számla szerkesztés" width="50%" height="50%" closable="true"
+            viewModel="@id('vm') @init('hu.user.lis.ui.view.InvoiceEditorModel')">
+        <borderlayout>
+            <center border="none" vflex="true" hflex="true">
+                <tabbox vflex="true" hflex="true">
+                    <tabs>
+                        <tab label="Adatok" selected="true"/>
+                        <tab label="Számlakép"/>
+                    </tabs>
+                    <tabpanels>
+                        <tabpanel>
+                            <vlayout hflex="true">
+                                <label value="Leírás"/>
+                                <textbox hflex="true" instant="true"
+                                         value="@bind(vm.formDocument.title) @validator(vm)"
+                                         forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                <label value="Partner"/>
+                                <partner-selector/>
+                                <hlayout>
+                                    <vlayout>
+                                        <label value="Tervezett"/>
+                                        <checkbox mold="switch" checked="@bind(vm.formDocument.planned)"/>
+                                    </vlayout>
+                                    <vlayout>
+                                        <label value="Pénznem"/>
+                                        <combobox instant="true" model="${currencies}"
+                                                  selectedItem="@bind(vm.formDocument.currency) @validator(vm)"
+                                                  onChange="@command('onNetAmountChange')"
+                                                  forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+
+                                    </vlayout>
+                                    <vlayout>
+                                        <label value="Nettó összeg"/>
+                                        <doublebox value="@bind(vm.formDocument.netAmount) @validator(vm)"
+                                                   format="#.##" instant="true"
+                                                   onChange="@command('onNetAmountChange')"
+                                                   forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                    </vlayout>
+                                    <vlayout>
+                                        <label value="Bruttó összeg"/>
+                                        <doublebox value="@bind(vm.formDocument.grossAmount) @validator(vm)"
+                                                   format="#.##" instant="true"
+                                                   forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                    </vlayout>
+                                    <vlayout>
+                                        <label value="ÁFA"/>
+                                        <doublebox value="@bind(vm.formDocument.vatAmount) @validator(vm)"
+                                                   format="#.##" instant="true"
+                                                   forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                    </vlayout>
+                                </hlayout>
+                                <hlayout>
+                                    <vlayout>
+                                        <label value="Tervezett"/>
+                                        <checkbox mold="switch" checked="@bind(vm.formDocument.planned)"/>
+                                    </vlayout>
+                                    <vlayout>
+                                        <label value="Kiállítás dátuma"/>
+                                        <datebox instant="true" locale="hu"
+                                                 value="@bind(vm.formDocument.createDate) @validator(vm)"
+                                                 forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                    </vlayout>
+                                    <vlayout>
+                                        <label value="Teljesítés dátuma"/>
+                                        <datebox instant="true" locale="hu"
+                                                 value="@bind(vm.formDocument.completionDate) @validator(vm)"
+                                                 forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                    </vlayout>
+                                    <vlayout>
+                                        <label value="Fizetési határidő"/>
+                                        <datebox instant="true" locale="hu"
+                                                 value="@bind(vm.formDocument.paymentDeadline) @validator(vm)"
+                                                 forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                    </vlayout>
+                                </hlayout>
+                            </vlayout>
+                        </tabpanel>
+                        <tabpanel>
+                            <borderlayout>
+                                <north flex="true">
+                                    <toolbar>
+                                        <toolbarbutton label="Feltöltés" iconSclass="z-icon-plus" upload="true"
+                                                       onUpload="@command('onUploadFile', evt=event)"/>
+                                        <toolbarbutton label="Törlés" iconSclass="z-icon-remove"
+                                                       onClick="@command('onRemoveFile')"
+                                                       disabled="@load(empty vm.formDocument.file)"/>
+                                    </toolbar>
+                                </north>
+                                <center border="none" flex="true">
+                                    <iframe hflex="true" vflex="true"
+                                            content="@load(vm.formDocument.file) @converter('hu.user.lis.ui.converter.ByteArrayToAMediaConverter')"/>
+                                </center>
+                            </borderlayout>
+                        </tabpanel>
+                    </tabpanels>
+                </tabbox>
+
+            </center>
+            <south border="none" flex="true" style="text-align: right; padding: 10px;">
+                <hlayout>
+                    <button id="cancel" label="Bezár"
+                            onClick="@command('onCloseWindow', target=invoicePopup, select=false)"/>
+                    <button id="submit" label="Mentés"
+                            onClick="@command('onCloseWindow', target=invoicePopup, select=true)"
+                            disabled="@bind(vm.formInvalid)"/>
+                </hlayout>
+            </south>
+        </borderlayout>
+    </window>
+</zk>
\ No newline at end of file
index e5c22680ad3103a93d38657f25d42d06a35e16d5..56556e4c10d7c7ee6f7bf4299c8c5b573b6ca9b8 100644 (file)
@@ -1,5 +1,5 @@
-<?component name="partners" inline="true" macroURI="~./partners.zul"?>
-<?component name="projects" inline="true" macroURI="~./projects.zul"?>
+<!--<?component name="partners" inline="true" macroURI="~./partners.zul"?>-->
+<!--<?component name="projects" inline="true" macroURI="~./projects.zul"?>-->
 <zk>
     <style>
         .z-window-header {
@@ -11,7 +11,7 @@
         <caption>
             <hlayout valign="middle">
                 <image width="24px" height="24px" src="~./static/images/logo.png"/>
-                <label value="LEADER INFORMATION SYSTEM"/>
+                <label value="SLY-CRM"/>
                 <separator orient="vertical"/>
                 <label style="font-size: 0.8em" value="@load(vm.buildProperties.version)"/>
             </hlayout>
@@ -21,9 +21,9 @@
                 <hlayout valign="middle">
                     <menubar autodrop="true" hflex="true">
                         <menuitem id="partnersMenuItem" iconSclass="z-icon-group" label="Partnerek"
-                                  onClick="mainContent.setSelectedIndex(0)"/>
+                                  onClick="@command(vm.selectPage('~./partners.zul'))"/>
                         <menuitem id="projectsMenuItem" iconSclass="z-icon-tasks" label="Projektek"
-                                  onClick="mainContent.setSelectedIndex(1)"/>
+                                  onClick="@command(vm.selectPage('~./projects.zul'))"/>
                     </menubar>
                     <hbox hflex="min" pack="right">
                         <textbox value="@bind(vm.searchPhrase)" onOK="@command('search')"></textbox>
                 </hlayout>
             </north>
             <center border="none" hflex="true">
-                <tabbox id="mainContent" vflex="true" hflex="true" orient="top" selectedIndex="@bind(vm.selectedPage)">
-                    <tabs visible="false">
-                        <tab id="tab0" label="Partnerek" selected="true"/>
-                        <tab id="tab1" label="Projektek"/>
-                    </tabs>
-                    <tabpanels>
-                        <tabpanel id="partnersTab">
-                            <partners/>
-                        </tabpanel>
-                        <tabpanel id="projectsTab"
-                                  fulfill="self.linkedTab.onSelect, projectsMenuItem.onClick, onFulFillProjectsTab">
-                            <projects/>
-                        </tabpanel>
-                    </tabpanels>
-                </tabbox>
+                <include src="@load(vm.page)" hflex="true" vflex="true"/>
+
+                <!--                <tabbox id="mainContent" vflex="true" hflex="true" orient="top" selectedIndex="@bind(vm.selectedPage)">-->
+                <!--                    <tabs visible="true">-->
+                <!--                        <tab id="tab0" label="Partnerek"/>-->
+                <!--                        <tab id="tab1" label="Projektek"/>-->
+                <!--                        <tab id="tab2" label="Szerkesztő"/>-->
+                <!--                    </tabs>-->
+                <!--                    <tabpanels>-->
+                <!--                        <tabpanel id="partnersTab">-->
+                <!--                            <partners/>-->
+                <!--                        </tabpanel>-->
+                <!--                        <tabpanel id="projectsTab"-->
+                <!--                                  fulfill="self.linkedTab.onSelect, projectsMenuItem.onClick, onFulFillProjectsTab">-->
+                <!--                            <projects/>-->
+                <!--                        </tabpanel>-->
+                <!--                        <tabpanel id="editorTab">-->
+                <!--                            <include src="@load(vm.editor)" hflex="true" vflex="true"/>-->
+                <!--                        </tabpanel>-->
+                <!--                    </tabpanels>-->
+                <!--                </tabbox>-->
             </center>
         </borderlayout>
     </window>
similarity index 80%
rename from lis-ui/src/main/resources/web/invoice.zul
rename to lis-ui/src/main/resources/web/outgoing-invoice-editor.zul
index f1d97c9688cf70a01a2ae26f396029fd73f01419..6a4b4dc765344f67c5e5c44be2d62d7654f34b64 100644 (file)
@@ -6,13 +6,14 @@
         import hu.user.lis.db.Currency;
         ListModelList currencies = new ListModelList(Currency.values());
     </zscript>
-    <window id="invoicePopup" title="Számla szerkesztés" width="50%" height="50%" closable="true"
+    <window id="invoicePopup" title="Kimenő számla szerkesztés" width="50%" height="50%" closable="true"
             viewModel="@id('vm') @init('hu.user.lis.ui.view.InvoiceEditorModel')">
         <borderlayout>
             <center border="none" vflex="true" hflex="true">
                 <tabbox vflex="true" hflex="true">
                     <tabs>
                         <tab label="Adatok" selected="true"/>
+                        <tab label="Számlakép"/>
                     </tabs>
                     <tabpanels>
                         <tabpanel>
                                                  forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
                                     </vlayout>
                                 </hlayout>
-                                <label value="Bevétel számla"/>
-                                <checkbox mold="switch" checked="@bind(vm.formDocument.income)" disabled="true"/>
                             </vlayout>
                         </tabpanel>
+                        <tabpanel>
+                            <borderlayout>
+                                <north flex="true">
+                                    <toolbar>
+                                        <toolbarbutton label="Feltöltés" iconSclass="z-icon-plus" upload="true"
+                                                       onUpload="@command('onUploadFile', evt=event)"/>
+                                        <toolbarbutton label="Törlés" iconSclass="z-icon-remove"
+                                                       onClick="@command('onRemoveFile')"
+                                                       disabled="@load(empty vm.formDocument.file)"/>
+                                    </toolbar>
+                                </north>
+                                <center border="none" flex="true">
+                                    <iframe hflex="true" vflex="true"
+                                            content="@load(vm.formDocument.file) @converter('hu.user.lis.ui.converter.ByteArrayToAMediaConverter')"/>
+                                </center>
+                            </borderlayout>
+                        </tabpanel>
                     </tabpanels>
                 </tabbox>
 
diff --git a/lis-ui/src/main/resources/web/project-editor.zul b/lis-ui/src/main/resources/web/project-editor.zul
new file mode 100644 (file)
index 0000000..02020cf
--- /dev/null
@@ -0,0 +1,132 @@
+<?link rel="stylesheet" type="text/css" href="~./static/css/skeleton.css" ?>
+<?link rel="stylesheet" type="text/css" href="~./static/css/webclient.css" ?>
+<?component name="partner-selector" inline="true" macroURI="~./partner-selector.zul"?>
+<zk>
+    <window id="projectEditor" title="Projekt szerkesztés" hflex="true" vflex="true"
+            viewModel="@id('vm') @init('hu.user.lis.ui.view.ProjectEditorModel')">
+        <borderlayout>
+            <center id="centerPanel" border="none" vflex="true" hflex="true" autoscroll="true">
+                <vlayout hflex="true" vflex="min">
+
+                    <tabbox>
+                        <tabs>
+                            <tab label="Adatok" selected="true"/>
+                        </tabs>
+                        <tabpanels>
+                            <tabpanel>
+                                <vlayout>
+                                    <label value="Azonosító"/>
+                                    <textbox hflex="true" instant="true"
+                                             value="@bind(vm.formDocument.humanId) @validator(vm)"
+                                             readonly="true"
+                                             forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                    <label value="Ügyfél"/>
+                                    <partner-selector/>
+                                    <label value="Megnevezés"/>
+                                    <textbox hflex="true" instant="true"
+                                             value="@bind(vm.formDocument.name) @validator(vm)"
+                                             forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                    <label value="Kapcsolattartó"/>
+                                    <textbox hflex="true" instant="true"
+                                             value="@bind(vm.formDocument.contactName) @validator(vm)"
+                                             forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                    <label value="Aktív"/>
+                                    <checkbox mold="switch" checked="@bind(vm.formDocument.active)"/>
+                                </vlayout>
+                            </tabpanel>
+                        </tabpanels>
+                    </tabbox>
+
+                    <panel collapsible="true" open="false" border="rounded"
+                           onOpen="@command('onOpenInvoicePanel', parentPanel=centerPanel)">
+                        <caption label="Bejövő számlák"
+                                 onClick="@command('onClickInvoicePanel', parentPanel=centerPanel, panel=self.parent)"/>
+                        <panelchildren>
+                            <vlayout>
+                                <toolbar>
+                                    <toolbarbutton label="Hozzáadás" iconSclass="z-icon-plus"
+                                                   onClick="@command('onAddIncoming')"/>
+                                    <toolbarbutton label="Szerkesztés" iconSclass="z-icon-edit"
+                                                   onClick="@command('onEditIncoming')"
+                                                   disabled="@load(empty vm.selectedIncomingInvoice)"/>
+                                    <toolbarbutton label="Törlés" iconSclass="z-icon-remove"
+                                                   onClick="@command('onRemoveIncoming')"
+                                                   disabled="@load(empty vm.selectedIncomingInvoice)"/>
+                                </toolbar>
+
+                                <listbox model="@load(vm.formDocument.incomingInvoices)"
+                                         selectedItem="@bind(vm.selectedIncomingInvoice)"
+                                         onDoubleClick="@command('onEditIncoming')"
+                                         forward="onOK=submit.onClick, onCancel=cancel.onClick">
+                                    <listhead>
+                                        <listheader label="Szállító" align="left"/>
+                                        <listheader label="Megnevezés" align="left"/>
+                                        <listheader label="Nettó összeg" align="left"/>
+                                        <listheader label="Pénznem" align="left"/>
+                                    </listhead>
+                                    <template name="model">
+                                        <listitem>
+                                            <listcell label="@load(each.partner.name)"/>
+                                            <listcell label="@load(each.title)"/>
+                                            <listcell label="@load(each.netAmount)"/>
+                                            <listcell label="@load(each.currency)"/>
+                                        </listitem>
+                                    </template>
+                                </listbox>
+                            </vlayout>
+                        </panelchildren>
+
+                    </panel>
+                    <panel collapsible="true" open="false" border="rounded"
+                           onOpen="@command('onOpenInvoicePanel', parentPanel=centerPanel)">
+                        <caption label="Kimenő számlák"
+                                 onClick="@command('onClickInvoicePanel', parentPanel=centerPanel, panel=self.parent)"/>
+                        <panelchildren>
+                            <vlayout>
+                                <toolbar>
+                                    <toolbarbutton label="Hozzáadás" iconSclass="z-icon-plus"
+                                                   onClick="@command('onAddOutgoing')"/>
+                                    <toolbarbutton label="Szerkesztés" iconSclass="z-icon-edit"
+                                                   onClick="@command('onEditOutgoing')"
+                                                   disabled="@load(empty vm.selectedOutgoingInvoice)"/>
+                                    <toolbarbutton label="Törlés" iconSclass="z-icon-remove"
+                                                   onClick="@command('onRemoveOutgoing')"
+                                                   disabled="@load(empty vm.selectedOutgoingInvoice)"/>
+                                </toolbar>
+                                <listbox model="@load(vm.formDocument.outgoingInvoices)"
+                                         selectedItem="@bind(vm.selectedOutgoingInvoice)"
+                                         onDoubleClick="@command('onEditOutgoing')"
+                                         forward="onOK=submit.onClick, onCancel=cancel.onClick">
+                                    <listhead>
+                                        <listheader label="Vevő" align="left"/>
+                                        <listheader label="Megnevezés" align="left"/>
+                                        <listheader label="Nettó összeg" align="left"/>
+                                        <listheader label="Pénznem" align="left"/>
+                                    </listhead>
+                                    <template name="model">
+                                        <listitem>
+                                            <listcell label="@load(each.partner.name)"/>
+                                            <listcell label="@load(each.title)"/>
+                                            <listcell label="@load(each.netAmount)"/>
+                                            <listcell label="@load(each.currency)"/>
+                                        </listitem>
+                                    </template>
+                                </listbox>
+                            </vlayout>
+                        </panelchildren>
+
+                    </panel>
+                </vlayout>
+            </center>
+            <south border="none" flex="true" style="text-align: right; padding: 10px;">
+                <hlayout>
+                    <button id="cancel" label="Mégsem"
+                            onClick="@command('onEndEdit', target=projectEditor, select=false)"/>
+                    <button id="submit" label="Mentés"
+                            onClick="@command('onEndEdit', target=projectEditor, select=true)"
+                            disabled="@bind(vm.formInvalid)"/>
+                </hlayout>
+            </south>
+        </borderlayout>
+    </window>
+</zk>
\ No newline at end of file
index cb94d4051fa18f1ac6516ad0868bf93ddc11d67e..9dad1021355b84fef7dfbd2cb17f36bd5dd8089f 100644 (file)
@@ -2,7 +2,7 @@
 <?link rel="stylesheet" type="text/css" href="~./static/css/webclient.css" ?>
 <?component name="partner-selector" inline="true" macroURI="~./partner-selector.zul"?>
 <zk>
-    <window id="projectPopup" title="Projekt szerkesztés" width="60%" height="80%" closable="true"
+    <window id="projectEditor" title="Projekt szerkesztés" width="60%" height="80%" closable="true"
             viewModel="@id('vm') @init('hu.user.lis.ui.view.ProjectEditorModel')">
         <borderlayout>
             <center border="none" vflex="true" hflex="true">
             <south border="none" flex="true" style="text-align: right; padding: 10px;">
                 <hlayout>
                     <button id="cancel" label="Bezár"
-                            onClick="@command('onCloseWindow', target=projectPopup, select=false)"/>
+                            onClick="@command('onEndEdit', target=projectEditor, select=false)"/>
                     <button id="submit" label="Mentés"
-                            onClick="@command('onCloseWindow', target=projectPopup, select=true)"
+                            onClick="@command('onEndEdit', target=projectEditor, select=true)"
                             disabled="@bind(vm.formInvalid)"/>
                 </hlayout>
             </south>
index fed4f79fe98fe6ae44dc015bffcccd8118442d5d..cb3e309f1a81eede76944192d161ed0b9aa7e17e 100644 (file)
@@ -7,7 +7,7 @@
         }
     </style>
     <script>
-        //history.pushState({}, "", "/projects");
+        history.pushState({}, "", "/projects");
     </script>
     <window title="Projektek" vflex="true" viewModel="@id('vm') @init('hu.user.lis.ui.view.ProjectsViewModel')">
         <borderlayout>
@@ -33,9 +33,9 @@
 
                     <listhead>
                         <listheader label="Azonosító" align="left"/>
-                        <listheader label="Név" align="left"/>
+                        <listheader label="Ügyfél" align="left"/>
+                        <listheader label="Megnevezés" align="left"/>
                         <listheader label="Kapcsolattartó" align="left"/>
-                        <listheader label="Partner" align="left"/>
                         <listheader label="Aktív" align="left"/>
                     </listhead>
                     <template name="model">
diff --git a/pom.xml b/pom.xml
index 576b70d7a4626563e9bf8c7bd0cba78f681cacfb..a955a454cd343dff3ed60274d91275f692384052 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>hu.user</groupId>
             <artifactId>log4j-api</artifactId>
             <version>2.20.0</version>
         </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>31.1-jre</version>
+        </dependency>
     </dependencies>
 </project>