Entity selector for project partner implemented
authorelgekko <vasary@elgekko.net>
Wed, 26 Jul 2023 21:55:48 +0000 (23:55 +0200)
committerelgekko <vasary@elgekko.net>
Wed, 26 Jul 2023 21:55:48 +0000 (23:55 +0200)
23 files changed:
lis-app/src/main/resources/application-dev.yaml
lis-app/src/main/resources/application.yaml
lis-db/migrations/environments/development.properties
lis-db/migrations/environments/prod.properties
lis-db/migrations/scripts/004_create_default_user.sql [deleted file]
lis-db/migrations/scripts/004_create_test_data.sql [new file with mode: 0644]
lis-services/src/main/java/hu/user/lis/services/data/AssociateEntityDataService.java [deleted file]
lis-services/src/main/java/hu/user/lis/services/data/EntityDataService.java
lis-ui/src/main/java/hu/user/lis/ui/Constants.java
lis-ui/src/main/java/hu/user/lis/ui/converter/PartnerToNameConverter.java
lis-ui/src/main/java/hu/user/lis/ui/editor/EntityEditorModel.java
lis-ui/src/main/java/hu/user/lis/ui/editor/InvoiceEditorModel.java
lis-ui/src/main/java/hu/user/lis/ui/editor/ProjectEditorModel.java
lis-ui/src/main/java/hu/user/lis/ui/editor/selector/EntitySelectorModel.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/editor/selector/EntitySelectorRouter.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/editor/selector/PartnerSelectorModel.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/editor/widget/EntitySelector.java [new file with mode: 0644]
lis-ui/src/main/java/hu/user/lis/ui/event/EventBus.java
lis-ui/src/main/resources/web/entity-selector.zul [new file with mode: 0644]
lis-ui/src/main/resources/web/login.zul
lis-ui/src/main/resources/web/partner-selector.zul
lis-ui/src/main/resources/web/partners.zul
lis-ui/src/main/resources/web/project-editor.zul

index ed967ffd40319f81f98455bbfbc543b573da90b2..fe8380907535bdfd13ec368fc166f0d73c4cba75 100644 (file)
@@ -9,7 +9,7 @@ spring:
   jpa:
     hibernate:
       use-new-id-generator-mappings: false
-    show-sql: true
+    show-sql: false
     properties:
       hibernate:
         format_sql: true
@@ -24,8 +24,8 @@ spring:
 logging:
   level:
     org.hibernate.engine.jdbc.spi.SqlExceptionHelper: ERROR
-    org.springframework.security: DEBUG
-    org.springframework.security.web: INFO
+#    org.springframework.security: DEBUG
+#    org.springframework.security.web: INFO
 #  pattern:
 #    console: "%d %-5level %logger : %msg%n"
 #    file: "%d %-5level [%thread] %logger : %msg%n"
\ No newline at end of file
index 3f2d8e42464d0269190e5976d4bfb41242a1769a..0607c5e2ea3374371966b3a0ae0a9be5ed6cbe23 100644 (file)
@@ -9,7 +9,7 @@ spring:
   jpa:
     hibernate:
       use-new-id-generator-mappings: false
-    show-sql: true
+    show-sql: false
     properties:
       hibernate:
         format_sql: true
@@ -24,8 +24,8 @@ spring:
 logging:
   level:
     org.hibernate.engine.jdbc.spi.SqlExceptionHelper: ERROR
-    org.springframework.security: DEBUG
-    org.springframework.security.web: INFO
+#    org.springframework.security: DEBUG
+#    org.springframework.security.web: INFO
 #  pattern:
 #    console: "%d %-5level %logger : %msg%n"
 #    file: "%d %-5level [%thread] %logger : %msg%n"
\ No newline at end of file
index 7f3b4541153c89ca96f1e73d16ad3db31d6b3cab..8ca0d80651191b0f9b58cea7077eaca540e754c2 100644 (file)
@@ -1,15 +1,12 @@
 ## Base time zone to ensure times are consistent across machines
 time_zone=GMT+0:00
-
 ## The character set that scripts are encoded with
 script_char_set=UTF-8
-
 ## JDBC connection properties.
 driver=com.ibm.db2.jcc.DB2Driver
 url=jdbc:db2://localhost:50000/lis
 username=db2admin
 password=password
-
 #
 # A NOTE ON STORED PROCEDURES AND DELIMITERS
 #
@@ -25,13 +22,11 @@ password=password
 # or databases don't support creating procs, functions or
 # even tables in a transaction, and others require it.
 #
-
 # This ignores the line delimiters and
 # simply sends the entire script at once.
 # Use with JDBC drivers that can accept large
 # blocks of delimited text at once.
 send_full_script=false
