Validator bug fixed and improved
authorelgekko <vasary@elgekko.net>
Fri, 21 Apr 2023 14:11:26 +0000 (16:11 +0200)
committerelgekko <vasary@elgekko.net>
Fri, 21 Apr 2023 14:11:26 +0000 (16:11 +0200)
26 files changed:
lis-app/pom.xml
lis-db/src/main/java/hu/user/lis/db/Currency.java
lis-db/src/main/java/hu/user/lis/db/Invoice.java
lis-db/src/main/java/hu/user/lis/db/Project.java
lis-services/pom.xml
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/PartnerService.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/config/ResourceConfigurer.java [moved from lis-ui/src/main/java/hu/user/lis/ui/ResourceConfigurer.java with 67% similarity]
lis-ui/src/main/java/hu/user/lis/ui/data/PartnerSelectorDataModel.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 [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/view/PartnerEditorModel.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/index.zul
lis-ui/src/main/resources/web/invoice.zul [new file with mode: 0644]
lis-ui/src/main/resources/web/partner-selector.zul
lis-ui/src/main/resources/web/partner.zul
lis-ui/src/main/resources/web/partners.zul
lis-ui/src/main/resources/web/project.zul
lis-ui/src/main/resources/web/projects.zul

index d6c5c541e0e8f5e138865e85315d5f359a20d527..e270057d78b3df1fefa15ece6763ba70a54d5935 100644 (file)
@@ -4,7 +4,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>hu.user</groupId>
     <artifactId>lis-app</artifactId>
-    <version>0.0.3-SNAPSHOT</version>
+    <version>0.0.4-SNAPSHOT</version>
     <parent>
         <groupId>hu.user</groupId>
         <artifactId>lis</artifactId>
index ac3255034f15b0f088e18712946daa92af328e1b..33ff0e3d92205dbafffd51d716cb2c9f89c851dd 100644 (file)
@@ -1,5 +1,16 @@
 package hu.user.lis.db;
 
+
+import lombok.Getter;
+
+@Getter
 public enum Currency {
-    HUF, USD, EURO
+    HUF(0), USD(1), EURO(2);
+    final int val;
+
+    Currency(int val) {
+        this.val = val;
+    }
+
+
 }
index 851c60577475ed4963a012b57f0097526b75cca9..8bf00e1064bba02f005185ff239177f7f85531de 100644 (file)
@@ -2,7 +2,7 @@ package hu.user.lis.db;
 
 import lombok.*;
 
-import java.time.LocalDate;
+import java.util.Date;
 
 @Getter
 @Setter
@@ -19,7 +19,7 @@ public class Invoice {
     double netAmount;
     double grossAmount;
     double vatAmount;
-    LocalDate completionDate;
-    LocalDate createDate;
-    LocalDate paymentDeadline;
+    Date completionDate;
+    Date createDate;
+    Date paymentDeadline;
 }
index 42817d325fad0a2a8f973677e8b744936edff67e..66e5bb62ee5476126d0bde87ad3c79db6a70b617 100644 (file)
@@ -2,6 +2,8 @@ package hu.user.lis.db;
 
 import lombok.*;
 
+import java.util.List;
+
 @Getter
 @Setter
 @Builder
@@ -14,4 +16,7 @@ public class Project {
     String contactName;
     Partner partner;
     boolean active;
+    List<Invoice> incomingInvoices;
+    List<Invoice> outgoingInvoices;
+
 }
index da1d43bb912b446a43675d51cda7855de167e85a..cef056e0aadc1ee08e7116dcc9cb765ead73f244 100644 (file)
@@ -37,9 +37,5 @@
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-        </dependency>
     </dependencies>
 </project>
index 06eff52f80a20be4e068ec1e494a0d0244d4ca47..a51a57143f1e8b67c325fc8ea8f127acffddd619 100644 (file)
@@ -14,5 +14,11 @@ public interface InvoiceService {
 
     Invoice copy(Invoice sourceEntity) throws JsonProcessingException;
 
+    String toString(Invoice sourceEntity) throws JsonProcessingException;
+
+    Invoice copy(Invoice sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException;
+
     void replace(Invoice targetEntity, Invoice replacementEntity);
+
+    List<Invoice> getRandom(boolean income);
 }
index b7eaa50e5973aa99e34837c0e9e43acb7d3615e1..e2c18c0cbd296db1dbe7702130d0f0401e658869 100644 (file)
@@ -2,29 +2,54 @@ package hu.user.lis.services.data;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 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 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.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 @Service
 public class InvoiceServiceImpl implements InvoiceService {
-    private List<Invoice> entities;
+    int GENERATE_COUNT = 1000;
+    private List<Invoice> incomingEntities;
+    private List<Invoice> outgoingEntities;
     @Autowired
     DataGeneratorService dataGeneratorService;
-
+    @Autowired
+    PartnerService partnerService;
     @Autowired
     ObjectMapper mapper;
 
     @Override
     public List<Invoice> getAll() {
-        if (entities == null) {
-            entities = generate();
+        if (incomingEntities == null) {
+            try {
+                incomingEntities = generate(true);
+            } catch (ParseException e) {
+                throw new RuntimeException(e);
+            }
         }
-        return entities;
+        if (outgoingEntities == null) {
+            try {
+                outgoingEntities = generate(false);
+            } catch (ParseException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        ArrayList<Invoice> result = new ArrayList<>(incomingEntities);
+        result.addAll(outgoingEntities);
+        return result;
     }
 
     @Override
@@ -35,31 +60,81 @@ public class InvoiceServiceImpl implements InvoiceService {
 
     @Override
     public void add(Invoice entity) {
-        entities.add(entity);
-    }
-
-    @Override
-    public Invoice copy(Invoice sourceEntity) throws JsonProcessingException {
-        ObjectMapper mapper = new ObjectMapper();
-        String json = mapper.writeValueAsString(sourceEntity);
-        return mapper.readValue(json, Invoice.class);
     }
 
     @Override
     public void replace(Invoice targetEntity, Invoice replacementEntity) {
-        Invoice listEntity = entities.stream().filter(p -> p.getId().equals(targetEntity.getId())).findFirst().get();
-        entities.remove(listEntity);
-        entities.add(replacementEntity);
     }
 
-    private List<Invoice> generate() {
+    private List<Invoice> generate(boolean income) throws ParseException {
         List<Invoice> result = new ArrayList<>();
-        for (int i = 0; i < 100; i++) {
+
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+        for (int i = 0; i < GENERATE_COUNT; i++) {
             String id = RandomStringUtils.random(8, "0123456789abcdef");
             String title = dataGeneratorService.faker().commerce().productName();
-            Invoice entity = Invoice.builder().id(id).title(title).build();
+            Partner partner = partnerService.getRandom();
+            Date completionDate = dataGeneratorService.faker().date().between(formatter.parse("2010-01-01"), new Date());
+            Date createDate = dataGeneratorService.faker().date().past(RandomUtils.nextInt(6, 20), TimeUnit.DAYS, completionDate);
+            Date paymentDeadline = dataGeneratorService.faker().date().future(1, TimeUnit.DAYS, completionDate);
+            int currencyIndex = RandomUtils.nextInt(0, 3);
+            Currency currency = Arrays.stream(Currency.values())
+                    .filter(p -> p.getVal() == currencyIndex)
+                    .findFirst().get();
+            double netAmount = RandomUtils.nextFloat(5000, 1000000);
+            double grossAmount = netAmount * 1.27;
+            double vatAmount = grossAmount - netAmount;
+            Invoice entity = Invoice.builder()
+                    .id(id)
+                    .title(title)
+                    .currency(currency)
+                    .partner(partner)
+                    .completionDate(completionDate)
+                    .createDate(createDate)
+                    .paymentDeadline(paymentDeadline)
+                    .netAmount(netAmount)
+                    .grossAmount(grossAmount)
+                    .vatAmount(vatAmount)
+                    .income(income)
+                    .build();
             result.add(entity);
         }
         return result;
     }
+
+    @Override
+    public List<Invoice> getRandom(boolean income) {
+        getAll();
+        int count = RandomUtils.nextInt(10, 20);
+        List<Invoice> result = new ArrayList<>();
+        for (int i = 0; i < count; i++) {
+            int index = RandomUtils.nextInt(0, 500);
+            if (income) {
+                result.add(incomingEntities.get(index));
+            } else {
+                result.add(outgoingEntities.get(index));
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Invoice copy(Invoice sourceEntity) throws JsonProcessingException {
+        String json = toString(sourceEntity);
+        return mapper.readValue(json, Invoice.class);
+    }
+
+    @Override
+    public String toString(Invoice sourceEntity) throws JsonProcessingException {
+        return mapper.writeValueAsString(sourceEntity);
+    }
+
+    @Override
+    public Invoice copy(Invoice sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException {
+        Invoice result = copy(sourceEntity);
+        Field field = result.getClass().getDeclaredField(property);
+        field.setAccessible(true);
+        field.set(result, value);
+        return result;
+    }
 }
index 0f1b02ad97ebc05d637f534b4190f29ae4e78120..8743cc299cd5630a20dfdeb0a3740da98dc25d80 100644 (file)
@@ -17,4 +17,8 @@ public interface PartnerService {
     void replace(Partner targetEntity, Partner replacementEntity);
 
     Partner getRandom();
+
+    String toString(Partner sourceEntity) throws JsonProcessingException;
+
+    Partner copy(Partner sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException;
 }
index ae99f3f95832144ac33a38e2a8dee8b6614339ec..ea4ac67c3f9367d0e345e0166298b0753f832189 100644 (file)
@@ -9,6 +9,7 @@ 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;
 
@@ -40,13 +41,6 @@ public class PartnerServiceImpl implements PartnerService {
         entities.add(entity);
     }
 
-    @Override
-    public Partner copy(Partner sourceEntity) throws JsonProcessingException {
-        ObjectMapper mapper = new ObjectMapper();
-        String json = mapper.writeValueAsString(sourceEntity);
-        return mapper.readValue(json, Partner.class);
-    }
-
     @Override
     public void replace(Partner targetEntity, Partner replacementEntity) {
         Partner listEntity = entities.stream().filter(p -> p.getId().equals(targetEntity.getId())).findFirst().get();
@@ -76,4 +70,24 @@ public class PartnerServiceImpl implements PartnerService {
         }
         return result;
     }
+
+    @Override
+    public Partner copy(Partner sourceEntity) throws JsonProcessingException {
+        String json = toString(sourceEntity);
+        return mapper.readValue(json, Partner.class);
+    }
+
+    @Override
+    public String toString(Partner sourceEntity) throws JsonProcessingException {
+        return mapper.writeValueAsString(sourceEntity);
+    }
+
+    @Override
+    public Partner copy(Partner sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException {
+        Partner result = copy(sourceEntity);
+        Field field = result.getClass().getDeclaredField(property);
+        field.setAccessible(true);
+        field.set(result, value);
+        return result;
+    }
 }
index c166af510f321d7deda8f2b6fc9943c2e38d1f9d..5f5b5acd92fb965b650f12f8c94b220e1b664962 100644 (file)
@@ -18,5 +18,7 @@ public interface ProjectService {
 
     boolean isInvalid(Project entity);
 
-    String toString(Project entity);
+    String toString(Project sourceEntity) throws JsonProcessingException;
+
+    Project copy(Project sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException;
 }
index 68df25a2dc08d434a5c0adc5ba19eb69f63f8102..41b6f4181d226f49ce07473ab978e1878b88d732 100644 (file)
@@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils;
 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;
 import java.util.Objects;
@@ -25,6 +26,9 @@ public class ProjectServiceImpl implements ProjectService {
     @Autowired
     PartnerService partnerService;
 
+    @Autowired
+    InvoiceService invoiceService;
+
     @Override
     public List<Project> getAll() {
         if (entities == null) {
@@ -37,7 +41,13 @@ public class ProjectServiceImpl implements ProjectService {
     public Project createNew() {
         String id = RandomStringUtils.random(8, "0123456789abcdef");
         String humanId = dataGeneratorService.faker().code().isbn13(true);
-        return Project.builder().id(id).humanId(humanId).active(true).build();
+        return Project.builder()
+                .id(id)
+                .humanId(humanId)
+                .incomingInvoices(new ArrayList<>())
+                .outgoingInvoices(new ArrayList<>())
+                .active(true)
+                .build();
     }
 
     @Override
@@ -45,13 +55,6 @@ public class ProjectServiceImpl implements ProjectService {
         entities.add(entity);
     }
 
-    @Override
-    public Project copy(Project sourceEntity) throws JsonProcessingException {
-        ObjectMapper mapper = new ObjectMapper();
-        String json = mapper.writeValueAsString(sourceEntity);
-        return mapper.readValue(json, Project.class);
-    }
-
     @Override
     public void replace(Project targetEntity, Project replacementEntity) {
         Project partnerInList = entities.stream().filter(p -> p.getId().equals(targetEntity.getId())).findFirst().get();
@@ -74,6 +77,8 @@ public class ProjectServiceImpl implements ProjectService {
                     .name(name)
                     .contactName(contactName)
                     .partner(partner)
+                    .incomingInvoices(invoiceService.getRandom(true))
+                    .outgoingInvoices(invoiceService.getRandom(false))
                     .build();
             result.add(entity);
         }
@@ -95,13 +100,22 @@ public class ProjectServiceImpl implements ProjectService {
     }
 
     @Override
-    public String toString(Project entity) {
-        ObjectMapper mapper = new ObjectMapper();
-        try {
-            return mapper.writeValueAsString(entity);
-        } catch (JsonProcessingException e) {
-            log.catching(e);
-        }
-        return null;
+    public Project copy(Project sourceEntity) throws JsonProcessingException {
+        String json = toString(sourceEntity);
+        return mapper.readValue(json, Project.class);
+    }
+
+    @Override
+    public String toString(Project sourceEntity) throws JsonProcessingException {
+        return mapper.writeValueAsString(sourceEntity);
+    }
+
+    @Override
+    public Project copy(Project sourceEntity, String property, Object value) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException {
+        Project result = copy(sourceEntity);
+        Field field = result.getClass().getDeclaredField(property);
+        field.setAccessible(true);
+        field.set(result, value);
+        return result;
     }
 }
similarity index 67%
rename from lis-ui/src/main/java/hu/user/lis/ui/ResourceConfigurer.java
rename to lis-ui/src/main/java/hu/user/lis/ui/config/ResourceConfigurer.java
index 745a8afbfd16595a3c7a4a0601dd4a26c88c261f..31b63dbe18e19250159ad3945d7c3b691364fe09 100644 (file)
@@ -1,4 +1,4 @@
-package hu.user.lis.ui;
+package hu.user.lis.ui.config;
 
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -9,4 +9,9 @@ public class ResourceConfigurer {
     public String admin() {
         return "admin/index";
     }
+
+    @GetMapping("/projects")
+    public String projects() {
+        return "index";
+    }
 }
index efb951ae3aba842b2a6db9877ee419c72072dd7f..8c2131aeddf028fe7ea480316d585bb75e74e34b 100644 (file)
@@ -5,6 +5,8 @@ import hu.user.lis.services.data.PartnerService;
 import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 import org.zkoss.bind.BindUtils;
 import org.zkoss.zul.FieldComparator;
@@ -15,6 +17,7 @@ import java.util.stream.Collectors;
 
 @Component
 @Log4j2
+@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 public class PartnerSelectorDataModel extends CachedDataModel<Partner> {
     static private final int SEARCH_LIMIT = 10;
     private String partialName;
index 16f8ea22b82a086b8bbf958905ed4026ad41262a..a98106857342ee50bc65dab6af83f991eeb2e504 100644 (file)
@@ -5,23 +5,34 @@ import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
 import org.springframework.boot.info.BuildProperties;
 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.select.annotation.VariableResolver;
 import org.zkoss.zk.ui.select.annotation.WireVariable;
 
+import javax.servlet.http.HttpServletRequest;
+
 @Log4j2
 @VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
+@Getter
+@Setter
 public class IndexViewModel {
-    @Getter
     @WireVariable
     BuildProperties buildProperties;
-
-    @Getter
-    @Setter
     String searchPhrase;
+    int selectedPage;
+
 
     @Init
     public void init() {
-        log.info("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"));
+        }
+        log.info("Init {}", path);
     }
 
+
 }
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/view/InvoiceEditorModel.java b/lis-ui/src/main/java/hu/user/lis/ui/view/InvoiceEditorModel.java
new file mode 100644 (file)
index 0000000..c98ce12
--- /dev/null
@@ -0,0 +1,122 @@
+package hu.user.lis.ui.view;
+
+import hu.user.lis.db.Currency;
+import hu.user.lis.db.Invoice;
+import hu.user.lis.services.data.InvoiceService;
+import hu.user.lis.ui.data.PartnerSelectorDataModel;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+import org.zkoss.bind.BindContext;
+import org.zkoss.bind.BindUtils;
+import org.zkoss.bind.ValidationContext;
+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.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.Objects;
+
+@Log4j2
+@Getter
+@Setter
+@VariableResolver(DelegatingVariableResolver.class)
+public class InvoiceEditorModel extends AbstractValidator {
+    private Invoice origDocument;
+    private Invoice formDocument;
+    @WireVariable
+    private PartnerSelectorDataModel partnerSelectorDataModel;
+    @WireVariable
+    private InvoiceService invoiceServiceImpl;
+    private boolean formInvalid = true;
+
+    @Init
+    public void init() {
+        log.info("Initialized");
+        origDocument = (Invoice) Executions.getCurrent().getArg().get("origDocument");
+        formDocument = (Invoice) Executions.getCurrent().getArg().get("formDocument");
+        partnerSelectorDataModel.clearSelection();
+    }
+
+    @Command
+    public void onNetAmountChange() {
+        if (Currency.HUF.equals(formDocument.getCurrency())) {
+            formDocument.setGrossAmount(formDocument.getNetAmount() * 1.27);
+            formDocument.setVatAmount(formDocument.getGrossAmount() - formDocument.getNetAmount());
+            BindUtils.postNotifyChange(this.formDocument, "grossAmount", "vatAmount");
+        }
+    }
+
+    @Command
+    public void onCloseWindow(@BindingParam("target") Window target, @BindingParam("select") boolean select) {
+        if (select && formInvalid) {
+            return;
+        }
+        Event closeEvent = new Event("onClose", target, select ? formDocument : null);
+        Events.postEvent(closeEvent);
+    }
+
+    @Command
+    public void onPartnerBandChanging(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
+        InputEvent event = (InputEvent) ctx.getTriggerEvent();
+        log.info("onPartnerBandChanging: {}", event.getValue());
+        partnerSelectorDataModel.search(event.getValue());
+    }
+
+    @Command
+    public void onPartnerBandOpen(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
+        OpenEvent event = (OpenEvent) ctx.getTriggerEvent();
+        log.info("onPartnerBandOpen: {}", event.isOpen());
+        partnerSelectorDataModel.search(null);
+    }
+
+    @Override
+    @NotifyChange("formInvalid")
+    public void validate(ValidationContext ctx) {
+        Component target = ctx.getBindContext().getComponent();
+        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);
+            }
+        } catch (Exception e) {
+            log.catching(e);
+        }
+
+    }
+
+    private void updateFormInvalid(boolean invalid) {
+        setFormInvalid(invalid);
+        BindUtils.postNotifyChange(this, "formInvalid");
+    }
+}
index 8aea7e5de7abfc1a1d314d1d0b4c9d366ab1d799..b65c949a344089f3089d2c185952f778f007f4bf 100644 (file)
@@ -1,6 +1,7 @@
 package hu.user.lis.ui.view;
 
 import hu.user.lis.db.Partner;
+import hu.user.lis.services.data.PartnerService;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
@@ -16,6 +17,7 @@ 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.select.annotation.VariableResolver;
+import org.zkoss.zk.ui.select.annotation.WireVariable;
 import org.zkoss.zkplus.spring.DelegatingVariableResolver;
 import org.zkoss.zul.Window;
 
@@ -27,11 +29,15 @@ import java.util.Objects;
 @VariableResolver(DelegatingVariableResolver.class)
 public class PartnerEditorModel extends AbstractValidator {
     private Partner formDocument;
-    private boolean formInvalid;
+    private Partner origDocument;
+    private boolean formInvalid = true;
+    @WireVariable
+    PartnerService partnerServiceImpl;
 
     @Init
     public void init() {
         log.info("Initialized");
+        origDocument = (Partner) Executions.getCurrent().getArg().get("origDocument");
         formDocument = (Partner) Executions.getCurrent().getArg().get("formDocument");
     }
 
@@ -50,7 +56,29 @@ public class PartnerEditorModel extends AbstractValidator {
         String property = ctx.getProperty().getProperty();
         Object value = ctx.getProperty().getValue();
         log.info("Validating caused by {} {} {}", target.getId(), property, value);
-        boolean invalid = Objects.isNull(value) || StringUtils.isBlank(Objects.toString(value));
+        updateFormInvalid(false);
+        try {
+            Partner newData = partnerServiceImpl.copy(formDocument, property, value);
+            if (!Objects.isNull(origDocument) && partnerServiceImpl.toString(origDocument).equals(partnerServiceImpl.toString(newData))) {
+                log.info("Document not changed");
+                updateFormInvalid(true);
+                return;
+            }
+            if (StringUtils.isBlank(newData.getName()) ||
+                    StringUtils.isBlank(newData.getAddress()) ||
+                    StringUtils.isBlank(newData.getVatNr())
+            ) {
+                log.info("Document is not valid");
+                updateFormInvalid(true);
+            }
+
+
+        } catch (Exception e) {
+            log.catching(e);
+        }
+    }
+
+    private void updateFormInvalid(boolean invalid) {
         setFormInvalid(invalid);
         BindUtils.postNotifyChange(this, "formInvalid");
     }
index c85abbe7a7d3d38723a26a1f8bb9d57ae9c317e6..347ae0ec454f138d070cfee568bd3d5a396c4124 100644 (file)
@@ -17,6 +17,8 @@ import org.zkoss.zul.Listbox;
 import org.zkoss.zul.Window;
 
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 
 @Log4j2
@@ -77,20 +79,22 @@ public class PartnersViewModel extends AsyncBaseModel {
     }
 
     @Command
-    public void onAddNew() {
+    public void onAdd() {
         String page = "~./partner.zul";
-        Partner editPartner = partnersDataModel.getPartnerService().createNew();
-        Window partnerWindow = (Window) Executions.createComponents(page, null,
-                Collections.singletonMap("formDocument", editPartner));
-        partnerWindow.addEventListener("onClose", e -> {
+        Partner newEntity = partnersDataModel.getPartnerService().createNew();
+        Window editorWindow = (Window) Executions.createComponents(page, null,
+                Collections.singletonMap("formDocument", newEntity));
+        editorWindow.addEventListener("onClose", e -> {
             if (e.getData() != null) {
                 log.info("Partner popup result {}", e.getData());
-                partnersDataModel.getPartnerService().add(editPartner);
+                partnersDataModel.getPartnerService().add(newEntity);
                 partnersDataModel.clearSelection();
                 refresh();
-                partnersDataModel.addToSelection(editPartner);
+                partnersDataModel.addToSelection(newEntity);
+                selectedPartner = newEntity;
+
 //                Optional<Listitem> listItem = partnersList.getItems().stream()
-//                        .filter(li -> ((Partner) li.getValue()).getId().equals(editPartner.getId()))
+//                        .filter(li -> ((Partner) li.getValue()).getId().equals(newEntity.getId()))
 //                        .findFirst();
 //                if (listItem.isPresent()) {
 //                    Clients.scrollIntoView(listItem.get());
@@ -99,16 +103,18 @@ public class PartnersViewModel extends AsyncBaseModel {
 //                });
             }
         });
-        partnerWindow.doModal();
+        editorWindow.doModal();
     }
 
     @Command
     public void onEdit() throws JsonProcessingException {
         String page = "~./partner.zul";
-        Partner editPartner = partnersDataModel.getPartnerService().copy(selectedPartner);
-        Window partnerWindow = (Window) Executions.createComponents(page, null,
-                Collections.singletonMap("formDocument", editPartner));
-        partnerWindow.addEventListener("onClose", e -> {
+        Partner editEntity = partnersDataModel.getPartnerService().copy(selectedPartner);
+        Map<String, Object> arg = new HashMap<>();
+        arg.put("origDocument", selectedPartner);
+        arg.put("formDocument", editEntity);
+        Window editorWindow = (Window) Executions.createComponents(page, null, arg);
+        editorWindow.addEventListener("onClose", e -> {
             if (e.getData() != null) {
                 log.info("Partner popup result {}", e.getData());
                 Partner modifiedEntity = (Partner) e.getData();
@@ -119,7 +125,7 @@ public class PartnersViewModel extends AsyncBaseModel {
                 selectedPartner = modifiedEntity;
             }
         });
-        partnerWindow.doModal();
+        editorWindow.doModal();
     }
 
 
index 804d145739bbe03ce02af1114a0b9b2d5a28b6ff..ffa02f14976755497a6d9fc5602f8652708ee949 100644 (file)
@@ -1,9 +1,11 @@
 package hu.user.lis.ui.view;
 
-import hu.user.lis.db.Partner;
+import com.fasterxml.jackson.core.JsonProcessingException;
+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.data.PartnerSelectorDataModel;
-import hu.user.lis.ui.data.ProjectsDataModel;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
@@ -24,7 +26,7 @@ import org.zkoss.zk.ui.select.annotation.WireVariable;
 import org.zkoss.zkplus.spring.DelegatingVariableResolver;
 import org.zkoss.zul.Window;
 
-import java.util.Objects;
+import java.util.*;
 
 @Log4j2
 @Getter
@@ -32,18 +34,22 @@ import java.util.Objects;
 @VariableResolver(DelegatingVariableResolver.class)
 public class ProjectEditorModel extends AbstractValidator {
     private Project formDocument;
-    private Partner selectedPartner;
+    private Project origDocument;
     @WireVariable
     private PartnerSelectorDataModel partnerSelectorDataModel;
     @WireVariable
-    private ProjectsDataModel projectsDataModel;
-    private boolean formInvalid;
+    private InvoiceService invoiceServiceImpl;
+    @WireVariable
+    private ProjectService projectServiceImpl;
+    private boolean formInvalid = true;
+    private Invoice selectedIncomingInvoice;
+    private Invoice selectedOutgoingInvoice;
 
     @Init
     public void init() {
         log.info("Initialized");
+        origDocument = (Project) Executions.getCurrent().getArg().get("origDocument");
         formDocument = (Project) Executions.getCurrent().getArg().get("formDocument");
-        selectedPartner = formDocument.getPartner();
         partnerSelectorDataModel.clearSelection();
     }
 
@@ -79,26 +85,156 @@ public class ProjectEditorModel extends AbstractValidator {
             if (e.getData() != null) {
                 partnerSelectorDataModel.clearSelection();
                 //setSelectedSupplierId(((Supplier) e.getData()).getId());
-                BindUtils.postNotifyChange(null, null, this, "selectedSupplierId");
+                BindUtils.postNotifyChange(this, "selectedSupplierId");
             }
         });
 
         suppliersWindow.doModal();
     }
 
-    @NotifyChange({"selectedPartner"})
-    public void setSelectedPartner(Partner selectedPartner) {
-        this.selectedPartner = selectedPartner;
-        formDocument.setPartner(selectedPartner);
-    }
-
     @Override
     public void validate(ValidationContext ctx) {
         Component target = ctx.getBindContext().getComponent();
         String property = ctx.getProperty().getProperty();
         Object value = ctx.getProperty().getValue();
         log.info("Validating caused by {} {} {}", target.getId(), property, value);
-        boolean invalid = Objects.isNull(value) || StringUtils.isBlank(Objects.toString(value));
+        try {
+            Project newData = projectServiceImpl.copy(formDocument, property, value);
+            validate(newData);
+        } catch (Exception e) {
+            log.catching(e);
+        }
+    }
+
+    private void validate(Project newData) throws JsonProcessingException {
+        updateFormInvalid(false);
+        if (!Objects.isNull(origDocument) && projectServiceImpl.toString(origDocument).equals(projectServiceImpl.toString(newData))) {
+            log.info("Document not changed");
+            updateFormInvalid(true);
+            return;
+        }
+
+        if (StringUtils.isBlank(newData.getName()) ||
+                StringUtils.isBlank(newData.getContactName()) ||
+                Objects.isNull(newData.getPartner())
+        ) {
+            log.info("Document is not valid");
+            updateFormInvalid(true);
+        }
+    }
+
+    @Command
+    public void onAddIncoming() {
+        String page = "~./invoice.zul";
+        Invoice editEntity = invoiceServiceImpl.createNew();
+        editEntity.setIncome(true);
+        Window editorWindow = (Window) Executions.createComponents(page, null,
+                Collections.singletonMap("formDocument", editEntity));
+        editorWindow.addEventListener("onClose", e -> {
+            if (e.getData() != null) {
+                formDocument.getIncomingInvoices().add(editEntity);
+                selectedIncomingInvoice = editEntity;
+                BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
+                BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
+                Project newData = projectServiceImpl.copy(formDocument);
+                validate(newData);
+            }
+        });
+        editorWindow.doModal();
+    }
+
+    @Command
+    public void onEditIncoming() throws JsonProcessingException {
+        String page = "~./invoice.zul";
+        Invoice editEntity = invoiceServiceImpl.copy(selectedIncomingInvoice);
+        Map<String, Object> arg = new HashMap<>();
+        arg.put("origDocument", selectedIncomingInvoice);
+        arg.put("formDocument", editEntity);
+        Window editorWindow = (Window) Executions.createComponents(page, null, arg);
+        editorWindow.addEventListener("onClose", e -> {
+            if (e.getData() != null) {
+                Invoice modifiedEntity = (Invoice) e.getData();
+                List<Invoice> incomingInvoices = formDocument.getIncomingInvoices();
+                int index = incomingInvoices.indexOf(selectedIncomingInvoice);
+                incomingInvoices.remove(selectedIncomingInvoice);
+                incomingInvoices.add(index, modifiedEntity);
+                selectedIncomingInvoice = modifiedEntity;
+                BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
+                BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
+                Project newData = projectServiceImpl.copy(formDocument);
+                validate(newData);
+            }
+        });
+        editorWindow.doModal();
+    }
+
+    @Command
+    public void onRemoveIncoming() {
+        if (selectedIncomingInvoice == null) {
+            return;
+        }
+        formDocument.getIncomingInvoices().remove(selectedIncomingInvoice);
+        selectedIncomingInvoice = null;
+        BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
+        BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
+    }
+
+    @Command
+    public void onAddOutgoing() {
+        String page = "~./invoice.zul";
+        Invoice editEntity = invoiceServiceImpl.createNew();
+        Window editorWindow = (Window) Executions.createComponents(page, null,
+                Collections.singletonMap("formDocument", editEntity));
+        editorWindow.addEventListener("onClose", e -> {
+            if (e.getData() != null) {
+                formDocument.getOutgoingInvoices().add(editEntity);
+                selectedOutgoingInvoice = editEntity;
+                BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
+                BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
+                Project newData = projectServiceImpl.copy(formDocument);
+                validate(newData);
+            }
+        });
+        editorWindow.doModal();
+    }
+
+    @Command
+    public void onEditOutgoing() throws JsonProcessingException {
+        String page = "~./invoice.zul";
+        Invoice editEntity = invoiceServiceImpl.copy(selectedOutgoingInvoice);
+        Map<String, Object> arg = new HashMap<>();
+        arg.put("origDocument", selectedOutgoingInvoice);
+        arg.put("formDocument", editEntity);
+        Window editorWindow = (Window) Executions.createComponents(page, null, arg);
+        editorWindow.addEventListener("onClose", e -> {
+            if (e.getData() != null) {
+                Invoice modifiedEntity = (Invoice) e.getData();
+                List<Invoice> outgoingInvoices = formDocument.getOutgoingInvoices();
+                int index = outgoingInvoices.indexOf(selectedOutgoingInvoice);
+                outgoingInvoices.remove(selectedOutgoingInvoice);
+                outgoingInvoices.add(index, modifiedEntity);
+                selectedOutgoingInvoice = modifiedEntity;
+                BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
+                BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
+                Project newData = projectServiceImpl.copy(formDocument);
+                validate(newData);
+            }
+        });
+        editorWindow.doModal();
+    }
+
+    @Command
+    public void onRemoveOutgoing() {
+        if (selectedOutgoingInvoice == null) {
+            return;
+        }
+        formDocument.getOutgoingInvoices().remove(selectedOutgoingInvoice);
+        selectedOutgoingInvoice = null;
+        BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
+        BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
+    }
+
+    private void updateFormInvalid(boolean invalid) {
         setFormInvalid(invalid);
         BindUtils.postNotifyChange(this, "formInvalid");
     }
index 80ac4fdd148e41f42226c0adbdbe8d23b0442f7b..ba355e36f1e85a2051b7d3c82b9dc81d6814b866 100644 (file)
@@ -15,6 +15,8 @@ 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
@@ -68,18 +70,19 @@ public class ProjectsViewModel extends AsyncBaseModel {
     }
 
     @Command
-    public void onAddNew() {
+    public void onAdd() {
         String page = "~./project.zul";
-        Project editEntity = projectsDataModel.getProjectService().createNew();
+        Project newEntity = projectsDataModel.getProjectService().createNew();
         Window partnerWindow = (Window) Executions.createComponents(page, null,
-                Collections.singletonMap("formDocument", editEntity));
+                Collections.singletonMap("formDocument", newEntity));
         partnerWindow.addEventListener("onClose", e -> {
             if (e.getData() != null) {
                 log.info("Partner popup result {}", e.getData());
-                projectsDataModel.getProjectService().add(editEntity);
+                projectsDataModel.getProjectService().add(newEntity);
                 projectsDataModel.clearSelection();
                 refresh();
-                projectsDataModel.addToSelection(editEntity);
+                projectsDataModel.addToSelection(newEntity);
+                selectedProject = newEntity;
 //                Optional<Listitem> listItem = partnersList.getItems().stream()
 //                        .filter(li -> ((Partner) li.getValue()).getId().equals(editPartner.getId()))
 //                        .findFirst();
@@ -97,8 +100,11 @@ public class ProjectsViewModel extends AsyncBaseModel {
     public void onEdit() throws JsonProcessingException {
         String page = "~./project.zul";
         Project editEntity = projectsDataModel.getProjectService().copy(selectedProject);
-        Window partnerWindow = (Window) Executions.createComponents(page, null,
-                Collections.singletonMap("formDocument", editEntity));
+        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());
index 100e7ceafc4ddb3bef183591c49100a7bc2a31c1..e5c22680ad3103a93d38657f25d42d06a35e16d5 100644 (file)
@@ -32,7 +32,7 @@
                 </hlayout>
             </north>
             <center border="none" hflex="true">
-                <tabbox id="mainContent" vflex="true" hflex="true" orient="top">
+                <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"/>
@@ -41,7 +41,8 @@
                         <tabpanel id="partnersTab">
                             <partners/>
                         </tabpanel>
-                        <tabpanel id="projectsTab" fulfill="self.linkedTab.onSelect, projectsMenuItem.onClick">
+                        <tabpanel id="projectsTab"
+                                  fulfill="self.linkedTab.onSelect, projectsMenuItem.onClick, onFulFillProjectsTab">
                             <projects/>
                         </tabpanel>
                     </tabpanels>
diff --git a/lis-ui/src/main/resources/web/invoice.zul b/lis-ui/src/main/resources/web/invoice.zul
new file mode 100644 (file)
index 0000000..f1d97c9
--- /dev/null
@@ -0,0 +1,94 @@
+<?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="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"/>
+                    </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="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="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>
+                                <label value="Bevétel számla"/>
+                                <checkbox mold="switch" checked="@bind(vm.formDocument.income)" disabled="true"/>
+                            </vlayout>
+                        </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 7eb2f5e920d47901c66752bab7ba5dfce0a80cad..240c2057467bf6141eefebf91b29fa0f82dda325 100644 (file)
@@ -1,7 +1,7 @@
 <zk xmlns:c="client">
     <hlayout>
         <bandbox id="bd" autodrop="true" iconSclass="z-icon-sort-down"
-                 value="@load(vm.selectedPartner) @converter('hu.user.lis.ui.converter.PartnerToNameConverter')"
+                 value="@load(vm.formDocument.partner) @converter('hu.user.lis.ui.converter.PartnerToNameConverter')"
                  onChanging="@command('onPartnerBandChanging')" onOpen="@command('onPartnerBandOpen')"
                  forward="onOK=submit.onClick, onCancel=cancel.onClick">
             <attribute c:name="_doKeyDown">
@@ -33,7 +33,7 @@
             <bandpopup>
                 <listbox id="bd-list" height="250px" width="450px"
                          model="@bind(vm.partnerSelectorDataModel)"
-                         selectedItem="@bind(vm.selectedPartner) @validator(vm)"
+                         selectedItem="@bind(vm.formDocument.partner) @validator(vm)"
                          onClick="bd.close()"
                          onDoubleClick="bd.close()">
                     <listhead visible="false">
index 17b9fe6ab9ce8ecc2628ef0232ab46cd5757f750..d4f2b06841e527825400c1bfeb6e87478dba67fe 100644 (file)
@@ -5,21 +5,31 @@
             viewModel="@id('vm') @init('hu.user.lis.ui.view.PartnerEditorModel')">
         <borderlayout>
             <center border="none" vflex="true" hflex="true">
-                <vlayout hflex="true">
-                    <label value="Név"/>
-                    <textbox hflex="true" instant="true" value="@bind(vm.formDocument.name) @validator(vm)"
-                             forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
-                    <label value="Adószám"/>
-                    <textbox hflex="true" instant="true" value="@bind(vm.formDocument.vatNr) @validator(vm)"
-                             forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
-                    <label value="Cím"/>
-                    <textbox hflex="true" instant="true" value="@bind(vm.formDocument.address) @validator(vm)"
-                             forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
-                    <label value="Aktív"/>
-                    <checkbox mold="switch" checked="@bind(vm.formDocument.active)"/>
-                </vlayout>
+                <tabbox vflex="true" hflex="true">
+                    <tabs>
+                        <tab label="Adatok" selected="true"/>
+                    </tabs>
+                    <tabpanels>
+                        <tabpanel>
+                            <vlayout hflex="true">
+                                <label value="Név"/>
+                                <textbox hflex="true" instant="true" value="@bind(vm.formDocument.name) @validator(vm)"
+                                         forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                <label value="Adószám"/>
+                                <textbox hflex="true" instant="true" value="@bind(vm.formDocument.vatNr) @validator(vm)"
+                                         forward="onOK=submit.onClick, onCancel=cancel.onClick"/>
+                                <label value="Cím"/>
+                                <textbox hflex="true" instant="true"
+                                         value="@bind(vm.formDocument.address) @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>
             </center>
-            <south flex="true" style="text-align: right; padding: 10px">
+            <south border="none" flex="true" style="text-align: right; padding: 10px">
                 <hlayout>
                     <button id="cancel" label="Bezár"
                             onClick="@command('onCloseWindow', target=partnerPopup, select=false)"/>
index ba031358847483f75e8b7205f01bbd13dd868229..25daa28edb087580fdd23f1f97e6f63d32306aa9 100644 (file)
@@ -11,7 +11,7 @@
         <borderlayout>
             <north flex="true">
                 <toolbar>
-                    <toolbarbutton label="Új partner" iconSclass="z-icon-plus" onClick="@command('onAddNew')"/>
+                    <toolbarbutton label="Hozzáadás" iconSclass="z-icon-plus" onClick="@command('onAdd')"/>
                     <toolbarbutton label="Szerkesztés" iconSclass="z-icon-edit" onClick="@command('onEdit')"
                                    disabled="@load(empty vm.selectedPartner)"/>
                     <separator orient="vertical"/>
index 3de37c129b7c9325a88561cd94d27214c11af5e9..cb94d4051fa18f1ac6516ad0868bf93ddc11d67e 100644 (file)
 <?link rel="stylesheet" type="text/css" href="~./static/css/webclient.css" ?>
 <?component name="partner-selector" inline="true" macroURI="~./partner-selector.zul"?>
 <zk>
-    <window id="currentPopup" title="Projekt szerkesztés" width="60%" height="40%" closable="true"
+    <window id="projectPopup" 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">
-                <vlayout hflex="true">
-                    <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="Név"/>
-                    <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="Partner"/>
-                    <partner-selector/>
-                    <label value="Aktív"/>
-                    <checkbox mold="switch" checked="@bind(vm.formDocument.active)"/>
-                </vlayout>
+                <tabbox vflex="true" hflex="true">
+                    <tabs>
+                        <tab label="Adatok" selected="true"/>
+                        <tab label="Számlák"/>
+                    </tabs>
+                    <tabpanels>
+                        <tabpanel>
+                            <vlayout hflex="true">
+                                <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="Név"/>
+                                <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="Partner"/>
+                                <partner-selector/>
+                                <label value="Aktív"/>
+                                <checkbox mold="switch" checked="@bind(vm.formDocument.active)"/>
+                            </vlayout>
+                        </tabpanel>
+                        <tabpanel>
+                            <hbox spacing="0" width="100%" height="100%">
+                                <window title="Bevétel" border="none" hflex="true" vflex="true">
+                                    <borderlayout>
+                                        <north border="none" flex="true">
+                                            <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>
+                                        </north>
+                                        <center border="none" flex="true">
+                                            <listbox vflex="true" model="@load(vm.formDocument.incomingInvoices)"
+                                                     selectedItem="@bind(vm.selectedIncomingInvoice)"
+                                                     onDoubleClick="@command('onEditIncoming')"
+                                                     forward="onOK=submit.onClick, onCancel=cancel.onClick">
+                                                <listhead>
+                                                    <listheader label="Leírás" align="left"/>
+                                                    <listheader label="Partner" align="left"/>
+                                                    <listheader label="Nettó összeg" align="left"/>
+                                                    <listheader label="Fizetési határidő" align="left"/>
+                                                </listhead>
+                                                <template name="model">
+                                                    <listitem>
+                                                        <listcell label="@load(each.title)"/>
+                                                        <listcell label="@load(each.partner.name)"/>
+                                                        <listcell label="@load(each.netAmount)"/>
+                                                        <listcell label="@load(each.paymentDeadline)"/>
+                                                    </listitem>
+                                                </template>
+                                            </listbox>
+                                        </center>
+                                    </borderlayout>
+                                </window>
+
+                                <splitter/>
+
+                                <window title="Kiadás" border="none" hflex="true" vflex="true">
+                                    <borderlayout>
+                                        <north border="none" flex="true">
+                                            <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>
+                                        </north>
+                                        <center border="none" flex="true">
+                                            <listbox vflex="true" model="@load(vm.formDocument.outgoingInvoices)"
+                                                     selectedItem="@bind(vm.selectedOutgoingInvoice)"
+                                                     onDoubleClick="@command('onEditOutgoing')"
+                                                     forward="onOK=submit.onClick, onCancel=cancel.onClick">
+                                                <listhead>
+                                                    <listheader label="Leírás" align="left"/>
+                                                    <listheader label="Partner" align="left"/>
+                                                    <listheader label="Nettó összeg" align="left"/>
+                                                    <listheader label="Fizetési határidő" align="left"/>
+                                                </listhead>
+                                                <template name="model">
+                                                    <listitem>
+                                                        <listcell label="@load(each.title)"/>
+                                                        <listcell label="@load(each.partner.name)"/>
+                                                        <listcell label="@load(each.netAmount)"/>
+                                                        <listcell label="@load(each.paymentDeadline)"/>
+                                                    </listitem>
+                                                </template>
+                                            </listbox>
+                                        </center>
+                                    </borderlayout>
+                                </window>
+                            </hbox>
+                        </tabpanel>
+                    </tabpanels>
+                </tabbox>
+
             </center>
-            <south flex="true" style="text-align: right; padding: 10px">
+            <south border="none" flex="true" style="text-align: right; padding: 10px;">
                 <hlayout>
                     <button id="cancel" label="Bezár"
-                            onClick="@command('onCloseWindow', target=currentPopup, select=false)"/>
+                            onClick="@command('onCloseWindow', target=projectPopup, select=false)"/>
                     <button id="submit" label="Mentés"
-                            onClick="@command('onCloseWindow', target=currentPopup, select=true)"
+                            onClick="@command('onCloseWindow', target=projectPopup, select=true)"
                             disabled="@bind(vm.formInvalid)"/>
                 </hlayout>
             </south>
index b3487198bd451eb10d687cdbeabffe11d5b62653..fed4f79fe98fe6ae44dc015bffcccd8118442d5d 100644 (file)
@@ -6,11 +6,14 @@
         font-weight: bold;
         }
     </style>
+    <script>
+        //history.pushState({}, "", "/projects");
+    </script>
     <window title="Projektek" vflex="true" viewModel="@id('vm') @init('hu.user.lis.ui.view.ProjectsViewModel')">
         <borderlayout>
             <north flex="true">
                 <toolbar>
-                    <toolbarbutton label="Új projekt" iconSclass="z-icon-plus" onClick="@command('onAddNew')"/>
+                    <toolbarbutton label="Hozzáadás" iconSclass="z-icon-plus" onClick="@command('onAdd')"/>
                     <toolbarbutton label="Szerkesztés" iconSclass="z-icon-edit" onClick="@command('onEdit')"
                                    disabled="@load(empty vm.selectedProject)"/>
                     <separator orient="vertical"/>
@@ -24,8 +27,8 @@
             </north>
             <center border="none" flex="true">
                 <listbox id="partnersList" vflex="true" model="@load(vm.projectsDataModel)"
-                         autopaging="true" pagingPosition="top"
-                         onSelect="@command('onListSelection')" onDoubleClick="@command('onEdit')">
+                         autopaging="true" pagingPosition="top" onSelect="@command('onListSelection')"
+                         onDoubleClick="@command('onEdit')">
                     <custom-attributes org.zkoss.zul.listbox.selectOnHighlight.disabled="true"/>
 
                     <listhead>