Skip to content

Commit 9287473

Browse files
committed
/collection/{slug}/estimation: add a page with prices of the series in a collection.
Fix #884
1 parent 3dcea70 commit 9287473

15 files changed

+316
-2
lines changed

Diff for: src/main/java/ru/mystamps/web/Url.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ public final class Url {
6767
public static final String GET_COUNTRIES_PAGE = "/countries";
6868
public static final String INFO_COUNTRY_PAGE = "/country/{slug}";
6969

70-
public static final String INFO_COLLECTION_PAGE = "/collection/{slug}";
70+
public static final String INFO_COLLECTION_PAGE = "/collection/{slug}";
71+
public static final String ESTIMATION_COLLECTION_PAGE = "/collection/{slug}/estimation";
7172

7273
public static final String GET_IMAGE_PAGE = "/image/{id}";
7374
public static final String GET_IMAGE_PREVIEW_PAGE = "/image/preview/{id}";
@@ -145,6 +146,7 @@ public static Map<String, String> asMap(boolean production) {
145146
map.put("AUTHENTICATION_PAGE", AUTHENTICATION_PAGE);
146147
map.put("BOOTSTRAP_LANGUAGE", BOOTSTRAP_LANGUAGE);
147148
map.put("DAILY_STATISTICS", DAILY_STATISTICS);
149+
map.put("ESTIMATION_COLLECTION_PAGE", ESTIMATION_COLLECTION_PAGE);
148150
map.put("GET_CATEGORIES_PAGE", GET_CATEGORIES_PAGE);
149151
map.put("GET_COUNTRIES_PAGE", GET_COUNTRIES_PAGE);
150152
map.put("INFO_CATEGORY_PAGE", INFO_CATEGORY_PAGE);

Diff for: src/main/java/ru/mystamps/web/controller/CollectionController.java

+34
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import ru.mystamps.web.Url;
3838
import ru.mystamps.web.dao.dto.CollectionInfoDto;
3939
import ru.mystamps.web.dao.dto.SeriesInCollectionDto;
40+
import ru.mystamps.web.dao.dto.SeriesInCollectionWithPriceDto;
4041
import ru.mystamps.web.service.CategoryService;
4142
import ru.mystamps.web.service.CollectionService;
4243
import ru.mystamps.web.service.CountryService;
@@ -53,6 +54,7 @@ public class CollectionController {
5354
private final SeriesService seriesService;
5455
private final MessageSource messageSource;
5556

57+
// @todo #884 /collection/{slug}: add a link to collection estimation page
5658
@GetMapping(Url.INFO_COLLECTION_PAGE)
5759
public String showInfoBySlug(
5860
@PathVariable("slug") String slug,
@@ -101,6 +103,38 @@ public String showInfoBySlug(
101103

102104
return "collection/info";
103105
}
106+
107+
// @todo #884 Add integration tests for collection estimation page
108+
@GetMapping(Url.ESTIMATION_COLLECTION_PAGE)
109+
public String showPrices(
110+
@PathVariable("slug") String slug,
111+
Model model,
112+
Locale userLocale,
113+
HttpServletResponse response)
114+
throws IOException {
115+
116+
if (slug == null) {
117+
response.sendError(HttpServletResponse.SC_NOT_FOUND);
118+
return null;
119+
}
120+
121+
// TODO: we need only ownerName, without id and slug
122+
CollectionInfoDto collection = collectionService.findBySlug(slug);
123+
if (collection == null) {
124+
response.sendError(HttpServletResponse.SC_NOT_FOUND);
125+
return null;
126+
}
127+
128+
String owner = collection.getOwnerName();
129+
model.addAttribute("ownerName", owner);
130+
131+
String lang = LocaleUtils.getLanguageOrNull(userLocale);
132+
List<SeriesInCollectionWithPriceDto> seriesOfCollection =
133+
collectionService.findSeriesWithPricesBySlug(slug, lang);
134+
model.addAttribute("seriesOfCollection", seriesOfCollection);
135+
136+
return "collection/estimation";
137+
}
104138

105139
@GetMapping(Url.INFO_COLLECTION_BY_ID_PAGE)
106140
public View showInfoById(

Diff for: src/main/java/ru/mystamps/web/controller/dto/AddToCollectionForm.java

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
// @todo #477 Add to collection: series quantity should be specified by default
3636
// @todo #477 Add to collection: add integration test for custom number of stamps
3737
// @todo #663 Add to collection: add integration test for specifying a price
38-
// @todo #663 Add a page with a list of series, their prices and total cost
3938
@Getter
4039
@Setter
4140
@MaxNumberOfStamps

Diff for: src/main/java/ru/mystamps/web/dao/CollectionDao.java

+2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424
import ru.mystamps.web.dao.dto.AddToCollectionDbDto;
2525
import ru.mystamps.web.dao.dto.CollectionInfoDto;
2626
import ru.mystamps.web.dao.dto.LinkEntityDto;
27+
import ru.mystamps.web.dao.dto.SeriesInCollectionWithPriceDto;
2728

2829
public interface CollectionDao {
2930
List<LinkEntityDto> findLastCreated(int quantity);
31+
List<SeriesInCollectionWithPriceDto> findSeriesWithPricesBySlug(String slug, String lang);
3032
long countCollectionsOfUsers();
3133
long countUpdatedSince(Date date);
3234
Integer add(AddCollectionDbDto collection);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (C) 2009-2018 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.dao.dto;
19+
20+
import java.math.BigDecimal;
21+
22+
import lombok.Getter;
23+
import lombok.RequiredArgsConstructor;
24+
25+
@Getter
26+
@RequiredArgsConstructor
27+
public class SeriesInCollectionWithPriceDto {
28+
private final Integer id;
29+
private final Integer releaseYear;
30+
private final Integer quantity;
31+
private final Integer numberOfStamps;
32+
private final Boolean perforated;
33+
private final String countryName;
34+
private final BigDecimal price;
35+
private final Currency currency;
36+
}

Diff for: src/main/java/ru/mystamps/web/dao/impl/JdbcCollectionDao.java

+20
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import ru.mystamps.web.dao.dto.AddToCollectionDbDto;
4343
import ru.mystamps.web.dao.dto.CollectionInfoDto;
4444
import ru.mystamps.web.dao.dto.LinkEntityDto;
45+
import ru.mystamps.web.dao.dto.SeriesInCollectionWithPriceDto;
4546

4647
@RequiredArgsConstructor
4748
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
@@ -53,6 +54,9 @@ public class JdbcCollectionDao implements CollectionDao {
5354
@Value("${collection.find_last_created}")
5455
private String findLastCreatedCollectionsSql;
5556

57+
@Value("${collection.find_series_with_prices_by_slug}")
58+
private String findSeriesWithPricesBySlugSql;
59+
5660
@Value("${collection.count_collections_of_users}")
5761
private String countCollectionsOfUsersSql;
5862

@@ -86,6 +90,22 @@ public List<LinkEntityDto> findLastCreated(int quantity) {
8690
);
8791
}
8892

93+
@Override
94+
public List<SeriesInCollectionWithPriceDto> findSeriesWithPricesBySlug(
95+
String slug,
96+
String lang) {
97+
98+
Map<String, Object> params = new HashMap<>();
99+
params.put("slug", slug);
100+
params.put("lang", lang);
101+
102+
return jdbcTemplate.query(
103+
findSeriesWithPricesBySlugSql,
104+
params,
105+
RowMappers::forSeriesInCollectionWithPriceDto
106+
);
107+
}
108+
89109
@Override
90110
public long countCollectionsOfUsers() {
91111
return jdbcTemplate.queryForObject(

Diff for: src/main/java/ru/mystamps/web/dao/impl/RowMappers.java

+26
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,32 @@ public static SeriesInCollectionDto forSeriesInCollectionDto(ResultSet rs, int u
109109
);
110110
}
111111

112+
public static SeriesInCollectionWithPriceDto forSeriesInCollectionWithPriceDto(
113+
ResultSet rs,
114+
int unused)
115+
throws SQLException {
116+
117+
Integer id = rs.getInt("id");
118+
Integer releaseYear = JdbcUtils.getInteger(rs, "release_year");
119+
Integer quantity = rs.getInt("quantity");
120+
Boolean perforated = rs.getBoolean("perforated");
121+
Integer numberOfStamps = rs.getInt("number_of_stamps");
122+
String country = rs.getString("country_name");
123+
BigDecimal price = rs.getBigDecimal("price");
124+
Currency currency = JdbcUtils.getCurrency(rs, "currency");
125+
126+
return new SeriesInCollectionWithPriceDto(
127+
id,
128+
releaseYear,
129+
quantity,
130+
numberOfStamps,
131+
perforated,
132+
country,
133+
price,
134+
currency
135+
);
136+
}
137+
112138
/**
113139
* @author Sergey Chechenev
114140
*/

Diff for: src/main/java/ru/mystamps/web/service/CollectionService.java

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import ru.mystamps.web.dao.dto.CollectionInfoDto;
2424
import ru.mystamps.web.dao.dto.LinkEntityDto;
25+
import ru.mystamps.web.dao.dto.SeriesInCollectionWithPriceDto;
2526
import ru.mystamps.web.service.dto.AddToCollectionDto;
2627

2728
public interface CollectionService {
@@ -32,5 +33,6 @@ public interface CollectionService {
3233
long countCollectionsOfUsers();
3334
long countUpdatedSince(Date date);
3435
List<LinkEntityDto> findRecentlyCreated(int quantity);
36+
List<SeriesInCollectionWithPriceDto> findSeriesWithPricesBySlug(String slug, String lang);
3537
CollectionInfoDto findBySlug(String slug);
3638
}

Diff for: src/main/java/ru/mystamps/web/service/CollectionServiceImpl.java

+15
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import ru.mystamps.web.dao.dto.AddToCollectionDbDto;
3737
import ru.mystamps.web.dao.dto.CollectionInfoDto;
3838
import ru.mystamps.web.dao.dto.LinkEntityDto;
39+
import ru.mystamps.web.dao.dto.SeriesInCollectionWithPriceDto;
3940
import ru.mystamps.web.service.dto.AddToCollectionDto;
4041
import ru.mystamps.web.support.spring.security.HasAuthority;
4142
import ru.mystamps.web.util.SlugUtils;
@@ -150,6 +151,20 @@ public List<LinkEntityDto> findRecentlyCreated(int quantity) {
150151
return collectionDao.findLastCreated(quantity);
151152
}
152153

154+
// @todo #884 CollectionService.findSeriesWithPricesBySlug(): add unit tests
155+
// @todo #884 CollectionService.findSeriesWithPricesBySlug(): restrict access by only an owner
156+
@Override
157+
@Transactional(readOnly = true)
158+
@PreAuthorize(HasAuthority.ADD_SERIES_PRICE)
159+
public List<SeriesInCollectionWithPriceDto> findSeriesWithPricesBySlug(
160+
String slug,
161+
String lang) {
162+
163+
Validate.isTrue(slug != null, "Collection slug must be non null");
164+
165+
return collectionDao.findSeriesWithPricesBySlug(slug, lang);
166+
}
167+
153168
@Override
154169
@Transactional(readOnly = true)
155170
public CollectionInfoDto findBySlug(String slug) {

Diff for: src/main/java/ru/mystamps/web/support/spring/security/HasAuthority.java

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
public final class HasAuthority {
2222
// Constants sorted in an ascending order.
2323
public static final String ADD_PARTICIPANT = "hasAuthority('" + StringAuthority.ADD_PARTICIPANT + "')";
24+
public static final String ADD_SERIES_PRICE = "hasAuthority('" + StringAuthority.ADD_SERIES_PRICE + "')";
2425
public static final String ADD_SERIES_SALES = "hasAuthority('" + StringAuthority.ADD_SERIES_SALES + "')";
2526
public static final String CREATE_CATEGORY = "hasAuthority('" + StringAuthority.CREATE_CATEGORY + "')";
2627
public static final String CREATE_COUNTRY = "hasAuthority('" + StringAuthority.CREATE_COUNTRY + "')";

Diff for: src/main/java/ru/mystamps/web/support/spring/security/SecurityConfig.java

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ protected void configure(HttpSecurity http) throws Exception {
8989
.mvcMatchers(Url.SITE_EVENTS_PAGE).hasAuthority(StringAuthority.VIEW_SITE_EVENTS)
9090
.mvcMatchers(Url.SUGGEST_SERIES_COUNTRY).hasAuthority(StringAuthority.CREATE_SERIES)
9191
.mvcMatchers(Url.DAILY_STATISTICS).hasAuthority(StringAuthority.VIEW_DAILY_STATS)
92+
// @todo #884 /collection/{slug}/estimation: only owner should have access to estimation page
93+
.mvcMatchers(Url.ESTIMATION_COLLECTION_PAGE).hasAnyAuthority(StringAuthority.ADD_SERIES_PRICE)
9294
.regexMatchers(HttpMethod.POST, "/series/[0-9]+")
9395
.hasAnyAuthority(
9496
StringAuthority.UPDATE_COLLECTION,

Diff for: src/main/resources/ru/mystamps/i18n/Messages.properties

+5
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ t_stamps_by_categories = Stamps by categories
192192
t_stamps_by_countries = Stamps by countries
193193
t_unspecified = Unspecified
194194

195+
# collection/estimation.html
196+
t_series = Series
197+
t_you_paid = You paid
198+
t_total = Total
199+
195200
# participant/add.html
196201
t_group = Group
197202

Diff for: src/main/resources/ru/mystamps/i18n/Messages_ru.properties

+5
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ t_stamps_by_categories = Марки по категориям
191191
t_stamps_by_countries = Марки по странам
192192
t_unspecified = Не указана
193193

194+
# collection/estimation.html
195+
t_series = Серия
196+
t_you_paid = Вы заплатили
197+
t_total = Всего
198+
194199
# participant/add.html
195200
t_group = Группа
196201

Diff for: src/main/resources/sql/collection_dao_queries.properties

+18
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@ collection.find_last_created = \
1010
ORDER BY c.id DESC \
1111
LIMIT :quantity
1212

13+
collection.find_series_with_prices_by_slug = \
14+
SELECT s.id \
15+
, s.release_year \
16+
, s.quantity \
17+
, s.perforated \
18+
, cs.number_of_stamps \
19+
, cs.price \
20+
, cs.currency \
21+
, CASE WHEN 'ru' = :lang THEN COALESCE(count.name_ru, count.name) ELSE count.name END AS country_name \
22+
FROM collections c \
23+
JOIN collections_series cs \
24+
ON cs.collection_id = c.id \
25+
JOIN series s \
26+
ON s.id = cs.series_id \
27+
LEFT JOIN countries count \
28+
ON count.id = s.country_id \
29+
WHERE c.slug = :slug
30+
1331
collection.count_collections_of_users = \
1432
SELECT COUNT(DISTINCT c.id) \
1533
FROM collections c \

0 commit comments

Comments
 (0)