-
 # This controls how statements are delimited.
 # By default statements are delimited by an
 # end of line semicolon.  Some databases may
@@ -40,25 +35,20 @@ send_full_script=false
 # These are ignored if send_full_script is true.
 delimiter=;
 full_line_delimiter=false
-
 # If set to true, each statement is isolated
 # in its own transaction.  Otherwise the entire
 # script is executed in one transaction.
 # Few databases should need this set to true,
 # but some do.
 auto_commit=false
-
 # If set to false, warnings from the database will interrupt migrations.
-ignore_warnings=false
-
+ignore_warnings=true
 # Custom driver path to allow you to centralize your driver files
 # Default requires the drivers to be in the drivers directory of your
 # initialized migration directory (created with "migrate init")
 # driver_path=
-
 # Name of the table that tracks changes to the database
 changelog=CHANGELOG
-
 # Migrations support variable substitutions in the form of ${variable}
 # in the migration scripts.  All of the above properties will be ignored though,
 # with the exception of changelog.
index 52d2dfdc0a0a01f3fc5e3fae4554328c6ba131fa..c5d02a9ac7147e3418bfeab8f1e86d3ba9f1c55b 100644 (file)
@@ -1,15 +1,12 @@
 ## Base time zone to ensure times are consistent across machines
 time_zone=GMT+0:00
-
 ## The character set that scripts are encoded with
 script_char_set=UTF-8
-
 ## JDBC connection properties.
 driver=com.ibm.db2.jcc.DB2Driver
 url=jdbc:db2://dvdev.in.useribm.hu:50000/lis
 username=db2admin
 password=password
-
 #
 # A NOTE ON STORED PROCEDURES AND DELIMITERS
 #
@@ -25,13 +22,11 @@ password=password
 # or databases don't support creating procs, functions or
 # even tables in a transaction, and others require it.
 #
-
 # This ignores the line delimiters and
 # simply sends the entire script at once.
 # Use with JDBC drivers that can accept large
 # blocks of delimited text at once.
 send_full_script=false
-
 # This controls how statements are delimited.
 # By default statements are delimited by an
 # end of line semicolon.  Some databases may
@@ -40,25 +35,20 @@ send_full_script=false
 # These are ignored if send_full_script is true.
 delimiter=;
 full_line_delimiter=false
-
 # If set to true, each statement is isolated
 # in its own transaction.  Otherwise the entire
 # script is executed in one transaction.
 # Few databases should need this set to true,
 # but some do.
 auto_commit=false
-
 # If set to false, warnings from the database will interrupt migrations.
-ignore_warnings=false
-
+ignore_warnings=true
 # Custom driver path to allow you to centralize your driver files
 # Default requires the drivers to be in the drivers directory of your
 # initialized migration directory (created with "migrate init")
 # driver_path=
-
 # Name of the table that tracks changes to the database
 changelog=CHANGELOG
-
 # Migrations support variable substitutions in the form of ${variable}
 # in the migration scripts.  All of the above properties will be ignored though,
 # with the exception of changelog.
diff --git a/lis-db/migrations/scripts/004_create_default_user.sql b/lis-db/migrations/scripts/004_create_default_user.sql
deleted file mode 100644 (file)
index 77589d4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
--- // create default user
--- Migration SQL that makes the change goes here.
-
-INSERT INTO ASSOCIATE (login, password, monthly_cost, active) VALUES ('user', 'password', 1, 1);
-
--- //@UNDO
--- SQL to undo the change goes here.
-
-DELETE FROM ASSOCIATE WHERE login = 'user';
-
diff --git a/lis-db/migrations/scripts/004_create_test_data.sql b/lis-db/migrations/scripts/004_create_test_data.sql
new file mode 100644 (file)
index 0000000..2549b12
--- /dev/null
@@ -0,0 +1,33 @@
+-- // create test data
+-- Migration SQL that makes the change goes here.
+
+INSERT INTO ASSOCIATE
+    (name, login, password, monthly_cost, active)
+VALUES
+    ('Test User', 'user', 'password', 1, 1);
+
+INSERT INTO PARTNER
+    (ID, NAME, VAT_NR, ACTIVE)
+VALUES
+    (1, 'NYÍRŐ', '00000000-00-0', 1),
+    (2, 'KOLOS', '00000000-00-0', 1);
+
+
+INSERT INTO PROJECT_STATUS
+    (ID, NAME, ACTIVE, "ORDER")
+VALUES
+    (1, 'START', 1, 1);
+
+INSERT INTO PROJECT
+    (ID, PROJECT_STATUS_ID, NAME, HUMAN_ID, CONTACT_NAME, PARTNER_ID, ACTIVE)
+VALUES
+    (1, 1, 'Halászat', '2023-01', 'Kovács', 1, 1);
+
+
+-- //@UNDO
+-- SQL to undo the change goes here.
+
+DELETE FROM ASSOCIATE;
+DELETE FROM PARTNER;
+DELETE FROM PROJECT_STATUS;
+DELETE FROM PROJECT;
diff --git a/lis-services/src/main/java/hu/user/lis/services/data/AssociateEntityDataService.java b/lis-services/src/main/java/hu/user/lis/services/data/AssociateEntityDataService.java
deleted file mode 100644 (file)
index 24789b3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-package hu.user.lis.services.data;
-
-import hu.user.lis.db.Associate;
-
-public class AssociateEntityDataService extends EntityDataService<Associate> {
-}
index 9220531866d57370a95e6b25ea7a9a40cf8f95c8..68636073a53076c10723da8abb6a6d5b780e9287 100644 (file)
@@ -32,7 +32,7 @@ public class EntityDataService<T extends Serializable> {
             field.set(entity, value);
             result = true;
         } catch (Exception e) {
-            //log.error(e.getMessage());
+            log.error(e);
         }
         return result;
     }
