Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5bd72d2678 | |||
| 1b42808efa | |||
| cd9752090f | |||
| 04df2ee1aa | |||
| 2b6e038a75 | |||
| a0589243f2 | |||
| c94d4015eb | |||
| 823ac56d8e | |||
| 346236ec09 | |||
| fa210d1e71 | |||
| 959808ab63 | |||
| 08c263f3df | |||
| 88c4c2ce70 | |||
| 4819d318b8 | |||
| 22e52ea46c | |||
| 313821ef7b | |||
| 620e615e72 | |||
| 5de13e8a2b | |||
| a75ae7d971 | |||
| afc46e3c41 | |||
| 5d6a0ae3e1 | |||
| 7076174e11 | |||
| 176861ccca | |||
| 3aa4688471 | |||
| bc77eec906 | |||
| e79cab687c | |||
| b06597f36e | |||
| f63cb0b946 | |||
| 7676b3f0d2 | |||
| 7b07f0861a | |||
| 44fe789f5d | |||
| 2372d8bd56 | |||
| 5e75b53d11 | |||
| c56a7e6dc4 | |||
| 35b10bc873 | |||
| 770791302c | |||
| a6731fcdfc | |||
| a59d438dbb | |||
| 576c5155d9 | |||
| 14b5142394 | |||
| 11e38ea299 | |||
| b8bb77e807 | |||
| 4719cd3e9a | |||
| d41c876258 | |||
| 6a57f63784 | |||
| 0e18d28ca9 | |||
| 0e3b17f152 | |||
| fe04681b74 | |||
| f41a08d52e | |||
| e51b15a114 | |||
| 7ae7cc1d36 | |||
| add69e7999 | |||
| db744d634b | |||
| 017548c0a3 | |||
| c56e8a4968 | |||
| 636c5ba88f | |||
| 73d382aa1f | |||
| d4ff2d503e | |||
| c609f1ecc6 |
@@ -40,6 +40,13 @@
|
|||||||
"relationshipName": "event",
|
"relationshipName": "event",
|
||||||
"relationshipSide": "right",
|
"relationshipSide": "right",
|
||||||
"relationshipType": "many-to-one"
|
"relationshipType": "many-to-one"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"otherEntityField": "name",
|
||||||
|
"otherEntityName": "userAccount",
|
||||||
|
"relationshipName": "userAccount",
|
||||||
|
"relationshipSide": "left",
|
||||||
|
"relationshipType": "many-to-one"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"searchEngine": "no"
|
"searchEngine": "no"
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"annotations": {
|
||||||
|
"changelogDate": "20241113134007"
|
||||||
|
},
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldName": "type",
|
||||||
|
"fieldType": "TransactionType",
|
||||||
|
"fieldValues": "PURCHASE,MATCH,FIELDPAYMENT,INTERNALTRANSFER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "date",
|
||||||
|
"fieldType": "LocalDate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "comment",
|
||||||
|
"fieldType": "String"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Transaction",
|
||||||
|
"pagination": "no",
|
||||||
|
"readOnly": false,
|
||||||
|
"relationships": [
|
||||||
|
{
|
||||||
|
"otherEntityField": "name",
|
||||||
|
"otherEntityName": "event",
|
||||||
|
"otherEntityRelationshipName": "transaction",
|
||||||
|
"relationshipName": "event",
|
||||||
|
"relationshipSide": "left",
|
||||||
|
"relationshipType": "many-to-one"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"searchEngine": "no",
|
||||||
|
"service": "no"
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"annotations": {
|
||||||
|
"changelogDate": "20241113151058"
|
||||||
|
},
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldName": "amount",
|
||||||
|
"fieldType": "BigDecimal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "comment",
|
||||||
|
"fieldType": "String",
|
||||||
|
"fieldValidateRules": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "locked",
|
||||||
|
"fieldType": "Boolean",
|
||||||
|
"fieldValidateRules": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "TransactionItem",
|
||||||
|
"pagination": "no",
|
||||||
|
"readOnly": false,
|
||||||
|
"relationships": [
|
||||||
|
{
|
||||||
|
"otherEntityField": "id",
|
||||||
|
"otherEntityName": "userAccount",
|
||||||
|
"otherEntityRelationshipName": "transactionItem",
|
||||||
|
"relationshipName": "userAccount",
|
||||||
|
"relationshipSide": "left",
|
||||||
|
"relationshipType": "many-to-one"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"otherEntityField": "id",
|
||||||
|
"otherEntityName": "transaction",
|
||||||
|
"otherEntityRelationshipName": "transactionItem",
|
||||||
|
"relationshipName": "transaction",
|
||||||
|
"relationshipSide": "left",
|
||||||
|
"relationshipType": "many-to-one"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"otherEntityField": "name",
|
||||||
|
"otherEntityName": "event",
|
||||||
|
"relationshipName": "event",
|
||||||
|
"relationshipSide": "left",
|
||||||
|
"relationshipType": "many-to-one"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"otherEntityField": "playerName",
|
||||||
|
"otherEntityName": "registration",
|
||||||
|
"otherEntityRelationshipName": "transactionItem",
|
||||||
|
"relationshipName": "registration",
|
||||||
|
"relationshipSide": "left",
|
||||||
|
"relationshipType": "many-to-one"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"searchEngine": "no",
|
||||||
|
"service": "no"
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"annotations": {
|
||||||
|
"changelogDate": "20241113135042"
|
||||||
|
},
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldName": "name",
|
||||||
|
"fieldType": "String"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "UserAccount",
|
||||||
|
"pagination": "no",
|
||||||
|
"readOnly": false,
|
||||||
|
"relationships": [
|
||||||
|
{
|
||||||
|
"otherEntityField": "login",
|
||||||
|
"otherEntityName": "user",
|
||||||
|
"otherEntityRelationshipName": "userAccount",
|
||||||
|
"relationshipName": "user",
|
||||||
|
"relationshipSide": "left",
|
||||||
|
"relationshipType": "many-to-many"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"searchEngine": "no",
|
||||||
|
"service": "no"
|
||||||
|
}
|
||||||
+2
-2
@@ -15,10 +15,10 @@
|
|||||||
"enableHibernateCache": null,
|
"enableHibernateCache": null,
|
||||||
"enableSwaggerCodegen": false,
|
"enableSwaggerCodegen": false,
|
||||||
"enableTranslation": false,
|
"enableTranslation": false,
|
||||||
"entities": ["Charge", "Event", "Registration"],
|
"entities": ["Charge", "Event", "Registration", "Transaction", "UserAccount", "TransactionItem"],
|
||||||
"feignClient": null,
|
"feignClient": null,
|
||||||
"jhipsterVersion": "8.7.2",
|
"jhipsterVersion": "8.7.2",
|
||||||
"lastLiquibaseTimestamp": 1730797803000,
|
"lastLiquibaseTimestamp": 1731505842000,
|
||||||
"messageBroker": false,
|
"messageBroker": false,
|
||||||
"microfrontend": null,
|
"microfrontend": null,
|
||||||
"microfrontends": [],
|
"microfrontends": [],
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
<maven-site-plugin.version>3.21.0</maven-site-plugin.version>
|
<maven-site-plugin.version>3.21.0</maven-site-plugin.version>
|
||||||
<maven-surefire-plugin.version>3.5.1</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>3.5.1</maven-surefire-plugin.version>
|
||||||
<maven-war-plugin.version>3.4.0</maven-war-plugin.version>
|
<maven-war-plugin.version>3.4.0</maven-war-plugin.version>
|
||||||
<modernizer-maven-plugin.version>2.9.0</modernizer-maven-plugin.version>
|
<!-- <modernizer-maven-plugin.version>2.9.0</modernizer-maven-plugin.version>-->
|
||||||
<nohttp-checkstyle.version>0.0.11</nohttp-checkstyle.version>
|
<nohttp-checkstyle.version>0.0.11</nohttp-checkstyle.version>
|
||||||
<profile.api-docs/>
|
<profile.api-docs/>
|
||||||
<profile.e2e/>
|
<profile.e2e/>
|
||||||
@@ -91,6 +91,12 @@
|
|||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.34</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>tech.jhipster</groupId>
|
<groupId>tech.jhipster</groupId>
|
||||||
<artifactId>jhipster-framework</artifactId>
|
<artifactId>jhipster-framework</artifactId>
|
||||||
@@ -287,6 +293,11 @@
|
|||||||
<artifactId>testcontainers</artifactId>
|
<artifactId>testcontainers</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -351,10 +362,10 @@
|
|||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>properties-maven-plugin</artifactId>
|
<artifactId>properties-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<!-- <plugin>-->
|
||||||
<groupId>org.gaul</groupId>
|
<!-- <groupId>org.gaul</groupId>-->
|
||||||
<artifactId>modernizer-maven-plugin</artifactId>
|
<!-- <artifactId>modernizer-maven-plugin</artifactId>-->
|
||||||
</plugin>
|
<!-- </plugin>-->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
@@ -719,23 +730,23 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<!-- <plugin>-->
|
||||||
<groupId>org.gaul</groupId>
|
<!-- <groupId>org.gaul</groupId>-->
|
||||||
<artifactId>modernizer-maven-plugin</artifactId>
|
<!-- <artifactId>modernizer-maven-plugin</artifactId>-->
|
||||||
<version>${modernizer-maven-plugin.version}</version>
|
<!-- <version>${modernizer-maven-plugin.version}</version>-->
|
||||||
<executions>
|
<!-- <executions>-->
|
||||||
<execution>
|
<!-- <execution>-->
|
||||||
<id>modernizer</id>
|
<!-- <id>modernizer</id>-->
|
||||||
<phase>package</phase>
|
<!-- <phase>package</phase>-->
|
||||||
<goals>
|
<!-- <goals>-->
|
||||||
<goal>modernizer</goal>
|
<!-- <goal>modernizer</goal>-->
|
||||||
</goals>
|
<!-- </goals>-->
|
||||||
</execution>
|
<!-- </execution>-->
|
||||||
</executions>
|
<!-- </executions>-->
|
||||||
<configuration>
|
<!-- <configuration>-->
|
||||||
<javaVersion>${java.version}</javaVersion>
|
<!-- <javaVersion>${java.version}</javaVersion>-->
|
||||||
</configuration>
|
<!-- </configuration>-->
|
||||||
</plugin>
|
<!-- </plugin>-->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jacoco</groupId>
|
<groupId>org.jacoco</groupId>
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
|||||||
@@ -3,15 +3,25 @@ package com.sasiedzi.event.config;
|
|||||||
import static org.springframework.security.config.Customizer.withDefaults;
|
import static org.springframework.security.config.Customizer.withDefaults;
|
||||||
import static org.springframework.security.oauth2.core.oidc.StandardClaimNames.PREFERRED_USERNAME;
|
import static org.springframework.security.oauth2.core.oidc.StandardClaimNames.PREFERRED_USERNAME;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.CurrentUserHolder;
|
||||||
|
import com.sasiedzi.event.repository.UserRepository;
|
||||||
import com.sasiedzi.event.security.*;
|
import com.sasiedzi.event.security.*;
|
||||||
import com.sasiedzi.event.security.SecurityUtils;
|
import com.sasiedzi.event.security.SecurityUtils;
|
||||||
import com.sasiedzi.event.security.oauth2.AudienceValidator;
|
import com.sasiedzi.event.security.oauth2.AudienceValidator;
|
||||||
import com.sasiedzi.event.security.oauth2.CustomClaimConverter;
|
import com.sasiedzi.event.security.oauth2.CustomClaimConverter;
|
||||||
|
import com.sasiedzi.event.service.EventService;
|
||||||
|
import com.sasiedzi.event.service.UserService;
|
||||||
|
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
||||||
import com.sasiedzi.event.web.filter.SpaWebFilter;
|
import com.sasiedzi.event.web.filter.SpaWebFilter;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@@ -21,8 +31,15 @@ import org.springframework.security.authentication.AbstractAuthenticationToken;
|
|||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig;
|
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.User;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
|
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
|
||||||
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
|
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
@@ -35,11 +52,14 @@ import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
|
|||||||
import org.springframework.security.oauth2.jwt.*;
|
import org.springframework.security.oauth2.jwt.*;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.RememberMeServices;
|
||||||
|
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
import org.springframework.security.web.csrf.*;
|
import org.springframework.security.web.csrf.*;
|
||||||
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
|
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
|
||||||
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
|
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.context.annotation.RequestScope;
|
||||||
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
||||||
import tech.jhipster.config.JHipsterProperties;
|
import tech.jhipster.config.JHipsterProperties;
|
||||||
import tech.jhipster.web.filter.CookieCsrfFilter;
|
import tech.jhipster.web.filter.CookieCsrfFilter;
|
||||||
@@ -82,27 +102,141 @@ public class SecurityConfiguration {
|
|||||||
.authorizeHttpRequests(authz ->
|
.authorizeHttpRequests(authz ->
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
authz
|
authz
|
||||||
.requestMatchers(mvc.pattern("/index.html"), mvc.pattern("/*.js"), mvc.pattern("/*.txt"), mvc.pattern("/*.json"), mvc.pattern("/*.map"), mvc.pattern("/*.css")).permitAll()
|
// .requestMatchers(mvc.pattern("/index.html"), mvc.pattern("/*.js"), mvc.pattern("/*.txt"), mvc.pattern("/*.json"), mvc.pattern("/*.map"), mvc.pattern("/*.css")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/*.ico"), mvc.pattern("/*.png"), mvc.pattern("/*.svg"), mvc.pattern("/*.webapp")).permitAll()
|
// .requestMatchers(mvc.pattern("/*.ico"), mvc.pattern("/*.png"), mvc.pattern("/*.svg"), mvc.pattern("/*.webapp")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/assets/**")).permitAll()
|
// .requestMatchers(mvc.pattern("/assets/**")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/swagger-ui/**")).permitAll()
|
// .requestMatchers(mvc.pattern("/swagger-ui/**")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/api/authenticate")).permitAll()
|
// .requestMatchers(mvc.pattern("/api/authenticate")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/api/auth-info")).permitAll()
|
// .requestMatchers(mvc.pattern("/api/auth-info")).permitAll()
|
||||||
|
.requestMatchers(mvc.pattern("/logout")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/api/admin/**")).hasAuthority(AuthoritiesConstants.ADMIN)
|
.requestMatchers(mvc.pattern("/api/admin/**")).hasAuthority(AuthoritiesConstants.ADMIN)
|
||||||
.requestMatchers(mvc.pattern("/api/**")).authenticated()
|
// .requestMatchers(mvc.pattern("/api/**")).authenticated()
|
||||||
|
.requestMatchers(mvc.pattern("/**")).authenticated()
|
||||||
.requestMatchers(mvc.pattern("/v3/api-docs/**")).hasAuthority(AuthoritiesConstants.ADMIN)
|
.requestMatchers(mvc.pattern("/v3/api-docs/**")).hasAuthority(AuthoritiesConstants.ADMIN)
|
||||||
.requestMatchers(mvc.pattern("/management/health")).permitAll()
|
// .requestMatchers(mvc.pattern("/management/health")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/management/health/**")).permitAll()
|
// .requestMatchers(mvc.pattern("/management/health/**")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/management/info")).permitAll()
|
// .requestMatchers(mvc.pattern("/management/info")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/management/prometheus")).permitAll()
|
// .requestMatchers(mvc.pattern("/management/prometheus")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/management/**")).hasAuthority(AuthoritiesConstants.ADMIN)
|
.requestMatchers(mvc.pattern("/management/**")).hasAuthority(AuthoritiesConstants.ADMIN)
|
||||||
)
|
)
|
||||||
.oauth2Login(oauth2 -> oauth2.loginPage("/").userInfoEndpoint(userInfo -> userInfo.oidcUserService(this.oidcUserService())))
|
.rememberMe(
|
||||||
|
rememberMe -> rememberMe.rememberMeServices(rememberMeServices()) // Klucz do szyfrowania tokenu
|
||||||
|
)
|
||||||
|
.oauth2Login(oauth2 ->
|
||||||
|
oauth2
|
||||||
|
.defaultSuccessUrl("/", true)
|
||||||
|
/*.loginPage("/")*/.userInfoEndpoint(userInfo -> userInfo.oidcUserService(this.oidcUserService()))
|
||||||
|
)
|
||||||
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(authenticationConverter())))
|
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(authenticationConverter())))
|
||||||
.oauth2Client(withDefaults());
|
.oauth2Client(withDefaults());
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RememberMeServices rememberMeServices() {
|
||||||
|
TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices(
|
||||||
|
"remember-me-cookie-key32342ff",
|
||||||
|
userDetailsService()
|
||||||
|
);
|
||||||
|
rememberMeServices.setTokenValiditySeconds(60 * 60 * 24 * 170);
|
||||||
|
rememberMeServices.setAlwaysRemember(true);
|
||||||
|
// Ustawienie czasu ważności tokenu na 170 dni
|
||||||
|
return rememberMeServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserRepository userRepository;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public UserDetailsService userDetailsService() {
|
||||||
|
// Jeśli korzystasz z in-memory użytkowników lub innego źródła, skonfiguruj tutaj.
|
||||||
|
return new UserDetailsService() {
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
String login = extractUsername(username);
|
||||||
|
// String[] authorities = extractGrantedAuthorities(username);
|
||||||
|
Map<String, Object> attributes = extractUserAttributes(username);
|
||||||
|
Optional<com.sasiedzi.event.domain.User> one = userRepository.findOneByLogin(login);
|
||||||
|
|
||||||
|
if (one.isPresent()) {
|
||||||
|
// return new User(one.get().getLogin(), "somepassword", one.get().getAuthorities().stream().map(authority-> new SimpleGrantedAuthority(authority.getName())).collect(Collectors.toSet()));
|
||||||
|
// return new User(login, "somepassword", Arrays.stream(authorities).map(authority-> new SimpleGrantedAuthority(authority)).collect(Collectors.toSet()));
|
||||||
|
return new User(username, "somepassword", extractRoles(username));
|
||||||
|
} else {
|
||||||
|
throw new UsernameNotFoundException("User not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String extractUsername(String input) {
|
||||||
|
Pattern pattern = Pattern.compile("Name:\\s+\\[([^]]+)]");
|
||||||
|
Matcher matcher = pattern.matcher(input);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] extractGrantedAuthorities(String input) {
|
||||||
|
Pattern pattern = Pattern.compile("Granted Authorities:\\s+\\[([^]]+)]");
|
||||||
|
Matcher matcher = pattern.matcher(input);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1).split(", ");
|
||||||
|
}
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<GrantedAuthority> extractRoles(String input) {
|
||||||
|
Set<GrantedAuthority> roles = new HashSet<>();
|
||||||
|
Pattern pattern = Pattern.compile("https://www\\.jhipster\\.tech/roles=\\[([^]]+)]");
|
||||||
|
Matcher matcher = pattern.matcher(input);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String rolesString = matcher.group(1);
|
||||||
|
String[] rolesArray = rolesString.split(",\\s*");
|
||||||
|
for (String role : rolesArray) {
|
||||||
|
roles.add(new SimpleGrantedAuthority(role));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> extractUserAttributes(String input) {
|
||||||
|
Map<String, Object> attributes = new HashMap<>();
|
||||||
|
Pattern pattern = Pattern.compile("User Attributes:\\s+\\[\\{([^}]+)\\}\\]");
|
||||||
|
Matcher matcher = pattern.matcher(input);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String attributesString = matcher.group(1);
|
||||||
|
String[] attributePairs = attributesString.split(",\\s*");
|
||||||
|
for (String pair : attributePairs) {
|
||||||
|
String[] keyValue = pair.split("=");
|
||||||
|
if (keyValue.length == 2) {
|
||||||
|
String key = keyValue[0];
|
||||||
|
String value = keyValue[1];
|
||||||
|
// Tutaj wartość jest zawsze String, ale można by to rozszerzyć by obsługiwało różne typy
|
||||||
|
attributes.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@RequestScope
|
||||||
|
public CurrentUserHolder currentUser(UserService userService, EventService eventService) {
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
if (authentication instanceof AbstractAuthenticationToken) {
|
||||||
|
AbstractAuthenticationToken authToken = (AbstractAuthenticationToken) authentication;
|
||||||
|
AdminUserDTO userFromAuthentication = userService.getUserFromAuthentication(authToken);
|
||||||
|
return new CurrentUserHolder(
|
||||||
|
userFromAuthentication,
|
||||||
|
eventService.getOrCreateUserAccountForLogin(userFromAuthentication.getLogin()),
|
||||||
|
authentication
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return new CurrentUserHolder();
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
|
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
|
||||||
return new MvcRequestMatcher.Builder(introspector);
|
return new MvcRequestMatcher.Builder(introspector);
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ public class Charge implements Serializable {
|
|||||||
private BigDecimal amount;
|
private BigDecimal amount;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JsonIgnoreProperties(value = { "registrations" }, allowSetters = true)
|
@JsonIgnoreProperties(value = { "registrations", "transactions" }, allowSetters = true)
|
||||||
private Event event;
|
private Event event;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JsonIgnoreProperties(value = { "user", "event" }, allowSetters = true)
|
@JsonIgnoreProperties(value = { "user", "event", "transactionItems" }, allowSetters = true)
|
||||||
private Registration registration;
|
private Registration registration;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.sasiedzi.event.domain;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.annotation.RequestScope;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequestScope
|
||||||
|
public class CurrentUserHolder {
|
||||||
|
|
||||||
|
AdminUserDTO adminUser;
|
||||||
|
UserAccount userAccount;
|
||||||
|
|
||||||
|
Authentication authentication;
|
||||||
|
|
||||||
|
public CurrentUserHolder() {}
|
||||||
|
|
||||||
|
public AdminUserDTO getAdminUser() {
|
||||||
|
return adminUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount getUserAccount() {
|
||||||
|
return userAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Authentication getAuthentication() {
|
||||||
|
return authentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLogin() {
|
||||||
|
if (adminUser == null) return null;
|
||||||
|
return adminUser.getLogin();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurrentUserHolder(AdminUserDTO adminUser, UserAccount userAccount, Authentication authentication) {
|
||||||
|
this.adminUser = adminUser;
|
||||||
|
this.userAccount = userAccount;
|
||||||
|
this.authentication = authentication;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
package com.sasiedzi.event.domain;
|
package com.sasiedzi.event.domain;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.*;
|
import jakarta.validation.constraints.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -44,9 +46,13 @@ public class Event implements Serializable {
|
|||||||
private String comment;
|
private String comment;
|
||||||
|
|
||||||
@OneToMany(fetch = FetchType.EAGER, mappedBy = "event")
|
@OneToMany(fetch = FetchType.EAGER, mappedBy = "event")
|
||||||
@JsonIgnoreProperties(value = { "event" }, allowSetters = true)
|
@JsonIgnoreProperties(value = { "event", "transactionItems" }, allowSetters = true)
|
||||||
private Set<Registration> registrations = new HashSet<>();
|
private Set<Registration> registrations = new HashSet<>();
|
||||||
|
|
||||||
|
@OneToMany(fetch = FetchType.LAZY, mappedBy = "event")
|
||||||
|
@JsonIgnoreProperties(value = { "event" }, allowSetters = true)
|
||||||
|
private Set<Transaction> transactions = new HashSet<>();
|
||||||
|
|
||||||
// jhipster-needle-entity-add-field - JHipster will add fields here
|
// jhipster-needle-entity-add-field - JHipster will add fields here
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@@ -88,6 +94,89 @@ public class Event implements Serializable {
|
|||||||
this.date = date;
|
this.date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Transient
|
||||||
|
// private Boolean editable;
|
||||||
|
|
||||||
|
@JsonProperty("editable")
|
||||||
|
public Boolean getEditable() {
|
||||||
|
if (date == null) return false;
|
||||||
|
LocalDate currentDate = LocalDate.now();
|
||||||
|
long daysBetween = ChronoUnit.DAYS.between(this.date, currentDate);
|
||||||
|
return daysBetween <= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private Long chargeTransactionId;
|
||||||
|
|
||||||
|
@JsonProperty("chargeTransactionId")
|
||||||
|
public Long getChargeTransactionId() {
|
||||||
|
return chargeTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChargeTransactionId(Long chargeTransactionId) {
|
||||||
|
this.chargeTransactionId = chargeTransactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void setEditable(Boolean editable) {
|
||||||
|
// this.editable = editable;
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private Boolean paid;
|
||||||
|
|
||||||
|
@JsonProperty("paid")
|
||||||
|
public Boolean getPaid() {
|
||||||
|
return paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPaid(Boolean paid) {
|
||||||
|
this.paid = paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private Boolean charged;
|
||||||
|
|
||||||
|
@JsonProperty("charged")
|
||||||
|
public Boolean getCharged() {
|
||||||
|
return charged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharged(Boolean charged) {
|
||||||
|
this.charged = charged;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private Boolean current;
|
||||||
|
|
||||||
|
@JsonProperty("current")
|
||||||
|
public Boolean getCurrent() {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrent(Boolean current) {
|
||||||
|
this.current = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("active")
|
||||||
|
public Boolean getActive() {
|
||||||
|
if (date == null) return false;
|
||||||
|
LocalDate currentDate = LocalDate.now();
|
||||||
|
long daysBetween = ChronoUnit.DAYS.between(this.date, currentDate);
|
||||||
|
return daysBetween <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Transient
|
||||||
|
// private Boolean deletable;
|
||||||
|
|
||||||
|
@JsonProperty("deletable")
|
||||||
|
public Boolean getDeletable() {
|
||||||
|
return getEditable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void setDeletable(Boolean deletable) {
|
||||||
|
// this.deletable = deletable;
|
||||||
|
// }
|
||||||
|
|
||||||
public Integer getPlayersLimit() {
|
public Integer getPlayersLimit() {
|
||||||
return this.playersLimit;
|
return this.playersLimit;
|
||||||
}
|
}
|
||||||
@@ -158,6 +247,37 @@ public class Event implements Serializable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Transaction> getTransactions() {
|
||||||
|
return this.transactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactions(Set<Transaction> transactions) {
|
||||||
|
if (this.transactions != null) {
|
||||||
|
this.transactions.forEach(i -> i.setEvent(null));
|
||||||
|
}
|
||||||
|
if (transactions != null) {
|
||||||
|
transactions.forEach(i -> i.setEvent(this));
|
||||||
|
}
|
||||||
|
this.transactions = transactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Event transactions(Set<Transaction> transactions) {
|
||||||
|
this.setTransactions(transactions);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Event addTransaction(Transaction transaction) {
|
||||||
|
this.transactions.add(transaction);
|
||||||
|
transaction.setEvent(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Event removeTransaction(Transaction transaction) {
|
||||||
|
this.transactions.remove(transaction);
|
||||||
|
transaction.setEvent(null);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
|
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import jakarta.persistence.*;
|
|||||||
import jakarta.validation.constraints.*;
|
import jakarta.validation.constraints.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Registration.
|
* A Registration.
|
||||||
@@ -41,9 +43,17 @@ public class Registration implements Serializable {
|
|||||||
private User user;
|
private User user;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JsonIgnoreProperties(value = { "registrations" }, allowSetters = true)
|
@JsonIgnoreProperties(value = { "registrations", "transactions" }, allowSetters = true)
|
||||||
private Event event;
|
private Event event;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JsonIgnoreProperties(value = { "users", "transactionItems" }, allowSetters = true)
|
||||||
|
private UserAccount userAccount;
|
||||||
|
|
||||||
|
@OneToMany(fetch = FetchType.LAZY, mappedBy = "registration")
|
||||||
|
@JsonIgnoreProperties(value = { "userAccount", "transaction", "event", "registration" }, allowSetters = true)
|
||||||
|
private Set<TransactionItem> transactionItems = new HashSet<>();
|
||||||
|
|
||||||
// jhipster-needle-entity-add-field - JHipster will add fields here
|
// jhipster-needle-entity-add-field - JHipster will add fields here
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@@ -137,6 +147,50 @@ public class Registration implements Serializable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserAccount getUserAccount() {
|
||||||
|
return this.userAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserAccount(UserAccount userAccount) {
|
||||||
|
this.userAccount = userAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Registration userAccount(UserAccount userAccount) {
|
||||||
|
this.setUserAccount(userAccount);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<TransactionItem> getTransactionItems() {
|
||||||
|
return this.transactionItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionItems(Set<TransactionItem> transactionItems) {
|
||||||
|
if (this.transactionItems != null) {
|
||||||
|
this.transactionItems.forEach(i -> i.setRegistration(null));
|
||||||
|
}
|
||||||
|
if (transactionItems != null) {
|
||||||
|
transactionItems.forEach(i -> i.setRegistration(this));
|
||||||
|
}
|
||||||
|
this.transactionItems = transactionItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Registration transactionItems(Set<TransactionItem> transactionItems) {
|
||||||
|
this.setTransactionItems(transactionItems);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Registration addTransactionItem(TransactionItem transactionItem) {
|
||||||
|
this.transactionItems.add(transactionItem);
|
||||||
|
transactionItem.setRegistration(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Registration removeTransactionItem(TransactionItem transactionItem) {
|
||||||
|
this.transactionItems.remove(transactionItem);
|
||||||
|
transactionItem.setRegistration(null);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
|
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,219 @@
|
|||||||
|
package com.sasiedzi.event.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.sasiedzi.event.domain.enumeration.TransactionType;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.*;
|
||||||
|
import org.hibernate.annotations.SortComparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Transaction.
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "transaction")
|
||||||
|
@SuppressWarnings("common-java:DuplicatedBlocks")
|
||||||
|
public class Transaction implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
||||||
|
@SequenceGenerator(name = "sequenceGenerator")
|
||||||
|
@Column(name = "id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(name = "type")
|
||||||
|
private TransactionType type;
|
||||||
|
|
||||||
|
@Column(name = "date")
|
||||||
|
private LocalDate date;
|
||||||
|
|
||||||
|
@Column(name = "comment")
|
||||||
|
private String comment;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JsonIgnoreProperties(value = { "registrations", "transactions" }, allowSetters = true)
|
||||||
|
private Event event;
|
||||||
|
|
||||||
|
@OneToMany(fetch = FetchType.LAZY, mappedBy = "transaction", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
|
@JsonIgnoreProperties(value = { "transaction", "event", "registration" }, allowSetters = true)
|
||||||
|
@SortComparator(TransactionItemComparator.class)
|
||||||
|
private SortedSet<TransactionItem> transactionItems = Transaction.getEmptyTransactionItemSet();
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private UserAccount beneficiary;
|
||||||
|
|
||||||
|
@JsonProperty("beneficiary")
|
||||||
|
public UserAccount getBeneficiary() {
|
||||||
|
return beneficiary;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("beneficiary")
|
||||||
|
public void setBeneficiary(UserAccount beneficiary) {
|
||||||
|
this.beneficiary = beneficiary;
|
||||||
|
}
|
||||||
|
|
||||||
|
// jhipster-needle-entity-add-field - JHipster will add fields here
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction id(Long id) {
|
||||||
|
this.setId(id);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionType getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction type(TransactionType type) {
|
||||||
|
this.setType(type);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Transient
|
||||||
|
// private Boolean editable;
|
||||||
|
|
||||||
|
@JsonProperty("editable")
|
||||||
|
public Boolean getEditable() {
|
||||||
|
if (date == null) return false;
|
||||||
|
LocalDate currentDate = LocalDate.now();
|
||||||
|
long daysBetween = ChronoUnit.DAYS.between(this.date, currentDate);
|
||||||
|
return daysBetween <= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void setEditable(Boolean editable) {
|
||||||
|
// this.editable = editable;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Transient
|
||||||
|
// private Boolean deletable;
|
||||||
|
|
||||||
|
@JsonProperty("deletable")
|
||||||
|
public Boolean getDeletable() {
|
||||||
|
return getEditable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void setDeletable(Boolean deletable) {
|
||||||
|
// this.deletable = deletable;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void setType(TransactionType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return this.date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction date(LocalDate date) {
|
||||||
|
this.setDate(date);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(LocalDate date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComment() {
|
||||||
|
return this.comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction comment(String comment) {
|
||||||
|
this.setComment(comment);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComment(String comment) {
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Event getEvent() {
|
||||||
|
return this.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEvent(Event event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction event(Event event) {
|
||||||
|
this.setEvent(event);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortedSet<TransactionItem> getTransactionItems() {
|
||||||
|
return this.transactionItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionItems(SortedSet<TransactionItem> transactionItems) {
|
||||||
|
if (this.transactionItems != null) {
|
||||||
|
this.transactionItems.forEach(i -> i.setTransaction(null));
|
||||||
|
}
|
||||||
|
if (transactionItems != null) {
|
||||||
|
transactionItems.forEach(i -> i.setTransaction(this));
|
||||||
|
}
|
||||||
|
this.transactionItems = transactionItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction transactionItems(SortedSet<TransactionItem> transactionItems) {
|
||||||
|
this.setTransactionItems(transactionItems);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction addTransactionItem(TransactionItem transactionItem) {
|
||||||
|
this.transactionItems.add(transactionItem);
|
||||||
|
transactionItem.setTransaction(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction removeTransactionItem(TransactionItem transactionItem) {
|
||||||
|
this.transactionItems.remove(transactionItem);
|
||||||
|
transactionItem.setTransaction(null);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof Transaction)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getId() != null && getId().equals(((Transaction) o).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
// see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
|
||||||
|
return getClass().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Transaction{" +
|
||||||
|
"id=" + getId() +
|
||||||
|
", type='" + getType() + "'" +
|
||||||
|
", date='" + getDate() + "'" +
|
||||||
|
", comment='" + getComment() + "'" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SortedSet<TransactionItem> getEmptyTransactionItemSet() {
|
||||||
|
return new TreeSet<>(new TransactionItemComparator());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package com.sasiedzi.event.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.sasiedzi.event.domain.enumeration.TransactionType;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
//@Data
|
||||||
|
//@Builder
|
||||||
|
public class TransactionDTO implements Serializable {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private TransactionType type;
|
||||||
|
|
||||||
|
private LocalDate date;
|
||||||
|
|
||||||
|
private String comment;
|
||||||
|
|
||||||
|
private Event event;
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(value = { "transaction", "event" }, allowSetters = true)
|
||||||
|
private List<TransactionItem> items = new ArrayList<>();
|
||||||
|
|
||||||
|
public TransactionDTO(Long id, TransactionType type, LocalDate date, String comment, Event event) {
|
||||||
|
this.id = id;
|
||||||
|
this.type = type;
|
||||||
|
this.date = date;
|
||||||
|
this.comment = comment;
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(TransactionType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(LocalDate date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComment() {
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComment(String comment) {
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Event getEvent() {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEvent(Event event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TransactionItem> getItems() {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItems(List<TransactionItem> items) {
|
||||||
|
this.items = items;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
package com.sasiedzi.event.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A TransactionItem.
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "transaction_item")
|
||||||
|
@SuppressWarnings("common-java:DuplicatedBlocks")
|
||||||
|
public class TransactionItem implements Serializable, Comparable<TransactionItem> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
||||||
|
@SequenceGenerator(name = "sequenceGenerator")
|
||||||
|
@Column(name = "id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "amount", precision = 21, scale = 2)
|
||||||
|
private BigDecimal amount;
|
||||||
|
|
||||||
|
@Column(name = "comment")
|
||||||
|
private String comment;
|
||||||
|
|
||||||
|
@Column(name = "locked")
|
||||||
|
private Boolean locked;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JsonIgnoreProperties(value = { "users", "transactionItems" }, allowSetters = true)
|
||||||
|
private UserAccount userAccount;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JsonIgnoreProperties(value = { "event", "transactionItems" }, allowSetters = true)
|
||||||
|
private Transaction transaction;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JsonIgnoreProperties(value = { "registrations", "transactions" }, allowSetters = true)
|
||||||
|
private Event event;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JsonIgnoreProperties(value = { "user", "event", "transactionItems" }, allowSetters = true)
|
||||||
|
private Registration registration;
|
||||||
|
|
||||||
|
// jhipster-needle-entity-add-field - JHipster will add fields here
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionItem id(Long id) {
|
||||||
|
this.setId(id);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getAmount() {
|
||||||
|
return this.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionItem amount(BigDecimal amount) {
|
||||||
|
this.setAmount(amount);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(BigDecimal amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComment() {
|
||||||
|
return this.comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionItem comment(String comment) {
|
||||||
|
this.setComment(comment);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComment(String comment) {
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getLocked() {
|
||||||
|
return this.locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionItem locked(Boolean locked) {
|
||||||
|
this.setLocked(locked);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocked(Boolean locked) {
|
||||||
|
this.locked = locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount getUserAccount() {
|
||||||
|
return this.userAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserAccount(UserAccount userAccount) {
|
||||||
|
this.userAccount = userAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionItem userAccount(UserAccount userAccount) {
|
||||||
|
this.setUserAccount(userAccount);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction getTransaction() {
|
||||||
|
return this.transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransaction(Transaction transaction) {
|
||||||
|
this.transaction = transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionItem transaction(Transaction transaction) {
|
||||||
|
this.setTransaction(transaction);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Event getEvent() {
|
||||||
|
return this.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEvent(Event event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionItem event(Event event) {
|
||||||
|
this.setEvent(event);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Registration getRegistration() {
|
||||||
|
return this.registration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRegistration(Registration registration) {
|
||||||
|
this.registration = registration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionItem registration(Registration registration) {
|
||||||
|
this.setRegistration(registration);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof TransactionItem)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getId() != null && getId().equals(((TransactionItem) o).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
// see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
|
||||||
|
return getClass().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TransactionItem{" +
|
||||||
|
"id=" + getId() +
|
||||||
|
", amount=" + getAmount() +
|
||||||
|
", comment='" + getComment() + "'" +
|
||||||
|
", locked='" + getLocked() + "'" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(TransactionItem o) {
|
||||||
|
return TransactionItemComparator.compare2(this, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.sasiedzi.event.domain;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class TransactionItemComparator implements Comparator<TransactionItem> {
|
||||||
|
|
||||||
|
private static final UserAccountComparator userAccountComparator = new UserAccountComparator();
|
||||||
|
|
||||||
|
public static int compare2(TransactionItem item1, TransactionItem item2) {
|
||||||
|
// Sprawdzamy, czy którykolwiek z obiektów jest null
|
||||||
|
if (item1 == null && item2 == null) return 0;
|
||||||
|
if (item1 == null) return -1;
|
||||||
|
if (item2 == null) return 1;
|
||||||
|
if (item1.getId() == null && item2.getId() == null) return -1;
|
||||||
|
if (Objects.equals(item1.getId(), item2.getId())) return 0;
|
||||||
|
|
||||||
|
// Teraz porównujemy pola userAccount
|
||||||
|
return compareUserAccounts(item1.getUserAccount(), item2.getUserAccount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(TransactionItem item1, TransactionItem item2) {
|
||||||
|
return compare2(item1, item2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int compareUserAccounts(UserAccount ua1, UserAccount ua2) {
|
||||||
|
// Używamy naszego komparatora UserAccount
|
||||||
|
int compare = userAccountComparator.compare(ua1, ua2);
|
||||||
|
if (compare == 0) {
|
||||||
|
// Porównanie id, uwzględniając null
|
||||||
|
if (ua1.getId() == null && ua2.getId() == null) {
|
||||||
|
return -1; // Jeśli oba id są null, to nie są równe, ale nie wiemy jak je uporządkować, więc zwracamy -1 (lub 1, zależnie od preferencji)
|
||||||
|
} else if (ua1.getId() == null) {
|
||||||
|
return -1; // Pusty ID jest "mniejszy" niż niepusty
|
||||||
|
} else if (ua2.getId() == null) {
|
||||||
|
return 1; // Pusty ID jest "mniejszy" niż niepusty
|
||||||
|
} else {
|
||||||
|
// Oba ID nie są null, więc porównujemy je normalnie
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -170,4 +170,20 @@ public class User extends AbstractAuditingEntity<String> implements Serializable
|
|||||||
", langKey='" + langKey + '\'' +
|
", langKey='" + langKey + '\'' +
|
||||||
"}";
|
"}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
public String getName() {
|
||||||
|
String out = "";
|
||||||
|
if (firstName != null) {
|
||||||
|
out = firstName;
|
||||||
|
}
|
||||||
|
if (lastName != null) {
|
||||||
|
out = (out + " " + lastName).trim();
|
||||||
|
}
|
||||||
|
if (out.isEmpty()) {
|
||||||
|
return login;
|
||||||
|
} else {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,165 @@
|
|||||||
|
package com.sasiedzi.event.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A UserAccount.
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "user_account")
|
||||||
|
@SuppressWarnings("common-java:DuplicatedBlocks")
|
||||||
|
public class UserAccount implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
||||||
|
@SequenceGenerator(name = "sequenceGenerator")
|
||||||
|
@Column(name = "id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.EAGER)
|
||||||
|
@JoinTable(
|
||||||
|
name = "rel_user_account__user",
|
||||||
|
joinColumns = @JoinColumn(name = "user_account_id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "user_id")
|
||||||
|
)
|
||||||
|
private Set<User> users = new HashSet<>();
|
||||||
|
|
||||||
|
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userAccount")
|
||||||
|
@JsonIgnoreProperties(value = { "userAccount", "transaction", "event", "registration" }, allowSetters = true)
|
||||||
|
private Set<TransactionItem> transactionItems = new HashSet<>();
|
||||||
|
|
||||||
|
// jhipster-needle-entity-add-field - JHipster will add fields here
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
// @JsonSerialize
|
||||||
|
BigDecimal balance = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
@JsonProperty("balance")
|
||||||
|
public BigDecimal getBalance() {
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount id(Long id) {
|
||||||
|
this.setId(id);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount name(String name) {
|
||||||
|
this.setName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<User> getUsers() {
|
||||||
|
return this.users;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsers(Set<User> users) {
|
||||||
|
this.users = users;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount users(Set<User> users) {
|
||||||
|
this.setUsers(users);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount addUser(User user) {
|
||||||
|
this.users.add(user);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount removeUser(User user) {
|
||||||
|
this.users.remove(user);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBalance(BigDecimal balance) {
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<TransactionItem> getTransactionItems() {
|
||||||
|
return this.transactionItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionItems(Set<TransactionItem> transactionItems) {
|
||||||
|
if (this.transactionItems != null) {
|
||||||
|
this.transactionItems.forEach(i -> i.setUserAccount(null));
|
||||||
|
}
|
||||||
|
if (transactionItems != null) {
|
||||||
|
transactionItems.forEach(i -> i.setUserAccount(this));
|
||||||
|
}
|
||||||
|
this.transactionItems = transactionItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount transactionItems(Set<TransactionItem> transactionItems) {
|
||||||
|
this.setTransactionItems(transactionItems);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount addTransactionItem(TransactionItem transactionItem) {
|
||||||
|
this.transactionItems.add(transactionItem);
|
||||||
|
transactionItem.setUserAccount(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount removeTransactionItem(TransactionItem transactionItem) {
|
||||||
|
this.transactionItems.remove(transactionItem);
|
||||||
|
transactionItem.setUserAccount(null);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof UserAccount)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getId() != null && getId().equals(((UserAccount) o).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
// see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
|
||||||
|
return getClass().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "UserAccount{" +
|
||||||
|
"id=" + getId() +
|
||||||
|
", name='" + getName() + "'" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.sasiedzi.event.domain;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.service.Account;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class UserAccountComparator implements Comparator<UserAccount> {
|
||||||
|
|
||||||
|
String[] specialAccounts;
|
||||||
|
|
||||||
|
public UserAccountComparator() {
|
||||||
|
ArrayList<String> specialAccountList = new ArrayList<String>();
|
||||||
|
specialAccountList.addAll(Arrays.stream(Account.values()).map(Enum::toString).toList());
|
||||||
|
specialAccountList.add("Tomasz Taraszewski");
|
||||||
|
this.specialAccounts = specialAccountList.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(UserAccount ua1, UserAccount ua2) {
|
||||||
|
// Sprawdzamy, czy obiekty nie są null
|
||||||
|
if (ua1 == null && ua2 == null) return 0;
|
||||||
|
if (ua1 == null) return -1;
|
||||||
|
if (ua2 == null) return 1;
|
||||||
|
if (ua1.getId() == null && ua2.getId() == null) return -1;
|
||||||
|
if (Objects.equals(ua1.getId(), ua2.getId())) return 0;
|
||||||
|
|
||||||
|
String name1 = ua1.getName();
|
||||||
|
String name2 = ua2.getName();
|
||||||
|
|
||||||
|
// Sprawdzamy, czy oba są null
|
||||||
|
if (name1 == null && name2 == null) return 0;
|
||||||
|
if (name1 == null) return -1;
|
||||||
|
if (name2 == null) return 1;
|
||||||
|
|
||||||
|
// Najpierw sprawdzamy, czy nazwy znajdują się w liście specjalnych nazw
|
||||||
|
int index1 = findSpecialNameIndex(name1);
|
||||||
|
int index2 = findSpecialNameIndex(name2);
|
||||||
|
|
||||||
|
// Jeśli obie nazwy są specjalne, porównujemy ich indeksy
|
||||||
|
if (index1 != -1 && index2 != -1) {
|
||||||
|
return Integer.compare(index1, index2);
|
||||||
|
}
|
||||||
|
// Jeśli tylko jedna nazwa jest specjalna, ona jest "mniejsza"
|
||||||
|
if (index1 != -1) return -1;
|
||||||
|
if (index2 != -1) return 1;
|
||||||
|
|
||||||
|
// Jeśli żadna z nazw nie jest specjalna, porównujemy alfabetycznie
|
||||||
|
return name1.compareTo(name2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findSpecialNameIndex(String name) {
|
||||||
|
for (int i = 0; i < specialAccounts.length; i++) {
|
||||||
|
if (specialAccounts[i].equalsIgnoreCase(name)) {
|
||||||
|
return i; // Zwracamy indeks specjalnej nazwy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1; // Nazwa nie jest specjalna
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.sasiedzi.event.domain.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The TransactionType enumeration.
|
||||||
|
*/
|
||||||
|
public enum TransactionType {
|
||||||
|
PURCHASE,
|
||||||
|
MATCH,
|
||||||
|
FIELDPAYMENT,
|
||||||
|
INTERNALTRANSFER,
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
package com.sasiedzi.event.repository;
|
package com.sasiedzi.event.repository;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.Charge;
|
||||||
import com.sasiedzi.event.domain.Event;
|
import com.sasiedzi.event.domain.Event;
|
||||||
|
import java.util.List;
|
||||||
import org.springframework.data.jpa.repository.*;
|
import org.springframework.data.jpa.repository.*;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,4 +12,7 @@ import org.springframework.stereotype.Repository;
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Repository
|
@Repository
|
||||||
public interface EventRepository extends JpaRepository<Event, Long> {}
|
public interface EventRepository extends JpaRepository<Event, Long> {
|
||||||
|
@Query("select event from Event event left join fetch event.transactions where event.id =:id")
|
||||||
|
Event findByIdWithTransactions(@Param("id") Long id);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.sasiedzi.event.repository;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.TransactionItem;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.*;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Data JPA repository for the TransactionItem entity.
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface TransactionItemRepository extends JpaRepository<TransactionItem, Long> {
|
||||||
|
default Optional<TransactionItem> findOneWithEagerRelationships(Long id) {
|
||||||
|
return this.findOneWithToOneRelationships(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<TransactionItem> findAllWithEagerRelationships() {
|
||||||
|
return this.findAllWithToOneRelationships();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Page<TransactionItem> findAllWithEagerRelationships(Pageable pageable) {
|
||||||
|
return this.findAllWithToOneRelationships(pageable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
value = "select transactionItem from TransactionItem transactionItem left join fetch transactionItem.event left join fetch transactionItem.registration",
|
||||||
|
countQuery = "select count(transactionItem) from TransactionItem transactionItem"
|
||||||
|
)
|
||||||
|
Page<TransactionItem> findAllWithToOneRelationships(Pageable pageable);
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"select transactionItem from TransactionItem transactionItem left join fetch transactionItem.event left join fetch transactionItem.registration"
|
||||||
|
)
|
||||||
|
List<TransactionItem> findAllWithToOneRelationships();
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"select transactionItem from TransactionItem transactionItem left join fetch transactionItem.event left join fetch transactionItem.registration where transactionItem.id =:id"
|
||||||
|
)
|
||||||
|
Optional<TransactionItem> findOneWithToOneRelationships(@Param("id") Long id);
|
||||||
|
|
||||||
|
@Query("select transactionItem from TransactionItem transactionItem where transactionItem.userAccount.id =:accountId")
|
||||||
|
List<TransactionItem> getTransactionItemsForAccountId(@Param("accountId") Long accountId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.sasiedzi.event.repository;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.Transaction;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.*;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Data JPA repository for the Transaction entity.
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface TransactionRepository extends JpaRepository<Transaction, Long> {
|
||||||
|
default Optional<Transaction> findOneWithEagerRelationships(Long id) {
|
||||||
|
return this.findOneWithToOneRelationships(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<Transaction> findAllWithEagerRelationships() {
|
||||||
|
return this.findAllWithToOneRelationships();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Page<Transaction> findAllWithEagerRelationships(Pageable pageable) {
|
||||||
|
return this.findAllWithToOneRelationships(pageable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
value = "select transaction from Transaction transaction left join fetch transaction.event",
|
||||||
|
countQuery = "select count(transaction) from Transaction transaction"
|
||||||
|
)
|
||||||
|
Page<Transaction> findAllWithToOneRelationships(Pageable pageable);
|
||||||
|
|
||||||
|
@Query("select transaction from Transaction transaction left join fetch transaction.event")
|
||||||
|
List<Transaction> findAllWithToOneRelationships();
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"select transaction from Transaction transaction left join fetch transaction.event left join fetch transaction.transactionItems where transaction.id =:id"
|
||||||
|
)
|
||||||
|
Optional<Transaction> findOneWithToOneRelationships(@Param("id") Long id);
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"select transaction from Transaction transaction left join fetch transaction.transactionItems where transaction.event.id =:eventId"
|
||||||
|
)
|
||||||
|
List<Transaction> findAllByEventId(Long eventId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.sasiedzi.event.repository;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.Charge;
|
||||||
|
import com.sasiedzi.event.domain.UserAccount;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.*;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Data JPA repository for the UserAccount entity.
|
||||||
|
*
|
||||||
|
* When extending this class, extend UserAccountRepositoryWithBagRelationships too.
|
||||||
|
* For more information refer to https://github.com/jhipster/generator-jhipster/issues/17990.
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface UserAccountRepository extends UserAccountRepositoryWithBagRelationships, JpaRepository<UserAccount, Long> {
|
||||||
|
default Optional<UserAccount> findOneWithEagerRelationships(Long id) {
|
||||||
|
return this.fetchBagRelationships(this.findById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<UserAccount> findAllWithEagerRelationships() {
|
||||||
|
return this.fetchBagRelationships(this.findAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
default Page<UserAccount> findAllWithEagerRelationships(Pageable pageable) {
|
||||||
|
return this.fetchBagRelationships(this.findAll(pageable));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query("select userAccount from UserAccount userAccount join fetch userAccount.users")
|
||||||
|
// List<UserAccount> findByUserLogin(String login);
|
||||||
|
List<UserAccount> findAllFetchAccounts();
|
||||||
|
|
||||||
|
List<UserAccount> findByName(String name);
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package com.sasiedzi.event.repository;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.UserAccount;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
|
public interface UserAccountRepositoryWithBagRelationships {
|
||||||
|
Optional<UserAccount> fetchBagRelationships(Optional<UserAccount> userAccount);
|
||||||
|
|
||||||
|
List<UserAccount> fetchBagRelationships(List<UserAccount> userAccounts);
|
||||||
|
|
||||||
|
Page<UserAccount> fetchBagRelationships(Page<UserAccount> userAccounts);
|
||||||
|
}
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
package com.sasiedzi.event.repository;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.UserAccount;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.PersistenceContext;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility repository to load bag relationships based on https://vladmihalcea.com/hibernate-multiplebagfetchexception/
|
||||||
|
*/
|
||||||
|
public class UserAccountRepositoryWithBagRelationshipsImpl implements UserAccountRepositoryWithBagRelationships {
|
||||||
|
|
||||||
|
private static final String ID_PARAMETER = "id";
|
||||||
|
private static final String USERACCOUNTS_PARAMETER = "userAccounts";
|
||||||
|
|
||||||
|
@PersistenceContext
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<UserAccount> fetchBagRelationships(Optional<UserAccount> userAccount) {
|
||||||
|
return userAccount.map(this::fetchUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<UserAccount> fetchBagRelationships(Page<UserAccount> userAccounts) {
|
||||||
|
return new PageImpl<>(
|
||||||
|
fetchBagRelationships(userAccounts.getContent()),
|
||||||
|
userAccounts.getPageable(),
|
||||||
|
userAccounts.getTotalElements()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserAccount> fetchBagRelationships(List<UserAccount> userAccounts) {
|
||||||
|
return Optional.of(userAccounts).map(this::fetchUsers).orElse(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
UserAccount fetchUsers(UserAccount result) {
|
||||||
|
return entityManager
|
||||||
|
.createQuery(
|
||||||
|
"select userAccount from UserAccount userAccount left join fetch userAccount.users where userAccount.id = :id",
|
||||||
|
UserAccount.class
|
||||||
|
)
|
||||||
|
.setParameter(ID_PARAMETER, result.getId())
|
||||||
|
.getSingleResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UserAccount> fetchUsers(List<UserAccount> userAccounts) {
|
||||||
|
HashMap<Object, Integer> order = new HashMap<>();
|
||||||
|
IntStream.range(0, userAccounts.size()).forEach(index -> order.put(userAccounts.get(index).getId(), index));
|
||||||
|
List<UserAccount> result = entityManager
|
||||||
|
.createQuery(
|
||||||
|
"select userAccount from UserAccount userAccount left join fetch userAccount.users where userAccount in :userAccounts",
|
||||||
|
UserAccount.class
|
||||||
|
)
|
||||||
|
.setParameter(USERACCOUNTS_PARAMETER, userAccounts)
|
||||||
|
.getResultList();
|
||||||
|
Collections.sort(result, (o1, o2) -> Integer.compare(order.get(o1.getId()), order.get(o2.getId())));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,8 @@ public final class AuthoritiesConstants {
|
|||||||
|
|
||||||
public static final String USER = "ROLE_USER";
|
public static final String USER = "ROLE_USER";
|
||||||
|
|
||||||
|
public static final String COUNTER = "ROLE_COUNTER";
|
||||||
|
|
||||||
public static final String ANONYMOUS = "ROLE_ANONYMOUS";
|
public static final String ANONYMOUS = "ROLE_ANONYMOUS";
|
||||||
|
|
||||||
private AuthoritiesConstants() {}
|
private AuthoritiesConstants() {}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.sasiedzi.event.service;
|
||||||
|
|
||||||
|
public enum Account {
|
||||||
|
Boisko,
|
||||||
|
Skarbiec,
|
||||||
|
Counter {
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Subkonto Tomka";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,11 +1,26 @@
|
|||||||
package com.sasiedzi.event.service;
|
package com.sasiedzi.event.service;
|
||||||
|
|
||||||
import com.sasiedzi.event.domain.Event;
|
import com.sasiedzi.event.domain.*;
|
||||||
import com.sasiedzi.event.repository.EventRepository;
|
import com.sasiedzi.event.domain.enumeration.TransactionType;
|
||||||
import java.util.List;
|
import com.sasiedzi.event.repository.*;
|
||||||
import java.util.Optional;
|
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
||||||
|
import com.sasiedzi.event.web.rest.AccountResource;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.RememberMeAuthenticationToken;
|
||||||
|
import org.springframework.security.core.AuthenticatedPrincipal;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -20,6 +35,15 @@ public class EventService {
|
|||||||
|
|
||||||
private final EventRepository eventRepository;
|
private final EventRepository eventRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AccountResource accountResource;
|
||||||
|
|
||||||
public EventService(EventRepository eventRepository) {
|
public EventService(EventRepository eventRepository) {
|
||||||
this.eventRepository = eventRepository;
|
this.eventRepository = eventRepository;
|
||||||
}
|
}
|
||||||
@@ -102,6 +126,25 @@ public class EventService {
|
|||||||
return eventRepository.findById(id);
|
return eventRepository.findById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Event getEventForRegistration(Long id) {
|
||||||
|
LOG.debug("Request to get Event : {}", id);
|
||||||
|
Event event = eventRepository.findByIdWithTransactions(id);
|
||||||
|
event.setCurrent(id.equals(getCurrentEventId()));
|
||||||
|
event.setPaid(event.getTransactions().stream().anyMatch(t -> TransactionType.FIELDPAYMENT.equals(t.getType())));
|
||||||
|
event.setCharged(event.getTransactions().stream().anyMatch(t -> TransactionType.MATCH.equals(t.getType())));
|
||||||
|
event.setChargeTransactionId(
|
||||||
|
event
|
||||||
|
.getTransactions()
|
||||||
|
.stream()
|
||||||
|
.filter(t -> TransactionType.MATCH.equals(t.getType()))
|
||||||
|
.map(Transaction::getId)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null)
|
||||||
|
);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the event by id.
|
* Delete the event by id.
|
||||||
*
|
*
|
||||||
@@ -111,4 +154,220 @@ public class EventService {
|
|||||||
LOG.debug("Request to delete Event : {}", id);
|
LOG.debug("Request to delete Event : {}", id);
|
||||||
eventRepository.deleteById(id);
|
eventRepository.deleteById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
TransactionRepository transactionRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserAccountRepository userAccountRepository;
|
||||||
|
|
||||||
|
public Optional<Event> settle(@Valid Event eventFromUI) {
|
||||||
|
Event event = eventRepository.getReferenceById(eventFromUI.getId());
|
||||||
|
Long eventId = event.getId();
|
||||||
|
List<Transaction> allTransactions = transactionRepository
|
||||||
|
.findAllByEventId(eventId)
|
||||||
|
.stream()
|
||||||
|
.filter(transaction -> TransactionType.MATCH.equals(transaction.getType()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Transaction transaction;
|
||||||
|
if (allTransactions.isEmpty()) {
|
||||||
|
transaction = new Transaction();
|
||||||
|
transaction.setEvent(event);
|
||||||
|
transaction.setType(TransactionType.MATCH);
|
||||||
|
transaction.setDate(LocalDate.now());
|
||||||
|
transaction.setTransactionItems(Transaction.getEmptyTransactionItemSet());
|
||||||
|
transactionRepository.save(transaction);
|
||||||
|
} else {
|
||||||
|
transaction = allTransactions.get(0);
|
||||||
|
if (transaction.getTransactionItems().isEmpty()) {
|
||||||
|
// transaction.setTransactionItems(new HashSet<>());
|
||||||
|
}
|
||||||
|
transaction.getTransactionItems().clear();
|
||||||
|
transactionRepository.save(transaction);
|
||||||
|
}
|
||||||
|
if (event.getRegistrations() != null && !event.getRegistrations().isEmpty()) {
|
||||||
|
List<UserAccount> accounts = userAccountRepository.findAll();
|
||||||
|
Map<String, UserAccount> accountsByLogin = new HashMap<>();
|
||||||
|
accounts.forEach(acc -> {
|
||||||
|
acc
|
||||||
|
.getUsers()
|
||||||
|
.forEach(user -> {
|
||||||
|
accountsByLogin.put(user.getLogin(), acc);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Map<String, UserAccount> accountsByAccountName = accounts
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(UserAccount::getName, Function.identity(), (existing, replacement) -> existing));
|
||||||
|
if (!accountsByAccountName.containsKey(Account.Boisko.name())) {
|
||||||
|
UserAccount entity = new UserAccount();
|
||||||
|
entity.setName(Account.Boisko.name());
|
||||||
|
entity = userAccountRepository.save(entity);
|
||||||
|
accountsByAccountName.put(Account.Boisko.name(), entity);
|
||||||
|
}
|
||||||
|
if (!accountsByAccountName.containsKey(Account.Skarbiec.name())) {
|
||||||
|
UserAccount entity = new UserAccount();
|
||||||
|
entity.setName(Account.Skarbiec.name());
|
||||||
|
entity = userAccountRepository.save(entity);
|
||||||
|
accountsByAccountName.put(Account.Skarbiec.name(), entity);
|
||||||
|
}
|
||||||
|
List<TransactionItem> itemsToCharge = new ArrayList<>();
|
||||||
|
List<Registration> registrationsToCharge = event
|
||||||
|
.getRegistrations()
|
||||||
|
.stream()
|
||||||
|
.filter(registration -> !Boolean.FALSE.equals(registration.getActive()))
|
||||||
|
.sorted(Comparator.comparing(Registration::getDateTime))
|
||||||
|
.limit(event.getPlayersLimit() == null ? 10000 : event.getPlayersLimit()) // Ograniczamy do pierwszych n elementów
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
registrationsToCharge.forEach(registration -> {
|
||||||
|
String login = registration.getUser().getLogin();
|
||||||
|
UserAccount userAccount = accountsByLogin.get(login);
|
||||||
|
if (userAccount == null) {
|
||||||
|
userAccount = createNewAccountForLogin(login);
|
||||||
|
accountsByLogin.put(login, userAccount);
|
||||||
|
}
|
||||||
|
TransactionItem transactionForPlayer = new TransactionItem();
|
||||||
|
transactionForPlayer.setRegistration(registration);
|
||||||
|
transactionForPlayer.setUserAccount(userAccount);
|
||||||
|
itemsToCharge.add(transactionForPlayer);
|
||||||
|
});
|
||||||
|
TransactionItem fieldServiceItem = new TransactionItem();
|
||||||
|
fieldServiceItem.setEvent(event);
|
||||||
|
fieldServiceItem.setAmount(new BigDecimal(375));
|
||||||
|
fieldServiceItem.setUserAccount(accountsByAccountName.get(Account.Boisko.name()));
|
||||||
|
fieldServiceItem.setTransaction(transaction);
|
||||||
|
transaction.getTransactionItems().add(fieldServiceItem);
|
||||||
|
itemsToCharge.forEach(transactionForPlayer -> {
|
||||||
|
transactionForPlayer.setEvent(event);
|
||||||
|
transactionForPlayer.setAmount(event.getCost().divide(BigDecimal.valueOf(-itemsToCharge.size()), 2, RoundingMode.HALF_UP));
|
||||||
|
transactionForPlayer.setTransaction(transaction);
|
||||||
|
transaction.getTransactionItems().add(transactionForPlayer);
|
||||||
|
});
|
||||||
|
BigDecimal vaultValue = transaction
|
||||||
|
.getTransactionItems()
|
||||||
|
.stream()
|
||||||
|
.map(TransactionItem::getAmount)
|
||||||
|
.map(BigDecimal::negate)
|
||||||
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
if (vaultValue.compareTo(BigDecimal.ZERO) != 0) {
|
||||||
|
TransactionItem vaultItem = new TransactionItem();
|
||||||
|
vaultItem.setEvent(event);
|
||||||
|
vaultItem.setAmount(vaultValue);
|
||||||
|
vaultItem.setUserAccount(accountsByAccountName.get(Account.Skarbiec.name()));
|
||||||
|
vaultItem.setTransaction(transaction);
|
||||||
|
transaction.getTransactionItems().add(vaultItem);
|
||||||
|
}
|
||||||
|
transactionRepository.save(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventRepository.findById(event.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AdminUserDTO currentUser;
|
||||||
|
|
||||||
|
// public String getCurrentAuthenticatedUserAsDTO() {
|
||||||
|
// if (SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// if (SecurityContextHolder.getContext() == null) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
|
// if (principal instanceof AuthenticatedPrincipal) {
|
||||||
|
// return extractUsername((AuthenticatedPrincipal) principal).getName();
|
||||||
|
// // return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal);
|
||||||
|
// } else if (principal instanceof UserDetails) {
|
||||||
|
// return asdf((UserDetails) principal).getUsername();
|
||||||
|
// // return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal);
|
||||||
|
// } else {
|
||||||
|
// throw new RuntimeException("User could not be found");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
private static String extractUsername(String input) {
|
||||||
|
Pattern pattern = Pattern.compile("Name:\\s+\\[([^]]+)]");
|
||||||
|
Matcher matcher = pattern.matcher(input);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount createNewAccountForLogin(String login) {
|
||||||
|
UserAccount entity = new UserAccount();
|
||||||
|
Optional<User> oneByLogin = userRepository.findOneByLogin(login);
|
||||||
|
if (oneByLogin.isPresent()) {
|
||||||
|
entity.setName(oneByLogin.get().getName());
|
||||||
|
entity.getUsers().add(oneByLogin.get());
|
||||||
|
entity = userAccountRepository.save(entity);
|
||||||
|
return entity;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("user not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount getOrCreateUserAccountForLogin(String username) {
|
||||||
|
if (username != null) {
|
||||||
|
// List<UserAccount> userAccounts = userAccountRepository.findByUserLogin(currentAuthenticatedUserAsDTO.getLogin());
|
||||||
|
List<UserAccount> userAccounts = userAccountRepository
|
||||||
|
.findAllFetchAccounts()
|
||||||
|
.stream()
|
||||||
|
.filter(accountResource -> {
|
||||||
|
return accountResource.getUsers().stream().anyMatch(user -> user.getLogin().equals(username));
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
if (userAccounts.isEmpty()) {
|
||||||
|
return createNewAccountForLogin(username);
|
||||||
|
} else {
|
||||||
|
UserAccount userAccount = userAccounts.get(0);
|
||||||
|
List<TransactionItem> transactionItemsForAccountId = transactionItemRepository.getTransactionItemsForAccountId(
|
||||||
|
userAccount.getId()
|
||||||
|
);
|
||||||
|
|
||||||
|
BigDecimal totalBalance = transactionItemsForAccountId
|
||||||
|
.stream()
|
||||||
|
.map(TransactionItem::getAmount)
|
||||||
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
|
||||||
|
userAccount.setBalance(totalBalance);
|
||||||
|
|
||||||
|
return userAccount;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UserAccount userAccount = new UserAccount();
|
||||||
|
userAccount.setName("Unauthenticated User");
|
||||||
|
return userAccount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCurrentEventId() {
|
||||||
|
List<Event> allEvents = eventRepository.findAll();
|
||||||
|
Event currentEvent = allEvents
|
||||||
|
.stream()
|
||||||
|
.filter(event -> event.getDate() != null && event.getDate().isAfter(LocalDate.now()))
|
||||||
|
.min(Comparator.comparing(Event::getDate))
|
||||||
|
.orElse(null);
|
||||||
|
if (currentEvent == null) {
|
||||||
|
Event latestEvent = allEvents
|
||||||
|
.stream()
|
||||||
|
.filter(event -> event.getDate() != null)
|
||||||
|
.max(Comparator.comparing(Event::getDate))
|
||||||
|
.orElse(null);
|
||||||
|
if (latestEvent != null) {
|
||||||
|
return latestEvent.getId();
|
||||||
|
} else {
|
||||||
|
return -1L;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return currentEvent.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
TransactionItemRepository transactionItemRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
RegistrationRepository registrationRepository;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,255 @@
|
|||||||
|
package com.sasiedzi.event.service;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.*;
|
||||||
|
import com.sasiedzi.event.domain.enumeration.TransactionType;
|
||||||
|
import com.sasiedzi.event.repository.TransactionItemRepository;
|
||||||
|
import com.sasiedzi.event.repository.TransactionRepository;
|
||||||
|
import com.sasiedzi.event.repository.UserAccountRepository;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional
|
||||||
|
public class TransactionService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
TransactionRepository transactionRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserAccountRepository userAccountRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TransactionItemRepository transactionItemRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventService eventService;
|
||||||
|
|
||||||
|
public Transaction save(Transaction transaction) {
|
||||||
|
SortedSet<TransactionItem> items = transaction.getTransactionItems();
|
||||||
|
String beneficiaryAccountName = transaction.getBeneficiary() == null
|
||||||
|
? Account.Skarbiec.toString()
|
||||||
|
: transaction.getBeneficiary().getName();
|
||||||
|
Set<TransactionItem> beneficiaryItems = items
|
||||||
|
.stream()
|
||||||
|
.filter(item -> beneficiaryAccountName.equals(item.getUserAccount().getName()))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
Set<TransactionItem> nonBeneficiaryItems = items
|
||||||
|
.stream()
|
||||||
|
.filter(item -> !beneficiaryAccountName.equals(item.getUserAccount().getName()))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
BigDecimal beneficiaryValue = nonBeneficiaryItems
|
||||||
|
.stream()
|
||||||
|
.map(TransactionItem::getAmount)
|
||||||
|
.map(BigDecimal::negate)
|
||||||
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
|
||||||
|
boolean beneficiaryItemIsNeeded = beneficiaryValue.compareTo(BigDecimal.ZERO) != 0;
|
||||||
|
|
||||||
|
HashSet<TransactionItem> itemsToBeRemoved = new HashSet<>();
|
||||||
|
|
||||||
|
if (beneficiaryItemIsNeeded) {
|
||||||
|
if (beneficiaryItems.isEmpty()) {
|
||||||
|
TransactionItem transactionItem = new TransactionItem();
|
||||||
|
UserAccount beneficiaryAccount = userAccountRepository
|
||||||
|
.findAll()
|
||||||
|
.stream()
|
||||||
|
.filter(item -> beneficiaryAccountName.equals(item.getName()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
transactionItem.setUserAccount(beneficiaryAccount);
|
||||||
|
transactionItem.setAmount(beneficiaryValue);
|
||||||
|
transactionItem.setTransaction(transaction);
|
||||||
|
transaction.getTransactionItems().add(transactionItem);
|
||||||
|
} else {
|
||||||
|
TransactionItem first = null;
|
||||||
|
for (TransactionItem item : beneficiaryItems) {
|
||||||
|
if (first == null) {
|
||||||
|
first = item;
|
||||||
|
} else {
|
||||||
|
itemsToBeRemoved.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first.setAmount(beneficiaryValue);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
itemsToBeRemoved.addAll(beneficiaryItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsToBeRemoved.forEach(transactionItem -> {
|
||||||
|
transaction.getTransactionItems().remove(transactionItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (transaction.getDate() == null) transaction.setDate(LocalDate.now());
|
||||||
|
return transactionRepository.save(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction createOpposite(Long id) {
|
||||||
|
Transaction existing = transactionRepository.findOneWithEagerRelationships(id).orElseGet(Transaction::new);
|
||||||
|
Transaction newTransaction = new Transaction();
|
||||||
|
newTransaction.setType(TransactionType.INTERNALTRANSFER);
|
||||||
|
newTransaction.setEvent(existing.getEvent());
|
||||||
|
for (TransactionItem item : existing.getTransactionItems()) {
|
||||||
|
TransactionItem newItem = new TransactionItem();
|
||||||
|
newItem.setAmount(item.getAmount().negate());
|
||||||
|
newItem.setTransaction(newTransaction);
|
||||||
|
newItem.setUserAccount(item.getUserAccount());
|
||||||
|
newItem.setEvent(item.getEvent());
|
||||||
|
newItem.setRegistration(item.getRegistration());
|
||||||
|
newItem.setComment(item.getComment());
|
||||||
|
newTransaction.getTransactionItems().add(newItem);
|
||||||
|
}
|
||||||
|
return newTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction createPayments(Long id) {
|
||||||
|
Transaction existing = transactionRepository.findOneWithEagerRelationships(id).orElseGet(Transaction::new);
|
||||||
|
Transaction newTransaction = new Transaction();
|
||||||
|
newTransaction.setType(TransactionType.INTERNALTRANSFER);
|
||||||
|
setBeneficiary(newTransaction);
|
||||||
|
newTransaction.setEvent(existing.getEvent());
|
||||||
|
calculateBalances(existing.getTransactionItems().stream().map(TransactionItem::getUserAccount).toList());
|
||||||
|
Set<Long> processedAccounts = new HashSet<>();
|
||||||
|
for (TransactionItem item : existing.getTransactionItems()) {
|
||||||
|
BigDecimal accountBalance = item.getUserAccount().getBalance();
|
||||||
|
if (accountBalance == null) {
|
||||||
|
accountBalance = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
accountBalance.compareTo(BigDecimal.ZERO) < 0 &&
|
||||||
|
!Account.Skarbiec.toString().equals(item.getUserAccount().getName()) &&
|
||||||
|
!Account.Boisko.toString().equals(item.getUserAccount().getName()) &&
|
||||||
|
!Account.Counter.toString().equals(item.getUserAccount().getName()) &&
|
||||||
|
!processedAccounts.contains(item.getUserAccount().getId())
|
||||||
|
) {
|
||||||
|
TransactionItem newItem = new TransactionItem();
|
||||||
|
newItem.setAmount(accountBalance.negate());
|
||||||
|
newItem.setTransaction(newTransaction);
|
||||||
|
newItem.setUserAccount(item.getUserAccount());
|
||||||
|
newItem.setEvent(item.getEvent());
|
||||||
|
newItem.setRegistration(item.getRegistration());
|
||||||
|
newItem.setComment(item.getComment());
|
||||||
|
newTransaction.getTransactionItems().add(newItem);
|
||||||
|
processedAccounts.add(item.getUserAccount().getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction createFieldPayment(Long eventId) {
|
||||||
|
Transaction newTransaction = new Transaction();
|
||||||
|
newTransaction.setType(TransactionType.FIELDPAYMENT);
|
||||||
|
setBeneficiary(newTransaction);
|
||||||
|
Event event = null;
|
||||||
|
if (eventId != null) {
|
||||||
|
event = eventService.findOne(eventId).orElse(null);
|
||||||
|
newTransaction.setEvent(event);
|
||||||
|
}
|
||||||
|
TransactionItem newItem = new TransactionItem();
|
||||||
|
newItem.setAmount(new BigDecimal("375"));
|
||||||
|
newItem.setTransaction(newTransaction);
|
||||||
|
newItem.setUserAccount(getAccount(Account.Counter));
|
||||||
|
newItem.setEvent(event);
|
||||||
|
newTransaction.getTransactionItems().add(newItem);
|
||||||
|
return newTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateBalances(List<UserAccount> userAccounts) {
|
||||||
|
Map<Long, List<TransactionItem>> itemsByUserAccountId = transactionItemRepository
|
||||||
|
.findAll()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.groupingBy(item -> item.getUserAccount().getId()));
|
||||||
|
for (UserAccount userAccount : userAccounts) {
|
||||||
|
List<TransactionItem> itemsForAccount = itemsByUserAccountId.get(userAccount.getId());
|
||||||
|
BigDecimal balance = itemsForAccount.stream().map(TransactionItem::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
userAccount.setBalance(balance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction get(Long id) {
|
||||||
|
Transaction transaction = transactionRepository.findOneWithEagerRelationships(id).orElse(null);
|
||||||
|
setBeneficiary(transaction);
|
||||||
|
return transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBeneficiary(Transaction transaction) {
|
||||||
|
switch (transaction.getType()) {
|
||||||
|
case INTERNALTRANSFER -> {
|
||||||
|
transaction.setBeneficiary(getAccount(Account.Counter));
|
||||||
|
}
|
||||||
|
case MATCH, PURCHASE -> {
|
||||||
|
transaction.setBeneficiary(getAccount(Account.Skarbiec));
|
||||||
|
}
|
||||||
|
case FIELDPAYMENT -> {
|
||||||
|
transaction.setBeneficiary(getAccount(Account.Boisko));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount getAccount(Account account) {
|
||||||
|
return userAccountRepository.findByName(account.toString()).stream().min(Comparator.comparing(UserAccount::getId)).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TransactionDTO> getAllTransactions() {
|
||||||
|
// LOG.debug("REST request to get all Transactions");
|
||||||
|
// if (eagerload) {
|
||||||
|
// return transactionRepository.findAllWithEagerRelationships();
|
||||||
|
// } else {
|
||||||
|
// return transactionRepository.findAll();
|
||||||
|
// }
|
||||||
|
List<Transaction> all = transactionRepository.findAll();
|
||||||
|
Map<UserAccount, TransactionItem> accounts = new HashMap<>();
|
||||||
|
Map<Pair<UserAccount, Transaction>, BigDecimal> items = new LinkedHashMap<>();
|
||||||
|
all.forEach(transaction -> {
|
||||||
|
transaction
|
||||||
|
.getTransactionItems()
|
||||||
|
.forEach(transactionItem -> {
|
||||||
|
accounts.put(transactionItem.getUserAccount(), transactionItem);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
all.forEach(transaction -> {
|
||||||
|
transaction
|
||||||
|
.getTransactionItems()
|
||||||
|
.forEach(transactionItem -> {
|
||||||
|
items.put(
|
||||||
|
Pair.of(transactionItem.getUserAccount(), transaction),
|
||||||
|
add(items.get(Pair.of(transactionItem.getUserAccount(), transaction)), transactionItem.getAmount())
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
List<UserAccount> accountsSorted = accounts.keySet().stream().sorted(new UserAccountComparator()).toList();
|
||||||
|
|
||||||
|
List<TransactionDTO> out = new ArrayList<>();
|
||||||
|
for (Transaction transaction : all.stream().sorted(Comparator.comparing(Transaction::getDate)).toList()) {
|
||||||
|
TransactionDTO transactionDTO = new TransactionDTO(
|
||||||
|
transaction.getId(),
|
||||||
|
transaction.getType(),
|
||||||
|
transaction.getDate(),
|
||||||
|
transaction.getComment(),
|
||||||
|
transaction.getEvent()
|
||||||
|
);
|
||||||
|
for (UserAccount userAccount : accountsSorted) {
|
||||||
|
BigDecimal amount = items.get(Pair.of(userAccount, transaction));
|
||||||
|
|
||||||
|
TransactionItem item = new TransactionItem();
|
||||||
|
item.setUserAccount(userAccount);
|
||||||
|
transactionDTO.getItems().add(item);
|
||||||
|
item.setAmount(amount);
|
||||||
|
}
|
||||||
|
out.add(transactionDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal add(BigDecimal val, BigDecimal val2) {
|
||||||
|
if (val == null) return val2;
|
||||||
|
return val.add(val2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,14 +8,20 @@ import com.sasiedzi.event.repository.UserRepository;
|
|||||||
import com.sasiedzi.event.security.SecurityUtils;
|
import com.sasiedzi.event.security.SecurityUtils;
|
||||||
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
||||||
import com.sasiedzi.event.service.dto.UserDTO;
|
import com.sasiedzi.event.service.dto.UserDTO;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.RememberMeAuthenticationToken;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||||
@@ -129,6 +135,48 @@ public class UserService {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> extractUserAttributes(String input) {
|
||||||
|
Map<String, Object> attributes = new HashMap<>();
|
||||||
|
Pattern pattern = Pattern.compile("User Attributes:\\s+\\[\\{([^}]+)\\}\\]");
|
||||||
|
Matcher matcher = pattern.matcher(input);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String attributesString = matcher.group(1);
|
||||||
|
String[] attributePairs = attributesString.split(",\\s*");
|
||||||
|
for (String pair : attributePairs) {
|
||||||
|
String[] keyValue = pair.split("=");
|
||||||
|
if (keyValue.length == 2) {
|
||||||
|
String key = keyValue[0];
|
||||||
|
String value = keyValue[1];
|
||||||
|
|
||||||
|
// Konwersja wartości "true" i "false" na typ Boolean
|
||||||
|
if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)) {
|
||||||
|
attributes.put(key, Boolean.parseBoolean(value));
|
||||||
|
} else {
|
||||||
|
// Próba sparsowania jako Instant
|
||||||
|
try {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
|
||||||
|
Instant instant = Instant.from(formatter.parse(value));
|
||||||
|
attributes.put(key, instant);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Jeśli nie jest datą, zostawiamy jako String
|
||||||
|
attributes.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private static String extractUsername(String input) {
|
||||||
|
// Pattern pattern = Pattern.compile("Name:\\s+\\[([^]]+)]");
|
||||||
|
// Matcher matcher = pattern.matcher(input);
|
||||||
|
// if (matcher.find()) {
|
||||||
|
// return matcher.group(1);
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the user from an OAuth 2.0 login or resource server with JWT.
|
* Returns the user from an OAuth 2.0 login or resource server with JWT.
|
||||||
* Synchronizes the user in the local repository.
|
* Synchronizes the user in the local repository.
|
||||||
@@ -143,6 +191,10 @@ public class UserService {
|
|||||||
attributes = ((OAuth2AuthenticationToken) authToken).getPrincipal().getAttributes();
|
attributes = ((OAuth2AuthenticationToken) authToken).getPrincipal().getAttributes();
|
||||||
} else if (authToken instanceof JwtAuthenticationToken) {
|
} else if (authToken instanceof JwtAuthenticationToken) {
|
||||||
attributes = ((JwtAuthenticationToken) authToken).getTokenAttributes();
|
attributes = ((JwtAuthenticationToken) authToken).getTokenAttributes();
|
||||||
|
} else if (authToken instanceof RememberMeAuthenticationToken) {
|
||||||
|
attributes = extractUserAttributes(authToken.getName());
|
||||||
|
// attributes = new HashMap<>();
|
||||||
|
// attributes = ((RememberMeAuthenticationToken) authToken).getTokenAttributes();
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("AuthenticationToken is not OAuth2 or JWT!");
|
throw new IllegalArgumentException("AuthenticationToken is not OAuth2 or JWT!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ import java.io.Serializable;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.annotation.RequestScope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A DTO representing a user, with his authorities.
|
* A DTO representing a user, with his authorities.
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
|
@RequestScope
|
||||||
public class AdminUserDTO implements Serializable {
|
public class AdminUserDTO implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.sasiedzi.event.service.dto;
|
package com.sasiedzi.event.service.dto;
|
||||||
|
|
||||||
import com.sasiedzi.event.domain.User;
|
import com.sasiedzi.event.domain.User;
|
||||||
|
import jakarta.persistence.Transient;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.sasiedzi.event.web.rest;
|
package com.sasiedzi.event.web.rest;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.CurrentUserHolder;
|
||||||
import com.sasiedzi.event.service.UserService;
|
import com.sasiedzi.event.service.UserService;
|
||||||
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -44,13 +46,16 @@ public class AccountResource {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/account")
|
@GetMapping("/account")
|
||||||
public AdminUserDTO getAccount(Principal principal) {
|
public AdminUserDTO getAccount(Principal principal) {
|
||||||
if (principal instanceof AbstractAuthenticationToken) {
|
if (currentUser != null) {
|
||||||
return userService.getUserFromAuthentication((AbstractAuthenticationToken) principal);
|
return currentUser.getAdminUser();
|
||||||
} else {
|
} else {
|
||||||
throw new AccountResourceException("User could not be found");
|
throw new AccountResourceException("User could not be found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CurrentUserHolder currentUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code GET /authenticate} : check if the user is authenticated, and return its login.
|
* {@code GET /authenticate} : check if the user is authenticated, and return its login.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.sasiedzi.event.web.rest;
|
|||||||
|
|
||||||
import com.sasiedzi.event.domain.Charge;
|
import com.sasiedzi.event.domain.Charge;
|
||||||
import com.sasiedzi.event.repository.ChargeRepository;
|
import com.sasiedzi.event.repository.ChargeRepository;
|
||||||
|
import com.sasiedzi.event.security.AuthoritiesConstants;
|
||||||
import com.sasiedzi.event.web.rest.errors.BadRequestAlertException;
|
import com.sasiedzi.event.web.rest.errors.BadRequestAlertException;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
@@ -14,6 +15,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.annotation.Secured;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import tech.jhipster.web.util.HeaderUtil;
|
import tech.jhipster.web.util.HeaderUtil;
|
||||||
@@ -25,6 +27,7 @@ import tech.jhipster.web.util.ResponseUtil;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/charges")
|
@RequestMapping("/api/charges")
|
||||||
@Transactional
|
@Transactional
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN })
|
||||||
public class ChargeResource {
|
public class ChargeResource {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ChargeResource.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ChargeResource.class);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.sasiedzi.event.web.rest;
|
|||||||
|
|
||||||
import com.sasiedzi.event.domain.Event;
|
import com.sasiedzi.event.domain.Event;
|
||||||
import com.sasiedzi.event.repository.EventRepository;
|
import com.sasiedzi.event.repository.EventRepository;
|
||||||
|
import com.sasiedzi.event.security.AuthoritiesConstants;
|
||||||
import com.sasiedzi.event.service.EventService;
|
import com.sasiedzi.event.service.EventService;
|
||||||
import com.sasiedzi.event.web.rest.errors.BadRequestAlertException;
|
import com.sasiedzi.event.web.rest.errors.BadRequestAlertException;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
@@ -15,6 +16,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.annotation.Secured;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import tech.jhipster.web.util.HeaderUtil;
|
import tech.jhipster.web.util.HeaderUtil;
|
||||||
import tech.jhipster.web.util.ResponseUtil;
|
import tech.jhipster.web.util.ResponseUtil;
|
||||||
@@ -50,6 +52,7 @@ public class EventResource {
|
|||||||
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
*/
|
*/
|
||||||
@PostMapping("")
|
@PostMapping("")
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN, AuthoritiesConstants.COUNTER })
|
||||||
public ResponseEntity<Event> createEvent(@Valid @RequestBody Event event) throws URISyntaxException {
|
public ResponseEntity<Event> createEvent(@Valid @RequestBody Event event) throws URISyntaxException {
|
||||||
LOG.debug("REST request to save Event : {}", event);
|
LOG.debug("REST request to save Event : {}", event);
|
||||||
if (event.getId() != null) {
|
if (event.getId() != null) {
|
||||||
@@ -61,6 +64,15 @@ public class EventResource {
|
|||||||
.body(event);
|
.body(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{id}/settle")
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN, AuthoritiesConstants.COUNTER })
|
||||||
|
public ResponseEntity<Optional<Event>> settleEvent(@RequestBody Optional<Event> event) throws URISyntaxException {
|
||||||
|
event = eventService.settle(event.orElse(null));
|
||||||
|
return ResponseEntity.ok()
|
||||||
|
.headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, event.get().getId().toString()))
|
||||||
|
.body(event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code PUT /events/:id} : Updates an existing event.
|
* {@code PUT /events/:id} : Updates an existing event.
|
||||||
*
|
*
|
||||||
@@ -72,6 +84,7 @@ public class EventResource {
|
|||||||
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
*/
|
*/
|
||||||
@PutMapping("/{id}")
|
@PutMapping("/{id}")
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN, AuthoritiesConstants.COUNTER })
|
||||||
public ResponseEntity<Event> updateEvent(@PathVariable(value = "id", required = false) final Long id, @Valid @RequestBody Event event)
|
public ResponseEntity<Event> updateEvent(@PathVariable(value = "id", required = false) final Long id, @Valid @RequestBody Event event)
|
||||||
throws URISyntaxException {
|
throws URISyntaxException {
|
||||||
LOG.debug("REST request to update Event : {}, {}", id, event);
|
LOG.debug("REST request to update Event : {}, {}", id, event);
|
||||||
@@ -103,6 +116,7 @@ public class EventResource {
|
|||||||
* or with status {@code 500 (Internal Server Error)} if the event couldn't be updated.
|
* or with status {@code 500 (Internal Server Error)} if the event couldn't be updated.
|
||||||
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
*/
|
*/
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN, AuthoritiesConstants.COUNTER })
|
||||||
@PatchMapping(value = "/{id}", consumes = { "application/json", "application/merge-patch+json" })
|
@PatchMapping(value = "/{id}", consumes = { "application/json", "application/merge-patch+json" })
|
||||||
public ResponseEntity<Event> partialUpdateEvent(
|
public ResponseEntity<Event> partialUpdateEvent(
|
||||||
@PathVariable(value = "id", required = false) final Long id,
|
@PathVariable(value = "id", required = false) final Long id,
|
||||||
@@ -146,10 +160,9 @@ public class EventResource {
|
|||||||
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the event, or with status {@code 404 (Not Found)}.
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the event, or with status {@code 404 (Not Found)}.
|
||||||
*/
|
*/
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public ResponseEntity<Event> getEvent(@PathVariable("id") Long id) {
|
public Event getEvent(@PathVariable("id") Long id) {
|
||||||
LOG.debug("REST request to get Event : {}", id);
|
LOG.debug("REST request to get Event : {}", id);
|
||||||
Optional<Event> event = eventService.findOne(id);
|
return eventService.getEventForRegistration(id);
|
||||||
return ResponseUtil.wrapOrNotFound(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,6 +172,7 @@ public class EventResource {
|
|||||||
* @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
|
* @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
|
||||||
*/
|
*/
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN })
|
||||||
public ResponseEntity<Void> deleteEvent(@PathVariable("id") Long id) {
|
public ResponseEntity<Void> deleteEvent(@PathVariable("id") Long id) {
|
||||||
LOG.debug("REST request to delete Event : {}", id);
|
LOG.debug("REST request to delete Event : {}", id);
|
||||||
eventService.delete(id);
|
eventService.delete(id);
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
package com.sasiedzi.event.web.rest;
|
package com.sasiedzi.event.web.rest;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.CurrentUserHolder;
|
||||||
|
import jakarta.servlet.http.Cookie;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
|
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
|
||||||
|
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
|
||||||
|
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
|
||||||
|
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@@ -23,24 +31,47 @@ public class LogoutResource {
|
|||||||
this.registration = registrations.findByRegistrationId("oidc");
|
this.registration = registrations.findByRegistrationId("oidc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CurrentUserHolder currentUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code POST /api/logout} : logout the current user.
|
* {@code POST /api/logout} : logout the current user.
|
||||||
*
|
*
|
||||||
* @param request the {@link HttpServletRequest}.
|
* @param request the {@link HttpServletRequest}.
|
||||||
* @param idToken the ID token.
|
* @param principal principal with the ID token.
|
||||||
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and a body with a global logout URL.
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and a body with a global logout URL.
|
||||||
*/
|
*/
|
||||||
@PostMapping("/api/logout")
|
@PostMapping("/api/logout")
|
||||||
public ResponseEntity<?> logout(HttpServletRequest request, @AuthenticationPrincipal(expression = "idToken") OidcIdToken idToken) {
|
public ResponseEntity<?> logout(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
OidcIdToken idToken = null;
|
||||||
|
Authentication authentication = currentUser.getAuthentication();
|
||||||
StringBuilder logoutUrl = new StringBuilder();
|
StringBuilder logoutUrl = new StringBuilder();
|
||||||
|
String originUrl = request.getHeader(HttpHeaders.ORIGIN);
|
||||||
|
if (authentication != null && authentication.getPrincipal() instanceof DefaultOAuth2User) {
|
||||||
|
idToken = ((DefaultOidcUser) authentication.getPrincipal()).getIdToken();
|
||||||
|
|
||||||
logoutUrl.append(this.registration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint").toString());
|
logoutUrl.append(this.registration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint").toString());
|
||||||
|
|
||||||
String originUrl = request.getHeader(HttpHeaders.ORIGIN);
|
if (idToken != null) {
|
||||||
|
|
||||||
logoutUrl.append("?id_token_hint=").append(idToken.getTokenValue()).append("&post_logout_redirect_uri=").append(originUrl);
|
logoutUrl.append("?id_token_hint=").append(idToken.getTokenValue()).append("&post_logout_redirect_uri=").append(originUrl);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logoutUrl.append(originUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
new SecurityContextLogoutHandler().logout(request, response, null);
|
||||||
|
|
||||||
|
// Ręczne usuwanie ciasteczka 'remember-me'
|
||||||
|
Cookie cookie = new Cookie("remember-me", null);
|
||||||
|
cookie.setPath("/");
|
||||||
|
cookie.setMaxAge(0);
|
||||||
|
response.addCookie(cookie);
|
||||||
|
|
||||||
|
HttpSession existingSession = request.getSession();
|
||||||
|
if (existingSession != null) {
|
||||||
|
existingSession.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
request.getSession().invalidate();
|
|
||||||
return ResponseEntity.ok().body(Map.of("logoutUrl", logoutUrl.toString()));
|
return ResponseEntity.ok().body(Map.of("logoutUrl", logoutUrl.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.sasiedzi.event.web.rest;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.service.EventService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.actuate.info.Info;
|
||||||
|
import org.springframework.boot.actuate.info.InfoContributor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class MyInfoContributor implements InfoContributor {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
EventService eventService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contribute(Info.Builder builder) {
|
||||||
|
builder.withDetail("currentEventId", eventService.getCurrentEventId());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package com.sasiedzi.event.web.rest;
|
package com.sasiedzi.event.web.rest;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.CurrentUserHolder;
|
||||||
import com.sasiedzi.event.domain.Registration;
|
import com.sasiedzi.event.domain.Registration;
|
||||||
import com.sasiedzi.event.domain.User;
|
import com.sasiedzi.event.domain.User;
|
||||||
import com.sasiedzi.event.repository.RegistrationRepository;
|
import com.sasiedzi.event.repository.RegistrationRepository;
|
||||||
import com.sasiedzi.event.repository.UserRepository;
|
import com.sasiedzi.event.repository.UserRepository;
|
||||||
|
import com.sasiedzi.event.service.EventService;
|
||||||
import com.sasiedzi.event.service.UserService;
|
import com.sasiedzi.event.service.UserService;
|
||||||
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
import com.sasiedzi.event.service.dto.AdminUserDTO;
|
||||||
import com.sasiedzi.event.web.rest.errors.BadRequestAlertException;
|
import com.sasiedzi.event.web.rest.errors.BadRequestAlertException;
|
||||||
@@ -20,6 +22,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@@ -49,11 +52,21 @@ public class RegistrationResource {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EventService eventService;
|
||||||
|
|
||||||
public RegistrationResource(RegistrationRepository registrationRepository, UserRepository userRepository) {
|
public RegistrationResource(RegistrationRepository registrationRepository, UserRepository userRepository) {
|
||||||
this.registrationRepository = registrationRepository;
|
this.registrationRepository = registrationRepository;
|
||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Long getCurrentEventId() {
|
||||||
|
return eventService.getCurrentEventId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CurrentUserHolder currentUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code POST /registrations} : Create a new registration.
|
* {@code POST /registrations} : Create a new registration.
|
||||||
*
|
*
|
||||||
@@ -64,6 +77,12 @@ public class RegistrationResource {
|
|||||||
@PostMapping("")
|
@PostMapping("")
|
||||||
public ResponseEntity<Registration> createRegistration(@Valid @RequestBody Registration registration, Principal principal)
|
public ResponseEntity<Registration> createRegistration(@Valid @RequestBody Registration registration, Principal principal)
|
||||||
throws URISyntaxException {
|
throws URISyntaxException {
|
||||||
|
if (
|
||||||
|
!currentUser.getAdminUser().getAuthorities().contains("ROLE_ADMIN") &&
|
||||||
|
!registration.getEvent().getId().equals(getCurrentEventId())
|
||||||
|
) {
|
||||||
|
throw new AccessDeniedException("Registration is closed for this event");
|
||||||
|
}
|
||||||
LOG.debug("REST request to save Registration : {}", registration);
|
LOG.debug("REST request to save Registration : {}", registration);
|
||||||
AdminUserDTO userFromAuthentication;
|
AdminUserDTO userFromAuthentication;
|
||||||
if (principal instanceof AbstractAuthenticationToken) {
|
if (principal instanceof AbstractAuthenticationToken) {
|
||||||
@@ -97,6 +116,12 @@ public class RegistrationResource {
|
|||||||
@PathVariable(value = "id", required = false) final Long id,
|
@PathVariable(value = "id", required = false) final Long id,
|
||||||
@Valid @RequestBody Registration registration
|
@Valid @RequestBody Registration registration
|
||||||
) throws URISyntaxException {
|
) throws URISyntaxException {
|
||||||
|
if (
|
||||||
|
!currentUser.getAdminUser().getAuthorities().contains("ROLE_ADMIN") &&
|
||||||
|
!registration.getEvent().getId().equals(getCurrentEventId())
|
||||||
|
) {
|
||||||
|
throw new AccessDeniedException("Registration is closed for this event");
|
||||||
|
}
|
||||||
LOG.debug("REST request to update Registration : {}, {}", id, registration);
|
LOG.debug("REST request to update Registration : {}, {}", id, registration);
|
||||||
if (registration.getId() == null) {
|
if (registration.getId() == null) {
|
||||||
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
||||||
@@ -131,6 +156,12 @@ public class RegistrationResource {
|
|||||||
@PathVariable(value = "id", required = false) final Long id,
|
@PathVariable(value = "id", required = false) final Long id,
|
||||||
@NotNull @RequestBody Registration registration
|
@NotNull @RequestBody Registration registration
|
||||||
) throws URISyntaxException {
|
) throws URISyntaxException {
|
||||||
|
if (
|
||||||
|
!currentUser.getAdminUser().getAuthorities().contains("ROLE_ADMIN") &&
|
||||||
|
!registration.getEvent().getId().equals(getCurrentEventId())
|
||||||
|
) {
|
||||||
|
throw new AccessDeniedException("Registration is closed for this event");
|
||||||
|
}
|
||||||
LOG.debug("REST request to partial update Registration partially : {}, {}", id, registration);
|
LOG.debug("REST request to partial update Registration partially : {}, {}", id, registration);
|
||||||
if (registration.getId() == null) {
|
if (registration.getId() == null) {
|
||||||
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
||||||
@@ -208,8 +239,16 @@ public class RegistrationResource {
|
|||||||
*/
|
*/
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
public ResponseEntity<Void> deleteRegistration(@PathVariable("id") Long id) {
|
public ResponseEntity<Void> deleteRegistration(@PathVariable("id") Long id) {
|
||||||
|
Registration registration = registrationRepository.findById(id).get();
|
||||||
|
if (
|
||||||
|
!currentUser.getAdminUser().getAuthorities().contains("ROLE_ADMIN") &&
|
||||||
|
!registration.getEvent().getId().equals(getCurrentEventId())
|
||||||
|
) {
|
||||||
|
throw new AccessDeniedException("Registration is closed for this event");
|
||||||
|
}
|
||||||
LOG.debug("REST request to delete Registration : {}", id);
|
LOG.debug("REST request to delete Registration : {}", id);
|
||||||
registrationRepository.deleteById(id);
|
registration.setActive(Boolean.FALSE);
|
||||||
|
registrationRepository.save(registration);
|
||||||
return ResponseEntity.noContent()
|
return ResponseEntity.noContent()
|
||||||
.headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString()))
|
.headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString()))
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
package com.sasiedzi.event.web.rest;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.TransactionItem;
|
||||||
|
import com.sasiedzi.event.repository.TransactionItemRepository;
|
||||||
|
import com.sasiedzi.event.security.AuthoritiesConstants;
|
||||||
|
import com.sasiedzi.event.web.rest.errors.BadRequestAlertException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.annotation.Secured;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import tech.jhipster.web.util.HeaderUtil;
|
||||||
|
import tech.jhipster.web.util.ResponseUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST controller for managing {@link com.sasiedzi.event.domain.TransactionItem}.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/transaction-items")
|
||||||
|
@Transactional
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN })
|
||||||
|
public class TransactionItemResource {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(TransactionItemResource.class);
|
||||||
|
|
||||||
|
private static final String ENTITY_NAME = "transactionItem";
|
||||||
|
|
||||||
|
@Value("${jhipster.clientApp.name}")
|
||||||
|
private String applicationName;
|
||||||
|
|
||||||
|
private final TransactionItemRepository transactionItemRepository;
|
||||||
|
|
||||||
|
public TransactionItemResource(TransactionItemRepository transactionItemRepository) {
|
||||||
|
this.transactionItemRepository = transactionItemRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code POST /transaction-items} : Create a new transactionItem.
|
||||||
|
*
|
||||||
|
* @param transactionItem the transactionItem to create.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new transactionItem, or with status {@code 400 (Bad Request)} if the transactionItem has already an ID.
|
||||||
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
|
*/
|
||||||
|
@PostMapping("")
|
||||||
|
public ResponseEntity<TransactionItem> createTransactionItem(@RequestBody TransactionItem transactionItem) throws URISyntaxException {
|
||||||
|
LOG.debug("REST request to save TransactionItem : {}", transactionItem);
|
||||||
|
if (transactionItem.getId() != null) {
|
||||||
|
throw new BadRequestAlertException("A new transactionItem cannot already have an ID", ENTITY_NAME, "idexists");
|
||||||
|
}
|
||||||
|
transactionItem = transactionItemRepository.save(transactionItem);
|
||||||
|
return ResponseEntity.created(new URI("/api/transaction-items/" + transactionItem.getId()))
|
||||||
|
.headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, transactionItem.getId().toString()))
|
||||||
|
.body(transactionItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code PUT /transaction-items/:id} : Updates an existing transactionItem.
|
||||||
|
*
|
||||||
|
* @param id the id of the transactionItem to save.
|
||||||
|
* @param transactionItem the transactionItem to update.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated transactionItem,
|
||||||
|
* or with status {@code 400 (Bad Request)} if the transactionItem is not valid,
|
||||||
|
* or with status {@code 500 (Internal Server Error)} if the transactionItem couldn't be updated.
|
||||||
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
|
*/
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public ResponseEntity<TransactionItem> updateTransactionItem(
|
||||||
|
@PathVariable(value = "id", required = false) final Long id,
|
||||||
|
@RequestBody TransactionItem transactionItem
|
||||||
|
) throws URISyntaxException {
|
||||||
|
LOG.debug("REST request to update TransactionItem : {}, {}", id, transactionItem);
|
||||||
|
if (transactionItem.getId() == null) {
|
||||||
|
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(id, transactionItem.getId())) {
|
||||||
|
throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transactionItemRepository.existsById(id)) {
|
||||||
|
throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
|
||||||
|
}
|
||||||
|
|
||||||
|
transactionItem = transactionItemRepository.save(transactionItem);
|
||||||
|
return ResponseEntity.ok()
|
||||||
|
.headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, transactionItem.getId().toString()))
|
||||||
|
.body(transactionItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code PATCH /transaction-items/:id} : Partial updates given fields of an existing transactionItem, field will ignore if it is null
|
||||||
|
*
|
||||||
|
* @param id the id of the transactionItem to save.
|
||||||
|
* @param transactionItem the transactionItem to update.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated transactionItem,
|
||||||
|
* or with status {@code 400 (Bad Request)} if the transactionItem is not valid,
|
||||||
|
* or with status {@code 404 (Not Found)} if the transactionItem is not found,
|
||||||
|
* or with status {@code 500 (Internal Server Error)} if the transactionItem couldn't be updated.
|
||||||
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
|
*/
|
||||||
|
@PatchMapping(value = "/{id}", consumes = { "application/json", "application/merge-patch+json" })
|
||||||
|
public ResponseEntity<TransactionItem> partialUpdateTransactionItem(
|
||||||
|
@PathVariable(value = "id", required = false) final Long id,
|
||||||
|
@RequestBody TransactionItem transactionItem
|
||||||
|
) throws URISyntaxException {
|
||||||
|
LOG.debug("REST request to partial update TransactionItem partially : {}, {}", id, transactionItem);
|
||||||
|
if (transactionItem.getId() == null) {
|
||||||
|
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(id, transactionItem.getId())) {
|
||||||
|
throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transactionItemRepository.existsById(id)) {
|
||||||
|
throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<TransactionItem> result = transactionItemRepository
|
||||||
|
.findById(transactionItem.getId())
|
||||||
|
.map(existingTransactionItem -> {
|
||||||
|
if (transactionItem.getAmount() != null) {
|
||||||
|
existingTransactionItem.setAmount(transactionItem.getAmount());
|
||||||
|
}
|
||||||
|
if (transactionItem.getComment() != null) {
|
||||||
|
existingTransactionItem.setComment(transactionItem.getComment());
|
||||||
|
}
|
||||||
|
if (transactionItem.getLocked() != null) {
|
||||||
|
existingTransactionItem.setLocked(transactionItem.getLocked());
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingTransactionItem;
|
||||||
|
})
|
||||||
|
.map(transactionItemRepository::save);
|
||||||
|
|
||||||
|
return ResponseUtil.wrapOrNotFound(
|
||||||
|
result,
|
||||||
|
HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, transactionItem.getId().toString())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GET /transaction-items} : get all the transactionItems.
|
||||||
|
*
|
||||||
|
* @param eagerload flag to eager load entities from relationships (This is applicable for many-to-many).
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of transactionItems in body.
|
||||||
|
*/
|
||||||
|
@GetMapping("")
|
||||||
|
public List<TransactionItem> getAllTransactionItems(
|
||||||
|
@RequestParam(name = "eagerload", required = false, defaultValue = "true") boolean eagerload
|
||||||
|
) {
|
||||||
|
LOG.debug("REST request to get all TransactionItems");
|
||||||
|
if (eagerload) {
|
||||||
|
return transactionItemRepository.findAllWithEagerRelationships();
|
||||||
|
} else {
|
||||||
|
return transactionItemRepository.findAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GET /transaction-items/:id} : get the "id" transactionItem.
|
||||||
|
*
|
||||||
|
* @param id the id of the transactionItem to retrieve.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the transactionItem, or with status {@code 404 (Not Found)}.
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseEntity<TransactionItem> getTransactionItem(@PathVariable("id") Long id) {
|
||||||
|
LOG.debug("REST request to get TransactionItem : {}", id);
|
||||||
|
Optional<TransactionItem> transactionItem = transactionItemRepository.findOneWithEagerRelationships(id);
|
||||||
|
return ResponseUtil.wrapOrNotFound(transactionItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code DELETE /transaction-items/:id} : delete the "id" transactionItem.
|
||||||
|
*
|
||||||
|
* @param id the id of the transactionItem to delete.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public ResponseEntity<Void> deleteTransactionItem(@PathVariable("id") Long id) {
|
||||||
|
LOG.debug("REST request to delete TransactionItem : {}", id);
|
||||||
|
transactionItemRepository.deleteById(id);
|
||||||
|
return ResponseEntity.noContent()
|
||||||
|
.headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,282 @@
|
|||||||
|
package com.sasiedzi.event.web.rest;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.*;
|
||||||
|
import com.sasiedzi.event.repository.TransactionRepository;
|
||||||
|
import com.sasiedzi.event.security.AuthoritiesConstants;
|
||||||
|
import com.sasiedzi.event.service.TransactionService;
|
||||||
|
import com.sasiedzi.event.web.rest.errors.BadRequestAlertException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.*;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.annotation.Secured;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import tech.jhipster.web.util.HeaderUtil;
|
||||||
|
import tech.jhipster.web.util.ResponseUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST controller for managing {@link com.sasiedzi.event.domain.Transaction}.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/transactions")
|
||||||
|
@Transactional
|
||||||
|
public class TransactionResource {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(TransactionResource.class);
|
||||||
|
|
||||||
|
private static final String ENTITY_NAME = "transaction";
|
||||||
|
|
||||||
|
@Value("${jhipster.clientApp.name}")
|
||||||
|
private String applicationName;
|
||||||
|
|
||||||
|
private final TransactionRepository transactionRepository;
|
||||||
|
|
||||||
|
public TransactionResource(TransactionRepository transactionRepository) {
|
||||||
|
this.transactionRepository = transactionRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code POST /transactions} : Create a new transaction.
|
||||||
|
*
|
||||||
|
* @param transaction the transaction to create.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new transaction, or with status {@code 400 (Bad Request)} if the transaction has already an ID.
|
||||||
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
|
*/
|
||||||
|
@PostMapping("")
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN, AuthoritiesConstants.COUNTER })
|
||||||
|
public ResponseEntity<Transaction> createTransaction(@RequestBody Transaction transaction) throws URISyntaxException {
|
||||||
|
LOG.debug("REST request to save Transaction : {}", transaction);
|
||||||
|
if (transaction.getId() != null) {
|
||||||
|
throw new BadRequestAlertException("A new transaction cannot already have an ID", ENTITY_NAME, "idexists");
|
||||||
|
}
|
||||||
|
transaction = transactionService.save(transaction);
|
||||||
|
return ResponseEntity.created(new URI("/api/transactions/" + transaction.getId()))
|
||||||
|
.headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, transaction.getId().toString()))
|
||||||
|
.body(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code PUT /transactions/:id} : Updates an existing transaction.
|
||||||
|
*
|
||||||
|
* @param id the id of the transaction to save.
|
||||||
|
* @param transaction the transaction to update.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated transaction,
|
||||||
|
* or with status {@code 400 (Bad Request)} if the transaction is not valid,
|
||||||
|
* or with status {@code 500 (Internal Server Error)} if the transaction couldn't be updated.
|
||||||
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
|
*/
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN, AuthoritiesConstants.COUNTER })
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public ResponseEntity<Transaction> updateTransaction(
|
||||||
|
@PathVariable(value = "id", required = false) final Long id,
|
||||||
|
@RequestBody Transaction transaction
|
||||||
|
) throws URISyntaxException {
|
||||||
|
LOG.debug("REST request to update Transaction : {}, {}", id, transaction);
|
||||||
|
if (transaction.getId() == null) {
|
||||||
|
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(id, transaction.getId())) {
|
||||||
|
throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transactionRepository.existsById(id)) {
|
||||||
|
throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction = transactionService.save(transaction);
|
||||||
|
return ResponseEntity.ok()
|
||||||
|
.headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, transaction.getId().toString()))
|
||||||
|
.body(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code PATCH /transactions/:id} : Partial updates given fields of an existing transaction, field will ignore if it is null
|
||||||
|
*
|
||||||
|
* @param id the id of the transaction to save.
|
||||||
|
* @param transaction the transaction to update.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated transaction,
|
||||||
|
* or with status {@code 400 (Bad Request)} if the transaction is not valid,
|
||||||
|
* or with status {@code 404 (Not Found)} if the transaction is not found,
|
||||||
|
* or with status {@code 500 (Internal Server Error)} if the transaction couldn't be updated.
|
||||||
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
|
*/
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN, AuthoritiesConstants.COUNTER })
|
||||||
|
@PatchMapping(value = "/{id}", consumes = { "application/json", "application/merge-patch+json" })
|
||||||
|
public ResponseEntity<Transaction> partialUpdateTransaction(
|
||||||
|
@PathVariable(value = "id", required = false) final Long id,
|
||||||
|
@RequestBody Transaction transaction
|
||||||
|
) throws URISyntaxException {
|
||||||
|
LOG.debug("REST request to partial update Transaction partially : {}, {}", id, transaction);
|
||||||
|
if (transaction.getId() == null) {
|
||||||
|
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(id, transaction.getId())) {
|
||||||
|
throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transactionRepository.existsById(id)) {
|
||||||
|
throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Transaction> result = transactionRepository
|
||||||
|
.findById(transaction.getId())
|
||||||
|
.map(existingTransaction -> {
|
||||||
|
if (transaction.getType() != null) {
|
||||||
|
existingTransaction.setType(transaction.getType());
|
||||||
|
}
|
||||||
|
if (transaction.getDate() != null) {
|
||||||
|
existingTransaction.setDate(transaction.getDate());
|
||||||
|
}
|
||||||
|
if (transaction.getComment() != null) {
|
||||||
|
existingTransaction.setComment(transaction.getComment());
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingTransaction;
|
||||||
|
})
|
||||||
|
.map(transactionRepository::save);
|
||||||
|
|
||||||
|
return ResponseUtil.wrapOrNotFound(
|
||||||
|
result,
|
||||||
|
HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, transaction.getId().toString())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/forAccount/{userAccountId}")
|
||||||
|
public List<TransactionDTO> getAllTransactionsForAccountId(
|
||||||
|
@PathVariable(value = "userAccountId", required = false) final Long userAccountId,
|
||||||
|
@RequestParam(name = "eagerload", required = false, defaultValue = "true") boolean eagerload
|
||||||
|
) {
|
||||||
|
List<TransactionDTO> allTransactions = getAllTransactions(true);
|
||||||
|
if (userAccountId != null) {
|
||||||
|
// allTransactions.removeFirst();
|
||||||
|
}
|
||||||
|
return allTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GET /transactions} : get all the transactions.
|
||||||
|
*
|
||||||
|
* @param eagerload flag to eager load entities from relationships (This is applicable for many-to-many).
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of transactions in body.
|
||||||
|
*/
|
||||||
|
@GetMapping("")
|
||||||
|
public List<TransactionDTO> getAllTransactions(
|
||||||
|
@RequestParam(name = "eagerload", required = false, defaultValue = "true") boolean eagerload
|
||||||
|
) {
|
||||||
|
return transactionService.getAllTransactions();
|
||||||
|
}
|
||||||
|
|
||||||
|
// private Comparator<UserAccount> getMyAccountFirstComparator (final String myAccountName) {
|
||||||
|
//
|
||||||
|
// Comparator<UserAccount> customOrder = Comparator.comparing(s -> {
|
||||||
|
// if (s.getName().equals(myAccountName)) {
|
||||||
|
// return 1;
|
||||||
|
// } else if (s.getName().equals("Boisko")) {
|
||||||
|
// return s.getName();
|
||||||
|
// } else if (s.getName().equals("Skarbiec")) {
|
||||||
|
// return 3;
|
||||||
|
// }
|
||||||
|
// return 4;
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// return customOrder.thenComparing(UserAccount::getName);
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public class CustomComparator implements Comparator<UserAccount> {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public int compare(UserAccount o1, UserAccount o2) {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// // Najpierw sortujemy według zdefiniowanego porządku
|
||||||
|
// int typeComparison = customOrder.compare(o1.getType(), o2.getType());
|
||||||
|
// if (typeComparison != 0) {
|
||||||
|
// return typeComparison;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Jeśli typy są takie same, sortujemy według nazwy
|
||||||
|
// return o1.getName().compareTo(o2.getName());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GET /transactions/:id} : get the "id" transaction.
|
||||||
|
*
|
||||||
|
* @param id the id of the transaction to retrieve.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the transaction, or with status {@code 404 (Not Found)}.
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Transaction getTransaction(@PathVariable("id") Long id) {
|
||||||
|
LOG.debug("REST request to get Transaction : {}", id);
|
||||||
|
return transactionService.get(id);
|
||||||
|
// Optional<Transaction> transaction = transactionRepository.findOneWithEagerRelationships(id);
|
||||||
|
// // if (transaction.isPresent()) {
|
||||||
|
// // transaction.get().getTransactionItems().stream().sorted();
|
||||||
|
// // transaction.get().getTransactionItems().sort(Comparator.comparing(item -> item.getUserAccount().getName()));
|
||||||
|
// // }
|
||||||
|
// return ResponseUtil.wrapOrNotFound(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
TransactionService transactionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GET /transactions/:id} : get the "id" transaction.
|
||||||
|
*
|
||||||
|
* @param id the id of the transaction to retrieve.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the transaction, or with status {@code 404 (Not Found)}.
|
||||||
|
*/
|
||||||
|
@GetMapping("/payments/{id}")
|
||||||
|
public Transaction createPayments(@PathVariable("id") Long id) {
|
||||||
|
LOG.debug("REST request to get Transaction : {}", id);
|
||||||
|
return transactionService.createPayments(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GET /transactions/:id} : get the "id" transaction.
|
||||||
|
*
|
||||||
|
* @param id the id of the transaction to retrieve.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the transaction, or with status {@code 404 (Not Found)}.
|
||||||
|
*/
|
||||||
|
@GetMapping("/field-payment/{id}")
|
||||||
|
public Transaction getTransactionPayments(@PathVariable("id") Long id) {
|
||||||
|
LOG.debug("REST request to get Transaction : {}", id);
|
||||||
|
return transactionService.createFieldPayment(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GET /transactions/:id} : get the "id" transaction.
|
||||||
|
*
|
||||||
|
* @param id the id of the transaction to retrieve.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the transaction, or with status {@code 404 (Not Found)}.
|
||||||
|
*/
|
||||||
|
@GetMapping("/opposing/{id}")
|
||||||
|
public Transaction getTransactionOpposite(@PathVariable("id") Long id) {
|
||||||
|
LOG.debug("REST request to get Transaction : {}", id);
|
||||||
|
return transactionService.createOpposite(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code DELETE /transactions/:id} : delete the "id" transaction.
|
||||||
|
*
|
||||||
|
* @param id the id of the transaction to delete.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN })
|
||||||
|
public ResponseEntity<Void> deleteTransaction(@PathVariable("id") Long id) {
|
||||||
|
LOG.debug("REST request to delete Transaction : {}", id);
|
||||||
|
transactionRepository.deleteById(id);
|
||||||
|
return ResponseEntity.noContent()
|
||||||
|
.headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
package com.sasiedzi.event.web.rest;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.domain.CurrentUserHolder;
|
||||||
|
import com.sasiedzi.event.domain.User;
|
||||||
|
import com.sasiedzi.event.domain.UserAccount;
|
||||||
|
import com.sasiedzi.event.repository.UserAccountRepository;
|
||||||
|
import com.sasiedzi.event.security.AuthoritiesConstants;
|
||||||
|
import com.sasiedzi.event.service.EventService;
|
||||||
|
import com.sasiedzi.event.service.UserService;
|
||||||
|
import com.sasiedzi.event.web.rest.errors.BadRequestAlertException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.annotation.Secured;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import tech.jhipster.web.util.HeaderUtil;
|
||||||
|
import tech.jhipster.web.util.ResponseUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST controller for managing {@link com.sasiedzi.event.domain.UserAccount}.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/user-accounts")
|
||||||
|
@Transactional
|
||||||
|
public class UserAccountResource {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(UserAccountResource.class);
|
||||||
|
|
||||||
|
private static final String ENTITY_NAME = "userAccount";
|
||||||
|
|
||||||
|
@Value("${jhipster.clientApp.name}")
|
||||||
|
private String applicationName;
|
||||||
|
|
||||||
|
private final UserAccountRepository userAccountRepository;
|
||||||
|
|
||||||
|
public UserAccountResource(UserAccountRepository userAccountRepository) {
|
||||||
|
this.userAccountRepository = userAccountRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code POST /user-accounts} : Create a new userAccount.
|
||||||
|
*
|
||||||
|
* @param userAccount the userAccount to create.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new userAccount, or with status {@code 400 (Bad Request)} if the userAccount has already an ID.
|
||||||
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
|
*/
|
||||||
|
@PostMapping("")
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN })
|
||||||
|
public ResponseEntity<UserAccount> createUserAccount(@RequestBody UserAccount userAccount) throws URISyntaxException {
|
||||||
|
LOG.debug("REST request to save UserAccount : {}", userAccount);
|
||||||
|
if (userAccount.getId() != null) {
|
||||||
|
throw new BadRequestAlertException("A new userAccount cannot already have an ID", ENTITY_NAME, "idexists");
|
||||||
|
}
|
||||||
|
userAccount = userAccountRepository.save(userAccount);
|
||||||
|
return ResponseEntity.created(new URI("/api/user-accounts/" + userAccount.getId()))
|
||||||
|
.headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, userAccount.getId().toString()))
|
||||||
|
.body(userAccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code PUT /user-accounts/:id} : Updates an existing userAccount.
|
||||||
|
*
|
||||||
|
* @param id the id of the userAccount to save.
|
||||||
|
* @param userAccount the userAccount to update.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated userAccount,
|
||||||
|
* or with status {@code 400 (Bad Request)} if the userAccount is not valid,
|
||||||
|
* or with status {@code 500 (Internal Server Error)} if the userAccount couldn't be updated.
|
||||||
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
|
*/
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN })
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public ResponseEntity<UserAccount> updateUserAccount(
|
||||||
|
@PathVariable(value = "id", required = false) final Long id,
|
||||||
|
@RequestBody UserAccount userAccount
|
||||||
|
) throws URISyntaxException {
|
||||||
|
LOG.debug("REST request to update UserAccount : {}, {}", id, userAccount);
|
||||||
|
if (userAccount.getId() == null) {
|
||||||
|
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(id, userAccount.getId())) {
|
||||||
|
throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userAccountRepository.existsById(id)) {
|
||||||
|
throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
|
||||||
|
}
|
||||||
|
|
||||||
|
userAccount = userAccountRepository.save(userAccount);
|
||||||
|
return ResponseEntity.ok()
|
||||||
|
.headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, userAccount.getId().toString()))
|
||||||
|
.body(userAccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code PATCH /user-accounts/:id} : Partial updates given fields of an existing userAccount, field will ignore if it is null
|
||||||
|
*
|
||||||
|
* @param id the id of the userAccount to save.
|
||||||
|
* @param userAccount the userAccount to update.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated userAccount,
|
||||||
|
* or with status {@code 400 (Bad Request)} if the userAccount is not valid,
|
||||||
|
* or with status {@code 404 (Not Found)} if the userAccount is not found,
|
||||||
|
* or with status {@code 500 (Internal Server Error)} if the userAccount couldn't be updated.
|
||||||
|
* @throws URISyntaxException if the Location URI syntax is incorrect.
|
||||||
|
*/
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN })
|
||||||
|
@PatchMapping(value = "/{id}", consumes = { "application/json", "application/merge-patch+json" })
|
||||||
|
public ResponseEntity<UserAccount> partialUpdateUserAccount(
|
||||||
|
@PathVariable(value = "id", required = false) final Long id,
|
||||||
|
@RequestBody UserAccount userAccount
|
||||||
|
) throws URISyntaxException {
|
||||||
|
LOG.debug("REST request to partial update UserAccount partially : {}, {}", id, userAccount);
|
||||||
|
if (userAccount.getId() == null) {
|
||||||
|
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(id, userAccount.getId())) {
|
||||||
|
throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userAccountRepository.existsById(id)) {
|
||||||
|
throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<UserAccount> result = userAccountRepository
|
||||||
|
.findById(userAccount.getId())
|
||||||
|
.map(existingUserAccount -> {
|
||||||
|
if (userAccount.getName() != null) {
|
||||||
|
existingUserAccount.setName(userAccount.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingUserAccount;
|
||||||
|
})
|
||||||
|
.map(userAccountRepository::save);
|
||||||
|
|
||||||
|
return ResponseUtil.wrapOrNotFound(
|
||||||
|
result,
|
||||||
|
HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, userAccount.getId().toString())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GET /user-accounts} : get all the userAccounts.
|
||||||
|
*
|
||||||
|
* @param eagerload flag to eager load entities from relationships (This is applicable for many-to-many).
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of userAccounts in body.
|
||||||
|
*/
|
||||||
|
@GetMapping("")
|
||||||
|
public List<UserAccount> getAllUserAccounts(
|
||||||
|
@RequestParam(name = "eagerload", required = false, defaultValue = "true") boolean eagerload
|
||||||
|
) {
|
||||||
|
LOG.debug("REST request to get all UserAccounts");
|
||||||
|
if (eagerload) {
|
||||||
|
return userAccountRepository.findAllWithEagerRelationships();
|
||||||
|
} else {
|
||||||
|
return userAccountRepository.findAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code GET /user-accounts/:id} : get the "id" userAccount.
|
||||||
|
*
|
||||||
|
* @param id the id of the userAccount to retrieve.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the userAccount, or with status {@code 404 (Not Found)}.
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseEntity<UserAccount> getUserAccount(@PathVariable("id") Long id) {
|
||||||
|
LOG.debug("REST request to get UserAccount : {}", id);
|
||||||
|
Optional<UserAccount> userAccount = userAccountRepository.findOneWithEagerRelationships(id);
|
||||||
|
return ResponseUtil.wrapOrNotFound(userAccount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/currentUser")
|
||||||
|
public UserAccount getCurrentUserAccount() {
|
||||||
|
return currentUser.getUserAccount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CurrentUserHolder currentUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code DELETE /user-accounts/:id} : delete the "id" userAccount.
|
||||||
|
*
|
||||||
|
* @param id the id of the userAccount to delete.
|
||||||
|
* @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
@Secured({ AuthoritiesConstants.ADMIN })
|
||||||
|
public ResponseEntity<Void> deleteUserAccount(@PathVariable("id") Long id) {
|
||||||
|
LOG.debug("REST request to delete UserAccount : {}", id);
|
||||||
|
userAccountRepository.deleteById(id);
|
||||||
|
return ResponseEntity.noContent()
|
||||||
|
.headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
EventService eventService;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.sasiedzi.event.web.rest.errors;
|
|||||||
|
|
||||||
import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation;
|
import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation;
|
||||||
|
|
||||||
|
import com.sasiedzi.event.SasiedziApp;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -9,7 +10,10 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
@@ -57,9 +61,16 @@ public class ExceptionTranslator extends ResponseEntityExceptionHandler {
|
|||||||
this.env = env;
|
this.env = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(ExceptionTranslator.class);
|
||||||
|
|
||||||
@ExceptionHandler
|
@ExceptionHandler
|
||||||
public ResponseEntity<Object> handleAnyException(Throwable ex, NativeWebRequest request) {
|
public ResponseEntity<Object> handleAnyException(Throwable ex, NativeWebRequest request) {
|
||||||
ProblemDetailWithCause pdCause = wrapAndCustomizeProblem(ex, request);
|
ProblemDetailWithCause pdCause = wrapAndCustomizeProblem(ex, request);
|
||||||
|
if (pdCause.getStatus() == HttpStatus.INTERNAL_SERVER_ERROR.value() && !env.matchesProfiles("dev")) {
|
||||||
|
// If profile is dev, then Logging Aspect will handle logging.
|
||||||
|
// In all other profiles no error is logged :-( No idea why that should be a good decision.
|
||||||
|
LOG.error("Internal Server error happened", ex);
|
||||||
|
}
|
||||||
return handleExceptionInternal((Exception) ex, pdCause, buildHeaders(ex), HttpStatusCode.valueOf(pdCause.getStatus()), request);
|
return handleExceptionInternal((Exception) ex, pdCause, buildHeaders(ex), HttpStatusCode.valueOf(pdCause.getStatus()), request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Added the entity Transaction.
|
||||||
|
-->
|
||||||
|
<changeSet id="20241113134007-1" author="jhipster">
|
||||||
|
<createTable tableName="transaction">
|
||||||
|
<column name="id" type="bigint">
|
||||||
|
<constraints primaryKey="true" nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="type" type="varchar(255)">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<column name="date" type="date">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<column name="comment" type="varchar(255)">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<column name="event_id" type="bigint">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<!-- jhipster-needle-liquibase-add-column - JHipster will add columns here -->
|
||||||
|
</createTable>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<!-- jhipster-needle-liquibase-add-changeset - JHipster will add changesets here -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Load sample data generated with Faker.js
|
||||||
|
- This data can be easily edited using a CSV editor (or even MS Excel) and
|
||||||
|
is located in the 'src/main/resources/config/liquibase/fake-data' directory
|
||||||
|
- By default this data is applied when running with the JHipster 'dev' profile.
|
||||||
|
This can be customized by adding or removing 'faker' in the 'spring.liquibase.contexts'
|
||||||
|
Spring Boot configuration key.
|
||||||
|
-->
|
||||||
|
<changeSet id="20241113134007-1-data" author="jhipster" context="faker">
|
||||||
|
<loadData
|
||||||
|
file="config/liquibase/fake-data/transaction.csv"
|
||||||
|
separator=";"
|
||||||
|
tableName="transaction"
|
||||||
|
usePreparedStatements="true">
|
||||||
|
<column name="id" type="numeric"/>
|
||||||
|
<column name="type" type="string"/>
|
||||||
|
<column name="date" type="date"/>
|
||||||
|
<column name="comment" type="string"/>
|
||||||
|
<!-- jhipster-needle-liquibase-add-loadcolumn - JHipster (and/or extensions) can add load columns here -->
|
||||||
|
</loadData>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
|
||||||
|
<!--
|
||||||
|
Added the constraints for entity Transaction.
|
||||||
|
-->
|
||||||
|
<changeSet id="20241113134007-2" author="jhipster">
|
||||||
|
|
||||||
|
<addForeignKeyConstraint baseColumnNames="event_id"
|
||||||
|
baseTableName="transaction"
|
||||||
|
constraintName="fk_transaction__event_id"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
referencedTableName="event"
|
||||||
|
/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Added the entity UserAccount.
|
||||||
|
-->
|
||||||
|
<changeSet id="20241113135042-1" author="jhipster">
|
||||||
|
<createTable tableName="user_account">
|
||||||
|
<column name="id" type="bigint">
|
||||||
|
<constraints primaryKey="true" nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="name" type="varchar(255)">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<!-- jhipster-needle-liquibase-add-column - JHipster will add columns here -->
|
||||||
|
</createTable>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet id="20241113135042-1-relations" author="jhipster">
|
||||||
|
|
||||||
|
<createTable tableName="rel_user_account__user">
|
||||||
|
<column name="user_id" type="varchar(100)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="user_account_id" type="bigint">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
</createTable>
|
||||||
|
|
||||||
|
<addPrimaryKey columnNames="user_account_id, user_id" tableName="rel_user_account__user"/>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<!-- jhipster-needle-liquibase-add-changeset - JHipster will add changesets here -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Load sample data generated with Faker.js
|
||||||
|
- This data can be easily edited using a CSV editor (or even MS Excel) and
|
||||||
|
is located in the 'src/main/resources/config/liquibase/fake-data' directory
|
||||||
|
- By default this data is applied when running with the JHipster 'dev' profile.
|
||||||
|
This can be customized by adding or removing 'faker' in the 'spring.liquibase.contexts'
|
||||||
|
Spring Boot configuration key.
|
||||||
|
-->
|
||||||
|
<changeSet id="20241113135042-1-data" author="jhipster" context="faker">
|
||||||
|
<loadData
|
||||||
|
file="config/liquibase/fake-data/user_account.csv"
|
||||||
|
separator=";"
|
||||||
|
tableName="user_account"
|
||||||
|
usePreparedStatements="true">
|
||||||
|
<column name="id" type="numeric"/>
|
||||||
|
<column name="name" type="string"/>
|
||||||
|
<!-- jhipster-needle-liquibase-add-loadcolumn - JHipster (and/or extensions) can add load columns here -->
|
||||||
|
</loadData>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
|
||||||
|
<!--
|
||||||
|
Added the constraints for entity UserAccount.
|
||||||
|
-->
|
||||||
|
<changeSet id="20241113135042-2" author="jhipster">
|
||||||
|
|
||||||
|
<addForeignKeyConstraint baseColumnNames="user_account_id"
|
||||||
|
baseTableName="rel_user_account__user"
|
||||||
|
constraintName="fk_rel_user_account__user__user_account_id"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
referencedTableName="user_account"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<addForeignKeyConstraint baseColumnNames="user_id"
|
||||||
|
baseTableName="rel_user_account__user"
|
||||||
|
constraintName="fk_rel_user_account__user__user_id"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
referencedTableName="jhi_user"
|
||||||
|
/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Added the entity TransactionItem.
|
||||||
|
-->
|
||||||
|
<changeSet id="20241113151058-1" author="jhipster">
|
||||||
|
<createTable tableName="transaction_item">
|
||||||
|
<column name="id" type="bigint">
|
||||||
|
<constraints primaryKey="true" nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="amount" type="decimal(21,2)">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<column name="comment" type="varchar(255)">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<column name="locked" type="boolean">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<column name="user_account_id" type="bigint">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<column name="transaction_id" type="bigint">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<column name="event_id" type="bigint">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<column name="registration_id" type="bigint">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
<!-- jhipster-needle-liquibase-add-column - JHipster will add columns here -->
|
||||||
|
</createTable>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<!-- jhipster-needle-liquibase-add-changeset - JHipster will add changesets here -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Load sample data generated with Faker.js
|
||||||
|
- This data can be easily edited using a CSV editor (or even MS Excel) and
|
||||||
|
is located in the 'src/main/resources/config/liquibase/fake-data' directory
|
||||||
|
- By default this data is applied when running with the JHipster 'dev' profile.
|
||||||
|
This can be customized by adding or removing 'faker' in the 'spring.liquibase.contexts'
|
||||||
|
Spring Boot configuration key.
|
||||||
|
-->
|
||||||
|
<changeSet id="20241113151058-1-data" author="jhipster" context="faker">
|
||||||
|
<loadData
|
||||||
|
file="config/liquibase/fake-data/transaction_item.csv"
|
||||||
|
separator=";"
|
||||||
|
tableName="transaction_item"
|
||||||
|
usePreparedStatements="true">
|
||||||
|
<column name="id" type="numeric"/>
|
||||||
|
<column name="amount" type="numeric"/>
|
||||||
|
<column name="comment" type="string"/>
|
||||||
|
<column name="locked" type="boolean"/>
|
||||||
|
<!-- jhipster-needle-liquibase-add-loadcolumn - JHipster (and/or extensions) can add load columns here -->
|
||||||
|
</loadData>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
|
||||||
|
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
|
||||||
|
<!--
|
||||||
|
Added the constraints for entity TransactionItem.
|
||||||
|
-->
|
||||||
|
<changeSet id="20241113151058-2" author="jhipster">
|
||||||
|
|
||||||
|
<addForeignKeyConstraint baseColumnNames="user_account_id"
|
||||||
|
baseTableName="transaction_item"
|
||||||
|
constraintName="fk_transaction_item__user_account_id"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
referencedTableName="user_account"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<addForeignKeyConstraint baseColumnNames="transaction_id"
|
||||||
|
baseTableName="transaction_item"
|
||||||
|
constraintName="fk_transaction_item__transaction_id"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
referencedTableName="transaction"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<addForeignKeyConstraint baseColumnNames="event_id"
|
||||||
|
baseTableName="transaction_item"
|
||||||
|
constraintName="fk_transaction_item__event_id"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
referencedTableName="event"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<addForeignKeyConstraint baseColumnNames="registration_id"
|
||||||
|
baseTableName="transaction_item"
|
||||||
|
constraintName="fk_transaction_item__registration_id"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
referencedTableName="registration"
|
||||||
|
/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
||||||
|
<changeSet author="Zet (generated)" id="1731926141078-7">
|
||||||
|
<addColumn tableName="registration">
|
||||||
|
<column name="user_account_id" type="bigint">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="Zet (generated)" id="1731926141078-8">
|
||||||
|
<addForeignKeyConstraint baseColumnNames="user_account_id"
|
||||||
|
baseTableName="registration"
|
||||||
|
constraintName="fk_registration__user_account_id"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
referencedTableName="user_account"
|
||||||
|
/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
id;type;date;comment
|
||||||
|
@@ -0,0 +1,2 @@
|
|||||||
|
id;amount;comment;locked
|
||||||
|
|
||||||
|
@@ -0,0 +1,2 @@
|
|||||||
|
id;name
|
||||||
|
|
||||||
|
@@ -14,9 +14,16 @@
|
|||||||
<include file="config/liquibase/changelog/20241105091001_added_entity_Charge.xml" relativeToChangelogFile="false"/>
|
<include file="config/liquibase/changelog/20241105091001_added_entity_Charge.xml" relativeToChangelogFile="false"/>
|
||||||
<include file="config/liquibase/changelog/20241105091002_added_entity_Event.xml" relativeToChangelogFile="false"/>
|
<include file="config/liquibase/changelog/20241105091002_added_entity_Event.xml" relativeToChangelogFile="false"/>
|
||||||
<include file="config/liquibase/changelog/20241105091003_added_entity_Registration.xml" relativeToChangelogFile="false"/>
|
<include file="config/liquibase/changelog/20241105091003_added_entity_Registration.xml" relativeToChangelogFile="false"/>
|
||||||
|
<include file="config/liquibase/changelog/20241113134007_added_entity_Transaction.xml" relativeToChangelogFile="false"/>
|
||||||
|
<include file="config/liquibase/changelog/20241113135042_added_entity_UserAccount.xml" relativeToChangelogFile="false"/>
|
||||||
|
<include file="config/liquibase/changelog/20241113151058_added_entity_TransactionItem.xml" relativeToChangelogFile="false"/>
|
||||||
<!-- jhipster-needle-liquibase-add-changelog - JHipster will add liquibase changelogs here -->
|
<!-- jhipster-needle-liquibase-add-changelog - JHipster will add liquibase changelogs here -->
|
||||||
<include file="config/liquibase/changelog/20241105091001_added_entity_constraints_Charge.xml" relativeToChangelogFile="false"/>
|
<include file="config/liquibase/changelog/20241105091001_added_entity_constraints_Charge.xml" relativeToChangelogFile="false"/>
|
||||||
<include file="config/liquibase/changelog/20241105091003_added_entity_constraints_Registration.xml" relativeToChangelogFile="false"/>
|
<include file="config/liquibase/changelog/20241105091003_added_entity_constraints_Registration.xml" relativeToChangelogFile="false"/>
|
||||||
|
<include file="config/liquibase/changelog/20241113134007_added_entity_constraints_Transaction.xml" relativeToChangelogFile="false"/>
|
||||||
|
<include file="config/liquibase/changelog/20241113135042_added_entity_constraints_UserAccount.xml" relativeToChangelogFile="false"/>
|
||||||
|
<include file="config/liquibase/changelog/20241113151058_added_entity_constraints_TransactionItem.xml" relativeToChangelogFile="false"/>
|
||||||
<!-- jhipster-needle-liquibase-add-constraints-changelog - JHipster will add liquibase constraints changelogs here -->
|
<!-- jhipster-needle-liquibase-add-constraints-changelog - JHipster will add liquibase constraints changelogs here -->
|
||||||
<!-- jhipster-needle-liquibase-add-incremental-changelog - JHipster will add incremental liquibase changelogs here -->
|
<!-- jhipster-needle-liquibase-add-incremental-changelog - JHipster will add incremental liquibase changelogs here -->
|
||||||
|
<include file="config/liquibase/changelog/20241118103414_changelog.xml" relativeToChangelogFile="false"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export default class AccountService {
|
|||||||
if (res.data && res.data.activeProfiles) {
|
if (res.data && res.data.activeProfiles) {
|
||||||
this.store.setRibbonOnProfiles(res.data['display-ribbon-on-profiles']);
|
this.store.setRibbonOnProfiles(res.data['display-ribbon-on-profiles']);
|
||||||
this.store.setActiveProfiles(res.data.activeProfiles);
|
this.store.setActiveProfiles(res.data.activeProfiles);
|
||||||
|
this.store.setCurrentEventId(res.data.currentEventId);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="footer" class="footer">
|
<div id="footer" class="footer">
|
||||||
<p>This is your footer</p>
|
<p>Coś nie działa? napisz na FB Sąsiedzi</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import { type Ref, computed, defineComponent, inject, ref } from 'vue';
|
import { type Ref, computed, defineComponent, inject, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import type LoginService from '@/account/login.service';
|
import type LoginService from '@/account/login.service';
|
||||||
import type AccountService from '@/account/account.service';
|
import type AccountService from '@/account/account.service';
|
||||||
import EntitiesMenu from '@/entities/entities-menu.vue';
|
import EntitiesMenu from '@/entities/entities-menu.vue';
|
||||||
|
|
||||||
import { useStore } from '@/store';
|
import { useStore } from '@/store';
|
||||||
|
import UserAccountService from '@/entities/user-account/user-account.service';
|
||||||
|
import { useAlertService } from '@/shared/alert/alert.service';
|
||||||
|
import type { IUserAccount } from '@/shared/model/user-account.model';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
compatConfig: { MODE: 3 },
|
compatConfig: { MODE: 3 },
|
||||||
@@ -27,6 +30,21 @@ export default defineComponent({
|
|||||||
const inProduction = computed(() => store.activeProfiles.indexOf('prod') > -1);
|
const inProduction = computed(() => store.activeProfiles.indexOf('prod') > -1);
|
||||||
const authenticated = computed(() => store.authenticated);
|
const authenticated = computed(() => store.authenticated);
|
||||||
|
|
||||||
|
const userAccountService = inject('userAccountService', () => new UserAccountService());
|
||||||
|
const userAccount: Ref<IUserAccount> = ref({});
|
||||||
|
|
||||||
|
const retrieveUserAccount = async () => {
|
||||||
|
try {
|
||||||
|
const res = await userAccountService().getCurrentUser();
|
||||||
|
userAccount.value = res;
|
||||||
|
} catch (error) {
|
||||||
|
userAccount.value = {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log('Asdf');
|
||||||
|
retrieveUserAccount();
|
||||||
|
console.log('Asdf2');
|
||||||
|
|
||||||
const openLogin = () => {
|
const openLogin = () => {
|
||||||
loginService.login();
|
loginService.login();
|
||||||
};
|
};
|
||||||
@@ -53,12 +71,14 @@ export default defineComponent({
|
|||||||
subIsActive,
|
subIsActive,
|
||||||
accountService,
|
accountService,
|
||||||
openLogin,
|
openLogin,
|
||||||
|
userAccount,
|
||||||
version,
|
version,
|
||||||
currentLanguage,
|
currentLanguage,
|
||||||
hasAnyAuthorityValues,
|
hasAnyAuthorityValues,
|
||||||
openAPIEnabled,
|
openAPIEnabled,
|
||||||
inProduction,
|
inProduction,
|
||||||
authenticated,
|
authenticated,
|
||||||
|
retrieveUserAccount,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<b-navbar data-cy="navbar" toggleable="md" type="dark" class="jh-navbar">
|
<b-navbar data-cy="navbar" toggleable="md" type="dark" class="jh-navbar">
|
||||||
<b-navbar-brand class="logo" b-link to="/">
|
<b-navbar-brand class="logo" b-link to="/">
|
||||||
<span class="logo-img"></span>
|
<!-- <span class="logo-img"></span>-->
|
||||||
<span class="navbar-title">Sasiedzi</span> <span class="navbar-version">{{ version }}</span>
|
<!-- <span class="navbar-title">Sasiedzi</span>-->
|
||||||
|
<!-- <span class="navbar-version">{{ // version }}</span>-->
|
||||||
|
<!-- <span class="navbar-version"><span class="bold">PLN {{ userAccount.name}}</span></span>-->
|
||||||
|
|
||||||
|
<router-link :to="{ name: 'MyTransaction', params: { userAccountId: userAccount.id } }">
|
||||||
|
<!-- <router-link :to="{ name: 'TransactionView' }">-->
|
||||||
|
<span class="navbar-title"> Saldo: {{ userAccount.balance }} PLN </span>
|
||||||
|
</router-link>
|
||||||
|
|
||||||
|
<button class="btn" @click="retrieveUserAccount">
|
||||||
|
<font-awesome-icon :icon="['fas', 'sync']" />
|
||||||
|
</button>
|
||||||
</b-navbar-brand>
|
</b-navbar-brand>
|
||||||
<b-navbar-toggle
|
<b-navbar-toggle
|
||||||
right
|
right
|
||||||
@@ -30,6 +41,12 @@
|
|||||||
<span>Wszystkie wydarzenia</span>
|
<span>Wszystkie wydarzenia</span>
|
||||||
</span>
|
</span>
|
||||||
</b-nav-item>
|
</b-nav-item>
|
||||||
|
<b-nav-item to="/transaction" exact>
|
||||||
|
<span>
|
||||||
|
<font-awesome-icon icon="th-list" />
|
||||||
|
<span>Finanse</span>
|
||||||
|
</span>
|
||||||
|
</b-nav-item>
|
||||||
<!-- <b-nav-item-dropdown right id="entity-menu" v-if="authenticated" active-class="active" class="pointer" data-cy="entity">-->
|
<!-- <b-nav-item-dropdown right id="entity-menu" v-if="authenticated" active-class="active" class="pointer" data-cy="entity">-->
|
||||||
<!-- <template #button-content>-->
|
<!-- <template #button-content>-->
|
||||||
<!-- <span class="navbar-dropdown-menu">-->
|
<!-- <span class="navbar-dropdown-menu">-->
|
||||||
@@ -88,7 +105,8 @@
|
|||||||
<template #button-content>
|
<template #button-content>
|
||||||
<span class="navbar-dropdown-menu">
|
<span class="navbar-dropdown-menu">
|
||||||
<font-awesome-icon icon="user" />
|
<font-awesome-icon icon="user" />
|
||||||
<span class="no-bold">Account</span>
|
<!-- <span class="no-bold">Stan konta {{userAccount.balance}} PLN</span>-->
|
||||||
|
<span class="no-bold">{{ userAccount.name }}</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<b-dropdown-item data-cy="logout" v-if="authenticated" @click="logout()" id="logout" active-class="active">
|
<b-dropdown-item data-cy="logout" v-if="authenticated" @click="logout()" id="logout" active-class="active">
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ describe('Service Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should partial update a Charge', async () => {
|
it('should partial update a Charge', async () => {
|
||||||
const patchObject = { chargeDate: dayjs(currentDate).format(DATE_FORMAT), type: 'BBBBBB', ...new Charge() };
|
const patchObject = { amount: 1, ...new Charge() };
|
||||||
const returnedFromService = Object.assign(patchObject, elemDefault);
|
const returnedFromService = Object.assign(patchObject, elemDefault);
|
||||||
|
|
||||||
const expected = { chargeDate: currentDate, ...returnedFromService };
|
const expected = { chargeDate: currentDate, ...returnedFromService };
|
||||||
|
|||||||
@@ -12,6 +12,14 @@
|
|||||||
<font-awesome-icon icon="asterisk" />
|
<font-awesome-icon icon="asterisk" />
|
||||||
<span>Registration</span>
|
<span>Registration</span>
|
||||||
</b-dropdown-item>
|
</b-dropdown-item>
|
||||||
|
<b-dropdown-item to="/transaction">
|
||||||
|
<font-awesome-icon icon="asterisk" />
|
||||||
|
<span>Transaction</span>
|
||||||
|
</b-dropdown-item>
|
||||||
|
<b-dropdown-item to="/user-account">
|
||||||
|
<font-awesome-icon icon="asterisk" />
|
||||||
|
<span>User Account</span>
|
||||||
|
</b-dropdown-item>
|
||||||
<!-- jhipster-needle-add-entity-to-menu - JHipster will add entities to the menu here -->
|
<!-- jhipster-needle-add-entity-to-menu - JHipster will add entities to the menu here -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { defineComponent, provide } from 'vue';
|
|||||||
import ChargeService from './charge/charge.service';
|
import ChargeService from './charge/charge.service';
|
||||||
import EventService from './event/event.service';
|
import EventService from './event/event.service';
|
||||||
import RegistrationService from './registration/registration.service';
|
import RegistrationService from './registration/registration.service';
|
||||||
|
import TransactionService from './transaction/transaction.service';
|
||||||
|
import UserAccountService from './user-account/user-account.service';
|
||||||
import UserService from '@/entities/user/user.service';
|
import UserService from '@/entities/user/user.service';
|
||||||
// jhipster-needle-add-entity-service-to-entities-component-import - JHipster will import entities services here
|
// jhipster-needle-add-entity-service-to-entities-component-import - JHipster will import entities services here
|
||||||
|
|
||||||
@@ -14,6 +16,8 @@ export default defineComponent({
|
|||||||
provide('chargeService', () => new ChargeService());
|
provide('chargeService', () => new ChargeService());
|
||||||
provide('eventService', () => new EventService());
|
provide('eventService', () => new EventService());
|
||||||
provide('registrationService', () => new RegistrationService());
|
provide('registrationService', () => new RegistrationService());
|
||||||
|
provide('transactionService', () => new TransactionService());
|
||||||
|
provide('userAccountService', () => new UserAccountService());
|
||||||
// jhipster-needle-add-entity-service-to-entities-component - JHipster will import entities services here
|
// jhipster-needle-add-entity-service-to-entities-component - JHipster will import entities services here
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,15 +10,19 @@ import type { IRegistration } from '@/shared/model/registration.model';
|
|||||||
import RegistrationService from '@/entities/registration/registration.service';
|
import RegistrationService from '@/entities/registration/registration.service';
|
||||||
import UserService from '@/entities/user/user.service';
|
import UserService from '@/entities/user/user.service';
|
||||||
import type AccountService from '@/account/account.service';
|
import type AccountService from '@/account/account.service';
|
||||||
|
import { useStore } from '@/store';
|
||||||
|
// import type EventService from '@/account/account.service';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
compatConfig: { MODE: 3 },
|
compatConfig: { MODE: 3 },
|
||||||
name: 'EventDetails',
|
name: 'EventDetails',
|
||||||
setup() {
|
setup() {
|
||||||
|
console.log('jestem tu');
|
||||||
const eventService = inject('eventService', () => new EventService());
|
const eventService = inject('eventService', () => new EventService());
|
||||||
const alertService = inject('alertService', () => useAlertService(), true);
|
const alertService = inject('alertService', () => useAlertService(), true);
|
||||||
const { formatDateShort } = useDateFormat();
|
const { formatDateShort } = useDateFormat();
|
||||||
const dataUtils = useDataUtils();
|
const dataUtils = useDataUtils();
|
||||||
|
const isCurrentEvent = ref(false);
|
||||||
|
|
||||||
const registrationService = inject('registrationService', () => new RegistrationService());
|
const registrationService = inject('registrationService', () => new RegistrationService());
|
||||||
const accountService = inject<AccountService>('accountService');
|
const accountService = inject<AccountService>('accountService');
|
||||||
@@ -30,9 +34,18 @@ export default defineComponent({
|
|||||||
const event: Ref<IEvent> = ref({});
|
const event: Ref<IEvent> = ref({});
|
||||||
const sortedAndIndexedRegistrations: Ref<IRegistration[]> = ref([]);
|
const sortedAndIndexedRegistrations: Ref<IRegistration[]> = ref([]);
|
||||||
|
|
||||||
|
let store = useStore();
|
||||||
|
|
||||||
const retrieveEvent = async (eventId: string) => {
|
const retrieveEvent = async (eventId: string) => {
|
||||||
try {
|
try {
|
||||||
|
console.log('event' + eventId);
|
||||||
|
let currentEventId = '' + store.currentEventId;
|
||||||
|
if (eventId == 'useCurrentEventId') {
|
||||||
|
eventId = currentEventId;
|
||||||
|
console.log('event2' + eventId);
|
||||||
|
}
|
||||||
const res = await eventService().find(eventId);
|
const res = await eventService().find(eventId);
|
||||||
|
isCurrentEvent.value = eventId == currentEventId;
|
||||||
event.value = res;
|
event.value = res;
|
||||||
// sortedAndIndexedRegistrations.value = res.registrations;
|
// sortedAndIndexedRegistrations.value = res.registrations;
|
||||||
sortedAndIndexedRegistrations.value = res.registrations.sort(
|
sortedAndIndexedRegistrations.value = res.registrations.sort(
|
||||||
@@ -43,8 +56,11 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('asdfasd' + route.meta?.eventId);
|
||||||
if (route.params?.eventId) {
|
if (route.params?.eventId) {
|
||||||
retrieveEvent(route.params.eventId as string);
|
retrieveEvent(route.params.eventId as string);
|
||||||
|
} else if (route.meta?.eventId) {
|
||||||
|
retrieveEvent(route.meta.eventId as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// const sortedAndIndexedRegistrations = () => {
|
// const sortedAndIndexedRegistrations = () => {
|
||||||
@@ -105,7 +121,9 @@ export default defineComponent({
|
|||||||
alertService,
|
alertService,
|
||||||
hasAnyAuthorityValues,
|
hasAnyAuthorityValues,
|
||||||
accountService,
|
accountService,
|
||||||
|
eventService,
|
||||||
event,
|
event,
|
||||||
|
isCurrentEvent,
|
||||||
...dataUtils,
|
...dataUtils,
|
||||||
formatDateShort,
|
formatDateShort,
|
||||||
previousState,
|
previousState,
|
||||||
@@ -127,5 +145,21 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
return this.hasAnyAuthorityValues[authorities] ?? false;
|
return this.hasAnyAuthorityValues[authorities] ?? false;
|
||||||
},
|
},
|
||||||
|
settle(): void {
|
||||||
|
this.isSaving = true;
|
||||||
|
if (this.event.id) {
|
||||||
|
this.eventService()
|
||||||
|
.settle(this.event)
|
||||||
|
.then(param => {
|
||||||
|
this.isSaving = false;
|
||||||
|
// this.previousState();
|
||||||
|
this.alertService.showInfo(`The event has been settled up`);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.isSaving = false;
|
||||||
|
this.alertService.showHttpError(error.response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-8">
|
<div class="col-12">
|
||||||
<div v-if="event">
|
<div v-if="event">
|
||||||
<!-- <h2 class="jh-entity-heading" data-cy="eventDetailsHeading"><span>Event</span> {{ event.id }}</h2>-->
|
<!-- <h2 class="jh-entity-heading" data-cy="eventDetailsHeading"><span>Event</span> {{ event.id }}</h2>-->
|
||||||
<dl class="row jh-entity-details">
|
<dl class="row jh-entity-details">
|
||||||
@@ -35,11 +35,27 @@
|
|||||||
<span>{{ event.comment }}</span>
|
<span>{{ event.comment }}</span>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<router-link :to="{ name: 'RegistrationCreateForEvent', params: { eventId: event.id } }" custom v-slot="{ navigate }">
|
<router-link
|
||||||
|
:to="{ name: 'RegistrationCreateForEvent', params: { eventId: event.id } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
v-if="event.active"
|
||||||
|
>
|
||||||
<button @click="navigate" class="btn btn-primary">
|
<button @click="navigate" class="btn btn-primary">
|
||||||
<font-awesome-icon icon="plus"></font-awesome-icon> <span>Dołącz do wydarzenia</span>
|
<font-awesome-icon icon="plus"></font-awesome-icon> <span>Dołącz do wydarzenia</span>
|
||||||
</button>
|
</button>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<!-- <router-link-->
|
||||||
|
<!-- :to="{ name: 'TransactionFieldPayment', params: { paymentForFieldByEventId: event.id } }"-->
|
||||||
|
<!-- custom-->
|
||||||
|
<!-- v-slot="{ navigate }"-->
|
||||||
|
<!-- v-if="hasAnyAuthority(['ROLE_ADMIN', 'ROLE_COUNTER'])"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <button @click="navigate" class="btn btn-primary">-->
|
||||||
|
<!-- <font-awesome-icon icon="plus"></font-awesome-icon> <span>Opłać boisko</span>-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<!-- </router-link>-->
|
||||||
|
|
||||||
<div class="table-responsive" v-if="event.registrations && event.registrations.length > 0">
|
<div class="table-responsive" v-if="event.registrations && event.registrations.length > 0">
|
||||||
<table class="table table-striped" aria-describedby="event.registrations">
|
<table class="table table-striped" aria-describedby="event.registrations">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -58,15 +74,22 @@
|
|||||||
<!-- Display row number or empty if not active -->
|
<!-- Display row number or empty if not active -->
|
||||||
{{ getRegistrationIndex(index) }}
|
{{ getRegistrationIndex(index) }}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ formatDateShort(registration.dateTime) || '' }}</td>
|
|
||||||
<td>
|
<td>
|
||||||
{{ registration.playerName }}
|
<span :class="{ strikethrough: registration.active === false }">{{ formatDateShort(registration.dateTime) || '' }}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span :class="{ strikethrough: registration.active === false }">{{ registration.playerName }}</span>
|
||||||
<b-button
|
<b-button
|
||||||
@click="prepareRemove(registration)"
|
@click="prepareRemove(registration)"
|
||||||
variant="danger"
|
variant="danger"
|
||||||
class="btn btn-sm"
|
class="btn btn-sm"
|
||||||
data-cy="entityDeleteButton"
|
data-cy="entityDeleteButton"
|
||||||
v-if="(registration.id && registration.user?.id == currentUserId) || hasAnyAuthority('ROLE_ADMIN')"
|
v-if="
|
||||||
|
((registration.id && registration.user?.id == currentUserId && isCurrentEvent) ||
|
||||||
|
hasAnyAuthority(['ROLE_ADMIN', 'ROLE_COUNTER'])) &&
|
||||||
|
registration.active !== false &&
|
||||||
|
(event.active || (event.editable && hasAnyAuthority(['ROLE_COUNTER'])) || hasAnyAuthority(['ROLE_ADMIN']))
|
||||||
|
"
|
||||||
v-b-modal.removeEntity
|
v-b-modal.removeEntity
|
||||||
>
|
>
|
||||||
<font-awesome-icon icon="times"></font-awesome-icon>
|
<font-awesome-icon icon="times"></font-awesome-icon>
|
||||||
@@ -138,6 +161,72 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="btn btn-primary float-right"
|
||||||
|
v-if="(event.editable && hasAnyAuthority(['ROLE_COUNTER'])) || hasAnyAuthority(['ROLE_ADMIN'])"
|
||||||
|
@click="settle()"
|
||||||
|
>
|
||||||
|
<font-awesome-icon icon="sync"></font-awesome-icon> <span v-if="!event.charged">Rozlicz wydarzenie</span
|
||||||
|
><span v-if="event.charged">Przelicz ponownie zobowiązania</span>
|
||||||
|
</button>
|
||||||
|
<router-link
|
||||||
|
v-if="event.id && event.paid == false"
|
||||||
|
:to="{ name: 'TransactionFieldPayment', params: { paymentForFieldByEventId: event.id } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
><!-- <router-link
|
||||||
|
v-if="transaction.id"
|
||||||
|
:to="{ name: 'TransactionCreateOpposite', params: { opposingTransactionId: transaction.id } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
>-->
|
||||||
|
<button @click="navigate" class="btn btn-primary" v-if="hasAnyAuthority(['ROLE_ADMIN', 'ROLE_COUNTER'])">
|
||||||
|
<font-awesome-icon icon="pencil-alt"></font-awesome-icon> <span>Dodaj płatność za boisko</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
|
||||||
|
<router-link
|
||||||
|
v-if="event.charged && event.editable"
|
||||||
|
:to="{ name: 'TransactionPaymentsForTransaction', params: { paymentsForTransactionId: event.chargeTransactionId } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
><!-- <router-link
|
||||||
|
v-if="transaction.id"
|
||||||
|
:to="{ name: 'TransactionCreateOpposite', params: { opposingTransactionId: transaction.id } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
>-->
|
||||||
|
<button @click="navigate" class="btn btn-primary" v-if="hasAnyAuthority(['ROLE_ADMIN', 'ROLE_COUNTER'])">
|
||||||
|
<font-awesome-icon icon="pencil-alt"></font-awesome-icon> <span>Dodaj wpłaty na konto</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
<div class="table-responsive" v-if="event.transactions && event.transactions.length > 0">
|
||||||
|
Rozliczenie:
|
||||||
|
<table class="table table-striped" aria-describedby="transactions">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<!-- <th/>-->
|
||||||
|
<!-- <th/>-->
|
||||||
|
<!-- <th/>-->
|
||||||
|
<th />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="transaction in event.transactions" :key="transaction.id" data-cy="entityTable">
|
||||||
|
<td>
|
||||||
|
<router-link :to="{ name: 'TransactionView', params: { transactionId: transaction.id } }"
|
||||||
|
>{{ transaction.date }} {{ transaction.type }}
|
||||||
|
</router-link>
|
||||||
|
<div v-if="transaction.comment">{{ transaction.comment }}</div>
|
||||||
|
</td>
|
||||||
|
<!-- <td>{{ transaction.type }}</td>-->
|
||||||
|
<!-- <td>{{ transaction.date }}</td>-->
|
||||||
|
<!-- <td>{{ transaction.comment }}</td>-->
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" src="./event-details.component.ts"></script>
|
<script lang="ts" src="./event-details.component.ts"></script>
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ describe('Service Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should partial update a Event', async () => {
|
it('should partial update a Event', async () => {
|
||||||
const patchObject = { name: 'BBBBBB', date: dayjs(currentDate).format(DATE_FORMAT), cost: 1, ...new Event() };
|
const patchObject = { name: 'BBBBBB', playersLimit: 1, cost: 1, ...new Event() };
|
||||||
const returnedFromService = Object.assign(patchObject, elemDefault);
|
const returnedFromService = Object.assign(patchObject, elemDefault);
|
||||||
|
|
||||||
const expected = { date: currentDate, ...returnedFromService };
|
const expected = { date: currentDate, ...returnedFromService };
|
||||||
|
|||||||
@@ -57,6 +57,19 @@ export default class EventService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public settle(entity: IEvent): Promise<IEvent> {
|
||||||
|
return new Promise<IEvent>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.post(`${baseApiUrl}/${entity.id}/settle`, entity)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public update(entity: IEvent): Promise<IEvent> {
|
public update(entity: IEvent): Promise<IEvent> {
|
||||||
return new Promise<IEvent>((resolve, reject) => {
|
return new Promise<IEvent>((resolve, reject) => {
|
||||||
axios
|
axios
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<button class="btn btn-info mr-2" @click="handleSyncList" :disabled="isFetching">
|
<button class="btn btn-info mr-2" @click="handleSyncList" :disabled="isFetching">
|
||||||
<font-awesome-icon icon="sync" :spin="isFetching"></font-awesome-icon> <span>Odśwież listę</span>
|
<font-awesome-icon icon="sync" :spin="isFetching"></font-awesome-icon> <span>Odśwież listę</span>
|
||||||
</button>
|
</button>
|
||||||
<router-link :to="{ name: 'EventCreate' }" custom v-slot="{ navigate }" v-if="hasAnyAuthority('ROLE_ADMIN')">
|
<router-link :to="{ name: 'EventCreate' }" custom v-slot="{ navigate }" v-if="hasAnyAuthority(['ROLE_ADMIN', 'ROLE_COUNTER'])">
|
||||||
<button
|
<button
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
id="jh-create-entity"
|
id="jh-create-entity"
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
:to="{ name: 'EventEdit', params: { eventId: event.id } }"
|
:to="{ name: 'EventEdit', params: { eventId: event.id } }"
|
||||||
custom
|
custom
|
||||||
v-slot="{ navigate }"
|
v-slot="{ navigate }"
|
||||||
v-if="hasAnyAuthority('ROLE_ADMIN')"
|
v-if="hasAnyAuthority(['ROLE_ADMIN', 'ROLE_COUNTER'])"
|
||||||
>
|
>
|
||||||
<button @click="navigate" class="btn btn-primary btn-sm edit" data-cy="entityEditButton">
|
<button @click="navigate" class="btn btn-primary btn-sm edit" data-cy="entityEditButton">
|
||||||
<font-awesome-icon icon="pencil-alt"></font-awesome-icon>
|
<font-awesome-icon icon="pencil-alt"></font-awesome-icon>
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ export default defineComponent({
|
|||||||
registration.value = res;
|
registration.value = res;
|
||||||
// Assuming you can retrieve event details here
|
// Assuming you can retrieve event details here
|
||||||
eventName.value = '' + registration.value.event?.name; // Set this from the event details
|
eventName.value = '' + registration.value.event?.name; // Set this from the event details
|
||||||
|
currentUserFullName.value = '' + registration.value.user?.firstName + ' ' + registration.value.user?.lastName;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alertService.showHttpError(error.response);
|
alertService.showHttpError(error.response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ describe('Service Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should partial update a Registration', async () => {
|
it('should partial update a Registration', async () => {
|
||||||
const patchObject = { comment: 'BBBBBB', ...new Registration() };
|
const patchObject = { playerName: 'BBBBBB', comment: 'BBBBBB', ...new Registration() };
|
||||||
const returnedFromService = Object.assign(patchObject, elemDefault);
|
const returnedFromService = Object.assign(patchObject, elemDefault);
|
||||||
|
|
||||||
const expected = { dateTime: currentDate, ...returnedFromService };
|
const expected = { dateTime: currentDate, ...returnedFromService };
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/* tslint:disable max-line-length */
|
||||||
|
import { vitest } from 'vitest';
|
||||||
|
import { type MountingOptions, shallowMount } from '@vue/test-utils';
|
||||||
|
import sinon, { type SinonStubbedInstance } from 'sinon';
|
||||||
|
import { type RouteLocation } from 'vue-router';
|
||||||
|
|
||||||
|
import TransactionDetails from './transaction-details.vue';
|
||||||
|
import TransactionService from './transaction.service';
|
||||||
|
import AlertService from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
type TransactionDetailsComponentType = InstanceType<typeof TransactionDetails>;
|
||||||
|
|
||||||
|
let route: Partial<RouteLocation>;
|
||||||
|
const routerGoMock = vitest.fn();
|
||||||
|
|
||||||
|
vitest.mock('vue-router', () => ({
|
||||||
|
useRoute: () => route,
|
||||||
|
useRouter: () => ({ go: routerGoMock }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const transactionSample = { id: 123 };
|
||||||
|
|
||||||
|
describe('Component Tests', () => {
|
||||||
|
let alertService: AlertService;
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vitest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Transaction Management Detail Component', () => {
|
||||||
|
let transactionServiceStub: SinonStubbedInstance<TransactionService>;
|
||||||
|
let mountOptions: MountingOptions<TransactionDetailsComponentType>['global'];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
route = {};
|
||||||
|
transactionServiceStub = sinon.createStubInstance<TransactionService>(TransactionService);
|
||||||
|
|
||||||
|
alertService = new AlertService({
|
||||||
|
bvToast: {
|
||||||
|
toast: vitest.fn(),
|
||||||
|
} as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
mountOptions = {
|
||||||
|
stubs: {
|
||||||
|
'font-awesome-icon': true,
|
||||||
|
'router-link': true,
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
alertService,
|
||||||
|
transactionService: () => transactionServiceStub,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Navigate to details', () => {
|
||||||
|
it('Should call load all on init', async () => {
|
||||||
|
// GIVEN
|
||||||
|
transactionServiceStub.find.resolves(transactionSample);
|
||||||
|
route = {
|
||||||
|
params: {
|
||||||
|
transactionId: `${123}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const wrapper = shallowMount(TransactionDetails, { global: mountOptions });
|
||||||
|
const comp = wrapper.vm;
|
||||||
|
// WHEN
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(comp.transaction).toMatchObject(transactionSample);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Previous state', () => {
|
||||||
|
it('Should go previous state', async () => {
|
||||||
|
transactionServiceStub.find.resolves(transactionSample);
|
||||||
|
const wrapper = shallowMount(TransactionDetails, { global: mountOptions });
|
||||||
|
const comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
comp.previousState();
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
expect(routerGoMock).toHaveBeenCalledWith(-1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import { type Ref, defineComponent, inject, ref } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
import TransactionService from './transaction.service';
|
||||||
|
import { type ITransaction } from '@/shared/model/transaction.model';
|
||||||
|
import { useAlertService } from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
compatConfig: { MODE: 3 },
|
||||||
|
name: 'TransactionDetails',
|
||||||
|
setup() {
|
||||||
|
const transactionService = inject('transactionService', () => new TransactionService());
|
||||||
|
const alertService = inject('alertService', () => useAlertService(), true);
|
||||||
|
const hasAnyAuthorityValues: Ref<any> = ref({});
|
||||||
|
const accountService = inject<AccountService>('accountService');
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const previousState = () => router.go(-1);
|
||||||
|
const transaction: Ref<ITransaction> = ref({});
|
||||||
|
|
||||||
|
const retrieveTransaction = async transactionId => {
|
||||||
|
try {
|
||||||
|
const res = await transactionService().find(transactionId);
|
||||||
|
transaction.value = res;
|
||||||
|
} catch (error) {
|
||||||
|
alertService.showHttpError(error.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (route.params?.transactionId) {
|
||||||
|
retrieveTransaction(route.params.transactionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
alertService,
|
||||||
|
transaction,
|
||||||
|
accountService,
|
||||||
|
hasAnyAuthorityValues,
|
||||||
|
previousState,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
hasAnyAuthority(authorities: any): boolean {
|
||||||
|
this.accountService.hasAnyAuthorityAndCheckAuth(authorities).then(value => {
|
||||||
|
if (this.hasAnyAuthorityValues[authorities] !== value) {
|
||||||
|
this.hasAnyAuthorityValues = { ...this.hasAnyAuthorityValues, [authorities]: value };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return this.hasAnyAuthorityValues[authorities] ?? false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
<template>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-12">
|
||||||
|
<div v-if="transaction">
|
||||||
|
<h2 class="jh-entity-heading" data-cy="transactionDetailsHeading"><span>Transaction</span> {{ transaction.id }}</h2>
|
||||||
|
<dl class="row jh-entity-details">
|
||||||
|
<dt>
|
||||||
|
<span>Type</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<span>{{ transaction.type }}</span>
|
||||||
|
</dd>
|
||||||
|
<dt>
|
||||||
|
<span>Date</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<span>{{ transaction.date }}</span>
|
||||||
|
</dd>
|
||||||
|
<dt>
|
||||||
|
<span>Comment</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<span>{{ transaction.comment }}</span>
|
||||||
|
</dd>
|
||||||
|
<dt>
|
||||||
|
<span>Event</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<div v-if="transaction.event">
|
||||||
|
<router-link :to="{ name: 'EventView', params: { eventId: transaction.event.id } }">{{ transaction.event.name }}</router-link>
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<button type="submit" @click.prevent="previousState()" class="btn btn-info" data-cy="entityDetailsBackButton">
|
||||||
|
<font-awesome-icon icon="arrow-left"></font-awesome-icon> <span>Back</span>
|
||||||
|
</button>
|
||||||
|
<router-link
|
||||||
|
v-if="transaction.id"
|
||||||
|
:to="{ name: 'TransactionEdit', params: { transactionId: transaction.id } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
>
|
||||||
|
<button @click="navigate" class="btn btn-primary" v-if="hasAnyAuthority(['ROLE_ADMIN', 'ROLE_COUNTER'])">
|
||||||
|
<font-awesome-icon icon="pencil-alt"></font-awesome-icon> <span>Edit</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
v-if="transaction.id && transaction.type == 'MATCH'"
|
||||||
|
:to="{ name: 'TransactionPaymentsForTransaction', params: { paymentsForTransactionId: transaction.id } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
><!-- <router-link
|
||||||
|
v-if="transaction.id"
|
||||||
|
:to="{ name: 'TransactionCreateOpposite', params: { opposingTransactionId: transaction.id } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
>-->
|
||||||
|
<button @click="navigate" class="btn btn-primary" v-if="hasAnyAuthority(['ROLE_ADMIN', 'ROLE_COUNTER'])">
|
||||||
|
<font-awesome-icon icon="pencil-alt"></font-awesome-icon> <span>Dodaj wpłaty na konto</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
<!-- :to="{ name: 'TransactionPaymentsForTransaction', params: { paymentsForTransactionId: transaction.id } }"-->
|
||||||
|
<!-- <router-link-->
|
||||||
|
<!-- :to="{ name: 'TransactionPaymentsForTransaction', params: { transactionId: transaction.id } }"-->
|
||||||
|
|
||||||
|
<!-- custom-->
|
||||||
|
<!-- v-slot="{ navigate }"-->
|
||||||
|
<!-- v-if="hasAnyAuthority(['ROLE_ADMIN', 'ROLE_COUNTER'])"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- <button @click="navigate" class="btn btn-primary">-->
|
||||||
|
<!-- <font-awesome-icon icon="plus"></font-awesome-icon> <span>Dodaj wpłaty na konto</span>-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<!-- </router-link>-->
|
||||||
|
<!-- <router-link :to="{ name: 'TransactionCreateOpposite', params: { opposingTransactionId: transaction.id } }">Create opposite transaction</router-link>-->
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped" aria-describedby="event.registrations">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col"><span>#</span></th>
|
||||||
|
<th scope="col"><span>Account</span></th>
|
||||||
|
<th scope="col"><span>Amount</span></th>
|
||||||
|
<th scope="col"><span>Comment</span></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="(item, index) in transaction.transactionItems" :key="index" class="transaction-item">
|
||||||
|
<td>
|
||||||
|
{{ index + 1 }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ item.userAccount?.name }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ item.amount }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ item.comment }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" src="./transaction-details.component.ts"></script>
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/* tslint:disable max-line-length */
|
||||||
|
import { vitest } from 'vitest';
|
||||||
|
import { type MountingOptions, shallowMount } from '@vue/test-utils';
|
||||||
|
import sinon, { type SinonStubbedInstance } from 'sinon';
|
||||||
|
import { type RouteLocation } from 'vue-router';
|
||||||
|
|
||||||
|
import TransactionUpdate from './transaction-update.vue';
|
||||||
|
import TransactionService from './transaction.service';
|
||||||
|
import AlertService from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
import EventService from '@/entities/event/event.service';
|
||||||
|
|
||||||
|
type TransactionUpdateComponentType = InstanceType<typeof TransactionUpdate>;
|
||||||
|
|
||||||
|
let route: Partial<RouteLocation>;
|
||||||
|
const routerGoMock = vitest.fn();
|
||||||
|
|
||||||
|
vitest.mock('vue-router', () => ({
|
||||||
|
useRoute: () => route,
|
||||||
|
useRouter: () => ({ go: routerGoMock }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const transactionSample = { id: 123 };
|
||||||
|
|
||||||
|
describe('Component Tests', () => {
|
||||||
|
let mountOptions: MountingOptions<TransactionUpdateComponentType>['global'];
|
||||||
|
let alertService: AlertService;
|
||||||
|
|
||||||
|
describe('Transaction Management Update Component', () => {
|
||||||
|
let comp: TransactionUpdateComponentType;
|
||||||
|
let transactionServiceStub: SinonStubbedInstance<TransactionService>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
route = {};
|
||||||
|
transactionServiceStub = sinon.createStubInstance<TransactionService>(TransactionService);
|
||||||
|
transactionServiceStub.retrieve.onFirstCall().resolves(Promise.resolve([]));
|
||||||
|
|
||||||
|
alertService = new AlertService({
|
||||||
|
bvToast: {
|
||||||
|
toast: vitest.fn(),
|
||||||
|
} as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
mountOptions = {
|
||||||
|
stubs: {
|
||||||
|
'font-awesome-icon': true,
|
||||||
|
'b-input-group': true,
|
||||||
|
'b-input-group-prepend': true,
|
||||||
|
'b-form-datepicker': true,
|
||||||
|
'b-form-input': true,
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
alertService,
|
||||||
|
transactionService: () => transactionServiceStub,
|
||||||
|
eventService: () =>
|
||||||
|
sinon.createStubInstance<EventService>(EventService, {
|
||||||
|
retrieve: sinon.stub().resolves({}),
|
||||||
|
} as any),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vitest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('save', () => {
|
||||||
|
it('Should call update service on save for existing entity', async () => {
|
||||||
|
// GIVEN
|
||||||
|
const wrapper = shallowMount(TransactionUpdate, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
comp.transaction = transactionSample;
|
||||||
|
transactionServiceStub.update.resolves(transactionSample);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
comp.save();
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(transactionServiceStub.update.calledWith(transactionSample)).toBeTruthy();
|
||||||
|
expect(comp.isSaving).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should call create service on save for new entity', async () => {
|
||||||
|
// GIVEN
|
||||||
|
const entity = {};
|
||||||
|
transactionServiceStub.create.resolves(entity);
|
||||||
|
const wrapper = shallowMount(TransactionUpdate, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
comp.transaction = entity;
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
comp.save();
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(transactionServiceStub.create.calledWith(entity)).toBeTruthy();
|
||||||
|
expect(comp.isSaving).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Before route enter', () => {
|
||||||
|
it('Should retrieve data', async () => {
|
||||||
|
// GIVEN
|
||||||
|
transactionServiceStub.find.resolves(transactionSample);
|
||||||
|
transactionServiceStub.retrieve.resolves([transactionSample]);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
route = {
|
||||||
|
params: {
|
||||||
|
transactionId: `${transactionSample.id}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const wrapper = shallowMount(TransactionUpdate, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(comp.transaction).toMatchObject(transactionSample);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Previous state', () => {
|
||||||
|
it('Should go previous state', async () => {
|
||||||
|
transactionServiceStub.find.resolves(transactionSample);
|
||||||
|
const wrapper = shallowMount(TransactionUpdate, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
comp.previousState();
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
expect(routerGoMock).toHaveBeenCalledWith(-1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
import { type Ref, computed, defineComponent, inject, ref } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useVuelidate } from '@vuelidate/core';
|
||||||
|
|
||||||
|
import TransactionService from './transaction.service';
|
||||||
|
import { useValidation } from '@/shared/composables';
|
||||||
|
import { useAlertService } from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
import EventService from '@/entities/event/event.service';
|
||||||
|
import { type IEvent } from '@/shared/model/event.model';
|
||||||
|
import { type ITransaction, Transaction } from '@/shared/model/transaction.model';
|
||||||
|
import { TransactionType } from '@/shared/model/enumerations/transaction-type.model';
|
||||||
|
import { type IUserAccount } from '@/shared/model/user-account.model';
|
||||||
|
import UserAccountService from '@/entities/user-account/user-account.service';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
compatConfig: { MODE: 3 },
|
||||||
|
name: 'TransactionUpdate',
|
||||||
|
setup() {
|
||||||
|
const transactionService = inject('transactionService', () => new TransactionService());
|
||||||
|
const alertService = inject('alertService', () => useAlertService(), true);
|
||||||
|
|
||||||
|
const transaction: Ref<ITransaction> = ref(new Transaction());
|
||||||
|
|
||||||
|
transaction.value.transactionItems = [];
|
||||||
|
const dictUserAccounts = ref([]) as Ref<IUserAccount[]>;
|
||||||
|
|
||||||
|
const eventService = inject('eventService', () => new EventService());
|
||||||
|
const userAccountService = inject('userAccountService', () => new UserAccountService());
|
||||||
|
|
||||||
|
const events: Ref<IEvent[]> = ref([]);
|
||||||
|
const transactionTypeValues: Ref<string[]> = ref(Object.keys(TransactionType));
|
||||||
|
const isSaving = ref(false);
|
||||||
|
const currentLanguage = inject('currentLanguage', () => computed(() => navigator.language ?? 'en'), true);
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const previousState = () => router.go(-1);
|
||||||
|
|
||||||
|
const retrieveTransaction = async (transactionId, opposing) => {
|
||||||
|
try {
|
||||||
|
if (dictUserAccounts.value.length == 0) {
|
||||||
|
const res2 = await userAccountService().retrieve();
|
||||||
|
dictUserAccounts.value = res2.data;
|
||||||
|
}
|
||||||
|
const res = await transactionService().find(transactionId, opposing);
|
||||||
|
transaction.value = res;
|
||||||
|
transaction.value.transactionItems.forEach((item, index) => {
|
||||||
|
const matchingAccount = dictUserAccounts.value.find(account => account.id === item.userAccount.id);
|
||||||
|
transaction.value.transactionItems[index].userAccount = matchingAccount || null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
alertService.showHttpError(error.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const retrieveTransactionForPayments = async transactionId => {
|
||||||
|
try {
|
||||||
|
if (dictUserAccounts.value.length == 0) {
|
||||||
|
const res2 = await userAccountService().retrieve();
|
||||||
|
dictUserAccounts.value = res2.data;
|
||||||
|
}
|
||||||
|
const res = await transactionService().payments(transactionId);
|
||||||
|
transaction.value = res;
|
||||||
|
transaction.value.transactionItems.forEach((item, index) => {
|
||||||
|
const matchingAccount = dictUserAccounts.value.find(account => account.id === item.userAccount.id);
|
||||||
|
transaction.value.transactionItems[index].userAccount = matchingAccount || null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
alertService.showHttpError(error.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const retrieveTransactionForFieldPayment = async eventId => {
|
||||||
|
try {
|
||||||
|
if (dictUserAccounts.value.length == 0) {
|
||||||
|
const res2 = await userAccountService().retrieve();
|
||||||
|
dictUserAccounts.value = res2.data;
|
||||||
|
}
|
||||||
|
const res = await transactionService().fieldPayment(eventId);
|
||||||
|
transaction.value = res;
|
||||||
|
transaction.value.transactionItems.forEach((item, index) => {
|
||||||
|
const matchingAccount = dictUserAccounts.value.find(account => account.id === item.userAccount.id);
|
||||||
|
transaction.value.transactionItems[index].userAccount = matchingAccount || null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
alertService.showHttpError(error.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const retrieveUserAccounts = async () => {
|
||||||
|
if (dictUserAccounts.value.length == 0) {
|
||||||
|
try {
|
||||||
|
const res = await userAccountService().retrieve();
|
||||||
|
console.log('got accounts' + res);
|
||||||
|
dictUserAccounts.value = res.data;
|
||||||
|
} catch (error) {
|
||||||
|
alertService.showHttpError(error.response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
retrieveUserAccounts();
|
||||||
|
|
||||||
|
if (route.params?.transactionId) {
|
||||||
|
console.log('a1');
|
||||||
|
retrieveTransaction(route.params.transactionId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.params?.opposingTransactionId) {
|
||||||
|
console.log('a2');
|
||||||
|
console.log('getting opposite transaction for ' + route.params?.opposingTransactionId);
|
||||||
|
retrieveTransaction(route.params.opposingTransactionId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.params?.paymentsForTransactionId) {
|
||||||
|
console.log('a3');
|
||||||
|
retrieveTransactionForPayments(route.params.paymentsForTransactionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.params?.paymentForFieldByEventId) {
|
||||||
|
console.log('a4');
|
||||||
|
retrieveTransactionForFieldPayment(route.params.paymentForFieldByEventId);
|
||||||
|
}
|
||||||
|
console.log('a5');
|
||||||
|
|
||||||
|
const initRelationships = () => {
|
||||||
|
eventService()
|
||||||
|
.retrieve()
|
||||||
|
.then(res => {
|
||||||
|
events.value = res.data;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
initRelationships();
|
||||||
|
|
||||||
|
const validations = useValidation();
|
||||||
|
const validationRules = {
|
||||||
|
type: {},
|
||||||
|
date: {},
|
||||||
|
comment: {},
|
||||||
|
event: {},
|
||||||
|
// transactionItems: {
|
||||||
|
// $each: {
|
||||||
|
// amount: { required: validations.required, minValue: validations.minValue(0.01) },
|
||||||
|
// comment: {},
|
||||||
|
// locked: {},
|
||||||
|
// userAccount: {},
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
const v$ = useVuelidate(validationRules, transaction as any);
|
||||||
|
v$.value.$validate();
|
||||||
|
|
||||||
|
const addTransactionItem = () => {
|
||||||
|
transaction.value.transactionItems.push({
|
||||||
|
amount: 0,
|
||||||
|
comment: '',
|
||||||
|
locked: false,
|
||||||
|
userAccount: null,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeTransactionItem = (index: number) => {
|
||||||
|
transaction.value.transactionItems.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const calculateUnsettledBalance = (): string => {
|
||||||
|
const balance = transaction.value.transactionItems.reduce((sum, item) => sum + item.amount, 0);
|
||||||
|
return balance.toFixed(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
transactionService,
|
||||||
|
alertService,
|
||||||
|
transaction,
|
||||||
|
previousState,
|
||||||
|
transactionTypeValues,
|
||||||
|
isSaving,
|
||||||
|
currentLanguage,
|
||||||
|
events,
|
||||||
|
v$,
|
||||||
|
dictUserAccounts,
|
||||||
|
addTransactionItem,
|
||||||
|
removeTransactionItem,
|
||||||
|
calculateUnsettledBalance,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
save(): void {
|
||||||
|
this.isSaving = true;
|
||||||
|
if (this.transaction.id) {
|
||||||
|
this.transactionService()
|
||||||
|
.update(this.transaction)
|
||||||
|
.then(param => {
|
||||||
|
this.isSaving = false;
|
||||||
|
this.previousState();
|
||||||
|
this.alertService.showInfo(`A Transaction is updated with identifier ${param.id}`);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.isSaving = false;
|
||||||
|
this.alertService.showHttpError(error.response);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.transactionService()
|
||||||
|
.create(this.transaction)
|
||||||
|
.then(param => {
|
||||||
|
this.isSaving = false;
|
||||||
|
this.previousState();
|
||||||
|
this.alertService.showSuccess(`A Transaction is created with identifier ${param.id}`);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.isSaving = false;
|
||||||
|
this.alertService.showHttpError(error.response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-12">
|
||||||
|
<form name="editForm" novalidate @submit.prevent="save()">
|
||||||
|
<h2 id="sasiedziApp.transaction.home.createOrEditLabel" data-cy="TransactionCreateUpdateHeading">Create or edit a Transaction</h2>
|
||||||
|
<div>
|
||||||
|
<div class="form-group" v-if="transaction.id">
|
||||||
|
<label for="id">ID</label>
|
||||||
|
<input type="text" class="form-control" id="id" name="id" v-model="transaction.id" readonly />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-control-label" for="transaction-type">Type</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="type"
|
||||||
|
:class="{ valid: !v$.type.$invalid, invalid: v$.type.$invalid }"
|
||||||
|
v-model="v$.type.$model"
|
||||||
|
id="transaction-type"
|
||||||
|
data-cy="type"
|
||||||
|
>
|
||||||
|
<option v-for="transactionType in transactionTypeValues" :key="transactionType" :value="transactionType">
|
||||||
|
{{ transactionType }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-control-label" for="transaction-date">Date</label>
|
||||||
|
<b-input-group class="mb-3">
|
||||||
|
<b-input-group-prepend>
|
||||||
|
<b-form-datepicker
|
||||||
|
aria-controls="transaction-date"
|
||||||
|
v-model="v$.date.$model"
|
||||||
|
name="date"
|
||||||
|
class="form-control"
|
||||||
|
:locale="currentLanguage"
|
||||||
|
button-only
|
||||||
|
today-button
|
||||||
|
reset-button
|
||||||
|
close-button
|
||||||
|
>
|
||||||
|
</b-form-datepicker>
|
||||||
|
</b-input-group-prepend>
|
||||||
|
<b-form-input
|
||||||
|
id="transaction-date"
|
||||||
|
data-cy="date"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
name="date"
|
||||||
|
:class="{ valid: !v$.date.$invalid, invalid: v$.date.$invalid }"
|
||||||
|
v-model="v$.date.$model"
|
||||||
|
/>
|
||||||
|
</b-input-group>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-control-label" for="transaction-comment">Comment</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
name="comment"
|
||||||
|
id="transaction-comment"
|
||||||
|
data-cy="comment"
|
||||||
|
:class="{ valid: !v$.comment.$invalid, invalid: v$.comment.$invalid }"
|
||||||
|
v-model="v$.comment.$model"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-control-label" for="transaction-event">Event</label>
|
||||||
|
<select class="form-control" id="transaction-event" data-cy="event" name="event" v-model="transaction.event">
|
||||||
|
<option :value="null"></option>
|
||||||
|
<option
|
||||||
|
:value="transaction.event && eventOption.id === transaction.event.id ? transaction.event : eventOption"
|
||||||
|
v-for="eventOption in events"
|
||||||
|
:key="eventOption.id"
|
||||||
|
>
|
||||||
|
{{ eventOption.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Destination account</label>
|
||||||
|
<select v-model="transaction.beneficiary" class="form-control" v-if="dictUserAccounts.length">
|
||||||
|
<option v-for="account in dictUserAccounts" :key="account.id" :value="account">{{ account.name }}</option>
|
||||||
|
</select>
|
||||||
|
<label>Unsettled Balance:</label>
|
||||||
|
<input type="text" class="form-control" :value="calculateUnsettledBalance()" readonly />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="button" @click="addTransactionItem" class="btn btn-success">Add Transaction Item</button>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped" aria-describedby="event.registrations">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col"><span></span></th>
|
||||||
|
<!-- <th scope="col"><span>Locked</span></th>-->
|
||||||
|
<th scope="col"><span>Account</span></th>
|
||||||
|
<th scope="col"><span>Amount</span></th>
|
||||||
|
<th scope="col"><span>Comment</span></th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="(item, index) in transaction.transactionItems" :key="index" class="transaction-item">
|
||||||
|
<td>
|
||||||
|
{{ item.id }}
|
||||||
|
</td>
|
||||||
|
<!-- <td>-->
|
||||||
|
<!-- <input type="checkbox" v-model="item.locked" class="form-check-input" />-->
|
||||||
|
<!-- </td>-->
|
||||||
|
<td>
|
||||||
|
<select v-model="item.userAccount" class="form-control" v-if="dictUserAccounts.length">
|
||||||
|
<option v-for="account in dictUserAccounts" :key="account.id" :value="account">{{ account.name }}</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="number" v-model="item.amount" step="0.01" class="form-control" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" v-model="item.comment" class="form-control" placeholder="Comment" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" @click="removeTransactionItem(index)" class="btn btn-danger">Remove</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="button" id="cancel-save" data-cy="entityCreateCancelButton" class="btn btn-secondary" @click="previousState()">
|
||||||
|
<font-awesome-icon icon="ban"></font-awesome-icon> <span>Cancel</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
id="save-entity"
|
||||||
|
data-cy="entityCreateSaveButton"
|
||||||
|
:disabled="v$.$invalid || isSaving"
|
||||||
|
class="btn btn-primary"
|
||||||
|
>
|
||||||
|
<font-awesome-icon icon="save"></font-awesome-icon> <span>Save</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" src="./transaction-update.component.ts"></script>
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/* tslint:disable max-line-length */
|
||||||
|
import { vitest } from 'vitest';
|
||||||
|
import { type MountingOptions, shallowMount } from '@vue/test-utils';
|
||||||
|
import sinon, { type SinonStubbedInstance } from 'sinon';
|
||||||
|
|
||||||
|
import Transaction from './transaction.vue';
|
||||||
|
import TransactionService from './transaction.service';
|
||||||
|
import AlertService from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
type TransactionComponentType = InstanceType<typeof Transaction>;
|
||||||
|
|
||||||
|
const bModalStub = {
|
||||||
|
render: () => {},
|
||||||
|
methods: {
|
||||||
|
hide: () => {},
|
||||||
|
show: () => {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Component Tests', () => {
|
||||||
|
let alertService: AlertService;
|
||||||
|
|
||||||
|
describe('Transaction Management Component', () => {
|
||||||
|
let transactionServiceStub: SinonStubbedInstance<TransactionService>;
|
||||||
|
let mountOptions: MountingOptions<TransactionComponentType>['global'];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
transactionServiceStub = sinon.createStubInstance<TransactionService>(TransactionService);
|
||||||
|
transactionServiceStub.retrieve.resolves({ headers: {} });
|
||||||
|
|
||||||
|
alertService = new AlertService({
|
||||||
|
bvToast: {
|
||||||
|
toast: vitest.fn(),
|
||||||
|
} as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
mountOptions = {
|
||||||
|
stubs: {
|
||||||
|
bModal: bModalStub as any,
|
||||||
|
'font-awesome-icon': true,
|
||||||
|
'b-badge': true,
|
||||||
|
'b-button': true,
|
||||||
|
'router-link': true,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
'b-modal': {},
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
alertService,
|
||||||
|
transactionService: () => transactionServiceStub,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Mount', () => {
|
||||||
|
it('Should call load all on init', async () => {
|
||||||
|
// GIVEN
|
||||||
|
transactionServiceStub.retrieve.resolves({ headers: {}, data: [{ id: 123 }] });
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
const wrapper = shallowMount(Transaction, { global: mountOptions });
|
||||||
|
const comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(transactionServiceStub.retrieve.calledOnce).toBeTruthy();
|
||||||
|
expect(comp.transactions[0]).toEqual(expect.objectContaining({ id: 123 }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('Handles', () => {
|
||||||
|
let comp: TransactionComponentType;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const wrapper = shallowMount(Transaction, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
transactionServiceStub.retrieve.reset();
|
||||||
|
transactionServiceStub.retrieve.resolves({ headers: {}, data: [] });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should call delete service on confirmDelete', async () => {
|
||||||
|
// GIVEN
|
||||||
|
transactionServiceStub.delete.resolves({});
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
comp.prepareRemove({ id: 123 });
|
||||||
|
|
||||||
|
comp.removeTransaction();
|
||||||
|
await comp.$nextTick(); // clear components
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(transactionServiceStub.delete.called).toBeTruthy();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
await comp.$nextTick(); // handle component clear watch
|
||||||
|
expect(transactionServiceStub.retrieve.callCount).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
import { type Ref, defineComponent, inject, onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import TransactionService from './transaction.service';
|
||||||
|
import { type ITransaction } from '@/shared/model/transaction.model';
|
||||||
|
import { useAlertService } from '@/shared/alert/alert.service';
|
||||||
|
import type AccountService from '@/account/account.service';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
compatConfig: { MODE: 3 },
|
||||||
|
name: 'Transaction',
|
||||||
|
props: {
|
||||||
|
userAccountId: {
|
||||||
|
type: [Number, String],
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
const transactionService = inject('transactionService', () => new TransactionService());
|
||||||
|
const alertService = inject('alertService', () => useAlertService(), true);
|
||||||
|
|
||||||
|
const transactions: Ref<ITransaction[]> = ref([]);
|
||||||
|
const hasAnyAuthorityValues: Ref<any> = ref({});
|
||||||
|
const accountService = inject<AccountService>('accountService');
|
||||||
|
|
||||||
|
const isFetching = ref(false);
|
||||||
|
const sums: Ref<number[]> = ref([]);
|
||||||
|
|
||||||
|
const clear = () => {};
|
||||||
|
// console.log(props.userAccountId);
|
||||||
|
const retrieveTransactions = async () => {
|
||||||
|
isFetching.value = true;
|
||||||
|
try {
|
||||||
|
// console.log(props);
|
||||||
|
const res = await transactionService().retrieve();
|
||||||
|
// const res = await transactionService().retrieveForAccount(props.userAccountId);
|
||||||
|
transactions.value = res.data;
|
||||||
|
sums.value = sumAmountsPerColumn(transactions.value);
|
||||||
|
} catch (err) {
|
||||||
|
alertService.showHttpError(err.response);
|
||||||
|
} finally {
|
||||||
|
isFetching.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSyncList = () => {
|
||||||
|
retrieveTransactions();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await retrieveTransactions();
|
||||||
|
});
|
||||||
|
|
||||||
|
const removeId: Ref<number> = ref(null);
|
||||||
|
const removeEntity = ref<any>(null);
|
||||||
|
const prepareRemove = (instance: ITransaction) => {
|
||||||
|
removeId.value = instance.id;
|
||||||
|
removeEntity.value.show();
|
||||||
|
};
|
||||||
|
const closeDialog = () => {
|
||||||
|
removeEntity.value.hide();
|
||||||
|
};
|
||||||
|
const removeTransaction = async () => {
|
||||||
|
try {
|
||||||
|
await transactionService().delete(removeId.value);
|
||||||
|
const message = `A Transaction is deleted with identifier ${removeId.value}`;
|
||||||
|
alertService.showInfo(message, { variant: 'danger' });
|
||||||
|
removeId.value = null;
|
||||||
|
retrieveTransactions();
|
||||||
|
closeDialog();
|
||||||
|
} catch (error) {
|
||||||
|
alertService.showHttpError(error.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function sumAmountsPerColumn(transactions: ITransaction[]): number[] {
|
||||||
|
// Jeżeli nie ma transakcji, zwracamy pustą tablicę
|
||||||
|
if (transactions.length === 0) return [];
|
||||||
|
// Liczba kolumn to liczba transactionItems w pierwszej transakcji
|
||||||
|
const columnCount = transactions[0].items.length;
|
||||||
|
// Inicjalizacja tablicy sum z zerami dla każdej kolumny
|
||||||
|
const sums = new Array(columnCount).fill(0);
|
||||||
|
|
||||||
|
// Iteracja przez każdą transakcję
|
||||||
|
for (const transaction of transactions) {
|
||||||
|
for (let i = 0; i < columnCount; i++) {
|
||||||
|
// Dodajemy amount z każdego transactionItem do odpowiedniej kolumny
|
||||||
|
sums[i] += transaction.items[i].amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zaokrąglanie każdej sumy do dwóch miejsc po przecinku
|
||||||
|
return sums.map(sum => Number(sum.toFixed(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
transactions,
|
||||||
|
handleSyncList,
|
||||||
|
isFetching,
|
||||||
|
retrieveTransactions,
|
||||||
|
clear,
|
||||||
|
sums,
|
||||||
|
removeId,
|
||||||
|
accountService,
|
||||||
|
hasAnyAuthorityValues,
|
||||||
|
removeEntity,
|
||||||
|
prepareRemove,
|
||||||
|
closeDialog,
|
||||||
|
removeTransaction,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
hasAnyAuthority(authorities: any): boolean {
|
||||||
|
this.accountService.hasAnyAuthorityAndCheckAuth(authorities).then(value => {
|
||||||
|
if (this.hasAnyAuthorityValues[authorities] !== value) {
|
||||||
|
this.hasAnyAuthorityValues = { ...this.hasAnyAuthorityValues, [authorities]: value };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return this.hasAnyAuthorityValues[authorities] ?? false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
/* tslint:disable max-line-length */
|
||||||
|
import axios from 'axios';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
import TransactionService from './transaction.service';
|
||||||
|
import { DATE_FORMAT } from '@/shared/composables/date-format';
|
||||||
|
import { Transaction } from '@/shared/model/transaction.model';
|
||||||
|
|
||||||
|
const error = {
|
||||||
|
response: {
|
||||||
|
status: null,
|
||||||
|
data: {
|
||||||
|
type: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const axiosStub = {
|
||||||
|
get: sinon.stub(axios, 'get'),
|
||||||
|
post: sinon.stub(axios, 'post'),
|
||||||
|
put: sinon.stub(axios, 'put'),
|
||||||
|
patch: sinon.stub(axios, 'patch'),
|
||||||
|
delete: sinon.stub(axios, 'delete'),
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Service Tests', () => {
|
||||||
|
describe('Transaction Service', () => {
|
||||||
|
let service: TransactionService;
|
||||||
|
let elemDefault;
|
||||||
|
let currentDate: Date;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
service = new TransactionService();
|
||||||
|
currentDate = new Date();
|
||||||
|
elemDefault = new Transaction(123, 'PURCHASE', currentDate, 'AAAAAAA');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Service methods', () => {
|
||||||
|
it('should find an element', async () => {
|
||||||
|
const returnedFromService = { date: dayjs(currentDate).format(DATE_FORMAT), ...elemDefault };
|
||||||
|
axiosStub.get.resolves({ data: returnedFromService });
|
||||||
|
|
||||||
|
return service.find(123).then(res => {
|
||||||
|
expect(res).toMatchObject(elemDefault);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not find an element', async () => {
|
||||||
|
axiosStub.get.rejects(error);
|
||||||
|
return service
|
||||||
|
.find(123)
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a Transaction', async () => {
|
||||||
|
const returnedFromService = { id: 123, date: dayjs(currentDate).format(DATE_FORMAT), ...elemDefault };
|
||||||
|
const expected = { date: currentDate, ...returnedFromService };
|
||||||
|
|
||||||
|
axiosStub.post.resolves({ data: returnedFromService });
|
||||||
|
return service.create({}).then(res => {
|
||||||
|
expect(res).toMatchObject(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not create a Transaction', async () => {
|
||||||
|
axiosStub.post.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.create({})
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update a Transaction', async () => {
|
||||||
|
const returnedFromService = { type: 'BBBBBB', date: dayjs(currentDate).format(DATE_FORMAT), comment: 'BBBBBB', ...elemDefault };
|
||||||
|
|
||||||
|
const expected = { date: currentDate, ...returnedFromService };
|
||||||
|
axiosStub.put.resolves({ data: returnedFromService });
|
||||||
|
|
||||||
|
return service.update(expected).then(res => {
|
||||||
|
expect(res).toMatchObject(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not update a Transaction', async () => {
|
||||||
|
axiosStub.put.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.update({})
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should partial update a Transaction', async () => {
|
||||||
|
const patchObject = { ...new Transaction() };
|
||||||
|
const returnedFromService = Object.assign(patchObject, elemDefault);
|
||||||
|
|
||||||
|
const expected = { date: currentDate, ...returnedFromService };
|
||||||
|
axiosStub.patch.resolves({ data: returnedFromService });
|
||||||
|
|
||||||
|
return service.partialUpdate(patchObject).then(res => {
|
||||||
|
expect(res).toMatchObject(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not partial update a Transaction', async () => {
|
||||||
|
axiosStub.patch.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.partialUpdate({})
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a list of Transaction', async () => {
|
||||||
|
const returnedFromService = { type: 'BBBBBB', date: dayjs(currentDate).format(DATE_FORMAT), comment: 'BBBBBB', ...elemDefault };
|
||||||
|
const expected = { date: currentDate, ...returnedFromService };
|
||||||
|
axiosStub.get.resolves([returnedFromService]);
|
||||||
|
return service.retrieve().then(res => {
|
||||||
|
expect(res).toContainEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not return a list of Transaction', async () => {
|
||||||
|
axiosStub.get.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.retrieve()
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete a Transaction', async () => {
|
||||||
|
axiosStub.delete.resolves({ ok: true });
|
||||||
|
return service.delete(123).then(res => {
|
||||||
|
expect(res.ok).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not delete a Transaction', async () => {
|
||||||
|
axiosStub.delete.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.delete(123)
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import { type ITransaction } from '@/shared/model/transaction.model';
|
||||||
|
|
||||||
|
const baseApiUrl = 'api/transactions';
|
||||||
|
|
||||||
|
export default class TransactionService {
|
||||||
|
public find(id: number, opposing: boolean): Promise<ITransaction> {
|
||||||
|
return new Promise<ITransaction>((resolve, reject) => {
|
||||||
|
let url = `${baseApiUrl}/${id}`;
|
||||||
|
if (opposing) {
|
||||||
|
url = `${baseApiUrl}/opposing/${id}`;
|
||||||
|
}
|
||||||
|
axios
|
||||||
|
.get(url)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public fieldPayment(eventId: number): Promise<ITransaction> {
|
||||||
|
return new Promise<ITransaction>((resolve, reject) => {
|
||||||
|
let url = `${baseApiUrl}/field-payment/${eventId}`;
|
||||||
|
axios
|
||||||
|
.get(url)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public payments(transactionId: number): Promise<ITransaction> {
|
||||||
|
return new Promise<ITransaction>((resolve, reject) => {
|
||||||
|
let url = `${baseApiUrl}/payments/${transactionId}`;
|
||||||
|
axios
|
||||||
|
.get(url)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public retrieve(): Promise<any> {
|
||||||
|
return new Promise<any>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.get(baseApiUrl)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// public retrieveForAccount(userAccountId: any): Promise<any> {
|
||||||
|
// return new Promise<any>((resolve, reject) => {
|
||||||
|
// axios
|
||||||
|
// .get(`${baseApiUrl}/forAccount/${userAccountId}`)
|
||||||
|
// .then(res => {
|
||||||
|
// resolve(res);
|
||||||
|
// })
|
||||||
|
// .catch(err => {
|
||||||
|
// reject(err);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
public delete(id: number): Promise<any> {
|
||||||
|
return new Promise<any>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.delete(`${baseApiUrl}/${id}`)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public create(entity: ITransaction): Promise<ITransaction> {
|
||||||
|
return new Promise<ITransaction>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.post(`${baseApiUrl}`, entity)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public update(entity: ITransaction): Promise<ITransaction> {
|
||||||
|
return new Promise<ITransaction>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.put(`${baseApiUrl}/${entity.id}`, entity)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public partialUpdate(entity: ITransaction): Promise<ITransaction> {
|
||||||
|
return new Promise<ITransaction>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.patch(`${baseApiUrl}/${entity.id}`, entity)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h2 id="page-heading" data-cy="TransactionHeading">
|
||||||
|
<span id="transaction-heading">Transactions</span>
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<button class="btn btn-info mr-2" @click="handleSyncList" :disabled="isFetching">
|
||||||
|
<font-awesome-icon icon="sync" :spin="isFetching"></font-awesome-icon> <span>Refresh list</span>
|
||||||
|
</button>
|
||||||
|
<router-link :to="{ name: 'TransactionCreate' }" custom v-slot="{ navigate }" v-if="hasAnyAuthority(['ROLE_ADMIN'])">
|
||||||
|
<button
|
||||||
|
@click="navigate"
|
||||||
|
id="jh-create-entity"
|
||||||
|
data-cy="entityCreateButton"
|
||||||
|
class="btn btn-primary jh-create-entity create-transaction"
|
||||||
|
>
|
||||||
|
<font-awesome-icon icon="plus"></font-awesome-icon>
|
||||||
|
<span>Create a new Transaction</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
|
<br />
|
||||||
|
<div class="alert alert-warning" v-if="!isFetching && transactions && transactions.length === 0">
|
||||||
|
<span>No Transactions found</span>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive" v-if="transactions && transactions.length > 0">
|
||||||
|
<table class="table table-striped" aria-describedby="transactions">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<!-- <th/>-->
|
||||||
|
<!-- <th/>-->
|
||||||
|
<!-- <th/>-->
|
||||||
|
<th />
|
||||||
|
<th />
|
||||||
|
|
||||||
|
<th class="rotate" scope="row" v-for="item in transactions[0].items">
|
||||||
|
<div class="rotate">{{ item.userAccount?.name }}</div>
|
||||||
|
</th>
|
||||||
|
<th scope="row"></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<!-- <th/>-->
|
||||||
|
<!-- <th/>-->
|
||||||
|
<!-- <th/>-->
|
||||||
|
<th />
|
||||||
|
<th>Saldo</th>
|
||||||
|
<th v-for="amount in sums" class="border-left" :class="{ inplus: amount > 0, inminus: amount < 0 }">
|
||||||
|
<span class="bold">{{ amount }}</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<!-- <th scope="row"><span>ID</span></th>-->
|
||||||
|
<!-- <th scope="row"><span>Type</span></th>-->
|
||||||
|
<th scope="row"><span>Date</span></th>
|
||||||
|
<!-- <th scope="row"><span>Comment</span></th>-->
|
||||||
|
|
||||||
|
<th scope="row"><span></span></th>
|
||||||
|
<!-- <th scope="row"><span>Transactions:</span></th>-->
|
||||||
|
<th scope="row" v-for="item in transactions[0].items" class="border-left">
|
||||||
|
<span></span>
|
||||||
|
<!-- <span>{{ item.userAccount?.name }}</span>-->
|
||||||
|
</th>
|
||||||
|
<th scope="row"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="transaction in transactions" :key="transaction.id" data-cy="entityTable">
|
||||||
|
<td>
|
||||||
|
<router-link :to="{ name: 'TransactionView', params: { transactionId: transaction.id } }"
|
||||||
|
>{{ transaction.date }} {{ transaction.type }}
|
||||||
|
</router-link>
|
||||||
|
<div v-if="transaction.comment">{{ transaction.comment }}</div>
|
||||||
|
</td>
|
||||||
|
<!-- <td>{{ transaction.type }}</td>-->
|
||||||
|
<!-- <td>{{ transaction.date }}</td>-->
|
||||||
|
<!-- <td>{{ transaction.comment }}</td>-->
|
||||||
|
<td>
|
||||||
|
<div v-if="transaction.event">
|
||||||
|
<router-link :to="{ name: 'EventView', params: { eventId: transaction.event.id } }">{{
|
||||||
|
transaction.event.name
|
||||||
|
}}</router-link>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td v-for="item in transaction.items" class="border-left">{{ item.amount }}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<router-link :to="{ name: 'TransactionView', params: { transactionId: transaction.id } }" custom v-slot="{ navigate }">
|
||||||
|
<button @click="navigate" class="btn btn-info btn-sm details" data-cy="entityDetailsButton">
|
||||||
|
<font-awesome-icon icon="eye"></font-awesome-icon>
|
||||||
|
<span class="d-none d-md-inline">View</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
:to="{ name: 'TransactionEdit', params: { transactionId: transaction.id } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
v-if="(transaction.editable && hasAnyAuthority(['ROLE_COUNTER'])) || hasAnyAuthority(['ROLE_ADMIN'])"
|
||||||
|
>
|
||||||
|
<button @click="navigate" class="btn btn-primary btn-sm edit" data-cy="entityEditButton">
|
||||||
|
<font-awesome-icon icon="pencil-alt"></font-awesome-icon>
|
||||||
|
<span class="d-none d-md-inline">Edit</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
<b-button
|
||||||
|
@click="prepareRemove(transaction)"
|
||||||
|
variant="danger"
|
||||||
|
class="btn btn-sm"
|
||||||
|
data-cy="entityDeleteButton"
|
||||||
|
v-if="hasAnyAuthority('ROLE_ADMIN')"
|
||||||
|
v-b-modal.removeEntity
|
||||||
|
>
|
||||||
|
<font-awesome-icon icon="times"></font-awesome-icon>
|
||||||
|
<span class="d-none d-md-inline">Delete</span>
|
||||||
|
</b-button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<b-modal ref="removeEntity" id="removeEntity">
|
||||||
|
<template #modal-title>
|
||||||
|
<span id="sasiedziApp.transaction.delete.question" data-cy="transactionDeleteDialogHeading">Confirm delete operation</span>
|
||||||
|
</template>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p id="jhi-delete-transaction-heading">Are you sure you want to delete Transaction {{ removeId }}?</p>
|
||||||
|
</div>
|
||||||
|
<template #modal-footer>
|
||||||
|
<div>
|
||||||
|
<button type="button" class="btn btn-secondary" @click="closeDialog()">Cancel</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-primary"
|
||||||
|
id="jhi-confirm-delete-transaction"
|
||||||
|
data-cy="entityConfirmDeleteButton"
|
||||||
|
@click="removeTransaction()"
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</b-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" src="./transaction.component.ts"></script>
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/* tslint:disable max-line-length */
|
||||||
|
import { vitest } from 'vitest';
|
||||||
|
import { type MountingOptions, shallowMount } from '@vue/test-utils';
|
||||||
|
import sinon, { type SinonStubbedInstance } from 'sinon';
|
||||||
|
import { type RouteLocation } from 'vue-router';
|
||||||
|
|
||||||
|
import UserAccountDetails from './user-account-details.vue';
|
||||||
|
import UserAccountService from './user-account.service';
|
||||||
|
import AlertService from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
type UserAccountDetailsComponentType = InstanceType<typeof UserAccountDetails>;
|
||||||
|
|
||||||
|
let route: Partial<RouteLocation>;
|
||||||
|
const routerGoMock = vitest.fn();
|
||||||
|
|
||||||
|
vitest.mock('vue-router', () => ({
|
||||||
|
useRoute: () => route,
|
||||||
|
useRouter: () => ({ go: routerGoMock }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const userAccountSample = { id: 123 };
|
||||||
|
|
||||||
|
describe('Component Tests', () => {
|
||||||
|
let alertService: AlertService;
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vitest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('UserAccount Management Detail Component', () => {
|
||||||
|
let userAccountServiceStub: SinonStubbedInstance<UserAccountService>;
|
||||||
|
let mountOptions: MountingOptions<UserAccountDetailsComponentType>['global'];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
route = {};
|
||||||
|
userAccountServiceStub = sinon.createStubInstance<UserAccountService>(UserAccountService);
|
||||||
|
|
||||||
|
alertService = new AlertService({
|
||||||
|
bvToast: {
|
||||||
|
toast: vitest.fn(),
|
||||||
|
} as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
mountOptions = {
|
||||||
|
stubs: {
|
||||||
|
'font-awesome-icon': true,
|
||||||
|
'router-link': true,
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
alertService,
|
||||||
|
userAccountService: () => userAccountServiceStub,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Navigate to details', () => {
|
||||||
|
it('Should call load all on init', async () => {
|
||||||
|
// GIVEN
|
||||||
|
userAccountServiceStub.find.resolves(userAccountSample);
|
||||||
|
route = {
|
||||||
|
params: {
|
||||||
|
userAccountId: `${123}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const wrapper = shallowMount(UserAccountDetails, { global: mountOptions });
|
||||||
|
const comp = wrapper.vm;
|
||||||
|
// WHEN
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(comp.userAccount).toMatchObject(userAccountSample);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Previous state', () => {
|
||||||
|
it('Should go previous state', async () => {
|
||||||
|
userAccountServiceStub.find.resolves(userAccountSample);
|
||||||
|
const wrapper = shallowMount(UserAccountDetails, { global: mountOptions });
|
||||||
|
const comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
comp.previousState();
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
expect(routerGoMock).toHaveBeenCalledWith(-1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { type Ref, defineComponent, inject, ref } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
import UserAccountService from './user-account.service';
|
||||||
|
import { type IUserAccount } from '@/shared/model/user-account.model';
|
||||||
|
import { useAlertService } from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
compatConfig: { MODE: 3 },
|
||||||
|
name: 'UserAccountDetails',
|
||||||
|
setup() {
|
||||||
|
const userAccountService = inject('userAccountService', () => new UserAccountService());
|
||||||
|
const alertService = inject('alertService', () => useAlertService(), true);
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const previousState = () => router.go(-1);
|
||||||
|
const userAccount: Ref<IUserAccount> = ref({});
|
||||||
|
|
||||||
|
const retrieveUserAccount = async userAccountId => {
|
||||||
|
try {
|
||||||
|
const res = await userAccountService().find(userAccountId);
|
||||||
|
userAccount.value = res;
|
||||||
|
} catch (error) {
|
||||||
|
alertService.showHttpError(error.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (route.params?.userAccountId) {
|
||||||
|
retrieveUserAccount(route.params.userAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
alertService,
|
||||||
|
userAccount,
|
||||||
|
|
||||||
|
previousState,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-8">
|
||||||
|
<div v-if="userAccount">
|
||||||
|
<h2 class="jh-entity-heading" data-cy="userAccountDetailsHeading"><span>User Account</span> {{ userAccount.id }}</h2>
|
||||||
|
<dl class="row jh-entity-details">
|
||||||
|
<dt>
|
||||||
|
<span>Name</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<span>{{ userAccount.name }}</span>
|
||||||
|
</dd>
|
||||||
|
<dt>
|
||||||
|
<span>User</span>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<span v-for="(user, i) in userAccount.users" :key="user.id"
|
||||||
|
>{{ i > 0 ? ', ' : '' }}
|
||||||
|
{{ user.login }}
|
||||||
|
</span>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<button type="submit" @click.prevent="previousState()" class="btn btn-info" data-cy="entityDetailsBackButton">
|
||||||
|
<font-awesome-icon icon="arrow-left"></font-awesome-icon> <span>Back</span>
|
||||||
|
</button>
|
||||||
|
<router-link
|
||||||
|
v-if="userAccount.id"
|
||||||
|
:to="{ name: 'UserAccountEdit', params: { userAccountId: userAccount.id } }"
|
||||||
|
custom
|
||||||
|
v-slot="{ navigate }"
|
||||||
|
>
|
||||||
|
<button @click="navigate" class="btn btn-primary">
|
||||||
|
<font-awesome-icon icon="pencil-alt"></font-awesome-icon> <span>Edit</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" src="./user-account-details.component.ts"></script>
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/* tslint:disable max-line-length */
|
||||||
|
import { vitest } from 'vitest';
|
||||||
|
import { type MountingOptions, shallowMount } from '@vue/test-utils';
|
||||||
|
import sinon, { type SinonStubbedInstance } from 'sinon';
|
||||||
|
import { type RouteLocation } from 'vue-router';
|
||||||
|
|
||||||
|
import UserAccountUpdate from './user-account-update.vue';
|
||||||
|
import UserAccountService from './user-account.service';
|
||||||
|
import AlertService from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
import UserService from '@/entities/user/user.service';
|
||||||
|
|
||||||
|
type UserAccountUpdateComponentType = InstanceType<typeof UserAccountUpdate>;
|
||||||
|
|
||||||
|
let route: Partial<RouteLocation>;
|
||||||
|
const routerGoMock = vitest.fn();
|
||||||
|
|
||||||
|
vitest.mock('vue-router', () => ({
|
||||||
|
useRoute: () => route,
|
||||||
|
useRouter: () => ({ go: routerGoMock }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const userAccountSample = { id: 123 };
|
||||||
|
|
||||||
|
describe('Component Tests', () => {
|
||||||
|
let mountOptions: MountingOptions<UserAccountUpdateComponentType>['global'];
|
||||||
|
let alertService: AlertService;
|
||||||
|
|
||||||
|
describe('UserAccount Management Update Component', () => {
|
||||||
|
let comp: UserAccountUpdateComponentType;
|
||||||
|
let userAccountServiceStub: SinonStubbedInstance<UserAccountService>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
route = {};
|
||||||
|
userAccountServiceStub = sinon.createStubInstance<UserAccountService>(UserAccountService);
|
||||||
|
userAccountServiceStub.retrieve.onFirstCall().resolves(Promise.resolve([]));
|
||||||
|
|
||||||
|
alertService = new AlertService({
|
||||||
|
bvToast: {
|
||||||
|
toast: vitest.fn(),
|
||||||
|
} as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
mountOptions = {
|
||||||
|
stubs: {
|
||||||
|
'font-awesome-icon': true,
|
||||||
|
'b-input-group': true,
|
||||||
|
'b-input-group-prepend': true,
|
||||||
|
'b-form-datepicker': true,
|
||||||
|
'b-form-input': true,
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
alertService,
|
||||||
|
userAccountService: () => userAccountServiceStub,
|
||||||
|
|
||||||
|
userService: () =>
|
||||||
|
sinon.createStubInstance<UserService>(UserService, {
|
||||||
|
retrieve: sinon.stub().resolves({}),
|
||||||
|
} as any),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vitest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('save', () => {
|
||||||
|
it('Should call update service on save for existing entity', async () => {
|
||||||
|
// GIVEN
|
||||||
|
const wrapper = shallowMount(UserAccountUpdate, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
comp.userAccount = userAccountSample;
|
||||||
|
userAccountServiceStub.update.resolves(userAccountSample);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
comp.save();
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(userAccountServiceStub.update.calledWith(userAccountSample)).toBeTruthy();
|
||||||
|
expect(comp.isSaving).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should call create service on save for new entity', async () => {
|
||||||
|
// GIVEN
|
||||||
|
const entity = {};
|
||||||
|
userAccountServiceStub.create.resolves(entity);
|
||||||
|
const wrapper = shallowMount(UserAccountUpdate, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
comp.userAccount = entity;
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
comp.save();
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(userAccountServiceStub.create.calledWith(entity)).toBeTruthy();
|
||||||
|
expect(comp.isSaving).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Before route enter', () => {
|
||||||
|
it('Should retrieve data', async () => {
|
||||||
|
// GIVEN
|
||||||
|
userAccountServiceStub.find.resolves(userAccountSample);
|
||||||
|
userAccountServiceStub.retrieve.resolves([userAccountSample]);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
route = {
|
||||||
|
params: {
|
||||||
|
userAccountId: `${userAccountSample.id}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const wrapper = shallowMount(UserAccountUpdate, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(comp.userAccount).toMatchObject(userAccountSample);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Previous state', () => {
|
||||||
|
it('Should go previous state', async () => {
|
||||||
|
userAccountServiceStub.find.resolves(userAccountSample);
|
||||||
|
const wrapper = shallowMount(UserAccountUpdate, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
comp.previousState();
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
expect(routerGoMock).toHaveBeenCalledWith(-1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import { type Ref, computed, defineComponent, inject, ref } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useVuelidate } from '@vuelidate/core';
|
||||||
|
|
||||||
|
import UserAccountService from './user-account.service';
|
||||||
|
import { useValidation } from '@/shared/composables';
|
||||||
|
import { useAlertService } from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
import UserService from '@/entities/user/user.service';
|
||||||
|
import { type IUserAccount, UserAccount } from '@/shared/model/user-account.model';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
compatConfig: { MODE: 3 },
|
||||||
|
name: 'UserAccountUpdate',
|
||||||
|
setup() {
|
||||||
|
const userAccountService = inject('userAccountService', () => new UserAccountService());
|
||||||
|
const alertService = inject('alertService', () => useAlertService(), true);
|
||||||
|
|
||||||
|
const userAccount: Ref<IUserAccount> = ref(new UserAccount());
|
||||||
|
const userService = inject('userService', () => new UserService());
|
||||||
|
const users: Ref<Array<any>> = ref([]);
|
||||||
|
const isSaving = ref(false);
|
||||||
|
const currentLanguage = inject('currentLanguage', () => computed(() => navigator.language ?? 'en'), true);
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const previousState = () => router.go(-1);
|
||||||
|
|
||||||
|
const retrieveUserAccount = async userAccountId => {
|
||||||
|
try {
|
||||||
|
const res = await userAccountService().find(userAccountId);
|
||||||
|
userAccount.value = res;
|
||||||
|
} catch (error) {
|
||||||
|
alertService.showHttpError(error.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (route.params?.userAccountId) {
|
||||||
|
retrieveUserAccount(route.params.userAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const initRelationships = () => {
|
||||||
|
userService()
|
||||||
|
.retrieve()
|
||||||
|
.then(res => {
|
||||||
|
users.value = res.data;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
initRelationships();
|
||||||
|
|
||||||
|
const validations = useValidation();
|
||||||
|
const validationRules = {
|
||||||
|
name: {},
|
||||||
|
users: {},
|
||||||
|
};
|
||||||
|
const v$ = useVuelidate(validationRules, userAccount as any);
|
||||||
|
v$.value.$validate();
|
||||||
|
|
||||||
|
return {
|
||||||
|
userAccountService,
|
||||||
|
alertService,
|
||||||
|
userAccount,
|
||||||
|
previousState,
|
||||||
|
isSaving,
|
||||||
|
currentLanguage,
|
||||||
|
users,
|
||||||
|
v$,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created(): void {
|
||||||
|
this.userAccount.users = [];
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
save(): void {
|
||||||
|
this.isSaving = true;
|
||||||
|
if (this.userAccount.id) {
|
||||||
|
this.userAccountService()
|
||||||
|
.update(this.userAccount)
|
||||||
|
.then(param => {
|
||||||
|
this.isSaving = false;
|
||||||
|
this.previousState();
|
||||||
|
this.alertService.showInfo(`A UserAccount is updated with identifier ${param.id}`);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.isSaving = false;
|
||||||
|
this.alertService.showHttpError(error.response);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.userAccountService()
|
||||||
|
.create(this.userAccount)
|
||||||
|
.then(param => {
|
||||||
|
this.isSaving = false;
|
||||||
|
this.previousState();
|
||||||
|
this.alertService.showSuccess(`A UserAccount is created with identifier ${param.id}`);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.isSaving = false;
|
||||||
|
this.alertService.showHttpError(error.response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getSelected(selectedVals, option, pkField = 'id'): any {
|
||||||
|
if (selectedVals) {
|
||||||
|
return selectedVals.find(value => option[pkField] === value[pkField]) ?? option;
|
||||||
|
}
|
||||||
|
return option;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-8">
|
||||||
|
<form name="editForm" novalidate @submit.prevent="save()">
|
||||||
|
<h2 id="sasiedziApp.userAccount.home.createOrEditLabel" data-cy="UserAccountCreateUpdateHeading">Create or edit a User Account</h2>
|
||||||
|
<div>
|
||||||
|
<div class="form-group" v-if="userAccount.id">
|
||||||
|
<label for="id">ID</label>
|
||||||
|
<input type="text" class="form-control" id="id" name="id" v-model="userAccount.id" readonly />
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-control-label" for="user-account-name">Name</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
name="name"
|
||||||
|
id="user-account-name"
|
||||||
|
data-cy="name"
|
||||||
|
:class="{ valid: !v$.name.$invalid, invalid: v$.name.$invalid }"
|
||||||
|
v-model="v$.name.$model"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="user-account-user">User</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
id="user-account-users"
|
||||||
|
data-cy="user"
|
||||||
|
multiple
|
||||||
|
name="user"
|
||||||
|
v-if="userAccount.users !== undefined"
|
||||||
|
v-model="userAccount.users"
|
||||||
|
>
|
||||||
|
<option :value="getSelected(userAccount.users, userOption, 'id')" v-for="userOption in users" :key="userOption.id">
|
||||||
|
{{ userOption.login }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="button" id="cancel-save" data-cy="entityCreateCancelButton" class="btn btn-secondary" @click="previousState()">
|
||||||
|
<font-awesome-icon icon="ban"></font-awesome-icon> <span>Cancel</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
id="save-entity"
|
||||||
|
data-cy="entityCreateSaveButton"
|
||||||
|
:disabled="v$.$invalid || isSaving"
|
||||||
|
class="btn btn-primary"
|
||||||
|
>
|
||||||
|
<font-awesome-icon icon="save"></font-awesome-icon> <span>Save</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" src="./user-account-update.component.ts"></script>
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/* tslint:disable max-line-length */
|
||||||
|
import { vitest } from 'vitest';
|
||||||
|
import { type MountingOptions, shallowMount } from '@vue/test-utils';
|
||||||
|
import sinon, { type SinonStubbedInstance } from 'sinon';
|
||||||
|
|
||||||
|
import UserAccount from './user-account.vue';
|
||||||
|
import UserAccountService from './user-account.service';
|
||||||
|
import AlertService from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
type UserAccountComponentType = InstanceType<typeof UserAccount>;
|
||||||
|
|
||||||
|
const bModalStub = {
|
||||||
|
render: () => {},
|
||||||
|
methods: {
|
||||||
|
hide: () => {},
|
||||||
|
show: () => {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Component Tests', () => {
|
||||||
|
let alertService: AlertService;
|
||||||
|
|
||||||
|
describe('UserAccount Management Component', () => {
|
||||||
|
let userAccountServiceStub: SinonStubbedInstance<UserAccountService>;
|
||||||
|
let mountOptions: MountingOptions<UserAccountComponentType>['global'];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
userAccountServiceStub = sinon.createStubInstance<UserAccountService>(UserAccountService);
|
||||||
|
userAccountServiceStub.retrieve.resolves({ headers: {} });
|
||||||
|
|
||||||
|
alertService = new AlertService({
|
||||||
|
bvToast: {
|
||||||
|
toast: vitest.fn(),
|
||||||
|
} as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
mountOptions = {
|
||||||
|
stubs: {
|
||||||
|
bModal: bModalStub as any,
|
||||||
|
'font-awesome-icon': true,
|
||||||
|
'b-badge': true,
|
||||||
|
'b-button': true,
|
||||||
|
'router-link': true,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
'b-modal': {},
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
alertService,
|
||||||
|
userAccountService: () => userAccountServiceStub,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Mount', () => {
|
||||||
|
it('Should call load all on init', async () => {
|
||||||
|
// GIVEN
|
||||||
|
userAccountServiceStub.retrieve.resolves({ headers: {}, data: [{ id: 123 }] });
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
const wrapper = shallowMount(UserAccount, { global: mountOptions });
|
||||||
|
const comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(userAccountServiceStub.retrieve.calledOnce).toBeTruthy();
|
||||||
|
expect(comp.userAccounts[0]).toEqual(expect.objectContaining({ id: 123 }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('Handles', () => {
|
||||||
|
let comp: UserAccountComponentType;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const wrapper = shallowMount(UserAccount, { global: mountOptions });
|
||||||
|
comp = wrapper.vm;
|
||||||
|
await comp.$nextTick();
|
||||||
|
userAccountServiceStub.retrieve.reset();
|
||||||
|
userAccountServiceStub.retrieve.resolves({ headers: {}, data: [] });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should call delete service on confirmDelete', async () => {
|
||||||
|
// GIVEN
|
||||||
|
userAccountServiceStub.delete.resolves({});
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
comp.prepareRemove({ id: 123 });
|
||||||
|
|
||||||
|
comp.removeUserAccount();
|
||||||
|
await comp.$nextTick(); // clear components
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(userAccountServiceStub.delete.called).toBeTruthy();
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
await comp.$nextTick(); // handle component clear watch
|
||||||
|
expect(userAccountServiceStub.retrieve.callCount).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import { type Ref, defineComponent, inject, onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import UserAccountService from './user-account.service';
|
||||||
|
import { type IUserAccount } from '@/shared/model/user-account.model';
|
||||||
|
import { useAlertService } from '@/shared/alert/alert.service';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
compatConfig: { MODE: 3 },
|
||||||
|
name: 'UserAccount',
|
||||||
|
setup() {
|
||||||
|
const userAccountService = inject('userAccountService', () => new UserAccountService());
|
||||||
|
const alertService = inject('alertService', () => useAlertService(), true);
|
||||||
|
|
||||||
|
const userAccounts: Ref<IUserAccount[]> = ref([]);
|
||||||
|
|
||||||
|
const isFetching = ref(false);
|
||||||
|
|
||||||
|
const clear = () => {};
|
||||||
|
|
||||||
|
const retrieveUserAccounts = async () => {
|
||||||
|
isFetching.value = true;
|
||||||
|
try {
|
||||||
|
const res = await userAccountService().retrieve();
|
||||||
|
userAccounts.value = res.data;
|
||||||
|
} catch (err) {
|
||||||
|
alertService.showHttpError(err.response);
|
||||||
|
} finally {
|
||||||
|
isFetching.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSyncList = () => {
|
||||||
|
retrieveUserAccounts();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await retrieveUserAccounts();
|
||||||
|
});
|
||||||
|
|
||||||
|
const removeId: Ref<number> = ref(null);
|
||||||
|
const removeEntity = ref<any>(null);
|
||||||
|
const prepareRemove = (instance: IUserAccount) => {
|
||||||
|
removeId.value = instance.id;
|
||||||
|
removeEntity.value.show();
|
||||||
|
};
|
||||||
|
const closeDialog = () => {
|
||||||
|
removeEntity.value.hide();
|
||||||
|
};
|
||||||
|
const removeUserAccount = async () => {
|
||||||
|
try {
|
||||||
|
await userAccountService().delete(removeId.value);
|
||||||
|
const message = `A UserAccount is deleted with identifier ${removeId.value}`;
|
||||||
|
alertService.showInfo(message, { variant: 'danger' });
|
||||||
|
removeId.value = null;
|
||||||
|
retrieveUserAccounts();
|
||||||
|
closeDialog();
|
||||||
|
} catch (error) {
|
||||||
|
alertService.showHttpError(error.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
userAccounts,
|
||||||
|
handleSyncList,
|
||||||
|
isFetching,
|
||||||
|
retrieveUserAccounts,
|
||||||
|
clear,
|
||||||
|
removeId,
|
||||||
|
removeEntity,
|
||||||
|
prepareRemove,
|
||||||
|
closeDialog,
|
||||||
|
removeUserAccount,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
/* tslint:disable max-line-length */
|
||||||
|
import axios from 'axios';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
|
||||||
|
import UserAccountService from './user-account.service';
|
||||||
|
import { UserAccount } from '@/shared/model/user-account.model';
|
||||||
|
|
||||||
|
const error = {
|
||||||
|
response: {
|
||||||
|
status: null,
|
||||||
|
data: {
|
||||||
|
type: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const axiosStub = {
|
||||||
|
get: sinon.stub(axios, 'get'),
|
||||||
|
post: sinon.stub(axios, 'post'),
|
||||||
|
put: sinon.stub(axios, 'put'),
|
||||||
|
patch: sinon.stub(axios, 'patch'),
|
||||||
|
delete: sinon.stub(axios, 'delete'),
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Service Tests', () => {
|
||||||
|
describe('UserAccount Service', () => {
|
||||||
|
let service: UserAccountService;
|
||||||
|
let elemDefault;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
service = new UserAccountService();
|
||||||
|
elemDefault = new UserAccount(123, 'AAAAAAA');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Service methods', () => {
|
||||||
|
it('should find an element', async () => {
|
||||||
|
const returnedFromService = { ...elemDefault };
|
||||||
|
axiosStub.get.resolves({ data: returnedFromService });
|
||||||
|
|
||||||
|
return service.find(123).then(res => {
|
||||||
|
expect(res).toMatchObject(elemDefault);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not find an element', async () => {
|
||||||
|
axiosStub.get.rejects(error);
|
||||||
|
return service
|
||||||
|
.find(123)
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a UserAccount', async () => {
|
||||||
|
const returnedFromService = { id: 123, ...elemDefault };
|
||||||
|
const expected = { ...returnedFromService };
|
||||||
|
|
||||||
|
axiosStub.post.resolves({ data: returnedFromService });
|
||||||
|
return service.create({}).then(res => {
|
||||||
|
expect(res).toMatchObject(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not create a UserAccount', async () => {
|
||||||
|
axiosStub.post.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.create({})
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update a UserAccount', async () => {
|
||||||
|
const returnedFromService = { name: 'BBBBBB', ...elemDefault };
|
||||||
|
|
||||||
|
const expected = { ...returnedFromService };
|
||||||
|
axiosStub.put.resolves({ data: returnedFromService });
|
||||||
|
|
||||||
|
return service.update(expected).then(res => {
|
||||||
|
expect(res).toMatchObject(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not update a UserAccount', async () => {
|
||||||
|
axiosStub.put.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.update({})
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should partial update a UserAccount', async () => {
|
||||||
|
const patchObject = { name: 'BBBBBB', ...new UserAccount() };
|
||||||
|
const returnedFromService = Object.assign(patchObject, elemDefault);
|
||||||
|
|
||||||
|
const expected = { ...returnedFromService };
|
||||||
|
axiosStub.patch.resolves({ data: returnedFromService });
|
||||||
|
|
||||||
|
return service.partialUpdate(patchObject).then(res => {
|
||||||
|
expect(res).toMatchObject(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not partial update a UserAccount', async () => {
|
||||||
|
axiosStub.patch.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.partialUpdate({})
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a list of UserAccount', async () => {
|
||||||
|
const returnedFromService = { name: 'BBBBBB', ...elemDefault };
|
||||||
|
const expected = { ...returnedFromService };
|
||||||
|
axiosStub.get.resolves([returnedFromService]);
|
||||||
|
return service.retrieve().then(res => {
|
||||||
|
expect(res).toContainEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not return a list of UserAccount', async () => {
|
||||||
|
axiosStub.get.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.retrieve()
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete a UserAccount', async () => {
|
||||||
|
axiosStub.delete.resolves({ ok: true });
|
||||||
|
return service.delete(123).then(res => {
|
||||||
|
expect(res.ok).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not delete a UserAccount', async () => {
|
||||||
|
axiosStub.delete.rejects(error);
|
||||||
|
|
||||||
|
return service
|
||||||
|
.delete(123)
|
||||||
|
.then()
|
||||||
|
.catch(err => {
|
||||||
|
expect(err).toMatchObject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import { type IUserAccount } from '@/shared/model/user-account.model';
|
||||||
|
|
||||||
|
const baseApiUrl = 'api/user-accounts';
|
||||||
|
|
||||||
|
export default class UserAccountService {
|
||||||
|
public find(id: number): Promise<IUserAccount> {
|
||||||
|
return new Promise<IUserAccount>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.get(`${baseApiUrl}/${id}`)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCurrentUser(): Promise<IUserAccount> {
|
||||||
|
return new Promise<IUserAccount>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.get(`${baseApiUrl}/currentUser`)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public retrieve(): Promise<any> {
|
||||||
|
return new Promise<any>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.get(baseApiUrl)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public delete(id: number): Promise<any> {
|
||||||
|
return new Promise<any>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.delete(`${baseApiUrl}/${id}`)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public create(entity: IUserAccount): Promise<IUserAccount> {
|
||||||
|
return new Promise<IUserAccount>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.post(`${baseApiUrl}`, entity)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public update(entity: IUserAccount): Promise<IUserAccount> {
|
||||||
|
return new Promise<IUserAccount>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.put(`${baseApiUrl}/${entity.id}`, entity)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public partialUpdate(entity: IUserAccount): Promise<IUserAccount> {
|
||||||
|
return new Promise<IUserAccount>((resolve, reject) => {
|
||||||
|
axios
|
||||||
|
.patch(`${baseApiUrl}/${entity.id}`, entity)
|
||||||
|
.then(res => {
|
||||||
|
resolve(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h2 id="page-heading" data-cy="UserAccountHeading">
|
||||||
|
<span id="user-account-heading">User Accounts</span>
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<button class="btn btn-info mr-2" @click="handleSyncList" :disabled="isFetching">
|
||||||
|
<font-awesome-icon icon="sync" :spin="isFetching"></font-awesome-icon> <span>Refresh list</span>
|
||||||
|
</button>
|
||||||
|
<router-link :to="{ name: 'UserAccountCreate' }" custom v-slot="{ navigate }">
|
||||||
|
<button
|
||||||
|
@click="navigate"
|
||||||
|
id="jh-create-entity"
|
||||||
|
data-cy="entityCreateButton"
|
||||||
|
class="btn btn-primary jh-create-entity create-user-account"
|
||||||
|
>
|
||||||
|
<font-awesome-icon icon="plus"></font-awesome-icon>
|
||||||
|
<span>Create a new User Account</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
|
<br />
|
||||||
|
<div class="alert alert-warning" v-if="!isFetching && userAccounts && userAccounts.length === 0">
|
||||||
|
<span>No User Accounts found</span>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive" v-if="userAccounts && userAccounts.length > 0">
|
||||||
|
<table class="table table-striped" aria-describedby="userAccounts">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><span>ID</span></th>
|
||||||
|
<th scope="row"><span>Name</span></th>
|
||||||
|
<th scope="row"><span>User</span></th>
|
||||||
|
<th scope="row"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="userAccount in userAccounts" :key="userAccount.id" data-cy="entityTable">
|
||||||
|
<td>
|
||||||
|
<router-link :to="{ name: 'UserAccountView', params: { userAccountId: userAccount.id } }">{{ userAccount.id }}</router-link>
|
||||||
|
</td>
|
||||||
|
<td>{{ userAccount.name }}</td>
|
||||||
|
<td>
|
||||||
|
<span v-for="(user, i) in userAccount.users" :key="user.id"
|
||||||
|
>{{ i > 0 ? ', ' : '' }}
|
||||||
|
{{ user.login }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<router-link :to="{ name: 'UserAccountView', params: { userAccountId: userAccount.id } }" custom v-slot="{ navigate }">
|
||||||
|
<button @click="navigate" class="btn btn-info btn-sm details" data-cy="entityDetailsButton">
|
||||||
|
<font-awesome-icon icon="eye"></font-awesome-icon>
|
||||||
|
<span class="d-none d-md-inline">View</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
<router-link :to="{ name: 'UserAccountEdit', params: { userAccountId: userAccount.id } }" custom v-slot="{ navigate }">
|
||||||
|
<button @click="navigate" class="btn btn-primary btn-sm edit" data-cy="entityEditButton">
|
||||||
|
<font-awesome-icon icon="pencil-alt"></font-awesome-icon>
|
||||||
|
<span class="d-none d-md-inline">Edit</span>
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
|
<b-button
|
||||||
|
@click="prepareRemove(userAccount)"
|
||||||
|
variant="danger"
|
||||||
|
class="btn btn-sm"
|
||||||
|
data-cy="entityDeleteButton"
|
||||||
|
v-b-modal.removeEntity
|
||||||
|
>
|
||||||
|
<font-awesome-icon icon="times"></font-awesome-icon>
|
||||||
|
<span class="d-none d-md-inline">Delete</span>
|
||||||
|
</b-button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<b-modal ref="removeEntity" id="removeEntity">
|
||||||
|
<template #modal-title>
|
||||||
|
<span id="sasiedziApp.userAccount.delete.question" data-cy="userAccountDeleteDialogHeading">Confirm delete operation</span>
|
||||||
|
</template>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p id="jhi-delete-userAccount-heading">Are you sure you want to delete User Account {{ removeId }}?</p>
|
||||||
|
</div>
|
||||||
|
<template #modal-footer>
|
||||||
|
<div>
|
||||||
|
<button type="button" class="btn btn-secondary" @click="closeDialog()">Cancel</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-primary"
|
||||||
|
id="jhi-confirm-delete-userAccount"
|
||||||
|
data-cy="entityConfirmDeleteButton"
|
||||||
|
@click="removeUserAccount()"
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</b-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" src="./user-account.component.ts"></script>
|
||||||
@@ -15,6 +15,14 @@ const Registration = () => import('@/entities/registration/registration.vue');
|
|||||||
const RegistrationUpdate = () => import('@/entities/registration/registration-update.vue');
|
const RegistrationUpdate = () => import('@/entities/registration/registration-update.vue');
|
||||||
const RegistrationDetails = () => import('@/entities/registration/registration-details.vue');
|
const RegistrationDetails = () => import('@/entities/registration/registration-details.vue');
|
||||||
|
|
||||||
|
const Transaction = () => import('@/entities/transaction/transaction.vue');
|
||||||
|
const TransactionUpdate = () => import('@/entities/transaction/transaction-update.vue');
|
||||||
|
const TransactionDetails = () => import('@/entities/transaction/transaction-details.vue');
|
||||||
|
|
||||||
|
const UserAccount = () => import('@/entities/user-account/user-account.vue');
|
||||||
|
const UserAccountUpdate = () => import('@/entities/user-account/user-account-update.vue');
|
||||||
|
const UserAccountDetails = () => import('@/entities/user-account/user-account-details.vue');
|
||||||
|
|
||||||
// jhipster-needle-add-entity-to-router-import - JHipster will import entities to the router here
|
// jhipster-needle-add-entity-to-router-import - JHipster will import entities to the router here
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -25,25 +33,25 @@ export default {
|
|||||||
path: 'charge',
|
path: 'charge',
|
||||||
name: 'Charge',
|
name: 'Charge',
|
||||||
component: Charge,
|
component: Charge,
|
||||||
meta: { authorities: [Authority.USER] },
|
meta: { authorities: [Authority.ADMIN] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'charge/new',
|
path: 'charge/new',
|
||||||
name: 'ChargeCreate',
|
name: 'ChargeCreate',
|
||||||
component: ChargeUpdate,
|
component: ChargeUpdate,
|
||||||
meta: { authorities: [Authority.USER] },
|
meta: { authorities: [Authority.ADMIN] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'charge/:chargeId/edit',
|
path: 'charge/:chargeId/edit',
|
||||||
name: 'ChargeEdit',
|
name: 'ChargeEdit',
|
||||||
component: ChargeUpdate,
|
component: ChargeUpdate,
|
||||||
meta: { authorities: [Authority.USER] },
|
meta: { authorities: [Authority.ADMIN] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'charge/:chargeId/view',
|
path: 'charge/:chargeId/view',
|
||||||
name: 'ChargeView',
|
name: 'ChargeView',
|
||||||
component: ChargeDetails,
|
component: ChargeDetails,
|
||||||
meta: { authorities: [Authority.USER] },
|
meta: { authorities: [Authority.ADMIN] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'event',
|
path: 'event',
|
||||||
@@ -55,13 +63,13 @@ export default {
|
|||||||
path: 'event/new',
|
path: 'event/new',
|
||||||
name: 'EventCreate',
|
name: 'EventCreate',
|
||||||
component: EventUpdate,
|
component: EventUpdate,
|
||||||
meta: { authorities: [Authority.USER] },
|
meta: { authorities: [Authority.ADMIN, Authority.COUNTER] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'event/:eventId/edit',
|
path: 'event/:eventId/edit',
|
||||||
name: 'EventEdit',
|
name: 'EventEdit',
|
||||||
component: EventUpdate,
|
component: EventUpdate,
|
||||||
meta: { authorities: [Authority.USER] },
|
meta: { authorities: [Authority.ADMIN, Authority.COUNTER] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'event/:eventId/view',
|
path: 'event/:eventId/view',
|
||||||
@@ -86,7 +94,7 @@ export default {
|
|||||||
path: 'registration/:registrationId/edit',
|
path: 'registration/:registrationId/edit',
|
||||||
name: 'RegistrationEdit',
|
name: 'RegistrationEdit',
|
||||||
component: RegistrationUpdate,
|
component: RegistrationUpdate,
|
||||||
meta: { authorities: [Authority.USER] },
|
meta: { authorities: [Authority.ADMIN] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'registration/:registrationId/view',
|
path: 'registration/:registrationId/view',
|
||||||
@@ -94,6 +102,84 @@ export default {
|
|||||||
component: RegistrationDetails,
|
component: RegistrationDetails,
|
||||||
meta: { authorities: [Authority.USER] },
|
meta: { authorities: [Authority.USER] },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'transaction',
|
||||||
|
name: 'Transaction',
|
||||||
|
component: Transaction,
|
||||||
|
meta: { authorities: [Authority.USER] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'my-transaction/:userAccountId?',
|
||||||
|
name: 'MyTransaction',
|
||||||
|
component: Transaction,
|
||||||
|
meta: { authorities: [Authority.USER] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'transaction/new',
|
||||||
|
name: 'TransactionCreate',
|
||||||
|
component: TransactionUpdate,
|
||||||
|
meta: { authorities: [Authority.ADMIN, Authority.COUNTER] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'transaction/opposing/:opposingTransactionId/new',
|
||||||
|
name: 'TransactionCreateOpposite',
|
||||||
|
component: TransactionUpdate,
|
||||||
|
meta: { authorities: [Authority.ADMIN, Authority.COUNTER] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'transaction/field-payment/:paymentForFieldByEventId/new',
|
||||||
|
name: 'TransactionFieldPayment',
|
||||||
|
component: TransactionUpdate,
|
||||||
|
meta: { authorities: [Authority.ADMIN, Authority.COUNTER] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'transaction/payments/:paymentsForTransactionId/new',
|
||||||
|
name: 'TransactionPaymentsForTransaction',
|
||||||
|
component: TransactionUpdate,
|
||||||
|
meta: { authorities: [Authority.ADMIN, Authority.COUNTER] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'transaction/opposing/:opposingTransactionId/new',
|
||||||
|
name: 'TransactionCreateOpposite',
|
||||||
|
component: TransactionUpdate,
|
||||||
|
meta: { authorities: [Authority.ADMIN, Authority.COUNTER] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'transaction/:transactionId/edit',
|
||||||
|
name: 'TransactionEdit',
|
||||||
|
component: TransactionUpdate,
|
||||||
|
meta: { authorities: [Authority.ADMIN, Authority.COUNTER] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'transaction/:transactionId/view',
|
||||||
|
name: 'TransactionView',
|
||||||
|
component: TransactionDetails,
|
||||||
|
meta: { authorities: [Authority.USER] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'user-account',
|
||||||
|
name: 'UserAccount',
|
||||||
|
component: UserAccount,
|
||||||
|
meta: { authorities: [Authority.ADMIN] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'user-account/new',
|
||||||
|
name: 'UserAccountCreate',
|
||||||
|
component: UserAccountUpdate,
|
||||||
|
meta: { authorities: [Authority.ADMIN] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'user-account/:userAccountId/edit',
|
||||||
|
name: 'UserAccountEdit',
|
||||||
|
component: UserAccountUpdate,
|
||||||
|
meta: { authorities: [Authority.ADMIN] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'user-account/:userAccountId/view',
|
||||||
|
name: 'UserAccountView',
|
||||||
|
component: UserAccountDetails,
|
||||||
|
meta: { authorities: [Authority.ADMIN] },
|
||||||
|
},
|
||||||
// jhipster-needle-add-entity-to-router - JHipster will add entities to the router here
|
// jhipster-needle-add-entity-to-router - JHipster will add entities to the router here
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ const Error = () => import('@/core/error/error.vue');
|
|||||||
import admin from '@/router/admin';
|
import admin from '@/router/admin';
|
||||||
import entities from '@/router/entities';
|
import entities from '@/router/entities';
|
||||||
import pages from '@/router/pages';
|
import pages from '@/router/pages';
|
||||||
|
// import { useStore } from '@/store';
|
||||||
|
import { Authority } from '@/shared/security/authority';
|
||||||
|
const EventDetails = () => import('@/entities/event/event-details.vue');
|
||||||
|
const Event = () => import('@/entities/event/event.vue');
|
||||||
|
|
||||||
export const createRouter = () =>
|
export const createRouter = () =>
|
||||||
createVueRouter({
|
createVueRouter({
|
||||||
@@ -12,7 +16,9 @@ export const createRouter = () =>
|
|||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
redirect: '/event/1551/view',
|
name: 'CurrentEventView',
|
||||||
|
component: EventDetails,
|
||||||
|
meta: { authorities: [Authority.USER], eventId: 'useCurrentEventId' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/forbidden',
|
path: '/forbidden',
|
||||||
@@ -22,9 +28,10 @@ export const createRouter = () =>
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/not-found',
|
path: '/not-found',
|
||||||
name: 'NotFound',
|
redirect: '/',
|
||||||
component: Error,
|
// name: 'NotFound',
|
||||||
meta: { error404: true },
|
// component: Error,
|
||||||
|
// meta: { error404: true },
|
||||||
},
|
},
|
||||||
...admin,
|
...admin,
|
||||||
entities,
|
entities,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export interface AccountStateStorable {
|
|||||||
profilesLoaded: boolean;
|
profilesLoaded: boolean;
|
||||||
ribbonOnProfiles: string;
|
ribbonOnProfiles: string;
|
||||||
activeProfiles: string;
|
activeProfiles: string;
|
||||||
|
currentEventId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultAccountState: AccountStateStorable = {
|
export const defaultAccountState: AccountStateStorable = {
|
||||||
@@ -16,6 +17,7 @@ export const defaultAccountState: AccountStateStorable = {
|
|||||||
profilesLoaded: false,
|
profilesLoaded: false,
|
||||||
ribbonOnProfiles: '',
|
ribbonOnProfiles: '',
|
||||||
activeProfiles: '',
|
activeProfiles: '',
|
||||||
|
currentEventId: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useAccountStore = defineStore('main', {
|
export const useAccountStore = defineStore('main', {
|
||||||
@@ -46,5 +48,8 @@ export const useAccountStore = defineStore('main', {
|
|||||||
setRibbonOnProfiles(ribbon) {
|
setRibbonOnProfiles(ribbon) {
|
||||||
this.ribbonOnProfiles = ribbon;
|
this.ribbonOnProfiles = ribbon;
|
||||||
},
|
},
|
||||||
|
setCurrentEventId(currentEventId) {
|
||||||
|
this.currentEventId = currentEventId;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export enum TransactionType {
|
||||||
|
PURCHASE = 'PURCHASE',
|
||||||
|
|
||||||
|
MATCH = 'MATCH',
|
||||||
|
|
||||||
|
FIELDPAYMENT = 'FIELDPAYMENT',
|
||||||
|
|
||||||
|
INTERNALTRANSFER = 'INTERNALTRANSFER',
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { IRegistration } from '@/shared/model/registration.model';
|
import type { IRegistration } from '@/shared/model/registration.model';
|
||||||
|
import type { ITransaction } from '@/shared/model/transaction.model';
|
||||||
|
|
||||||
export interface IEvent {
|
export interface IEvent {
|
||||||
id?: number;
|
id?: number;
|
||||||
@@ -8,6 +9,14 @@ export interface IEvent {
|
|||||||
cost?: number | null;
|
cost?: number | null;
|
||||||
comment?: string | null;
|
comment?: string | null;
|
||||||
registrations?: IRegistration[];
|
registrations?: IRegistration[];
|
||||||
|
transactions?: ITransaction[];
|
||||||
|
editable?: boolean | false;
|
||||||
|
deletable?: boolean | false;
|
||||||
|
charged?: boolean | false;
|
||||||
|
paid?: boolean | false;
|
||||||
|
active?: boolean | false;
|
||||||
|
current?: boolean | false;
|
||||||
|
chargeTransactionId?: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Event implements IEvent {
|
export class Event implements IEvent {
|
||||||
@@ -19,5 +28,13 @@ export class Event implements IEvent {
|
|||||||
public cost?: number | null,
|
public cost?: number | null,
|
||||||
public comment?: string | null,
|
public comment?: string | null,
|
||||||
public registrations?: IRegistration[],
|
public registrations?: IRegistration[],
|
||||||
|
public transactions?: ITransaction[],
|
||||||
|
public editable?: boolean | false,
|
||||||
|
public deletable?: boolean | false,
|
||||||
|
public charged?: boolean | false,
|
||||||
|
public paid?: boolean | false,
|
||||||
|
public active?: boolean | false,
|
||||||
|
public current?: boolean | false,
|
||||||
|
public chargeTransactionId?: number | null,
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { type IEvent } from '@/shared/model/event.model';
|
||||||
|
|
||||||
|
import { type TransactionType } from '@/shared/model/enumerations/transaction-type.model';
|
||||||
|
import type { IUserAccount } from '@/shared/model/user-account.model';
|
||||||
|
export interface ITransaction {
|
||||||
|
id?: number;
|
||||||
|
type?: keyof typeof TransactionType | null;
|
||||||
|
date?: Date | null;
|
||||||
|
comment?: string | null;
|
||||||
|
event?: IEvent | null;
|
||||||
|
transactionItems?: ITransactionItem[] | [];
|
||||||
|
items?: ITransactionItem[] | [];
|
||||||
|
beneficiary?: IUserAccount | null;
|
||||||
|
editable?: boolean | false;
|
||||||
|
deletable?: boolean | false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Transaction implements ITransaction {
|
||||||
|
constructor(
|
||||||
|
public id?: number,
|
||||||
|
public type?: keyof typeof TransactionType | null,
|
||||||
|
public date?: Date | null,
|
||||||
|
public comment?: string | null,
|
||||||
|
public event?: IEvent | null,
|
||||||
|
public items?: ITransactionItem[] | [],
|
||||||
|
public beneficiary?: IUserAccount | null,
|
||||||
|
public editable?: boolean | false,
|
||||||
|
public deletable?: boolean | false,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ITransactionItem {
|
||||||
|
id?: number;
|
||||||
|
comment?: string | null;
|
||||||
|
event?: IEvent | null;
|
||||||
|
amount?: number | null;
|
||||||
|
userAccount?: IUserAccount | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TransactionItem implements ITransactionItem {
|
||||||
|
constructor(
|
||||||
|
public id?: number,
|
||||||
|
public comment?: string | null,
|
||||||
|
public event?: IEvent | null,
|
||||||
|
public amount?: number | null,
|
||||||
|
public userAccount?: IUserAccount | null,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { type IUser } from '@/shared/model/user.model';
|
||||||
|
|
||||||
|
export interface IUserAccount {
|
||||||
|
id?: number;
|
||||||
|
name?: string | null;
|
||||||
|
users?: IUser[] | null;
|
||||||
|
balance?: number | 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UserAccount implements IUserAccount {
|
||||||
|
constructor(
|
||||||
|
public id?: number,
|
||||||
|
public name?: string | null,
|
||||||
|
public users?: IUser[] | null,
|
||||||
|
public balance?: number | 0,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ export interface IUser {
|
|||||||
login?: string;
|
login?: string;
|
||||||
firstName?: string;
|
firstName?: string;
|
||||||
lastName?: string;
|
lastName?: string;
|
||||||
|
name?: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
activated?: boolean;
|
activated?: boolean;
|
||||||
langKey?: string;
|
langKey?: string;
|
||||||
@@ -20,6 +21,7 @@ export class User implements IUser {
|
|||||||
public login?: string,
|
public login?: string,
|
||||||
public firstName?: string,
|
public firstName?: string,
|
||||||
public lastName?: string,
|
public lastName?: string,
|
||||||
|
public name?: string,
|
||||||
public email?: string,
|
public email?: string,
|
||||||
public activated?: boolean,
|
public activated?: boolean,
|
||||||
public langKey?: string,
|
public langKey?: string,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export enum Authority {
|
export enum Authority {
|
||||||
ADMIN = 'ROLE_ADMIN',
|
ADMIN = 'ROLE_ADMIN',
|
||||||
USER = 'ROLE_USER',
|
USER = 'ROLE_USER',
|
||||||
|
COUNTER = 'ROLE_COUNTER',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,3 +150,34 @@
|
|||||||
-webkit-animation-delay: 0s;
|
-webkit-animation-delay: 0s;
|
||||||
animation-delay: 0s;
|
animation-delay: 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
th.rotate {
|
||||||
|
/*height:10px;*/
|
||||||
|
height: 180px;
|
||||||
|
/*width:50px;*/
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
border: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th.rotate > div {
|
||||||
|
transform: rotate(290deg);
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 126px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.strikethrough {
|
||||||
|
text-decoration: line-through;
|
||||||
|
color: lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inplus {
|
||||||
|
background-color: lightgreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inminus {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user