From: elgekko Date: Mon, 15 May 2023 20:11:00 +0000 (+0200) Subject: Minor bug fixes, service records extended, settings basics X-Git-Url: http://git.useribm.hu/?a=commitdiff_plain;h=bc40813552d9700a93bfc1fca3e56e1bb1b31640;p=sly-crm.git Minor bug fixes, service records extended, settings basics --- diff --git a/TODO.txt b/TODO.txt index 1f0623b..d8a843b 100644 --- a/TODO.txt +++ b/TODO.txt @@ -6,6 +6,7 @@ * A be és kimenő számlák felviteli képernyőjén be lehessen állítani, hogy ez egy tervezett számla-e. * Számlakép feltöltés: pdf csatolás * Munkatárs lista és szerkesztő: név, óradíj + 0.0.7 * Tervezett számla esetén: a határidők nem ismertek, nem kötelező; áfa deviza esetén nem ismert, nem kötelező * Projekt szerkesztőben előbb van a kimenő számlák lista @@ -26,21 +27,40 @@ * Projekt szerkesztőben treasury műveletek lista: Eladás (aloszlop összeg és deviza), Vétel (aloszlop összeg és deviza),Üzletkötés dátuma, Értéknap * A treasury szerkesztőben banki visszaigazolás pdf csatolása -- Munkalap: külön lista xy hány órát (mindenki önköltség) dolgozott melyik projekten -- Projekt szerkesztőben tresaury táblázat alatt munkalap lista, ráfordítás összesítéssel (fixen 21 munkanappal számolva havonta) - -- Valós adatok a projekt, partner, számla nézetben (Kele Károly) +0.0.9 +* Munkalap: külön lista xy hány órát (mindenki önköltség) dolgozott melyik projekten +* Projekt szerkesztőben tresaury táblázat alatt munkalap lista, ráfordítás összesítéssel (fixen 21 munkanappal számolva havonta) +* Valós adatok a projekt, partner, számla nézetben (Kele Károly) +0.1.0 +* Treasury editor pénznem hibásan működik, mindkettő változik, ha az egyiket módosítom +* Munkalapon: "összefoglaló" és "részletes leírás" mezők; az összefoglaló kötelező +* Munkalaphoz: Aláírt munkalap feltöltésének lehetősége. Feltöltéskor kerüljön át a státusz "aláírt"-ba. +* Az oszlopszélesség minden listában állítható +* Treasury műveletek mentésénél nullpointer exception jön +- Munkalapon: "normális" elrendezés, nézzen ki jól +- Minden szám: legyen jobbra igazítva, oszlop fejlécek pedig középen; mindenhol két tizedes pontossággal +- Projekt: kell egy "státusz" mező: + Legyen rendszerparaméter, és egy lista amiből választani lehet és a sorrend is legyen változtatható a listaban, + (pl.: Új, Terv, Készül az ajánlat, Ajánlat kiküldve, Megrendelve, Számlázható, Kiszámlázva, Elbuktuk) de db-ből +- Projektekhez: Legyen kicsit normálisabb elrendezésű. +- Nem jól kalkulálódik az "óradíj" a munkalapon +- A projektekhez valos treasury karolytol +- A projektben a munkalap osszesitve jelenjen meg személyenként,de navigáljon el bontott nézetbe kattintásra +- A munkalapok lista szűrhető projektre és résztvevőre. Ezt használjuk ki, amikor a projekt összevont nézetből a munkalap + bontást szeretnénk látni - A projekt szerkesztés/részletezés tetején az adatok legyenek bal oldalon bekeretezve. A jobb oldalon pedig legyen látható a projekt árrése. Az árrés annyi sorból áll ahány devizanem van a projekt számláiban. Egy adott devizanem esetén a számolás: Kimenő - Bejövő - Treasury eladás + Treasury vétel -- számla kiegyenlítés +- Számla kiegyenlítés + - Minden kívülről leszipkázható adat jöjjön módosítható legyen REST API-n: szla kiegyenlítés, bejövő/kimenő számlák, munkalap Ez emiatt kell, a szinkronizációt egy külső app végzi? - - Autentikáció: AD és helyi - Authorizáció: SAP S3 authorization objects leírás +- legyen felhasználó specifikus beállításokra lehetőség + - Táblázatok: oszlopszélesség állítható és rendezhető legyen (minden oszlopra) mencse el a felhasználó preferenciához. - Munkalap rögzítés úgy, hogy raktáron lévő alkatrészt is fel lehessen vinni a munkalapra. - Plugin: lehet egyedi testreszabási igény, de ennek valahogy el kell teljesen különülnie a "core" forráskódtól. Pl. javascript motort be lehetne építeni, a szkriptek pedig meghatározott pontokon lehetnének becsatolva a logikába. Számla részletezés volt a példa (10000EUR számla 3 részletben forintban, kérdés mennyi pl. az utsó számla összege); 10 custom mező, javascripttel futna a custom mezők módosítására. diff --git a/lis-app/pom.xml b/lis-app/pom.xml index ae61ab2..f33aa88 100644 --- a/lis-app/pom.xml +++ b/lis-app/pom.xml @@ -4,7 +4,7 @@ 4.0.0 hu.user lis-app - 0.0.8-SNAPSHOT + 0.0.9-SNAPSHOT hu.user lis diff --git a/lis-db/src/main/java/hu/user/lis/db/ProjectStatus.java b/lis-db/src/main/java/hu/user/lis/db/ProjectStatus.java new file mode 100644 index 0000000..d0ee9ab --- /dev/null +++ b/lis-db/src/main/java/hu/user/lis/db/ProjectStatus.java @@ -0,0 +1,15 @@ +package hu.user.lis.db; + +import lombok.*; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProjectStatus { + String id; + String name; + boolean active; + int order; +} diff --git a/lis-db/src/main/java/hu/user/lis/db/ServiceRecord.java b/lis-db/src/main/java/hu/user/lis/db/ServiceRecord.java new file mode 100644 index 0000000..0ce1fd7 --- /dev/null +++ b/lis-db/src/main/java/hu/user/lis/db/ServiceRecord.java @@ -0,0 +1,22 @@ +package hu.user.lis.db; + +import lombok.*; + +import java.util.Date; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ServiceRecord { + String id; + Project project; + Associate associate; + Date workDay; + String description; + String details; + int workHours; + double cost; + byte[] file; +} diff --git a/lis-services/src/main/java/hu/user/lis/services/data/AssociateServiceImpl.java b/lis-services/src/main/java/hu/user/lis/services/data/AssociateServiceImpl.java index 8bc3e65..6fcc976 100644 --- a/lis-services/src/main/java/hu/user/lis/services/data/AssociateServiceImpl.java +++ b/lis-services/src/main/java/hu/user/lis/services/data/AssociateServiceImpl.java @@ -1,6 +1,5 @@ package hu.user.lis.services.data; -import com.fasterxml.jackson.databind.ObjectMapper; import hu.user.lis.db.Associate; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.RandomStringUtils; @@ -16,8 +15,6 @@ import java.util.List; @Service @Log4j2 public class AssociateServiceImpl extends DataServiceImpl implements AssociateService { - @Autowired - ObjectMapper mapper; @Autowired DataGeneratorService dataGeneratorService; private List entities; @@ -79,47 +76,65 @@ public class AssociateServiceImpl extends DataServiceImpl implements private List generate2() { List result = new ArrayList<>(); - - String id = RandomStringUtils.random(8, "0123456789abcdef"); - String name = "Kosztolányi Árpád"; - String login = "user1"; - String password = "password"; - Associate entity = Associate.builder().active(true).id(id).name(name).login(login).password(password).build(); - result.add(entity); + double monthlyCost = 0; + String id = RandomStringUtils.random(8, "0123456789abcdef"); + String name = "Kosztolányi Árpád"; + String login = "user1"; + String password = "password"; + monthlyCost = BigDecimal.valueOf(RandomUtils.nextDouble(300000, 1500000)) + .setScale(2, RoundingMode.CEILING).doubleValue(); + Associate entity = Associate.builder().monthlyCost(monthlyCost) + .active(true).id(id).name(name).login(login).password(password).build(); + result.add(entity); id = RandomStringUtils.random(8, "0123456789abcdef"); name = "Lévai Tibor"; login = "user2"; password = "password"; - entity = Associate.builder().active(true).id(id).name(name).login(login).password(password).build(); + monthlyCost = BigDecimal.valueOf(RandomUtils.nextDouble(300000, 1500000)) + .setScale(2, RoundingMode.CEILING).doubleValue(); + entity = Associate.builder().monthlyCost(monthlyCost) + .active(true).id(id).name(name).login(login).password(password).build(); result.add(entity); id = RandomStringUtils.random(8, "0123456789abcdef"); name = "Szabó Marcell"; login = "user3"; password = "password"; - entity = Associate.builder().active(true).id(id).name(name).login(login).password(password).build(); + monthlyCost = BigDecimal.valueOf(RandomUtils.nextDouble(300000, 1500000)) + .setScale(2, RoundingMode.CEILING).doubleValue(); + entity = Associate.builder().monthlyCost(monthlyCost) + .active(true).id(id).name(name).login(login).password(password).build(); result.add(entity); id = RandomStringUtils.random(8, "0123456789abcdef"); name = "Gulyás Csaba"; login = "user4"; password = "password"; - entity = Associate.builder().active(true).id(id).name(name).login(login).password(password).build(); + monthlyCost = BigDecimal.valueOf(RandomUtils.nextDouble(300000, 1500000)) + .setScale(2, RoundingMode.CEILING).doubleValue(); + entity = Associate.builder().monthlyCost(monthlyCost) + .active(true).id(id).name(name).login(login).password(password).build(); result.add(entity); id = RandomStringUtils.random(8, "0123456789abcdef"); name = "Lévai Csilla"; login = "user5"; password = "password"; - entity = Associate.builder().active(true).id(id).name(name).login(login).password(password).build(); + monthlyCost = BigDecimal.valueOf(RandomUtils.nextDouble(300000, 1500000)) + .setScale(2, RoundingMode.CEILING).doubleValue(); + entity = Associate.builder().monthlyCost(monthlyCost) + .active(true).id(id).name(name).login(login).password(password).build(); result.add(entity); id = RandomStringUtils.random(8, "0123456789abcdef"); name = "Vajda Krisztina"; login = "user6"; password = "password"; - entity = Associate.builder().active(true).id(id).name(name).login(login).password(password).build(); + monthlyCost = BigDecimal.valueOf(RandomUtils.nextDouble(300000, 1500000)) + .setScale(2, RoundingMode.CEILING).doubleValue(); + entity = Associate.builder().monthlyCost(monthlyCost) + .active(true).id(id).name(name).login(login).password(password).build(); result.add(entity); return result; diff --git a/lis-services/src/main/java/hu/user/lis/services/data/ProjectService.java b/lis-services/src/main/java/hu/user/lis/services/data/ProjectService.java index 912afb7..ab2b69e 100644 --- a/lis-services/src/main/java/hu/user/lis/services/data/ProjectService.java +++ b/lis-services/src/main/java/hu/user/lis/services/data/ProjectService.java @@ -1,6 +1,5 @@ package hu.user.lis.services.data; -import hu.user.lis.db.Partner; import hu.user.lis.db.Project; import java.util.List; @@ -12,6 +11,8 @@ public interface ProjectService { List getByPartner(String id); + Project getRandom(); + Project createNew(); void add(Project entity); diff --git a/lis-services/src/main/java/hu/user/lis/services/data/ProjectServiceImpl.java b/lis-services/src/main/java/hu/user/lis/services/data/ProjectServiceImpl.java index 49e337a..025af62 100644 --- a/lis-services/src/main/java/hu/user/lis/services/data/ProjectServiceImpl.java +++ b/lis-services/src/main/java/hu/user/lis/services/data/ProjectServiceImpl.java @@ -4,6 +4,7 @@ import hu.user.lis.db.Partner; import hu.user.lis.db.Project; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -73,6 +74,11 @@ public class ProjectServiceImpl extends DataServiceImpl implements Proj entities.add(replacementEntity); } + @Override + public Project getRandom() { + return getAll().get(RandomUtils.nextInt(0, entities.size())); + } + private List generate() { List result = new ArrayList<>(); DateFormat dateFormat = new SimpleDateFormat("yyyy"); @@ -114,8 +120,9 @@ public class ProjectServiceImpl extends DataServiceImpl implements Proj .name(name) .contactName(contactName) .partner(partner) - .incomingInvoices(invoiceService.getByHumanIds(new String[] {"VSz-2023/00070-"})) // VSz-2023/00070- - .outgoingInvoices(invoiceService.getByHumanIds(new String[] {"USER-2023-7"})) // USER-2023-7 + .incomingInvoices(invoiceService.getByHumanIds(new String[]{"VSz-2023/00070-"})) // VSz-2023/00070- + .outgoingInvoices(invoiceService.getByHumanIds(new String[]{"USER-2023-7"})) // USER-2023-7 + .treasuries(treasuryService.getRandom()) .build(); result.add(entity); @@ -131,8 +138,9 @@ public class ProjectServiceImpl extends DataServiceImpl implements Proj .name(name) .contactName(contactName) .partner(partner) - .incomingInvoices(invoiceService.getByHumanIds(new String[]{"582-SPI1003006-3021","582-SPI003118","582-SPI003680","582-SPI003681","582-SPI004090","9090010764","VSz-2021/00091"})) // 582-SPI1003006-3021, 582-SPI003118, 582-SPI003680, 582-SPI003681, 582-SPI004090, 9090010764, VSz-2021/00091 - .outgoingInvoices(invoiceService.getByHumanIds(new String[]{"2021/0001","2021/0069"})) // 2021/0001, 2021/0069 + .incomingInvoices(invoiceService.getByHumanIds(new String[]{"582-SPI1003006-3021", "582-SPI003118", "582-SPI003680", "582-SPI003681", "582-SPI004090", "9090010764", "VSz-2021/00091"})) // 582-SPI1003006-3021, 582-SPI003118, 582-SPI003680, 582-SPI003681, 582-SPI004090, 9090010764, VSz-2021/00091 + .outgoingInvoices(invoiceService.getByHumanIds(new String[]{"2021/0001", "2021/0069"})) // 2021/0001, 2021/0069 + .treasuries(treasuryService.getRandom()) .build(); result.add(entity); @@ -148,8 +156,9 @@ public class ProjectServiceImpl extends DataServiceImpl implements Proj .name(name) .contactName(contactName) .partner(partner) - .incomingInvoices(invoiceService.getByHumanIds(new String[]{"EURSZLA0177/2022","19044","9171058452","9171058628","2022-SOV/000495","2022-SOV/000496","E-SYMPR-2022-105"})) // EURSZLA0177/2022, 19044, 9171058452, 9171058628, V-SZ3-2022/00001, 2022-SOV/000495, 2022-SOV/000496, E-SYMPR-2022-105 - .outgoingInvoices(invoiceService.getByHumanIds(new String[]{"E-USER-2023-12","E-USER-2023-13"})) // E-USER-2023-12, E-USER-2023-13 + .incomingInvoices(invoiceService.getByHumanIds(new String[]{"EURSZLA0177/2022", "19044", "9171058452", "9171058628", "2022-SOV/000495", "2022-SOV/000496", "E-SYMPR-2022-105"})) // EURSZLA0177/2022, 19044, 9171058452, 9171058628, V-SZ3-2022/00001, 2022-SOV/000495, 2022-SOV/000496, E-SYMPR-2022-105 + .outgoingInvoices(invoiceService.getByHumanIds(new String[]{"E-USER-2023-12", "E-USER-2023-13"})) // E-USER-2023-12, E-USER-2023-13 + .treasuries(treasuryService.getRandom()) .build(); result.add(entity); @@ -167,6 +176,7 @@ public class ProjectServiceImpl extends DataServiceImpl implements Proj .partner(partner) .incomingInvoices(invoiceService.getByHumanIds(new String[]{"17356/23"})) // 17356/23 .outgoingInvoices(invoiceService.getByHumanIds(new String[]{"E-USER-2023-53"})) // E-USER-2023-53 + .treasuries(treasuryService.getRandom()) .build(); result.add(entity); @@ -184,6 +194,7 @@ public class ProjectServiceImpl extends DataServiceImpl implements Proj .partner(partner) .incomingInvoices(invoiceService.getByHumanIds(new String[]{"2023-SOV/000123"})) // 2023-SOV/000123 .outgoingInvoices(invoiceService.getByHumanIds(new String[]{"E-USER-2023-95"})) // E-USER-2023-95 + .treasuries(treasuryService.getRandom()) .build(); result.add(entity); diff --git a/lis-services/src/main/java/hu/user/lis/services/data/ProjectStatusService.java b/lis-services/src/main/java/hu/user/lis/services/data/ProjectStatusService.java new file mode 100644 index 0000000..cfcfa67 --- /dev/null +++ b/lis-services/src/main/java/hu/user/lis/services/data/ProjectStatusService.java @@ -0,0 +1,19 @@ +package hu.user.lis.services.data; + +import hu.user.lis.db.ProjectStatus; + +import java.util.List; + +public interface ProjectStatusService extends DataService { + List getAll(); + + ProjectStatus getById(String id); + + ProjectStatus createNew(); + + void add(ProjectStatus entity); + + ProjectStatus getRandom(); + + void replace(ProjectStatus targetEntity, ProjectStatus replacementEntity); +} diff --git a/lis-services/src/main/java/hu/user/lis/services/data/ProjectStatusServiceImpl.java b/lis-services/src/main/java/hu/user/lis/services/data/ProjectStatusServiceImpl.java new file mode 100644 index 0000000..8c96ade --- /dev/null +++ b/lis-services/src/main/java/hu/user/lis/services/data/ProjectStatusServiceImpl.java @@ -0,0 +1,77 @@ +package hu.user.lis.services.data; + +import hu.user.lis.db.ProjectStatus; +import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomUtils; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +@Log4j2 +public class ProjectStatusServiceImpl extends DataServiceImpl implements ProjectStatusService { + private Map entities; + + @Override + public List getAll() { + if (entities == null) { + entities = generate(); + } + return entities.values().stream().sorted(Comparator.comparing(ProjectStatus::getOrder)).collect(Collectors.toList()); + } + + @Override + public ProjectStatus getById(String id) { + return entities.get(id); + } + + @Override + public ProjectStatus createNew() { + String id = RandomStringUtils.random(8, "0123456789abcdef"); + return ProjectStatus.builder().id(id).active(true).build(); + } + + @Override + public void add(ProjectStatus entity) { + entities.put(entity.getId(), entity); + } + + @Override + public void replace(ProjectStatus targetEntity, ProjectStatus replacementEntity) { + entities.put(replacementEntity.getId(), replacementEntity); + } + + @Override + public ProjectStatus getRandom() { + return getAll().get(RandomUtils.nextInt(0, entities.size())); + } + + private void createStatus(String name, Map entities) { + ProjectStatus entity = ProjectStatus.builder() + .active(true) + .id(RandomStringUtils.random(8, "0123456789abcdef")) + .name("Új") + .order(entities.size()) + .build(); + entities.put(entity.getId(), entity); + } + + private Map generate() { + Map result = new HashMap<>(); + createStatus("Új", result); + createStatus("Terv", result); + createStatus("Készül az ajánlat", result); + createStatus("Ajánlat kiküldve", result); + createStatus("Megrendelve", result); + createStatus("Számlázható", result); + createStatus("Kiszámlázva", result); + createStatus("Elbuktuk", result); + return result; + } + +} diff --git a/lis-services/src/main/java/hu/user/lis/services/data/ServiceRecordService.java b/lis-services/src/main/java/hu/user/lis/services/data/ServiceRecordService.java new file mode 100644 index 0000000..a74541d --- /dev/null +++ b/lis-services/src/main/java/hu/user/lis/services/data/ServiceRecordService.java @@ -0,0 +1,30 @@ +package hu.user.lis.services.data; + +import hu.user.lis.db.Project; +import hu.user.lis.db.ServiceRecord; + +import java.util.List; + +public interface ServiceRecordService { + List getAll(); + + ServiceRecord getById(String id); + + List getByProject(String id); + + ServiceRecord createNew(); + + List getRandom(Project project); + + void add(ServiceRecord entity); + + ServiceRecord copy(ServiceRecord sourceEntity); + + void calculateCost(ServiceRecord entity); + + void replace(ServiceRecord targetEntity, ServiceRecord replacementEntity); + + String toString(ServiceRecord sourceEntity); + + ServiceRecord copy(ServiceRecord sourceEntity, String property, Object value); +} diff --git a/lis-services/src/main/java/hu/user/lis/services/data/ServiceRecordServiceImpl.java b/lis-services/src/main/java/hu/user/lis/services/data/ServiceRecordServiceImpl.java new file mode 100644 index 0000000..61f16e4 --- /dev/null +++ b/lis-services/src/main/java/hu/user/lis/services/data/ServiceRecordServiceImpl.java @@ -0,0 +1,118 @@ +package hu.user.lis.services.data; + +import hu.user.lis.db.Associate; +import hu.user.lis.db.Project; +import hu.user.lis.db.ServiceRecord; +import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.RandomUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +@Service +@Log4j2 +public class ServiceRecordServiceImpl extends DataServiceImpl implements ServiceRecordService { + @Autowired + DataGeneratorService dataGeneratorService; + @Autowired + ProjectService projectService; + @Autowired + AssociateService associateService; + private HashMap projectRecords = new HashMap<>(); + private List entities; + + @Override + public List getAll() { + + if (entities == null) { + entities = generate(); + } + return entities; + } + + @Override + public ServiceRecord getById(String id) { + return getAll().stream().filter(p -> p.getId().equals(id)).findFirst().get(); + } + + @Override + public List getByProject(String id) { + return getAll().stream().filter(p -> p.getProject().getId().equals(id)).collect(Collectors.toList()); + } + + + @Override + public ServiceRecord createNew() { + String id = RandomStringUtils.random(8, "0123456789abcdef"); + return ServiceRecord.builder() + .id(id) + .build(); + } + + @Override + public List getRandom(Project project) { + return null; + } + + @Override + public void add(ServiceRecord entity) { + calculateCost(entity); + entities.add(entity); + } + + @Override + public void calculateCost(ServiceRecord entity) { + double cost = 0; + try { + cost = entity.getAssociate().getMonthlyCost() * entity.getWorkHours() / 21; + entity.setCost(cost); + } catch (Exception e) { + log.catching(e); + } + } + + @Override + public void replace(ServiceRecord targetEntity, ServiceRecord replacementEntity) { + ServiceRecord target = entities.stream().filter(p -> p.getId().equals(targetEntity.getId())).findFirst().get(); + entities.remove(target); + entities.add(replacementEntity); + } + + private List generate() { + List result = new ArrayList<>(); + + projectService.getAll().forEach(p -> { + int serviceRecordCount = RandomUtils.nextInt(3, 10); + for (int i = 0; i < serviceRecordCount; i++) { + String id = RandomStringUtils.random(8, "0123456789abcdef"); + Date workDay = dataGeneratorService.faker().date().past(i * 10 + 1, TimeUnit.DAYS); + Associate associate = associateService.getRandom(); + String description = dataGeneratorService.faker().lorem().sentence(10); + int workHours = RandomUtils.nextInt(1, 9); + ServiceRecord entity = ServiceRecord.builder() + .associate(associate) + .project(p) + .workDay(workDay) + .workHours(workHours) + .description(description) + .id(id) + .build(); + calculateCost(entity); + result.add(entity); + projectRecords.put(p.getId(), entity); + } + + }); + + return result; + } + + +} diff --git a/lis-ui/src/main/java/hu/user/lis/ui/config/ResourceConfigurer.java b/lis-ui/src/main/java/hu/user/lis/ui/config/ResourceConfigurer.java index e0dc293..6d9985b 100644 --- a/lis-ui/src/main/java/hu/user/lis/ui/config/ResourceConfigurer.java +++ b/lis-ui/src/main/java/hu/user/lis/ui/config/ResourceConfigurer.java @@ -10,7 +10,7 @@ public class ResourceConfigurer { return "admin/index"; } - @GetMapping({"/projects", "/associates", "/project-associates", "/project/**"}) + @GetMapping({"/projects", "/associates", "/project-associates", "/service-records", "/settings", "/project/**"}) public String index() { return "index"; } diff --git a/lis-ui/src/main/java/hu/user/lis/ui/converter/AssociateToNameConverter.java b/lis-ui/src/main/java/hu/user/lis/ui/converter/AssociateToNameConverter.java new file mode 100644 index 0000000..86a66b4 --- /dev/null +++ b/lis-ui/src/main/java/hu/user/lis/ui/converter/AssociateToNameConverter.java @@ -0,0 +1,19 @@ +package hu.user.lis.ui.converter; + +import hu.user.lis.db.Associate; +import org.zkoss.bind.BindContext; +import org.zkoss.bind.Converter; +import org.zkoss.zul.Bandbox; + +public class AssociateToNameConverter implements Converter { + + @Override + public String coerceToUi(Associate Associate, Bandbox bandbox, BindContext bindContext) { + return Associate == null ? null : Associate.getName(); + } + + @Override + public Associate coerceToBean(String s, Bandbox bandbox, BindContext bindContext) { + return null; + } +} \ No newline at end of file diff --git a/lis-ui/src/main/java/hu/user/lis/ui/converter/ProjectToNameConverter.java b/lis-ui/src/main/java/hu/user/lis/ui/converter/ProjectToNameConverter.java new file mode 100644 index 0000000..c89de12 --- /dev/null +++ b/lis-ui/src/main/java/hu/user/lis/ui/converter/ProjectToNameConverter.java @@ -0,0 +1,19 @@ +package hu.user.lis.ui.converter; + +import hu.user.lis.db.Project; +import org.zkoss.bind.BindContext; +import org.zkoss.bind.Converter; +import org.zkoss.zul.Bandbox; + +public class ProjectToNameConverter implements Converter { + + @Override + public String coerceToUi(Project project, Bandbox bandbox, BindContext bindContext) { + return project == null ? null : project.getHumanId(); + } + + @Override + public Project coerceToBean(String s, Bandbox bandbox, BindContext bindContext) { + return null; + } +} \ No newline at end of file diff --git a/lis-ui/src/main/java/hu/user/lis/ui/data/AssociateSelectorDataModel.java b/lis-ui/src/main/java/hu/user/lis/ui/data/AssociateSelectorDataModel.java new file mode 100644 index 0000000..4ab3241 --- /dev/null +++ b/lis-ui/src/main/java/hu/user/lis/ui/data/AssociateSelectorDataModel.java @@ -0,0 +1,63 @@ +package hu.user.lis.ui.data; + +import hu.user.lis.db.Associate; +import hu.user.lis.services.data.AssociateService; +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; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +@Component +@Log4j2 +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class AssociateSelectorDataModel extends CachedDataModel { + static private final int SEARCH_LIMIT = 10; + @Autowired + AssociateService associateService; + private String partialName; + + private boolean filter(Associate associate) { + if (StringUtils.isBlank(partialName)) { + return true; + } else { + if (associate.getName().toLowerCase().startsWith(partialName.toLowerCase())) { + return true; + } + } + return false; + } + + @Override + protected List getResultSet(long offset, int limit, FieldComparator sortComparator) { + List result = associateService.getAll().stream() + .sorted(Comparator.comparing(Associate::getName)) + .filter(s -> filter(s)) + .limit(SEARCH_LIMIT) + .collect(Collectors.toList()); + return result; + } + + @Override + public int getResultSetCount() { + int result = (int) associateService.getAll().stream() + .filter(s -> filter(s)) + .limit(SEARCH_LIMIT) + .count(); + return result; + } + + public void search(String partialName) { + log.info("Searching associate using filter {}", partialName); + this.partialName = partialName; + super.reset(); + BindUtils.postNotifyChange(null, null, this, "*"); + } +} diff --git a/lis-ui/src/main/java/hu/user/lis/ui/data/ProjectSelectorDataModel.java b/lis-ui/src/main/java/hu/user/lis/ui/data/ProjectSelectorDataModel.java new file mode 100644 index 0000000..807334d --- /dev/null +++ b/lis-ui/src/main/java/hu/user/lis/ui/data/ProjectSelectorDataModel.java @@ -0,0 +1,63 @@ +package hu.user.lis.ui.data; + +import hu.user.lis.db.Project; +import hu.user.lis.services.data.ProjectService; +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; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +@Component +@Log4j2 +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class ProjectSelectorDataModel extends CachedDataModel { + static private final int SEARCH_LIMIT = 10; + @Autowired + ProjectService projectService; + private String partialName; + + private boolean filter(Project project) { + if (StringUtils.isBlank(partialName)) { + return true; + } else { + if (project.getHumanId().toLowerCase().startsWith(partialName.toLowerCase())) { + return true; + } + } + return false; + } + + @Override + protected List getResultSet(long offset, int limit, FieldComparator sortComparator) { + List result = projectService.getAll().stream() + .sorted(Comparator.comparing(Project::getName)) + .filter(s -> filter(s)) + .limit(SEARCH_LIMIT) + .collect(Collectors.toList()); + return result; + } + + @Override + public int getResultSetCount() { + int result = (int) projectService.getAll().stream() + .filter(s -> filter(s)) + .limit(SEARCH_LIMIT) + .count(); + return result; + } + + public void search(String partialName) { + log.info("Searching project using filter {}", partialName); + this.partialName = partialName; + super.reset(); + BindUtils.postNotifyChange(null, null, this, "*"); + } +} diff --git a/lis-ui/src/main/java/hu/user/lis/ui/data/ProjectStatusDataModel.java b/lis-ui/src/main/java/hu/user/lis/ui/data/ProjectStatusDataModel.java new file mode 100644 index 0000000..fdaa832 --- /dev/null +++ b/lis-ui/src/main/java/hu/user/lis/ui/data/ProjectStatusDataModel.java @@ -0,0 +1,39 @@ +package hu.user.lis.ui.data; + +import hu.user.lis.db.ProjectStatus; +import hu.user.lis.services.data.ProjectStatusService; +import lombok.Getter; +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.BindUtils; +import org.zkoss.zul.FieldComparator; + +import java.util.List; + +@Component +@Log4j2 +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class ProjectStatusDataModel extends CachedDataModel { + @Getter + @Autowired + ProjectStatusService projectStatusService; + + @Override + protected List getResultSet(long offset, int limit, FieldComparator sortComparator) { + return projectStatusService.getAll(); + } + + @Override + public int getResultSetCount() { + return projectStatusService.getAll().size(); + } + + public void listAll() { + super.reset(); + BindUtils.postNotifyChange(null, null, this, "*"); + } + +} diff --git a/lis-ui/src/main/java/hu/user/lis/ui/data/ServiceRecordsDataModel.java b/lis-ui/src/main/java/hu/user/lis/ui/data/ServiceRecordsDataModel.java new file mode 100644 index 0000000..4063d5b --- /dev/null +++ b/lis-ui/src/main/java/hu/user/lis/ui/data/ServiceRecordsDataModel.java @@ -0,0 +1,92 @@ +package hu.user.lis.ui.data; + +import hu.user.lis.db.ServiceRecord; +import hu.user.lis.services.data.ServiceRecordService; +import lombok.Getter; +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.bind.annotation.Init; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.FieldComparator; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +@Component +@Log4j2 +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class ServiceRecordsDataModel extends CachedDataModel { + @Getter + @Autowired + ServiceRecordService serviceRecordService; + private boolean listAll; + private String projectId; + + @Init + public void init() { + Clients.evalJavaScript("pushNav('/service-records')"); + log.info("Initialized"); + } + + private boolean canExecuteSearch() { + boolean result = listAll || !StringUtils.isBlank(projectId); + log.info("Can execute search: {}", result); + return result; + } + + private boolean filter(ServiceRecord entity) { + if (listAll) { + return true; + } + boolean result = true; + if (!entity.getProject().getId().equals(projectId)) { + result = false; + } + + return result; + } + + @Override + protected List getResultSet(long offset, int limit, FieldComparator sortComparator) { + List result = null; + if (canExecuteSearch()) { + result = serviceRecordService.getAll().stream() + .filter(s -> filter(s)) + .sorted(Comparator.comparing(ServiceRecord::getWorkDay)) + .collect(Collectors.toList()); + } + return result; + } + + @Override + public int getResultSetCount() { + int result = 0; + if (canExecuteSearch()) { + result = (int) serviceRecordService.getAll().stream() + .filter(s -> filter(s)) + .count(); + } + return result; + } + + public void listAll() { + log.info("List all service records"); + listAll = true; + super.reset(); + BindUtils.postNotifyChange(null, null, this, "*"); + } + + public void search(String projectId) { + log.info("Searching project using filter {}", projectId); + this.projectId = projectId; + listAll = false; + super.reset(); + BindUtils.postNotifyChange(null, null, this, "*"); + } +} diff --git a/lis-ui/src/main/java/hu/user/lis/ui/editor/ProjectEditorModel.java b/lis-ui/src/main/java/hu/user/lis/ui/editor/ProjectEditorModel.java index 3c24dee..df6b8f1 100644 --- a/lis-ui/src/main/java/hu/user/lis/ui/editor/ProjectEditorModel.java +++ b/lis-ui/src/main/java/hu/user/lis/ui/editor/ProjectEditorModel.java @@ -6,13 +6,11 @@ import hu.user.lis.db.Associate; import hu.user.lis.db.Invoice; import hu.user.lis.db.Project; import hu.user.lis.db.Treasury; -import hu.user.lis.services.data.InvoiceService; -import hu.user.lis.services.data.ProjectAssociateService; -import hu.user.lis.services.data.ProjectService; -import hu.user.lis.services.data.TreasuryService; +import hu.user.lis.services.data.*; import hu.user.lis.ui.Constants; import hu.user.lis.ui.data.AssociatesDataModel; import hu.user.lis.ui.data.PartnerSelectorDataModel; +import hu.user.lis.ui.data.ServiceRecordsDataModel; import hu.user.lis.ui.event.EventBus; import lombok.Getter; import lombok.Setter; @@ -47,6 +45,8 @@ public class ProjectEditorModel extends AbstractValidator implements EventListen AssociatesDataModel associatesDataModel; @WireVariable ProjectAssociateService projectAssociateServiceImpl; + @WireVariable + ServiceRecordService serviceRecordServiceImpl; private Project formDocument; private Project origDocument; private Map origAssociates; @@ -60,6 +60,9 @@ public class ProjectEditorModel extends AbstractValidator implements EventListen @WireVariable private TreasuryService treasuryServiceImpl; + + @WireVariable + private ServiceRecordsDataModel serviceRecordsDataModel; @WireVariable private EventBus eventBus; private boolean formInvalid = true; @@ -297,7 +300,7 @@ public class ProjectEditorModel extends AbstractValidator implements EventListen } @Command - public void onEditTreasury() throws JsonProcessingException { + public void onEditTreasury() { String page = "~./treasury-editor.zul"; Treasury editEntity = treasuryServiceImpl.copy(selectedTreasury); Map arg = ImmutableMap.of("origDocument", selectedTreasury, "formDocument", editEntity); @@ -343,6 +346,8 @@ public class ProjectEditorModel extends AbstractValidator implements EventListen formDocument = (Project) data.get("formDocument"); BindUtils.postNotifyChange(this, "formDocument"); associatesDataModel.listAll(); + + serviceRecordsDataModel.search(formDocument.getId()); } } @@ -395,4 +400,5 @@ public class ProjectEditorModel extends AbstractValidator implements EventListen log.info("Associate checked"); validate(projectServiceImpl.copy(formDocument)); } + } diff --git a/lis-ui/src/main/java/hu/user/lis/ui/editor/ServiceRecordEditorModel.java b/lis-ui/src/main/java/hu/user/lis/ui/editor/ServiceRecordEditorModel.java new file mode 100644 index 0000000..294b83f --- /dev/null +++ b/lis-ui/src/main/java/hu/user/lis/ui/editor/ServiceRecordEditorModel.java @@ -0,0 +1,141 @@ +package hu.user.lis.ui.editor; + +import hu.user.lis.db.ServiceRecord; +import hu.user.lis.services.data.ServiceRecordService; +import hu.user.lis.ui.data.AssociateSelectorDataModel; +import hu.user.lis.ui.data.ProjectSelectorDataModel; +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.*; +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.Messagebox; +import org.zkoss.zul.Window; + +import java.util.Objects; + +@Log4j2 +@Getter +@Setter +@VariableResolver(DelegatingVariableResolver.class) +public class ServiceRecordEditorModel extends AbstractValidator { + @WireVariable + ServiceRecordService serviceRecordServiceImpl; + @WireVariable + private AssociateSelectorDataModel associateSelectorDataModel; + @WireVariable + private ProjectSelectorDataModel projectSelectorDataModel; + private ServiceRecord formDocument; + private ServiceRecord origDocument; + private boolean formInvalid = true; + + @Init + public void init() { + log.info("Initialized"); + origDocument = (ServiceRecord) Executions.getCurrent().getArg().get("origDocument"); + formDocument = (ServiceRecord) Executions.getCurrent().getArg().get("formDocument"); + } + + @Command + public void onProjectBandChanging(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) { + InputEvent event = (InputEvent) ctx.getTriggerEvent(); + log.info("onProjectBandChanging: {}", event.getValue()); + projectSelectorDataModel.search(event.getValue()); + } + + @Command + public void onProjectBandOpen(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) { + OpenEvent event = (OpenEvent) ctx.getTriggerEvent(); + log.info("onProjectBandOpen: {}", event.isOpen()); + projectSelectorDataModel.search(null); + } + + @Command + public void onAssociatetBandChanging(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) { + InputEvent event = (InputEvent) ctx.getTriggerEvent(); + log.info("onAssociatetBandChanging: {}", event.getValue()); + associateSelectorDataModel.search(event.getValue()); + } + + @Command + public void onAssociateBandOpen(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) { + OpenEvent event = (OpenEvent) ctx.getTriggerEvent(); + log.info("onAssociateBandOpen: {}", event.isOpen()); + associateSelectorDataModel.search(null); + } + + @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); + } + + @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); + try { + ServiceRecord newData = serviceRecordServiceImpl.copy(formDocument, property, value); + validate(newData); + } catch (Exception e) { + log.catching(e); + } + } + + private void validate(ServiceRecord newData) { + updateFormInvalid(false); + if (!Objects.isNull(origDocument) && serviceRecordServiceImpl.toString(origDocument).equals(serviceRecordServiceImpl.toString(newData))) { + log.info("Document not changed"); + updateFormInvalid(true); + return; + } + if (Objects.isNull(newData.getProject()) || + Objects.isNull(newData.getAssociate()) || + Objects.isNull(newData.getWorkDay()) || + StringUtils.isBlank(newData.getDescription()) || + newData.getWorkHours() < 1 + ) { + log.info("Document is not valid"); + updateFormInvalid(true); + } + } + + private void updateFormInvalid(boolean invalid) { + setFormInvalid(invalid); + BindUtils.postNotifyChange(this, "formInvalid"); + } + + @Command + public void onUploadFile(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) { + UploadEvent evt = (UploadEvent) ctx.getTriggerEvent(); + if (!evt.getMedia().getName().toLowerCase().endsWith(".pdf")) { + Messagebox.show("Csak PDF állomány feltöltése támogatott.", "Error", Messagebox.OK, Messagebox.ERROR); + return; + } + formDocument.setFile(evt.getMedia().getByteData()); + BindUtils.postNotifyChange(this.formDocument, "file"); + validate(serviceRecordServiceImpl.copy(formDocument)); + } + + @Command + public void onRemoveFile() { + formDocument.setFile(null); + BindUtils.postNotifyChange(this.formDocument, "file"); + validate(serviceRecordServiceImpl.copy(formDocument)); + } +} diff --git a/lis-ui/src/main/java/hu/user/lis/ui/view/IndexViewModel.java b/lis-ui/src/main/java/hu/user/lis/ui/view/IndexViewModel.java index 6bad32b..96c02c7 100644 --- a/lis-ui/src/main/java/hu/user/lis/ui/view/IndexViewModel.java +++ b/lis-ui/src/main/java/hu/user/lis/ui/view/IndexViewModel.java @@ -31,6 +31,8 @@ public class IndexViewModel implements EventListener { private static final String PROJECT_EDITOR = "~./project-editor.zul"; private static final String ASSOCIATES_LIST = "~./associates.zul"; private static final String PROJECT_ASSOCIATES_LIST = "~./project-associates.zul"; + private static final String SERVICE_RECORDS_LIST = "~./service-records.zul"; + private static final String SETTINGS_LIST = "~./settings.zul"; @WireVariable BuildProperties buildProperties; @@ -42,7 +44,10 @@ public class IndexViewModel implements EventListener { "/projects", PROJECTS_LIST, "/project", PROJECT_EDITOR, "/associates", ASSOCIATES_LIST, - "/project-associates", PROJECT_ASSOCIATES_LIST + "/project-associates", PROJECT_ASSOCIATES_LIST, + "/service-records", SERVICE_RECORDS_LIST, + "/settings", SETTINGS_LIST + ); @Init diff --git a/lis-ui/src/main/java/hu/user/lis/ui/view/ProjectsViewModel.java b/lis-ui/src/main/java/hu/user/lis/ui/view/ProjectsViewModel.java index 90eb386..ca3a449 100644 --- a/lis-ui/src/main/java/hu/user/lis/ui/view/ProjectsViewModel.java +++ b/lis-ui/src/main/java/hu/user/lis/ui/view/ProjectsViewModel.java @@ -77,7 +77,6 @@ public class ProjectsViewModel extends AsyncBaseModel implements EventListener { @Command public void onAdd() { - String page = "~./project.zul"; Project newEntity = projectsDataModel.getProjectService().createNew(); eventBus.showProjectEditor(ImmutableMap.of("formDocument", newEntity)); } diff --git a/lis-ui/src/main/java/hu/user/lis/ui/view/ServiceRecordsViewModel.java b/lis-ui/src/main/java/hu/user/lis/ui/view/ServiceRecordsViewModel.java new file mode 100644 index 0000000..ac36317 --- /dev/null +++ b/lis-ui/src/main/java/hu/user/lis/ui/view/ServiceRecordsViewModel.java @@ -0,0 +1,110 @@ +package hu.user.lis.ui.view; + +import com.google.common.collect.ImmutableMap; +import hu.user.lis.db.ServiceRecord; +import hu.user.lis.ui.data.ServiceRecordsDataModel; +import hu.user.lis.ui.event.EventBus; +import lombok.Getter; +import lombok.extern.log4j.Log4j2; +import org.zkoss.bind.annotation.*; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.select.Selectors; +import org.zkoss.zk.ui.select.annotation.VariableResolver; +import org.zkoss.zk.ui.select.annotation.WireVariable; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zkplus.spring.DelegatingVariableResolver; +import org.zkoss.zul.Window; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + + +@Log4j2 +@VariableResolver(DelegatingVariableResolver.class) +public class ServiceRecordsViewModel { + @WireVariable + @Getter + ServiceRecordsDataModel serviceRecordsDataModel; + @WireVariable + EventBus eventBus; + @Getter + private ServiceRecord selectedEntity; + + @AfterCompose + public void onAfterCompose(@ContextParam(ContextType.VIEW) Component view) { + Selectors.wireComponents(view, this, false); + Selectors.wireEventListeners(view, this); + } + + @Init + public void init() { + Clients.evalJavaScript("pushNav('/service-records')"); + refresh(); + log.info("Initialized"); + } + + private void refresh() { + serviceRecordsDataModel.clearSelection(); + selectedEntity = null; + serviceRecordsDataModel.listAll(); + } + + @Command + @NotifyChange("selectedProject") + public void search() { + } + + @Command + @NotifyChange("selectedProject") + public void onListSelection() { + selectedEntity = null; + Set selections = serviceRecordsDataModel.getSelection(); + if (selections.size() == 1) { + selectedEntity = selections.iterator().next(); + log.info("Selected {}", selectedEntity); + } + } + + @Command + public void onAdd() { + String page = "~./service-record-editor.zul"; + ServiceRecord newEntity = serviceRecordsDataModel.getServiceRecordService().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()); + serviceRecordsDataModel.getServiceRecordService().add(newEntity); + serviceRecordsDataModel.clearSelection(); + refresh(); + serviceRecordsDataModel.addToSelection(newEntity); + selectedEntity = newEntity; + } + }); + editorWindow.doModal(); + } + + @Command + public void onEdit() { + String page = "~./service-record-editor.zul"; + ServiceRecord editEntity = serviceRecordsDataModel.getServiceRecordService().copy(selectedEntity); + Map arg = ImmutableMap.of("origDocument", selectedEntity, "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()); + ServiceRecord modifiedEntity = (ServiceRecord) e.getData(); + serviceRecordsDataModel.clearSelection(); + serviceRecordsDataModel.getServiceRecordService().replace(selectedEntity, modifiedEntity); + refresh(); + serviceRecordsDataModel.addToSelection(modifiedEntity); + selectedEntity = modifiedEntity; + } + }); + editorWindow.doModal(); + } + + +} diff --git a/lis-ui/src/main/java/hu/user/lis/ui/view/SettingsViewModel.java b/lis-ui/src/main/java/hu/user/lis/ui/view/SettingsViewModel.java new file mode 100644 index 0000000..3c6472b --- /dev/null +++ b/lis-ui/src/main/java/hu/user/lis/ui/view/SettingsViewModel.java @@ -0,0 +1,168 @@ +package hu.user.lis.ui.view; + +import com.fasterxml.jackson.core.JsonProcessingException; +import hu.user.lis.db.Partner; +import hu.user.lis.ui.data.PartnersDataModel; +import lombok.Getter; +import lombok.extern.log4j.Log4j2; +import org.zkoss.bind.annotation.*; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.select.Selectors; +import org.zkoss.zk.ui.select.annotation.VariableResolver; +import org.zkoss.zk.ui.select.annotation.Wire; +import org.zkoss.zk.ui.select.annotation.WireVariable; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zkplus.spring.DelegatingVariableResolver; +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 +@VariableResolver(DelegatingVariableResolver.class) +public class SettingsViewModel extends AsyncBaseModel { + @WireVariable + @Getter + PartnersDataModel partnersDataModel; + @Wire + Listbox partnersList; + @Getter + private Partner selectedPartner; + private boolean filterShowInActive; + private boolean filterShowActive; + private boolean filterShowBoth; + + @AfterCompose + public void onAfterCompose(@ContextParam(ContextType.VIEW) Component view) { + Selectors.wireComponents(view, this, false); + Selectors.wireEventListeners(view, this); + } + + @Init + public void init() { + setFilterShowActive(true); + Clients.evalJavaScript("pushNav('/settings')"); + log.info("Initialized"); + } + + private void refresh() { + partnersDataModel.clearSelection(); + selectedPartner = null; + if (filterShowBoth) { + partnersDataModel.search(true, true); + } else { + partnersDataModel.search(filterShowActive, filterShowInActive); + } + } + + @Command + @NotifyChange("selectedPartner") + public void search() { + } + + @Command + @NotifyChange("selectedPartner") + public void onListSelection() { + selectedPartner = null; + Set selections = partnersDataModel.getSelection(); + if (selections.size() == 1) { + selectedPartner = selections.iterator().next(); + log.info("Selected {}", selectedPartner); + } + } + + @Command + public void onAfterRenderPartners() { + } + + @Command + public void onAdd() { + String page = "~./partner-editor.zul"; + 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(newEntity); + partnersDataModel.clearSelection(); + refresh(); + partnersDataModel.addToSelection(newEntity); + selectedPartner = newEntity; + +// Optional listItem = partnersList.getItems().stream() +// .filter(li -> ((Partner) li.getValue()).getId().equals(newEntity.getId())) +// .findFirst(); +// if (listItem.isPresent()) { +// Clients.scrollIntoView(listItem.get()); +// } +// registerTask(() -> { +// }); + } + }); + editorWindow.doModal(); + } + + @Command + public void onEdit() throws JsonProcessingException { + String page = "~./partner-editor.zul"; + Partner editEntity = partnersDataModel.getPartnerService().copy(selectedPartner); + Map 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(); + partnersDataModel.clearSelection(); + partnersDataModel.getPartnerService().replace(selectedPartner, modifiedEntity); + refresh(); + partnersDataModel.addToSelection(modifiedEntity); + selectedPartner = modifiedEntity; + } + }); + editorWindow.doModal(); + } + + + public boolean isFilterShowInActive() { + return filterShowInActive; + } + + @NotifyChange({"filterShowActive", "filterShowInActive", "filterShowBoth"}) + public void setFilterShowInActive(boolean filterShowInActive) { + this.filterShowBoth = false; + this.filterShowActive = false; + this.filterShowInActive = filterShowInActive; + refresh(); + } + + public boolean isFilterShowActive() { + return filterShowActive; + } + + @NotifyChange({"filterShowActive", "filterShowInActive", "filterShowBoth"}) + public void setFilterShowActive(boolean filterShowActive) { + this.filterShowBoth = false; + this.filterShowInActive = false; + this.filterShowActive = filterShowActive; + refresh(); + } + + public boolean isFilterShowBoth() { + return this.filterShowBoth; + } + + @NotifyChange({"filterShowActive", "filterShowInActive", "filterShowBoth"}) + public void setFilterShowBoth(boolean filterShowBoth) { + this.filterShowActive = false; + this.filterShowInActive = false; + this.filterShowBoth = filterShowBoth; + refresh(); + } +} diff --git a/lis-ui/src/main/resources/web/associate-selector.zul b/lis-ui/src/main/resources/web/associate-selector.zul new file mode 100644 index 0000000..4ec56ad --- /dev/null +++ b/lis-ui/src/main/resources/web/associate-selector.zul @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lis-ui/src/main/resources/web/associates.zul b/lis-ui/src/main/resources/web/associates.zul index 9168afa..d446f2c 100644 --- a/lis-ui/src/main/resources/web/associates.zul +++ b/lis-ui/src/main/resources/web/associates.zul @@ -28,9 +28,7 @@ autopaging="true" pagingPosition="top" multiple="false" onSelect="@command('onListSelection')" onDoubleClick="@command('onEdit')" onAfterRender="@command('onAfterRenderList')"> - - - + diff --git a/lis-ui/src/main/resources/web/index.zul b/lis-ui/src/main/resources/web/index.zul index c169f42..afa7f49 100644 --- a/lis-ui/src/main/resources/web/index.zul +++ b/lis-ui/src/main/resources/web/index.zul @@ -1,5 +1,5 @@ - - + + @@ -29,9 +22,7 @@ autopaging="true" pagingPosition="top" multiple="false" onSelect="@command('onListSelection')" onDoubleClick="@command('onEdit')" onAfterRender="@command('onAfterRenderPartners')"> - - - + diff --git a/lis-ui/src/main/resources/web/project-editor.zul b/lis-ui/src/main/resources/web/project-editor.zul index 22bbb9a..4f6ed2e 100644 --- a/lis-ui/src/main/resources/web/project-editor.zul +++ b/lis-ui/src/main/resources/web/project-editor.zul @@ -1,5 +1,3 @@ - - - - - + @@ -92,7 +88,7 @@ selectedItem="@bind(vm.selectedOutgoingInvoice)" onDoubleClick="@command('onEditOutgoing')" forward="onOK=submit.onClick, onCancel=cancel.onClick"> - + @@ -136,12 +132,11 @@ onClick="@command('onRemoveIncoming')" disabled="@load(empty vm.selectedIncomingInvoice)"/> - - + @@ -195,7 +190,7 @@ - + @@ -222,6 +217,35 @@ + + + + + + + + + + + + + + + + diff --git a/lis-ui/src/main/resources/web/project-selector.zul b/lis-ui/src/main/resources/web/project-selector.zul new file mode 100644 index 0000000..171f46e --- /dev/null +++ b/lis-ui/src/main/resources/web/project-selector.zul @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lis-ui/src/main/resources/web/project.zul b/lis-ui/src/main/resources/web/project.zul index 8356b45..f3680f8 100644 --- a/lis-ui/src/main/resources/web/project.zul +++ b/lis-ui/src/main/resources/web/project.zul @@ -1,5 +1,3 @@ - - - - @@ -27,9 +20,7 @@ - - - + diff --git a/lis-ui/src/main/resources/web/service-record-editor.zul b/lis-ui/src/main/resources/web/service-record-editor.zul new file mode 100644 index 0000000..695d42d --- /dev/null +++ b/lis-ui/src/main/resources/web/service-record-editor.zul @@ -0,0 +1,71 @@ + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+