index f669779988b21f3451d304f3d994d300ac835b57..04ef7d41d54cb20d25bea0fc157bacc2ce883e48 100644 (file)
@@ -1,8 +1,10 @@
 package hu.user.lis.ui;
 
 public class Constants {
+    public static final String BINDING_QUEUE = "$ZKBIND_DEFQUE$";
     public static final String SHOW_PROJECT_EDITOR = "SHOW_PROJECT_EDITOR";
     public static final String SHOW_PROJECTS_LIST = "SHOW_PROJECTS_LIST";
+
     public static final String SHOW_SERVICE_RECORDS_LIST = "SHOW_SERVICE_RECORDS_LIST";
     public static final String SET_SERVICE_RECORDS_LIST_DATA = "SET_SERVICE_RECORDS_LIST_DATA";
     public static final String SET_PROJECT_EDITOR_DATA = "SET_PROJECT_EDITOR_DATA";
index 8422789cd90b0f1800cc2b9d083e81c23a4c301c..c152fff357307fec354b4a0a388c1e4f89d12adb 100644 (file)
@@ -1,10 +1,15 @@
 package hu.user.lis.ui.converter;
 
 import hu.user.lis.db.Partner;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
 import org.zkoss.bind.BindContext;
 import org.zkoss.bind.Converter;
 import org.zkoss.zul.Bandbox;
 
+@Component
+@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 public class PartnerToNameConverter implements Converter<String, Partner, Bandbox> {
 
     @Override
index ca9927df8fc9aead767ddaffaee5c75035556450..ce7ed176e3aef6a76fe9c6b221fbcc2985e19708 100644 (file)
@@ -1,40 +1,46 @@
 package hu.user.lis.ui.editor;
 
 import hu.user.lis.services.data.EntityDataService;
+import hu.user.lis.ui.editor.selector.EntitySelectorRouter;
+import hu.user.lis.ui.event.EventBus;
 import lombok.Getter;
 import lombok.extern.log4j.Log4j2;
 import org.zkoss.bind.BindUtils;
+import org.zkoss.bind.PropertyChangeEvent;
 import org.zkoss.bind.ValidationContext;
-import org.zkoss.bind.annotation.*;
+import org.zkoss.bind.annotation.BindingParam;
+import org.zkoss.bind.annotation.Command;
 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.EventListener;
 import org.zkoss.zk.ui.event.Events;
-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.io.Serializable;
+import java.util.Objects;
 
 
 @Log4j2
 @VariableResolver(DelegatingVariableResolver.class)
-public abstract class EntityEditorModel<T extends Serializable> extends AbstractValidator {
+public abstract class EntityEditorModel<T extends Serializable> extends AbstractValidator implements EventListener {
 
+    @WireVariable
+    protected EventBus eventBus;
     @Getter
     T formDocument;
-
     T origDocument;
-
     @Getter
     boolean saveEnabled;
-
     @WireVariable
     EntityDataService<T> entityDataService;
-
+    @Getter
+    @WireVariable
+    EntitySelectorRouter entitySelectorRouter;
 
     @Command
     public void onCloseWindow(@BindingParam("target") Window target, @BindingParam("save") boolean save) {
@@ -53,14 +59,10 @@ public abstract class EntityEditorModel<T extends Serializable> extends Abstract
         BindUtils.postNotifyChange(this, "saveEnabled");
     }
 
-    @AfterCompose
-    public void onAfterCompose(@ContextParam(ContextType.VIEW) Component view) {
-        Selectors.wireComponents(view, this, false);
-        Selectors.wireEventListeners(view, this);
-    }
-
-    @Init
     public void init() {
+        eventBus.register(this);
+        eventBus.registerForBinding(this);
+
         origDocument = (T) Executions.getCurrent().getArg().get("origDocument");
         formDocument = (T) Executions.getCurrent().getArg().get("formDocument");
     }
@@ -89,4 +91,19 @@ public abstract class EntityEditorModel<T extends Serializable> extends Abstract
         setSaveEnabled(enable);
     }
 
+    protected void validate() {
+        validate(formDocument);
+    }
+
+    @Override
+    public void onEvent(Event evt) {
+        if (evt instanceof PropertyChangeEvent) {
+            PropertyChangeEvent propertyEvent = (PropertyChangeEvent) evt;
+            if (Objects.nonNull(propertyEvent.getBase()) && Objects.nonNull(formDocument) && propertyEvent.getBase().equals(formDocument)) {
+                log.info("Event {}", evt.getName());
+                validate();
+            }
+        }
+    }
+
 }
index 1f897d20fb3fd8acd4304b1c76e13e18cbe5c68d..9dfa198f1947cc8fe2ed6867c582ebbee6b05fd8 100644 (file)
@@ -41,7 +41,7 @@ public class InvoiceEditorModel extends EntityEditorModel<Invoice> {
             formDocument.setGrossAmount(formDocument.getNetAmount() * 1.27);
             formDocument.setVatAmount(formDocument.getGrossAmount() - formDocument.getNetAmount());
             BindUtils.postNotifyChange(this.formDocument, "grossAmount", "vatAmount");
-            validate(formDocument);
+            validate();
         }
     }
 
@@ -82,13 +82,13 @@ public class InvoiceEditorModel extends EntityEditorModel<Invoice> {
         }
         formDocument.setFile(evt.getMedia().getByteData());
         BindUtils.postNotifyChange(this.formDocument, "file");
-        validate(formDocument);
+        validate();
     }
 
     @Command
     public void onRemoveFile() {
         formDocument.setFile(null);
         BindUtils.postNotifyChange(this.formDocument, "file");
-        validate(formDocument);
+        validate();
     }
 }
