(To enable remove @SpringBootApplication with exludes and @ComponentScan)
https://www.baeldung.com/get-user-in-spring-security
https://www.baeldung.com/spring-security-authentication-provider
+https://www.zkoss.org/wiki/ZK_Developer%27s_Reference/Security_Tips/SSO_Redirect_Handling
##### ZK Style
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
+* auth/ldap ldap:fds.in.useribm.hu:389,ldaps:fds.useribm.hu:636
-
-db persist
-- servicerecord:
- project generalas
- generalas
- project szuro
-
-auth/ldap
autorizacio
nav
szamla erkeztetes camunda: egy felasznalohoz jon be, projekthez lehessen csatolni, projektszanot ellenorizze
- 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.
-fds.in.useribm.hu
-389
-
-ldaps
-fds.useribm.hu
-636
jpa:
hibernate:
use-new-id-generator-mappings: false
- show-sql: true
+ show-sql: false
properties:
hibernate:
format_sql: true
package hu.user.lis.db;
+import com.fasterxml.jackson.annotation.JsonIncludeProperties;
import lombok.*;
import javax.persistence.*;
String title;
@OneToOne
@JoinColumn(name = "partner_id")
+ @JsonIncludeProperties({"id"})
Partner partner;
@ManyToOne
@JoinColumn(name = "project_id")
+ @JsonIncludeProperties({"id"})
Project project;
boolean income;
Currency currency;
package hu.user.lis.db;
+import com.fasterxml.jackson.annotation.JsonIncludeProperties;
import lombok.*;
import javax.persistence.*;
-import java.util.List;
+import java.util.Set;
@Getter
@Setter
String contactName;
@ManyToOne
@JoinColumn(name = "partner_id")
+ @JsonIncludeProperties({"id"})
Partner partner;
boolean active;
- @OneToMany(mappedBy = "project")
- List<Invoice> incomingInvoices;
- @OneToMany(mappedBy = "project")
- List<Invoice> outgoingInvoices;
- @OneToMany(mappedBy = "project")
- List<Treasury> treasuries;
+ @OneToMany(mappedBy = "project", fetch = FetchType.EAGER)
+ @JsonIncludeProperties({"id"})
+ Set<Invoice> incomingInvoices;
+ @OneToMany(mappedBy = "project", fetch = FetchType.EAGER)
+ @JsonIncludeProperties({"id"})
+ Set<Invoice> outgoingInvoices;
+ @OneToMany(mappedBy = "project", fetch = FetchType.EAGER)
+ @JsonIncludeProperties({"id"})
+ Set<Treasury> treasuries;
}
package hu.user.lis.db;
+import com.fasterxml.jackson.annotation.JsonIncludeProperties;
import lombok.*;
import javax.persistence.*;
Long id;
@ManyToOne
@JoinColumn(name = "project_id")
+ @JsonIncludeProperties({"id"})
Project project;
String humanId;
double buyAmount;
import hu.user.lis.db.Associate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.query.QueryUtils;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
Root<Associate> root = cq.from(Associate.class);
cq.where(getPredicates(cb, root, partialName, filterShowActive, filterShowInActive));
+ cq.orderBy(QueryUtils.toOrders(pageable.getSort(), root, cb));
TypedQuery<Associate> query = entityManager.createQuery(cq);
query.setMaxResults(pageable.getPageSize());
query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
import java.util.List;
public interface PartnerRepositorySearch {
- List<Partner> search(String partialName, String partialVatNr, String partialAddress, boolean filterShowActive, boolean filterShowInActive, Pageable pageable);
+ List<Partner> search(String partialSearch, boolean filterShowActive, boolean filterShowInActive, Pageable pageable);
- long count(String partialName, String partialVatNr, String partialAddress, boolean filterShowActive, boolean filterShowInActive);
+ long count(String ppartialSearch, boolean filterShowActive, boolean filterShowInActive);
}
import hu.user.lis.db.Partner;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.query.QueryUtils;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
@PersistenceContext
EntityManager entityManager;
- Predicate[] getPredicates(CriteriaBuilder cb, Root<Partner> root, String partialName,
- String partialVatNr, String partialAddress, boolean filterShowActive, boolean filterShowInActive) {
+ Predicate[] getPredicates(CriteriaBuilder cb, Root<Partner> root, String partialSearch, boolean filterShowActive, boolean filterShowInActive) {
List<Predicate> predicates = new ArrayList<>();
- List<Predicate> orPredicates = new ArrayList<>();
- if (StringUtils.isNotBlank(partialName)) {
- orPredicates.add(cb.like(root.get("name"), "%" + partialName + "%"));
- }
- if (StringUtils.isNotBlank(partialVatNr)) {
- orPredicates.add(cb.like(root.get("vat_nr"), "%" + partialVatNr + "%"));
- }
- if (StringUtils.isNotBlank(partialAddress)) {
- orPredicates.add(cb.like(root.get("address"), "%" + partialAddress + "%"));
- }
- if (orPredicates.size() > 0) {
+ if (StringUtils.isNotBlank(partialSearch)) {
+ List<Predicate> orPredicates = new ArrayList<>();
+ orPredicates.add(cb.like(cb.lower(root.get("name")), "%" + partialSearch.toLowerCase() + "%"));
+ orPredicates.add(cb.like(cb.lower(root.get("vat_nr")), "%" + partialSearch.toLowerCase() + "%"));
+ orPredicates.add(cb.like(cb.lower(root.get("address")), "%" + partialSearch.toLowerCase() + "%"));
predicates.add(cb.or(orPredicates.toArray(new Predicate[]{})));
}
+
if (filterShowActive && !filterShowInActive) {
predicates.add(cb.isTrue(root.get("active")));
}
return predicates.toArray(new Predicate[]{});
}
- Predicate[] getPredicates(CriteriaBuilder cb, Root<Partner> root, String partialName, boolean filterShowActive) {
- List<Predicate> predicates = new ArrayList<>();
- if (StringUtils.isNotBlank(partialName)) {
- predicates.add(cb.like(root.get("name"), "%" + partialName + "%"));
- }
- if (filterShowActive) {
- predicates.add(cb.isTrue(root.get("active")));
- } else {
- predicates.add(cb.isFalse(root.get("active")));
- }
- return predicates.toArray(new Predicate[]{});
- }
-
@Override
- public List<Partner> search(String partialName, String partialVatNr, String partialAddress, boolean filterShowActive, boolean filterShowInActive, Pageable pageable) {
+ public List<Partner> search(String partialSearch, boolean filterShowActive, boolean filterShowInActive, Pageable pageable) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Partner> cq = cb.createQuery(Partner.class);
Root<Partner> root = cq.from(Partner.class);
- cq.where(getPredicates(cb, root, partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive));
+ cq.where(getPredicates(cb, root, partialSearch, filterShowActive, filterShowInActive));
+ cq.orderBy(QueryUtils.toOrders(pageable.getSort(), root, cb));
TypedQuery<Partner> query = entityManager.createQuery(cq);
query.setMaxResults(pageable.getPageSize());
query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
}
@Override
- public long count(String partialName, String partialVatNr, String partialAddress, boolean filterShowActive, boolean filterShowInActive) {
+ public long count(String partialSearch, boolean filterShowActive, boolean filterShowInActive) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<Partner> root = cq.from(Partner.class);
cq.select(cb.count(root));
- cq.where(getPredicates(cb, root, partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive));
+ cq.where(getPredicates(cb, root, partialSearch, filterShowActive, filterShowInActive));
return entityManager.createQuery(cq).getSingleResult();
}
package hu.user.lis.db.repository;
import hu.user.lis.db.ProjectAssociate;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
+import java.util.List;
+
public interface ProjectAssociateRepository extends JpaRepository<ProjectAssociate, Long> {
- Page<ProjectAssociate> findAllByProjectId(Long projectId, Pageable pageable);
+ List<ProjectAssociate> findAllByProjectId(Long projectId);
Long countByProjectId(Long projectId);
import hu.user.lis.db.Project;
import org.springframework.data.jpa.repository.JpaRepository;
+import java.util.List;
+
public interface ProjectRepository extends JpaRepository<Project, Long>, ProjectRepositorySearch {
+ List<Project> findByHumanIdLikeOrderByHumanIdDesc(String yearSearch);
+
+ Project findFirstByHumanIdLikeOrderByHumanIdDesc(String yearSearch);
+
}
import hu.user.lis.db.Project;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.query.QueryUtils;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
Root<Project> root = cq.from(Project.class);
cq.where(getPredicates(cb, root, partialSearch, filterShowActive, filterShowInActive));
+ cq.orderBy(QueryUtils.toOrders(pageable.getSort(), root, cb));
TypedQuery<Project> query = entityManager.createQuery(cq);
query.setMaxResults(pageable.getPageSize());
query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
List<ProjectStatus> findByActiveIsTrue(Sort sort);
long countByActiveIsTrue();
+
+ ProjectStatus findByOrder(int order);
}
package hu.user.lis.db.repository;
import hu.user.lis.db.ServiceRecord;
+import lombok.extern.log4j.Log4j2;
import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.query.QueryUtils;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
import java.util.Objects;
+@Log4j2
public class ServiceRecordRepositorySearchImpl implements ServiceRecordRepositorySearch {
@PersistenceContext
EntityManager entityManager;
Predicate[] getPredicates(CriteriaBuilder cb, Root<ServiceRecord> root, Long filterProjectId, Long filterAssociateId) {
List<Predicate> predicates = new ArrayList<>();
if (Objects.nonNull(filterProjectId)) {
- predicates.add(cb.equal(root.join("project").get("id"), filterProjectId));
+ predicates.add(cb.equal(root.get("project"), filterProjectId));
}
if (Objects.nonNull(filterAssociateId)) {
- predicates.add(cb.equal(root.join("associate").get("id"), filterAssociateId));
+ predicates.add(cb.equal(root.get("associate"), filterAssociateId));
}
return predicates.toArray(new Predicate[]{});
}
Root<ServiceRecord> root = cq.from(ServiceRecord.class);
cq.where(getPredicates(cb, root, filterProjectId, filterAssociateId));
+ cq.orderBy(QueryUtils.toOrders(pageable.getSort(), root, cb));
TypedQuery<ServiceRecord> query = entityManager.createQuery(cq);
query.setMaxResults(pageable.getPageSize());
query.setFirstResult(pageable.getPageSize() * pageable.getPageNumber());
package hu.user.lis.services.api;
import hu.user.lis.services.data.DataService;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
+
public abstract class DbApi<T, R extends JpaRepository<T, Long>, S extends DataService<T>> {
protected abstract S getService();
return getRepository().findAll();
}
+ @GetMapping("/page")
+ public Page<T> page(Pageable pageable) {
+ return getRepository().findAll(pageable);
+ }
+
@GetMapping("/get/{id}")
public T get(@PathVariable long id) {
return getRepository().findById(id).orElse(null);
@GetMapping("/generate")
public List<T> generate() {
- deleteAll();
- return getRepository().saveAll(getService().getAll());
+ List<T> result = getRepository().saveAll(getService().getAll());
+ afterSave(result);
+ return result;
+ }
+
+ protected void afterSave(List<T> entities) {
+
}
}
@GetMapping("/all")
public String list() {
+ serviceRecordApi.deleteAll();
+ projectAssociateApi.deleteAll();
+ treasuryApi.deleteAll();
+ invoiceApi.deleteAll();
+ associateApi.deleteAll();
+ projectApi.deleteAll();
+ partnerApi.deleteAll();
+ projectStatusApi.deleteAll();
+
log.info("projectStatus");
projectStatusApi.generate();
log.info("partner");
package hu.user.lis.services.api;
+import hu.user.lis.db.Invoice;
import hu.user.lis.db.Project;
+import hu.user.lis.db.Treasury;
+import hu.user.lis.db.repository.InvoiceRepository;
import hu.user.lis.db.repository.ProjectRepository;
+import hu.user.lis.db.repository.TreasuryRepository;
import hu.user.lis.services.data.ProjectService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
@Log4j2
@RestController
@RequestMapping("/api/project")
ProjectRepository projectRepository;
@Autowired
ProjectService projectService;
+ @Autowired
+ private TreasuryRepository treasuryRepository;
+ @Autowired
+ private InvoiceRepository invoiceRepository;
@Override
protected ProjectService getService() {
protected ProjectRepository getRepository() {
return projectRepository;
}
+
+ @Override
+ protected void afterSave(List<Project> entities) {
+ entities.forEach(p -> {
+ Set<Invoice> incomingInvoices = p.getIncomingInvoices();
+ if (Objects.nonNull(incomingInvoices)) {
+ incomingInvoices.forEach(i -> {
+ i.setProject(p);
+ invoiceRepository.save(i);
+ });
+ }
+
+ Set<Invoice> outgoingInvoices = p.getOutgoingInvoices();
+ if (Objects.nonNull(outgoingInvoices)) {
+ outgoingInvoices.forEach(i -> {
+ i.setProject(p);
+ invoiceRepository.save(i);
+ });
+ }
+
+ Set<Treasury> treasuries = p.getTreasuries();
+ treasuries.forEach(t -> {
+ t.setProject(p);
+ treasuryRepository.save(t);
+ });
+ });
+ }
+
}
import hu.user.lis.db.Invoice;
import java.util.List;
+import java.util.Set;
public interface InvoiceService extends DataService<Invoice> {
void setAll(List<Invoice> entities);
void replace(Invoice targetEntity, Invoice replacementEntity);
- List<Invoice> getRandom(boolean income);
+ Set<Invoice> getRandom(boolean income);
Invoice getById(String id);
Invoice getByHumanId(String id);
- List<Invoice> getByHumanIds(String[] ids);
+ Set<Invoice> getByHumanIds(String[] ids);
}
package hu.user.lis.services.data;
-import com.fasterxml.jackson.databind.ObjectMapper;
import hu.user.lis.db.Currency;
import hu.user.lis.db.Invoice;
import hu.user.lis.db.Partner;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
import java.util.concurrent.TimeUnit;
@Service
DataGeneratorService dataGeneratorService;
@Autowired
PartnerService partnerService;
- @Autowired
- ObjectMapper mapper;
+
private List<Invoice> incomingEntities;
private List<Invoice> outgoingEntities;
}
@Override
- public List<Invoice> getByHumanIds(String[] ids) {
- List<Invoice> result = new ArrayList<>();
+ public Set<Invoice> getByHumanIds(String[] ids) {
+ Set<Invoice> result = new HashSet<>();
for (String i : ids) {
result.add(getByHumanId(i));
@Override
- public List<Invoice> getRandom(boolean income) {
+ public Set<Invoice> getRandom(boolean income) {
getAll();
int count = RandomUtils.nextInt(2, 5);
- List<Invoice> result = new ArrayList<>();
+ Set<Invoice> result = new HashSet<>();
for (int i = 0; i < count; i++) {
if (income) {
int index = RandomUtils.nextInt(0, incomingEntities.size());
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Override
public Project createNew() {
- String humanId = dataGeneratorService.faker().code().isbn13(true);
+// String humanId = dataGeneratorService.faker().code().isbn13(true);
ProjectStatus projectStatus = projectStatusService.getAll().get(0);
return Project.builder()
.projectStatus(projectStatus)
- .humanId(humanId)
- .incomingInvoices(new ArrayList<>())
- .outgoingInvoices(new ArrayList<>())
- .treasuries(new ArrayList<>())
+ .incomingInvoices(new HashSet<>())
+ .outgoingInvoices(new HashSet<>())
+ .treasuries(new HashSet<>())
.active(true)
.build();
}
.partner(partner)
.incomingInvoices(invoiceService.getRandom(true))
.outgoingInvoices(invoiceService.getRandom(false))
- .treasuries(new ArrayList<>())
+ .treasuries(new HashSet<>())
.build();
result.add(entity);
}
.partner(partner)
.incomingInvoices(invoiceService.getByHumanIds(new String[]{"VSz-2023/00070-"})) // VSz-2023/00070-
.outgoingInvoices(invoiceService.getByHumanIds(new String[]{"USER-2023-7"})) // USER-2023-7
- .treasuries(new ArrayList<>())
+ .treasuries(new HashSet<>())
.build();
result.add(entity);
.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(new ArrayList<>())
+ .treasuries(new HashSet<>())
.build();
result.add(entity);
import hu.user.lis.db.Treasury;
import java.util.List;
+import java.util.Set;
public interface TreasuryService extends DataService<Treasury> {
Treasury createNew();
Treasury getByHumanId(String id);
- List<Treasury> getByHumanIds(String[] ids);
+ Set<Treasury> getByHumanIds(String[] ids);
}
import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
import java.util.concurrent.TimeUnit;
@Service
}
@Override
- public List<Treasury> getByHumanIds(String[] ids) {
- List<Treasury> result = new ArrayList<>();
+ public Set<Treasury> getByHumanIds(String[] ids) {
+ Set<Treasury> result = new HashSet<>();
for (String i : ids) {
result.add(getByHumanId(i));
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import static hu.user.lis.ui.view.IndexViewModel.NAVIGATION;
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public static final String ZUL_FILES = "/zkau/web/**/*.zul";
-
- public static final String[] ZK_RESOURCES = {"/zkau/web/**/js/**", "/zkau/web/**/zul/css/**", "/zkau/web/**/img/**"};
-
// allow desktop cleanup after logout or when reloading login page
public static final String REMOVE_DESKTOP_REGEX = "/zkau\\?dtid=.*&cmd_0=rmDesktop&.*";
+
+
+ public static final String[] ZK_RESOURCES = {"/zkau/web/**/js/**", "/zkau/web/**/zul/css/**", "/zkau/web/**/img/**", "/zkau/web/**/static/**"};
@Autowired
LocalAuthProvider localAuthProvider;
.antMatchers(HttpMethod.GET, ZK_RESOURCES).permitAll() // allow zk resources
.regexMatchers(HttpMethod.GET, REMOVE_DESKTOP_REGEX).permitAll() // allow desktop cleanup
.requestMatchers(req -> "rmDesktop".equals(req.getParameter("cmd_0"))).permitAll() // allow desktop cleanup from ZATS
- .mvcMatchers("/", "/login", "/logout").permitAll()
+ .mvcMatchers("/", "/login", "/logout", "/api/**").permitAll()
//mvcMatchers(navigation).hasRole("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").defaultSuccessUrl("/partners")
.and()
- .logout().logoutUrl("/logout").logoutSuccessUrl("/");
+ .logout().logoutUrl("/logout").logoutSuccessUrl("/")
+ .and()
+ .exceptionHandling()
+ .defaultAuthenticationEntryPointFor(
+ new Http403ForbiddenEntryPoint(),
+ new AntPathRequestMatcher("/zkau", "POST"));
}
@Autowired
package hu.user.lis.ui.converter;
import hu.user.lis.db.ProjectStatus;
-import hu.user.lis.services.data.ProjectStatusService;
+import hu.user.lis.db.repository.ProjectStatusRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zkoss.bind.BindContext;
@Component
public class ProjectStatusConverter implements Converter<Object, ProjectStatus, Selectbox> {
@Autowired
- ProjectStatusService projectStatusService;
+ ProjectStatusRepository projectStatusRepository;
@Override
public Object coerceToUi(ProjectStatus projectStatus, Selectbox box, BindContext bindContext) {
@Override
public ProjectStatus coerceToBean(Object order, Selectbox bandbox, BindContext bindContext) {
- return projectStatusService.getAll().get((Integer) order);
+ return projectStatusRepository.findByOrder((Integer) order + 1);
}
}
\ No newline at end of file
public static final String NATURAL = "natural";
public static final String ASCENDING = "ascending";
public static final String DESCENDING = "descending";
- private int cacheSize = 100;
+ private int CACHE_SIZE = 100;
private int cacheStart;
private int cacheEnd;
private int resultSetSize = -1;
return this.resultSetSize;
}
-// private void loadCache(int forIndex) {
+// protected void loadCache(int forIndex) {
// try {
-// int halfSize = this.cacheSize / 2;
-// int rowLimit = this.cacheSize; // 200
+// int halfSize = this.CACHE_SIZE / 2;
+// int rowLimit = this.CACHE_SIZE;
// int startPos = 0;
-// if ((forIndex - halfSize) > 0) { // forIndex=60 startPos=0
-// // cache=0-200, forIndex=150
-// // startPos=50 cache=50-250
+// if ((forIndex - halfSize) > 0) {
// startPos = (forIndex - halfSize);
// }
//
// log.info("Result item count is {}", resultSetSize);
// }
//
-// log.info("Query result from {} to {}", startPos, endPos);
-//
// int limit = endPos - startPos;
-// int page = (int) Math.ceil(this.resultSetSize / limit);
+//
+// // (int) Math.ceil(this.resultSetSize / limit);
+// int page = forIndex == 0 ? 0 : (int) Math.ceil(limit / forIndex);
+// log.info("Query result from {} to {} for item {} | page {} pageSize {}", startPos, endPos, forIndex, page, limit);
// List<T> resList = getResultSet(page, limit, sortComparator);
//
// if (resList != null) {
// log.info("Got {} records", resList.size());
// for (int c = 0; c < resList.size(); c++) {
// cache.put(startPos + c, resList.get(c));
-// // logger.debug("CachedListMode.cached idx: " +
-// // (startPos + c));
// }
// }
-// // logger.debug("CachedListMode.cacheSize: " + cache.size());
//
// cacheStart = startPos + 1;
// cacheEnd = cacheStart + (cache.size() == 0 ? 0 : (cache.size() - 1));
// }
// }
- private void loadCache(int forIndex) {
- try {
- int halfSize = this.cacheSize / 2;
- int rowLimit = this.cacheSize; // 200
- int startPos = 0;
- if ((forIndex - halfSize) > 0) { // forIndex=60 startPos=0
- // cache=0-200, forIndex=150
- // startPos=50 cache=50-250
- startPos = (forIndex - halfSize);
- }
-
- int endPos = (startPos + rowLimit);
- endPos = ((this.resultSetSize < 0) || (endPos <= this.resultSetSize)) ? endPos : this.resultSetSize;
-
+ protected void loadCache(int forIndex) {
+ try {
+ int page = forIndex == 0 ? 0 : (int) Math.ceil(forIndex / CACHE_SIZE);
+ log.info("{} query result for item {} | page {} pageSize {}", getClass().getSimpleName(), forIndex, page, CACHE_SIZE);
if (this.resultSetSize < 0) {
this.resultSetSize = getResultSetCount();
- log.info("Result item count is {}", resultSetSize);
+ log.info("Result item total count is {}", resultSetSize);
}
-
- int limit = endPos - startPos;
-
- // (int) Math.ceil(this.resultSetSize / limit);
- int page = forIndex == 0 ? 0 : (int) Math.ceil(limit / forIndex);
- log.info("Query result from {} to {} | page {} pageSize {}", startPos, endPos, page, limit);
- List<T> resList = getResultSet(page, limit, sortComparator);
+ List<T> resList = getResultSet(page, CACHE_SIZE, sortComparator);
if (resList != null) {
log.info("Got {} records", resList.size());
+ cacheStart = forIndex;
for (int c = 0; c < resList.size(); c++) {
- cache.put(startPos + c, resList.get(c));
- // logger.debug("CachedListMode.cached idx: " +
- // (startPos + c));
+ cache.put(forIndex + c, resList.get(c));
+ cacheEnd++;
}
}
- // logger.debug("CachedListMode.cacheSize: " + cache.size());
- cacheStart = startPos + 1;
- cacheEnd = cacheStart + (cache.size() == 0 ? 0 : (cache.size() - 1));
} catch (Exception e) {
log.error("", e);
}
@Override
public void sort(Comparator<T> cmpr, boolean ascending) {
sortComparator = (FieldComparator) cmpr;
- log.info("Sort {} {}", sortComparator.getOrderBy(), ascending);
+// log.info("Sort {} {}", sortComparator.getOrderBy(), ascending);
reset();
}
}
Sort.Direction direction = sortComparator.isAscending() ? Sort.Direction.ASC : Sort.Direction.DESC;
pageable = PageRequest.of(page, pageSize, Sort.by(direction, orderBy));
}
+ log.info("{} {}", getClass().getSimpleName(), pageable);
return pageable;
}
+
}
public void recalculate(Project project) {
clear();
Map<Currency, Double> balances = new HashMap<>();
- List<Invoice> outgoingInvoices = project.getOutgoingInvoices();
+ Set<Invoice> outgoingInvoices = project.getOutgoingInvoices();
if (Objects.nonNull(outgoingInvoices)) {
for (Invoice invoice : outgoingInvoices) {
addBalance(balances, invoice.getCurrency(), invoice.getNetAmount());
}
}
- List<Invoice> incomingInvoices = project.getIncomingInvoices();
+ Set<Invoice> incomingInvoices = project.getIncomingInvoices();
if (Objects.nonNull(incomingInvoices)) {
for (Invoice invoice : incomingInvoices) {
substractBalance(balances, invoice.getCurrency(), invoice.getNetAmount());
}
}
- List<Treasury> treasuries = project.getTreasuries();
+ Set<Treasury> treasuries = project.getTreasuries();
if (Objects.nonNull(treasuries)) {
for (Treasury treasury : treasuries) {
substractBalance(balances, treasury.getSellCurrency(), treasury.getSellAmount());
--- /dev/null
+package hu.user.lis.ui.data;
+
+import hu.user.lis.db.Invoice;
+import hu.user.lis.db.Project;
+import hu.user.lis.db.repository.InvoiceRepository;
+import hu.user.lis.services.data.InvoiceService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityExistsException;
+
+@Component
+@Log4j2
+public class InvoiceDataModel {
+
+ @Autowired
+ InvoiceService invoiceService;
+ @Autowired
+ InvoiceRepository invoiceRepository;
+
+ public Invoice copy(Invoice entity) {
+ return invoiceRepository.findById(entity.getId()).orElseThrow(EntityExistsException::new);
+ }
+
+ public Invoice createNew(Project formDocument) {
+ Invoice result = invoiceService.createNew();
+ result.setProject(formDocument);
+ return result;
+ }
+}
@Autowired
PartnerRepository partnerRepository;
- private String partialName;
+ private String partialSearch;
@Override
public List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
Pageable pageable = createPageable(page, pageSize, sortComparator);
- List<Partner> result = StringUtils.isBlank(partialName) ? partnerRepository.findAll() :
- partnerRepository.search(partialName, partialName, partialName, true, false, pageable);
+ List<Partner> result = StringUtils.isBlank(partialSearch) ? partnerRepository.findAll() :
+ partnerRepository.search(partialSearch, true, false, pageable);
return result;
}
@Override
public int getResultSetCount() {
- int result = StringUtils.isBlank(partialName) ?
+ int result = StringUtils.isBlank(partialSearch) ?
(int) partnerRepository.count() :
- (int) partnerRepository.count(partialName, partialName, partialName, true, false);
+ (int) partnerRepository.count(partialSearch, true, false);
return result > SEARCH_LIMIT ? SEARCH_LIMIT : result;
}
public void search(String partialName) {
log.info("Searching partner using filter {}", partialName);
- this.partialName = partialName;
+ this.partialSearch = partialName;
super.reset();
}
}
@Autowired
PartnerService partnerService;
- private String partialName;
-
- private String partialAddress;
-
- private String partialVatNr;
+ private String partialSearch;
private boolean listAll;
public List<Partner> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
Pageable pageable = createPageable(page, pageSize, sortComparator);
List<Partner> result = listAll ? partnerRepository.findAll() :
- partnerRepository.search(partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive, pageable);
+ partnerRepository.search(partialSearch, filterShowActive, filterShowInActive, pageable);
return result;
}
@Override
public int getResultSetCount() {
long result = listAll ? partnerRepository.count() :
- partnerRepository.count(partialName, partialVatNr, partialAddress, filterShowActive, filterShowInActive);
+ partnerRepository.count(partialSearch, filterShowActive, filterShowInActive);
return (int) result;
}
- public void search(String partialName, String partialVatNr, String partialAddress) {
- log.info("Searching partner using filters: name LIKE {}, VAT number LIKE {}, Address LIKE {}",
- partialName, partialVatNr, partialAddress);
+ public void search(String partialSearch) {
+ log.info("Searching partner using filters: name or VAT number or Address LIKE {}",
+ partialSearch);
listAll = false;
- this.partialName = partialName;
- this.partialVatNr = partialVatNr;
- this.partialAddress = partialAddress;
+ this.partialSearch = partialSearch;
super.reset();
}
import hu.user.lis.db.ProjectAssociate;
import hu.user.lis.db.repository.ProjectAssociateRepository;
-import hu.user.lis.services.data.ProjectAssociateService;
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.data.domain.Pageable;
import org.springframework.stereotype.Component;
-import org.zkoss.zul.FieldComparator;
import java.util.List;
+import java.util.Objects;
@Component
@Log4j2
-@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
-public class ProjectAssociatesDataModel extends CachedSpringDataModel<ProjectAssociate> {
+public class ProjectAssociatesDataModel {
@Autowired
ProjectAssociateRepository projectAssociateRepository;
- @Autowired
- ProjectAssociateService projectAssociateService;
-
- private Long projectId;
-
-
- @Override
- public List<ProjectAssociate> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
- Pageable pageable = createPageable(page, pageSize, sortComparator);
- List<ProjectAssociate> result = projectAssociateRepository.findAllByProjectId(projectId, pageable).getContent();
+ public List<ProjectAssociate> search(Long projectId) {
+ List<ProjectAssociate> result = null;
+ if (Objects.nonNull(projectId)) {
+ log.info("Searching project associate using filter: projectId LIKE {}", projectId);
+ result = projectAssociateRepository.findAllByProjectId(projectId);
+ }
return result;
}
- @Override
- public int getResultSetCount() {
- long result = projectAssociateRepository.countByProjectId(projectId);
- return (int) result;
- }
-
- public void search(Long projectId) {
- log.info("Searching project associate using filter: projectId LIKE {}", projectId);
- this.projectId = projectId;
- super.reset();
- }
-
}
public void save(ProjectStatus entity) {
projectStatusRepository.save(entity);
}
+
+ public ProjectStatus getDefault() {
+ return projectStatusRepository.findByOrder(1);
+ }
}
package hu.user.lis.ui.data;
import hu.user.lis.db.Project;
+import hu.user.lis.db.ProjectStatus;
import hu.user.lis.db.repository.ProjectRepository;
-import hu.user.lis.services.data.ProjectService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.stereotype.Component;
import org.zkoss.zul.FieldComparator;
+import javax.persistence.EntityNotFoundException;
+import java.lang.reflect.Field;
+import java.text.DecimalFormat;
+import java.time.Year;
+import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
@Component
@Log4j2
ProjectRepository projectRepository;
@Autowired
- ProjectService projectService;
+ ProjectStatusDataModel projectStatusDataModel;
private String partialName;
}
public Project createNew() {
- return projectService.createNew();
+ String yearSearch = String.format("%s-%%", Year.now().getValue());
+ Project lastInYear = projectRepository.findFirstByHumanIdLikeOrderByHumanIdDesc(yearSearch);
+ int sortOrder = Integer.parseInt(lastInYear.getHumanId().split("-")[1]);
+ DecimalFormat decFormat = new DecimalFormat("0000");
+ String humanId = String.format("%s-%s", Year.now().getValue(), decFormat.format(++sortOrder));
+ ProjectStatus projectStatus = projectStatusDataModel.getDefault();
+ return Project.builder()
+ .projectStatus(projectStatus)
+ .humanId(humanId)
+ .incomingInvoices(new HashSet<>())
+ .outgoingInvoices(new HashSet<>())
+ .treasuries(new HashSet<>())
+ .active(true)
+ .build();
}
public void addNew(Project entity) {
projectRepository.save(entity);
}
- public Project copy(Project selectedEntity) {
- return projectService.copy(selectedEntity);
+ public Project copy(Project entity) {
+ return projectRepository.findById(entity.getId()).orElseThrow(EntityNotFoundException::new);
+ }
+
+ public Project copy(Project entity, String property, Object value) {
+ Project result = copy(entity);
+ setPropertyValue(result, property, value);
+ return result;
+ }
+
+ public void setPropertyValue(Project entity, String property, Object value) {
+ if (Objects.isNull(property)) {
+ return;
+ }
+ try {
+ Field field = entity.getClass().getDeclaredField(property);
+ field.setAccessible(true);
+ field.set(entity, value);
+ } catch (Exception e) {
+ log.catching(e);
+ }
}
public Project save(Project selectedEntity) {
return projectRepository.save(selectedEntity);
}
+
+ public Project getById(Long id) {
+ return projectRepository.findById(id).orElseThrow(EntityNotFoundException::new);
+ }
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
@Component
@Log4j2
@Override
public List<ServiceRecord> getResultSet(int page, int pageSize, FieldComparator sortComparator) {
+ if (groupByAssociate) {
+ return getGroupedServiceRecords().values().stream().collect(Collectors.toList());
+ }
Pageable pageable = createPageable(page, pageSize, sortComparator);
List<ServiceRecord> result = listAll ? serviceRecordRepository.findAll(pageable).toList() :
serviceRecordRepository.search(filterProjectId, filterAssociateId, pageable);
serviceRecord.setCost(serviceRecord.getCost() + s.getCost());
serviceRecord.setWorkHours(serviceRecord.getWorkHours() + s.getWorkHours());
} else {
- ServiceRecord serviceRecord = serviceRecordService.copy(s);
+ ServiceRecord serviceRecord = serviceRecordRepository.findById(s.getId()).orElseThrow(EntityNotFoundException::new);
serviceRecord.setWorkDay(null);
grouped.put(serviceRecord.getAssociate().getId(), serviceRecord);
}
@Override
public int getResultSetCount() {
+ if (groupByAssociate) {
+ return getGroupedServiceRecords().size();
+ }
long result = listAll ? serviceRecordRepository.count() :
serviceRecordRepository.count(filterProjectId, filterAssociateId);
return (int) result;
--- /dev/null
+package hu.user.lis.ui.data;
+
+import hu.user.lis.db.Project;
+import hu.user.lis.db.Treasury;
+import hu.user.lis.db.repository.TreasuryRepository;
+import hu.user.lis.services.data.TreasuryService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityExistsException;
+
+@Component
+@Log4j2
+public class TreasuryDataModel {
+
+ @Autowired
+ TreasuryService treasuryService;
+
+ @Autowired
+ TreasuryRepository treasuryRepository;
+
+ public Treasury copy(Treasury entity) {
+ return treasuryRepository.findById(entity.getId()).orElseThrow(EntityExistsException::new);
+ }
+
+ public Treasury createNew(Project formDocument) {
+ Treasury result = treasuryService.createNew();
+ result.setProject(formDocument);
+ return result;
+ }
+}
@Command
public void onCloseWindow(@BindingParam("target") Window target, @BindingParam("select") boolean select) {
- if (select && formInvalid) {
- return;
+ if (select && !formInvalid) {
+ Event closeEvent = new Event("onClose", target, select ? formDocument : null);
+ Events.postEvent(closeEvent);
}
- Event closeEvent = new Event("onClose", target, select ? formDocument : null);
- Events.postEvent(closeEvent);
}
@Override
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.collect.ImmutableMap;
-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.*;
+import hu.user.lis.db.*;
+import hu.user.lis.services.data.ProjectService;
+import hu.user.lis.services.data.ServiceRecordService;
import hu.user.lis.ui.Constants;
import hu.user.lis.ui.converter.ProjectStatusConverter;
import hu.user.lis.ui.data.*;
public class ProjectEditorModel extends AbstractValidator implements EventListener {
@WireVariable
AssociatesDataModel associatesDataModel;
- @WireVariable
- ProjectAssociateService projectAssociateServiceImpl;
+
@WireVariable
ServiceRecordService serviceRecordServiceImpl;
+
@WireVariable
SessionSettings sessionSettings;
- private Project formDocument;
- private Project origDocument;
- private Map<Associate, Boolean> origAssociates;
- private Map<Associate, Boolean> formAssociates;
+
+ @WireVariable
+ private ProjectsDataModel projectsDataModel;
+
@WireVariable
private PartnerSelectorDataModel partnerSelectorDataModel;
+
@WireVariable
- private InvoiceService invoiceServiceImpl;
+ private InvoiceDataModel invoiceDataModel;
+
@WireVariable
- private ProjectService projectServiceImpl;
+ private TreasuryDataModel treasuryDataModel;
+
@WireVariable
- private TreasuryService treasuryServiceImpl;
+ private ProjectService projectServiceImpl;
+
@WireVariable
private ServiceRecordsDataModel serviceRecordsDataModel;
+
@WireVariable
private ProjectStatusDataModel projectStatusDataModel;
- @Getter
+
@WireVariable
- private ProjectStatusService projectStatusServiceImpl;
+ private IncomeMarginsDataModel incomeMarginsDataModel;
+
@WireVariable
- private ProjectStatusConverter projectStatusConverter;
+ private ProjectAssociatesDataModel projectAssociatesDataModel;
+
@WireVariable
- private IncomeMarginsDataModel incomeMarginsDataModel;
+ private ProjectStatusConverter projectStatusConverter;
+
@WireVariable
private EventBus eventBus;
+
+ private Project formDocument;
+
+ private Project origDocument;
+
+ private Map<Long, Boolean> origAssociates;
+
+ private Map<Long, Boolean> formAssociates;
+
private boolean formInvalid = true;
+
private Invoice selectedIncomingInvoice;
+
private Invoice selectedOutgoingInvoice;
+
private Treasury selectedTreasury;
+
private String partialAssociateName;
@Init
if (Constants.SET_PROJECT_EDITOR_DATA.equals(evt.getName())) {
log.info("Got event {}", Constants.SET_PROJECT_EDITOR_DATA);
Object data = evt.getData();
- if (data instanceof Map) {
- Map<String, Object> mapData = (Map<String, Object>) evt.getData();
- origDocument = (Project) mapData.get("origDocument");
- formDocument = (Project) mapData.get("formDocument");
- }
-
- if (data instanceof String) {
- String id = (String) data;
- log.info("Loading entity {} to editor", id);
- origDocument = projectServiceImpl.getById(id);
- formDocument = projectServiceImpl.copy(origDocument);
- }
-
if (Objects.isNull(data)) {
- formDocument = projectServiceImpl.createNew();
+ 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.getById(id);
}
- if (Objects.nonNull(formDocument)) {
- Clients.evalJavaScript(String.format("pushNav('/project/%s')", formDocument.getId()));
- serviceRecordsDataModel.search(formDocument, true);
- associatesDataModel.listAll();
- incomeMarginsDataModel.recalculate(formDocument);
- BindUtils.postNotifyChange(this, "formDocument");
- }
+ serviceRecordsDataModel.search(formDocument, true);
+ initAssociates();
+ incomeMarginsDataModel.recalculate(formDocument);
+ BindUtils.postNotifyChange(this, "formDocument");
}
}
@Command
public void onEndEdit(@BindingParam("target") Window target, @BindingParam("select") boolean select) {
- if (select && formInvalid) {
- return;
- }
- Map<String, Project> args = null;
- if (select) {
- if (Objects.isNull(origDocument)) {
- args = ImmutableMap.of("formDocument", formDocument);
- } else {
- args = ImmutableMap.of("origDocument", origDocument, "formDocument", formDocument);
- }
- projectAssociateServiceImpl.update(formDocument, formAssociates);
+ if (select && !formInvalid) {
+ projectsDataModel.save(formDocument);
+ eventBus.showProjectsList(ImmutableMap.of("formDocument", formDocument));
}
-
- eventBus.showProjectsList(args);
}
@Command
Object value = ctx.getProperty().getValue();
log.info("Validating caused by {} {} {}", target.getId(), property, value);
try {
- Project newData = projectServiceImpl.copy(formDocument, property, value);
+
+ Project newData = getEntityToValidate(property, value);
validate(newData);
} catch (Exception e) {
log.catching(e);
}
}
+ private Project getEntityToValidate() {
+ return getEntityToValidate(null, null);
+ }
+
+ private Project getEntityToValidate(String property, Object value) {
+ Project newData;
+ if (Objects.isNull(origDocument)) {
+ if (Objects.nonNull(property)) {
+ projectsDataModel.setPropertyValue(formDocument, property, value);
+ }
+ newData = formDocument;
+ } else {
+ newData = projectsDataModel.copy(formDocument, property, value);
+ }
+ return newData;
+ }
+
private void validate(Project newData) {
incomeMarginsDataModel.recalculate(formDocument);
updateFormInvalid(false);
- if (!Objects.isNull(origDocument)) {
+ if (Objects.nonNull(origDocument)) {
boolean invalid = projectServiceImpl.toString(origDocument).equals(projectServiceImpl.toString(newData))
&& !isAssociatesChanged();
updateFormInvalid(invalid);
@Command
public void onAddIncoming() {
String page = "~./incoming-invoice-editor.zul";
- Invoice editEntity = invoiceServiceImpl.createNew();
+ Invoice editEntity = invoiceDataModel.createNew(formDocument);
editEntity.setIncome(true);
Window editorWindow = (Window) Executions.createComponents(page, null,
Collections.singletonMap("formDocument", editEntity));
selectedIncomingInvoice = editEntity;
BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
- validate(projectServiceImpl.copy(formDocument));
+ validate(getEntityToValidate());
}
});
editorWindow.doModal();
@Command
public void onEditIncoming() throws JsonProcessingException {
String page = "~./incoming-invoice-editor.zul";
- Invoice editEntity = invoiceServiceImpl.copy(selectedIncomingInvoice);
+ Invoice editEntity = invoiceDataModel.copy(selectedIncomingInvoice);
Map<String, Object> arg = new HashMap<>();
arg.put("origDocument", selectedIncomingInvoice);
arg.put("formDocument", editEntity);
editorWindow.addEventListener("onClose", e -> {
if (e.getData() != null) {
Invoice modifiedEntity = (Invoice) e.getData();
- List<Invoice> incomingInvoices = formDocument.getIncomingInvoices();
- int index = incomingInvoices.indexOf(selectedIncomingInvoice);
+ Set<Invoice> incomingInvoices = formDocument.getIncomingInvoices();
incomingInvoices.remove(selectedIncomingInvoice);
- incomingInvoices.add(index, modifiedEntity);
+ incomingInvoices.add(modifiedEntity);
selectedIncomingInvoice = modifiedEntity;
BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
- validate(projectServiceImpl.copy(formDocument));
+ validate(getEntityToValidate());
}
});
editorWindow.doModal();
selectedIncomingInvoice = null;
BindUtils.postNotifyChange(this, "selectedIncomingInvoice");
BindUtils.postNotifyChange(this.formDocument, "incomingInvoices");
- validate(projectServiceImpl.copy(formDocument));
}
@Command
public void onAddOutgoing() {
String page = "~./outgoing-invoice-editor.zul";
- Invoice editEntity = invoiceServiceImpl.createNew();
+ Invoice editEntity = invoiceDataModel.createNew(formDocument);
Window editorWindow = (Window) Executions.createComponents(page, null,
Collections.singletonMap("formDocument", editEntity));
editorWindow.addEventListener("onClose", e -> {
selectedOutgoingInvoice = editEntity;
BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
- validate(projectServiceImpl.copy(formDocument));
+ validate(getEntityToValidate());
}
});
editorWindow.doModal();
@Command
public void onEditOutgoing() throws JsonProcessingException {
String page = "~./outgoing-invoice-editor.zul";
- Invoice editEntity = invoiceServiceImpl.copy(selectedOutgoingInvoice);
+ Invoice editEntity = invoiceDataModel.copy(selectedOutgoingInvoice);
Map<String, Object> arg = new HashMap<>();
arg.put("origDocument", selectedOutgoingInvoice);
arg.put("formDocument", editEntity);
editorWindow.addEventListener("onClose", e -> {
if (e.getData() != null) {
Invoice modifiedEntity = (Invoice) e.getData();
- List<Invoice> outgoingInvoices = formDocument.getOutgoingInvoices();
- int index = outgoingInvoices.indexOf(selectedOutgoingInvoice);
+ Set<Invoice> outgoingInvoices = formDocument.getOutgoingInvoices();
outgoingInvoices.remove(selectedOutgoingInvoice);
- outgoingInvoices.add(index, modifiedEntity);
+ outgoingInvoices.add(modifiedEntity);
selectedOutgoingInvoice = modifiedEntity;
BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
- validate(projectServiceImpl.copy(formDocument));
+ validate(getEntityToValidate());
}
});
editorWindow.doModal();
selectedOutgoingInvoice = null;
BindUtils.postNotifyChange(this, "selectedOutgoingInvoice");
BindUtils.postNotifyChange(this.formDocument, "outgoingInvoices");
- validate(projectServiceImpl.copy(formDocument));
}
@Command
public void onAddTreasury() {
String page = "~./treasury-editor.zul";
- Treasury editEntity = treasuryServiceImpl.createNew();
+ Treasury editEntity = treasuryDataModel.createNew(formDocument);
Window editorWindow = (Window) Executions.createComponents(page, null,
Collections.singletonMap("formDocument", editEntity));
editorWindow.addEventListener("onClose", e -> {
selectedTreasury = editEntity;
BindUtils.postNotifyChange(this, "selectedTreasury");
BindUtils.postNotifyChange(this.formDocument, "treasuries");
- validate(projectServiceImpl.copy(formDocument));
+ validate(getEntityToValidate());
}
});
editorWindow.doModal();
@Command
public void onEditTreasury() {
String page = "~./treasury-editor.zul";
- Treasury editEntity = treasuryServiceImpl.copy(selectedTreasury);
+ Treasury editEntity = treasuryDataModel.copy(selectedTreasury);
Map<String, Object> arg = ImmutableMap.of("origDocument", selectedTreasury, "formDocument", editEntity);
Window editorWindow = (Window) Executions.createComponents(page, null, arg);
editorWindow.addEventListener("onClose", e -> {
if (e.getData() != null) {
Treasury modifiedEntity = (Treasury) e.getData();
- List<Treasury> treasuries = formDocument.getTreasuries();
- int index = treasuries.indexOf(selectedTreasury);
+ Set<Treasury> treasuries = formDocument.getTreasuries();
treasuries.remove(selectedTreasury);
- treasuries.add(index, modifiedEntity);
+ treasuries.add(modifiedEntity);
selectedTreasury = modifiedEntity;
BindUtils.postNotifyChange(this, "selectedTreasury");
BindUtils.postNotifyChange(this.formDocument, "treasuries");
- validate(projectServiceImpl.copy(formDocument));
+ validate(getEntityToValidate());
}
});
editorWindow.doModal();
selectedTreasury = null;
BindUtils.postNotifyChange(this, "selectedTreasury");
BindUtils.postNotifyChange(this.formDocument, "treasuries");
- validate(projectServiceImpl.copy(formDocument));
}
private void updateFormInvalid(boolean invalid) {
@Command
@NotifyChange("formAssociates")
public void onAfterRenderAssociates() {
+ }
+
+ @NotifyChange("formAssociates")
+ private void initAssociates() {
+ associatesDataModel.listAll();
formAssociates = new HashMap<>();
origAssociates = new HashMap<>();
+ if (Objects.isNull(formDocument.getId())) {
+ return;
+ }
+ List<ProjectAssociate> projectAssociates = projectAssociatesDataModel.search(formDocument.getId());
for (int i = 0; i < associatesDataModel.getSize(); i++) {
Associate associate = associatesDataModel.getElementAt(i);
- boolean exists = projectAssociateServiceImpl.getAll().stream()
+ boolean exists = projectAssociates.stream()
.anyMatch(
pa -> pa.getProject().getId().equals(formDocument.getId()) &&
pa.getAssociate().getId().equals(associate.getId())
if (exists) {
log.info("{} is on project {}", associate.getName(), formDocument.getName());
}
- formAssociates.put(associate, exists);
- origAssociates.put(associate, exists);
+ formAssociates.put(associate.getId(), exists);
+ origAssociates.put(associate.getId(), exists);
}
+ BindUtils.postNotifyChange(this, "formAssociates");
}
private boolean isAssociatesChanged() {
@Command
public void onAssociateChecked() {
log.info("Associate checked");
- validate(projectServiceImpl.copy(formDocument));
+ validate(origDocument);
}
}
getQueue().publish(new Event(Constants.SET_SERVICE_RECORDS_LIST_DATA, null, data));
}
- public void setProjectEditorData(Object data) {
+ public void setProjectEditorData(Long data) {
getQueue().publish(new Event(Constants.SET_PROJECT_EDITOR_DATA, null, data));
}
String id = path.split("/")[2];
selectPage(PROJECT_EDITOR);
// eventBus.setProjectEditorData(Collections.singletonMap("id", id));
- eventBus.setProjectEditorData(id);
+ eventBus.setProjectEditorData(Long.parseLong(id));
} else {
if (NAVIGATION.containsKey(path)) {
setPage(NAVIGATION.get(path));
}
if (Constants.SHOW_PROJECT_EDITOR.equals(event.getName())) {
selectPage(PROJECT_EDITOR);
- eventBus.setProjectEditorData(event.getData());
+ eventBus.setProjectEditorData((Long) event.getData());
}
if (Constants.SHOW_PROJECTS_LIST.equals(event.getName())) {
selectPage(PROJECTS_LIST);
--- /dev/null
+package hu.user.lis.ui.view;
+
+import lombok.Getter;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.boot.info.BuildProperties;
+import org.zkoss.zk.ui.select.annotation.VariableResolver;
+import org.zkoss.zk.ui.select.annotation.WireVariable;
+
+@Log4j2
+@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
+@Getter
+public class LoginViewModel {
+ @WireVariable
+ BuildProperties buildProperties;
+
+ public LoginViewModel() {
+
+ }
+}
@Command
public void onAdd() {
- Project newEntity = projectsDataModel.createNew();
-// eventBus.showProjectEditor(ImmutableMap.of("formDocument", newEntity));
eventBus.showProjectEditor(null);
}
if (Objects.isNull(selectedProject)) {
return;
}
-// Project editEntity = projectsDataModel.getProjectService().copy(selectedProject);
-// eventBus.showProjectEditor(ImmutableMap.of("origDocument", selectedProject, "formDocument", editEntity));
- eventBus.showProjectEditor(selectedProject.getId());
+ Project editEntity = projectsDataModel.copy(selectedProject);
+ eventBus.showProjectEditor(editEntity.getId());
}
public boolean isFilterShowInActive() {
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.*;
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.InputEvent;
-import org.zkoss.zk.ui.event.OpenEvent;
+import org.zkoss.zk.ui.event.*;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zk.ui.util.Clients;
serviceRecordsDataModel.listAll();
}
+ @Command
+ public void onSort(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
+ SortEvent evt = (SortEvent) ctx.getTriggerEvent();
+ //evt.stopPropagation();
+ }
+
@Override
public void onEvent(Event evt) throws Exception {
if (Constants.SET_SERVICE_RECORDS_LIST_DATA.equals(evt.getName())) {
import hu.user.lis.ui.data.ProjectStatusDataModel;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
-import org.zkoss.bind.BindContext;
+import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
-import org.zkoss.bind.annotation.ContextParam;
-import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.Init;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
}
@Command
- public void onActiveChecked(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {
-// CheckEvent evt = (CheckEvent) ctx.getTriggerEvent();
-// ProjectStatus entity = (ProjectStatus) evt.getData();
-// projectStatusDataModel.save(entity);
+ public void onActiveChecked(@BindingParam("entity") ProjectStatus entity) {
+ projectStatusDataModel.save(entity);
}
public void setSelectedProjectStatus(ProjectStatus selectedProjectStatus) {
- log.info("Sekected {}", selectedProjectStatus.getName());
this.selectedProjectStatus = selectedProjectStatus;
}
}
<session-timeout>300</session-timeout>
<timeout-uri>/timeout</timeout-uri>
</session-config>
+ <client-config>
+ <error-reload>
+ <device-type>ajax</device-type>
+ <error-code>403</error-code>
+ <reload-uri>/login</reload-uri>
+ </error-reload>
+ <error-reload>
+ <device-type>ajax</device-type>
+ <error-code>410</error-code>
+ <reload-uri>/timeout</reload-uri>
+ <connection-type>server-push</connection-type>
+ </error-reload>
+ <!-- <click-filter-delay>0</click-filter-delay>-->
+ <!-- <debug-js>false</debug-js>-->
+ <!-- <disable-behind-modal>false</disable-behind-modal>-->
+ <!-- <error-reload>-->
+ <!-- <device-type>ajax</device-type>-->
+ <!-- <error-code>301</error-code>-->
+ <!-- <reload-uri></reload-uri>-->
+ <!-- </error-reload>-->
+ <!-- <keep-across-visits>true</keep-across-visits>-->
+ <!-- <processing-prompt-delay>900</processing-prompt-delay>-->
+ <!-- <tooltip-delay>800</tooltip-delay>-->
+ <!-- <resend-delay>9000</resend-delay>-->
+ </client-config>
<!-- <error-page>-->
<!-- <exception-type>java.lang.Throwable</exception-type>-->
<!-- <location>/timeout</location>-->
<?link rel="stylesheet" type="text/css" href="~./static/css/webclient.css" ?>
<zk>
<style>
- <!-- .z-caption-content {-->
- <!-- width: 100%;-->
- <!-- }-->
+ .header > .z-caption-content {
+ width: 100%;
+ }
.z-window-header {
font-size: 18px;
font-weight: bolder;
}
</script>
<window vflex="true" viewModel="@id('vm') @init('hu.user.lis.ui.view.IndexViewModel')">
- <caption>
+ <caption sclass="header">
<div style="display: block">
<div style="display: inline; float: left">
<hlayout valign="middle">
display:table;
margin:auto;
}
+ .z-row:hover>.z-row-inner,
+ .z-row:hover>.z-cell {
+ background-color: white;
+ }
+ .z-grid-odd > .z-row-inner, .z-grid-odd > .z-cell {
+ background: none repeat scroll 0 0 white;
+ }
</n:style>
<n:form action="/login" method="POST">
- <grid style="margin-top: 200px">
- <columns>
- <column width="100px"/>
- <column width="280px"/>
- </columns>
- <rows>
- <row spans="2" align="center">
+
+ <window viewModel="@id('vm') @init('hu.user.lis.ui.view.LoginViewModel')"
+ style="margin-top: 200px" border="normal">
+ <caption sclass="header">
+ <div style="display: block">
<hlayout valign="middle">
- <!-- <image width="24px" height="24px" src="~./static/images/logo.png"/>-->
- <label value="SLY-CRM bejelentkezés"/>
- </hlayout>
- </row>
- <row>
- <label value="User"/>
- <textbox name="username" value="user"/>
- </row>
- <row>
- <label value="Password"/>
- <textbox type="password" name="password" value="password"/>
- </row>
- <row spans="2" align="right">
- <hlayout>
- <button type="reset" label="Mégsem"/>
- <button type="submit" label="Belépés"/>
+ <image width="24px" height="24px" src="~./static/images/logo.png"/>
+ <label value="SLY-CRM"/>
+ <separator orient="vertical"/>
+ <label style="font-size: 0.8em" value="@load(vm.buildProperties.version)"/>
</hlayout>
- </row>
- </rows>
- </grid>
+ </div>
+ </caption>
+ <grid>
+ <columns>
+ <column width="100px"/>
+ <column width="300px"/>
+ </columns>
+ <rows>
+ <row>
+ <label value="User"/>
+ <textbox name="username" value="user1" hflex="true"/>
+ </row>
+ <row>
+ <label value="Password"/>
+ <textbox type="password" name="password" value="password" hflex="true"/>
+ </row>
+ <row spans="2" align="right">
+ <hlayout>
+ <button type="submit" label="Belépés"/>
+ </hlayout>
+ </row>
+ </rows>
+ </grid>
+
+ </window>
</n:form>
</zk>
\ No newline at end of file
<!-- <comboitem label="${each.name}"/>-->
<!-- </template>-->
<!-- </combobox>-->
- <selectbox model="@load(vm.projectStatusServiceImpl.getAll())"
+ <selectbox model="@load(vm.projectStatusDataModel)"
width="100%"
selectedIndex="@bind(vm.formDocument.projectStatus) @converter(vm.projectStatusConverter) @validator(vm)"
forward="onOK=submit.onClick, onCancel=cancel.onClick">
autopaging="true" pagingPosition="top" onSelect="@command('onListSelection')"
onDoubleClick="@command('onEdit')">
<listhead sizable="true">
- <listheader label="Azonosító" align="left"/>
- <listheader label="Ügyfél" align="left"/>
- <listheader label="Státusz" align="left"/>
- <listheader label="Megnevezés" align="left"/>
- <listheader label="Kapcsolattartó" align="left"/>
- <listheader label="Aktív" align="left"/>
+ <listheader label="Azonosító" sort="auto(humanId)" align="left"/>
+ <listheader label="Ügyfél" sort="auto(partner.name)" align="left"/>
+ <listheader label="Státusz" sort="auto(projectStatus.name)" align="left"/>
+ <listheader label="Megnevezés" sort="auto(name)" align="left"/>
+ <listheader label="Kapcsolattartó" sort="auto(contactName)" align="left"/>
+ <listheader label="Aktív" sort="auto(active)" align="left"/>
</listhead>
<template name="model">
<listitem>
autopaging="true" mold="paging" pagingPosition="top" onSelect="@command('onListSelection')"
onDoubleClick="@command('onEdit')">
<listhead sizable="true">
- <listheader label="Projekt azonosító" sort="auto(project.humanId)" align="left"/>
+ <!--
+ https://www.zkoss.org/wiki/ZK_Component_Reference/Data/Listbox
+ -->
+ <listheader label="Projekt azonosító" sort="auto(project.humanId)" align="left"
+ sortDirection="ascending"/>
<listheader label="Projekt név" sort="auto(project.name)" align="left"/>
<listheader label="Partner név" sort="auto(project.partner.name)" align="left"/>
<listheader label="Munkatárs" sort="auto(associate.name)" align="left"/>
<textbox inplace="true" instant="true" width="100%" value="@bind(each.name)"/>
</listcell>
<listcell>
- <checkbox checked="@bind(each.active)" onCheck="@command('onActiveChecked')"/>
+ <checkbox checked="@bind(each.active)"
+ onCheck="@command('onActiveChecked', entity=each)"/>
</listcell>
</listitem>
</template>
-.z-loading {
- left: 45% !important;
+.z-loading { left: 45% !important;
/*
top: 50% !important;
align: center;
resize: none;
}
+/*
.z-listitem-selected>.z-listcell>.z-listcell-content {
font-weight: bold;
}
-
+*/
.container .form-label {
font-family: "Calibri";
line-height: 1.5em;