index 0128c81952468a85917f2a96851176f67d0e847e..519cc5873d27a5e163208351ff628e02af7cf7f8 100644 (file)
@@ -6,7 +6,6 @@ import hu.user.lis.db.*;
 import hu.user.lis.ui.Constants;
 import hu.user.lis.ui.converter.ProjectStatusConverter;
 import hu.user.lis.ui.data.*;
-import hu.user.lis.ui.event.EventBus;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.log4j.Log4j2;
@@ -15,7 +14,6 @@ import org.zkoss.bind.BindContext;
 import org.zkoss.bind.BindUtils;
 import org.zkoss.bind.annotation.*;
 import org.zkoss.zk.ui.event.Event;
-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.WireVariable;
@@ -27,82 +25,95 @@ import org.zkoss.zul.Window;
 import java.util.*;
 
 @Log4j2
-@Getter
-@Setter
-public class ProjectEditorModel extends EntityEditorModel<Project> implements EventListener {
+public class ProjectEditorModel extends EntityEditorModel<Project> {
+    @Getter
+    @Setter
     @WireVariable
     AssociatesDataModel associatesDataModel;
-
     @WireVariable
     ProjectsDataModel projectsDataModel;
-
     @WireVariable
     private PartnerSelectorDataModel partnerSelectorDataModel;
-
     @WireVariable
     private InvoiceDataModel invoiceDataModel;
-
     @WireVariable
     private TreasuryDataModel treasuryDataModel;
-
+    @Getter
+    @Setter
     @WireVariable
     private ServiceRecordsDataModel serviceRecordsDataModel;
-
+    @Getter
+    @Setter
     @WireVariable
     private ProjectStatusDataModel projectStatusDataModel;
-
+    @Getter
+    @Setter
     @WireVariable
     private IncomeMarginsDataModel incomeMarginsDataModel;
-
     @WireVariable
     private ProjectAssociatesDataModel projectAssociatesDataModel;
-
+    @Getter
+    @Setter
     @WireVariable
     private ProjectStatusConverter projectStatusConverter;
-
-    @WireVariable
-    private EventBus eventBus;
-
     private Map<Long, Boolean> origAssociates;
-
+    @Getter
+    @Setter
     private Map<Long, Boolean> formAssociates;
-
+    @Getter
+    @Setter
     private IncomingInvoice selectedIncomingInvoice;
-
+    @Getter
+    @Setter
     private OutgoingInvoice selectedOutgoingInvoice;
-
+    @Getter
+    @Setter
     private Treasury selectedTreasury;
-
+    @Getter
+    @Setter
     private String partialAssociateName;
 
     @Init
     public void init() {
+        super.init();
         projectStatusDataModel.listAll();
-        eventBus.register(this);
+    }
+
+    @Command
+    public void onSelectedEntityChanged(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
+        Event event = (Event) ctx.getTriggerEvent();
+        log.info("{}", event);
     }
 
     @Override
     public void onEvent(Event evt) {
+        super.onEvent(evt);
         if (Constants.SET_PROJECT_EDITOR_DATA.equals(evt.getName())) {
-            log.info("Got event {}", Constants.SET_PROJECT_EDITOR_DATA);
             Object data = evt.getData();
-            if (Objects.isNull(data)) {
-                formDocument = projectsDataModel.createNew();
-                log.info("Loading new entity {} to editor", formDocument.getId());
-            } else {
-                Long id = (Long) data;
-
-                Clients.evalJavaScript(String.format("pushNav('/project/%d')", id));
-                log.info("Loading entity {} to editor", id);
-                formDocument = projectsDataModel.getById(id);
-                origDocument = projectsDataModel.clone(formDocument);
-            }
+            initDocuments(data);
+            initDetails();
+        }
+    }
+
+    private void initDetails() {
+        initAssociates();
+        serviceRecordsDataModel.search(formDocument, true);
+        incomeMarginsDataModel.recalculate(formDocument);
+        entitySelectorRouter.setFormDocument(Partner.class, formDocument, "partner");
+    }
 
-            initAssociates();
-            serviceRecordsDataModel.search(formDocument, true);
-            incomeMarginsDataModel.recalculate(formDocument);
-            BindUtils.postNotifyChange(this, "formDocument");
+    private void initDocuments(Object data) {
+        if (Objects.isNull(data)) {
+            formDocument = projectsDataModel.createNew();
+            log.info("Loading new entity {} to editor", formDocument.getId());
+        } else {
+            Long id = (Long) data;
+            Clients.evalJavaScript(String.format("pushNav('/project/%d')", id));
+            log.info("Loading entity {} to editor", id);
+            formDocument = projectsDataModel.getById(id);
+            origDocument = projectsDataModel.clone(formDocument);
         }
+        BindUtils.postNotifyChange(this, "formDocument");
     }
 
     @NotifyChange("associatesDataModel")
@@ -173,7 +184,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
         Editors.doEdit(Editors.INCOMING_INVOICE, entity, modifiedEntity -> {
             formDocument.getIncomingInvoices().add(modifiedEntity);
             selectedIncomingInvoice = modifiedEntity;
-            validate(formDocument);
+            validate();
             BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
             BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
         });
@@ -187,7 +198,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
             incomingInvoices.remove(selectedIncomingInvoice);
             incomingInvoices.add(modifiedEntity);
             selectedIncomingInvoice = modifiedEntity;
-            validate(formDocument);
+            validate();
             BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
             BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
         });
@@ -198,7 +209,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
         if (Objects.nonNull(selectedIncomingInvoice)) {
             formDocument.getIncomingInvoices().remove(selectedIncomingInvoice);
             selectedIncomingInvoice = null;
-            validate(formDocument);
+            validate();
             BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
             BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
         }
@@ -210,7 +221,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
         Editors.doEdit(Editors.OUTGOING_INVOICE, entity, modifiedEntity -> {
             formDocument.getOutgoingInvoices().add(modifiedEntity);
             selectedOutgoingInvoice = modifiedEntity;
-            validate(formDocument);
+            validate();
             BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
             BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
         });
@@ -224,7 +235,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
             outgoingInvoices.remove(selectedOutgoingInvoice);
             outgoingInvoices.add(modifiedEntity);
             selectedOutgoingInvoice = modifiedEntity;
-            validate(formDocument);
+            validate();
             BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
             BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
         });
@@ -235,7 +246,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
         if (Objects.nonNull(selectedOutgoingInvoice)) {
             formDocument.getOutgoingInvoices().remove(selectedOutgoingInvoice);
             selectedOutgoingInvoice = null;
-            validate(formDocument);
+            validate();
             BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
             BindUtils.postNotifyChange(this.formDocument, "outgoingInvoice");
         }
@@ -247,7 +258,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
         Editors.doEdit(Editors.TREASURY, entity, modifiedEntity -> {
             formDocument.getTreasuries().add(modifiedEntity);
             selectedTreasury = modifiedEntity;
-            validate(formDocument);
+            validate();
             BindUtils.postNotifyChange(this, "selectedTreasury");
             BindUtils.postNotifyChange(this.formDocument, "treasuries");
         });
@@ -261,7 +272,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
             treasuries.remove(selectedTreasury);
             treasuries.add(modifiedEntity);
             selectedTreasury = modifiedEntity;
-            validate(formDocument);
+            validate();
             BindUtils.postNotifyChange(this, "selectedTreasury");
             BindUtils.postNotifyChange(this.formDocument, "treasuries");
         });
@@ -272,7 +283,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
         if (Objects.nonNull(selectedTreasury)) {
             formDocument.getTreasuries().remove(selectedTreasury);
             selectedTreasury = null;
-            validate(formDocument);
+            validate();
             BindUtils.postNotifyChange(this, "selectedTreasury");
             BindUtils.postNotifyChange(this.formDocument, "treasuries");
         }
@@ -341,7 +352,7 @@ public class ProjectEditorModel extends EntityEditorModel<Project> implements Ev
     @Command
     public void onAssociateChecked() {
         log.info("Associate checked");
-        validate(formDocument);
+        validate();
     }
 
 }
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/editor/selector/EntitySelectorModel.java b/lis-ui/src/main/java/hu/user/lis/ui/editor/selector/EntitySelectorModel.java
new file mode 100644 (file)
index 0000000..cfba1ed
--- /dev/null
@@ -0,0 +1,76 @@
+package hu.user.lis.ui.editor.selector;
+
+import hu.user.lis.ui.data.CachedSpringDataModel;
+import lombok.extern.log4j.Log4j2;
+import org.zkoss.bind.BindContext;
+import org.zkoss.bind.BindUtils;
+import org.zkoss.bind.Converter;
+import org.zkoss.bind.annotation.Command;
+import org.zkoss.bind.annotation.ContextParam;
+import org.zkoss.bind.annotation.ContextType;
+import org.zkoss.zk.ui.event.InputEvent;
+import org.zkoss.zk.ui.event.OpenEvent;
+import org.zkoss.zul.Bandbox;
+
+import java.lang.reflect.Field;
+
+@Log4j2
+public abstract class EntitySelectorModel<T> {
+
+    private T selectedEntity;
+    private Object formDocument;
+    private String member;
+
+    public abstract String selectorIdentifier();
+
+    public abstract Converter<String, T, Bandbox> getDisplayConverter();
+
+    public abstract CachedSpringDataModel<T> getDataModel();
+
+    @Command
+    public void onEntityBandChanging(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
+        InputEvent event = (InputEvent) ctx.getTriggerEvent();
+        log.info("onEntityBandChanging: {}", event.getValue());
+        search(event.getValue());
+    }
+
+    @Command
+    public void onEntityBandOpen(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
+        OpenEvent event = (OpenEvent) ctx.getTriggerEvent();
+        log.info("onEntityBandOpen: {}", event.isOpen());
+        reset();
+    }
+
+    protected abstract void search(String filter);
+
+    protected abstract void reset();
+
+    public T getSelectedEntity() {
+        return selectedEntity;
+    }
+
+    public void setSelectedEntity(T selectedEntity) {
+        this.selectedEntity = selectedEntity;
+        try {
+            Field field = formDocument.getClass().getDeclaredField(member);
+            field.setAccessible(true);
+            field.set(formDocument, selectedEntity);
+            BindUtils.postNotifyChange(formDocument, member);
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+    public void setFormDocument(Object formDocument, String member) {
+        this.formDocument = formDocument;
+        this.member = member;
+        try {
+            Field field = formDocument.getClass().getDeclaredField(member);
+            field.setAccessible(true);
+            selectedEntity = (T) field.get(formDocument);
+            BindUtils.postNotifyChange(this, "selectedEntity");
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+}
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/editor/selector/EntitySelectorRouter.java b/lis-ui/src/main/java/hu/user/lis/ui/editor/selector/EntitySelectorRouter.java
new file mode 100644 (file)
index 0000000..a45643e
--- /dev/null
@@ -0,0 +1,46 @@
+package hu.user.lis.ui.editor.selector;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.log4j.Log4j2;
+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 java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Log4j2
+@Getter
+@Setter
+@Component
+@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+public class EntitySelectorRouter {
+
+    private Map<String, EntitySelectorModel> models;
+
+    private List<EntitySelectorModel> usedModels = new ArrayList<>();
+
+    @Autowired
+    public EntitySelectorRouter(List<EntitySelectorModel> modelList) {
+        models = modelList.stream()
+                .collect(Collectors.toMap(EntitySelectorModel::selectorIdentifier, Function.identity()));
+    }
+
+    public EntitySelectorModel getEntitySelectorModel(String entityName) {
+        EntitySelectorModel result = models.get(entityName);
+        usedModels.add(result);
+        return result;
+    }
+
+    public void setFormDocument(Class<?> entityClass, Object formDocument, String member) {
+        usedModels.stream()
+                .filter(m -> m.selectorIdentifier().equals(entityClass.getSimpleName()))
+                .forEach(m -> m.setFormDocument(formDocument, member));
+    }
+
+}
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/editor/selector/PartnerSelectorModel.java b/lis-ui/src/main/java/hu/user/lis/ui/editor/selector/PartnerSelectorModel.java
new file mode 100644 (file)
index 0000000..c07efbf
--- /dev/null
@@ -0,0 +1,52 @@
+package hu.user.lis.ui.editor.selector;
+
+import hu.user.lis.db.Partner;
+import hu.user.lis.ui.converter.PartnerToNameConverter;
+import hu.user.lis.ui.data.CachedSpringDataModel;
+import hu.user.lis.ui.data.PartnerSelectorDataModel;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.log4j.Log4j2;
+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.Converter;
+import org.zkoss.zul.Bandbox;
+
+@Log4j2
+@Getter
+@Setter
+@Component
+@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+public class PartnerSelectorModel extends EntitySelectorModel<Partner> {
+    @Autowired
+    PartnerToNameConverter partnerToNameConverter;
+    @Autowired
+    PartnerSelectorDataModel partnerSelectorDataModel;
+
+    @Override
+    public String selectorIdentifier() {
+        return Partner.class.getSimpleName();
+    }
+
+    @Override
+    public Converter<String, Partner, Bandbox> getDisplayConverter() {
+        return partnerToNameConverter;
+    }
+
+    @Override
+    public CachedSpringDataModel<Partner> getDataModel() {
+        return partnerSelectorDataModel;
+    }
+
+    @Override
+    protected void search(String filter) {
+        partnerSelectorDataModel.search(filter);
+    }
+
+    @Override
+    protected void reset() {
+        partnerSelectorDataModel.search(null);
+    }
+}
diff --git a/lis-ui/src/main/java/hu/user/lis/ui/editor/widget/EntitySelector.java b/lis-ui/src/main/java/hu/user/lis/ui/editor/widget/EntitySelector.java
new file mode 100644 (file)
index 0000000..44c91a8
--- /dev/null
@@ -0,0 +1,22 @@
+package hu.user.lis.ui.editor.widget;
+
+import lombok.extern.log4j.Log4j2;
+import org.zkoss.zk.ui.Component;
+import org.zkoss.zul.Include;
+
+@Log4j2
+public class EntitySelector extends Include {
+
+    public EntitySelector() {
+        setSrc("~./entity-selector.zul");
+    }
+
+    @Override
+    public void setDynamicProperty(String name, Object value) {
+        super.setDynamicProperty(name, value);
+        setAttribute(name, value, Component.SPACE_SCOPE);
+        log.info("Setting {} = {}", name, value);
+
+    }
+
+}
index 21559db8e84c227b4ca2b29c0032ad831dfe2af3..92542ade7febc018fcea52d4a1bb06a8db4ebfcf 100644 (file)
@@ -11,14 +11,32 @@ import org.zkoss.zk.ui.event.EventQueues;
 @Service
 @Log4j2
 public class EventBus {
+
+    public EventBus() {
+//        EventQueue<Event> queue = EventQueues.lookup("$ZKBIND_DEFQUE$", EventQueues.SESSION, true);
+//        queue.subscribe(event -> {
+//            log.info("EVT: {}", event.getName());
+//        });
+
+
+    }
+
     private EventQueue<Event> getQueue() {
         return EventQueues.lookup(Constants.PROJECT_EDITOR_QUEUE, EventQueues.SESSION, true);
     }
 
+    private EventQueue<Event> getBindingQueue() {
+        return EventQueues.lookup(Constants.BINDING_QUEUE, EventQueues.DESKTOP, true);
+    }
+
     public void register(EventListener listener) {
         getQueue().subscribe(listener);
     }
 
+    public void registerForBinding(EventListener listener) {
+        getBindingQueue().subscribe(listener);
+    }
+
     public void unregister(EventListener listener) {
         try {
             getQueue().unsubscribe(listener);
diff --git a/lis-ui/src/main/resources/web/entity-selector.zul b/lis-ui/src/main/resources/web/entity-selector.zul
new file mode 100644 (file)
index 0000000..1f71241
--- /dev/null
@@ -0,0 +1,53 @@
+<zk xmlns:c="client">
+    <hlayout viewModel="@id('vmEntity') @init(vm.getEntitySelectorRouter().getEntitySelectorModel(entity))">
+        <bandbox id="entityBandBox" autodrop="true" iconSclass="z-icon-sort-down" hflex="true" mold="rounded"
+                 value="@load(vmEntity.selectedEntity) @converter(vmEntity.displayConverter)"
+                 onChanging="@command('onEntityBandChanging')" onOpen="@command('onEntityBandOpen')"
+                 forward="onOK=submit.onClick, onCancel=cancel.onClick">
+            <attribute c:name="_doKeyDown">
+                <![CDATA[
+                            function (evt) {
+                                var keyCode = evt.keyCode;
+                                console.log(keyCode);
+                                if (keyCode == 13){
+                                    zk.$("$entityBandBox").close();
+                                    zk.$("$entityBandBox").focus();
+                                    return;
+                                }
+                                if (keyCode == 40){
+                                    if (!zk.$("$entityBandBox").isOpen()) {
+                                        zk.$("$entityBandBox").open();
+                                        zAu.send(new zk.Event(zk.Widget.$('$entityBandBox'), "onOpen", {'open': true}, {toServer:true}));
+                                    }
+                                    console.log("List", zk.$("$entityList"));
+
+                                    zk.$("$entityList").focus();
+                                    return;
+                                }
+                                if (keyCode == 27){
+                                    zk.$("$entityBandBox").close()
+                                    zk.$("$entityBandBox").focus();
+                                    return;
+                                }
+                            }
+                        ]]>
+            </attribute>
+            <bandpopup style="background: red" width="400px">
+                <listbox id="entityList" height="250px"
+                         model="@bind(vmEntity.dataModel)"
+                         selectedItem="@bind(vmEntity.selectedEntity)"
+                         onClick="entityBandBox.close()"
+                         onDoubleClick="entityBandBox.close()">
+                    <listhead visible="false">
+                        <listheader label="name" vflex="max"/>
+                    </listhead>
+                    <template name="model">
+                        <listitem>
+                            <listcell label="@load(each.name)"/>
+                        </listitem>
+                    </template>
+                </listbox>
+            </bandpopup>
+        </bandbox>
+    </hlayout>
+</zk>
index 8f4a36ce2166a3c31fdc2a1fb44a7575a334165a..158c21d800a418167a3b58046f5f1df93b57ced8 100644 (file)
                 <rows>
                     <row>
                         <label value="User"/>
-                        <textbox name="username" value="user" hflex="true"/>
+                        <textbox name="username" hflex="true" value="user"/>
                     </row>
                     <row>
                         <label value="Password"/>
-                        <textbox type="password" name="password" value="password" hflex="true"/>
+                        <textbox type="password" name="password" hflex="true" value="password"/>
                     </row>
                     <row spans="2" align="right">
                         <hlayout>
index 54ae1ecce3a400675fc9928719d78a3c5143b213..ead141a80e183ee4b1a4ed2ab25bc60673a75501 100644 (file)
@@ -19,7 +19,9 @@
                                         zk.$("$partnerBandBox").open();
                                         zAu.send(new zk.Event(zk.Widget.$('$partnerBandBox'), "onOpen", {'open': true}, {toServer:true}));
                                     }
-                                    zk.$("$partenerList").focus();
+                                    console.log("List", zk.$("$partnerList"));
+
+                                    zk.$("$partnerList").focus();
                                     return;
                                 }
                                 if (keyCode == 27){
@@ -31,7 +33,7 @@
                         ]]>
             </attribute>
             <bandpopup>
-                <listbox id="partenerlist" height="250px" width="450px"
+                <listbox id="partnerList" height="250px" width="450px"
                          model="@bind(vm.partnerSelectorDataModel)"
                          selectedItem="@bind(vm.formDocument.partner) @validator(vm)"
                          onClick="partnerBandBox.close()"
index 7c2bb352458ba5589b03db01816c31337aa379c4..b8030eddb4980e3e98f8e0679417f0ebe5943ae3 100644 (file)
@@ -41,6 +41,5 @@
                 </listbox>
             </center>
         </borderlayout>
-
     </window>
 </zk>
\ No newline at end of file
index 153ca3dba60d5669f71996f222b31217f60f687a..92c1d1afb153034da039f4ffb9ec5f10784daed1 100644 (file)
@@ -1,4 +1,5 @@
-<?component name="partner-selector" inline="true" macroURI="~./partner-selector.zul"?>
+<!--<?component name="partner-selector" inline="true" macroURI="~./partner-selector.zul"?>-->
+<?component name="entity-selector" inline="true" class="hu.user.lis.ui.editor.widget.EntitySelector"?>
 <zk>
     <window id="projectEditor" hflex="true" vflex="true"
             viewModel="@id('vm') @init('hu.user.lis.ui.editor.ProjectEditorModel')">
@@ -38,8 +39,9 @@
                                                 </row>
                                                 <row>
                                                     <vlayout>
-                                                        <label value="Ügyfél"/>
-                                                        <partner-selector/>
+                                                        <label id="label1" value="Ügyfél"/>
+                                                        <entity-selector entity="Partner"
+                                                                         property="formDocument.partner"/>
                                                     </vlayout>
                                                     <vlayout>
                                                         <label value="Kapcsolattartó"/>