Skip to content

Commit fe9f30d

Browse files
committed
Implement feature "admin can add a link to a page where someone sells series".
Fix #198
1 parent f1e2eee commit fe9f30d

35 files changed

+896
-30
lines changed

NEWS.txt

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
- (infrastructure) ported to Spring's JdbcTemplate (get rid of Spring-Data-JPA and Hibernate)
1111
- (functionality) send daily reports to admin by e-mail
1212
- (infrastructure) use logback (instead of log4j) for logging
13+
- (functionality) add possibility for adding series sales
14+
- (functionality) add interface for viewing series sales (contributed by Sergey Chechenev)
1315

1416
0.3
1517
- (functionality) implemented possibility to user to add series to his collection

src/main/config/checkstyle-suppressions.xml

+3
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@
1414
<!-- These files will be removed during porting integration tests to Cucumber JVM (see #18) -->
1515
<suppress checks="ImportOrder" files="src/test/java/ru/mystamps/web/tests" />
1616

17+
<!-- false positives beause these files contain SQL queries -->
18+
<suppress checks="Translation" files="src/main/resources/sql" />
19+
1720
</suppressions>

src/main/config/findbugs-filter.xml

+9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88
<Class name="~.*\.dto\..*" />
99
<Bug pattern="EI_EXPOSE_REP,EI_EXPOSE_REP2" />
1010
</Match>
11+
<Match>
12+
<!--
13+
Our DTO classes expose it's internal representation.
14+
Most of the time because they're using Date class and
15+
storing data in byte[].
16+
-->
17+
<Class name="~.*\.model\..*" />
18+
<Bug pattern="EI_EXPOSE_REP,EI_EXPOSE_REP2" />
19+
</Match>
1120
<Match>
1221
<!--
1322
It's ok, that we're don't override parent's equals() method.

src/main/java/ru/mystamps/web/Url.java

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public final class Url {
5353
public static final String ADD_SERIES_PAGE = "/series/add";
5454
public static final String ADD_SERIES_WITH_CATEGORY_PAGE = "/series/add/category/{slug}";
5555
public static final String ADD_SERIES_WITH_COUNTRY_PAGE = "/series/add/country/{slug}";
56+
public static final String ADD_SERIES_ASK_PAGE = "/series/{id}/ask";
5657
public static final String INFO_SERIES_PAGE = "/series/{id}";
5758
public static final String ADD_IMAGE_SERIES_PAGE = "/series/{id}/image";
5859
public static final String SEARCH_SERIES_BY_CATALOG = "/series/search/by_catalog";
@@ -127,6 +128,7 @@ public static Map<String, String> asMap(boolean serveContentFromSingleHost) {
127128
map.put("ADD_SERIES_PAGE", ADD_SERIES_PAGE);
128129
map.put("ADD_SERIES_WITH_CATEGORY_PAGE", ADD_SERIES_WITH_CATEGORY_PAGE);
129130
map.put("ADD_SERIES_WITH_COUNTRY_PAGE", ADD_SERIES_WITH_COUNTRY_PAGE);
131+
map.put("ADD_SERIES_ASK_PAGE", ADD_SERIES_ASK_PAGE);
130132
map.put("INFO_SERIES_PAGE", INFO_SERIES_PAGE);
131133
map.put("ADD_IMAGE_SERIES_PAGE", ADD_IMAGE_SERIES_PAGE);
132134
map.put("SEARCH_SERIES_BY_CATALOG", SEARCH_SERIES_BY_CATALOG);

src/main/java/ru/mystamps/web/config/ApplicationContext.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholder
5151
new ClassPathResource("sql/user_dao_queries.properties"),
5252
new ClassPathResource("sql/users_activation_dao_queries.properties"),
5353
new ClassPathResource("sql/series_dao_queries.properties"),
54-
new ClassPathResource("sql/suspicious_activity_dao_queries.properties")
54+
new ClassPathResource("sql/series_sales_dao_queries.properties"),
55+
new ClassPathResource("sql/suspicious_activity_dao_queries.properties"),
56+
new ClassPathResource("sql/transaction_participants_dao_queries.properties")
5557
);
5658
return configurer;
5759
}

src/main/java/ru/mystamps/web/config/ControllersConfig.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ public SeriesController getSeriesController() {
8989
servicesConfig.getCategoryService(),
9090
servicesConfig.getCollectionService(),
9191
servicesConfig.getCountryService(),
92-
servicesConfig.getSeriesService()
92+
servicesConfig.getSeriesService(),
93+
servicesConfig.getSeriesSalesService(),
94+
servicesConfig.getTransactionParticipantService()
9395
);
9496
}
9597

src/main/java/ru/mystamps/web/config/DaoConfig.java

+10
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ public SeriesDao getSeriesDao() {
9797
return new JdbcSeriesDao(jdbcTemplate);
9898
}
9999

100+
@Bean
101+
public SeriesSalesDao getSeriesSalesDao() {
102+
return new JdbcSeriesSalesDao(jdbcTemplate);
103+
}
104+
100105
@Bean
101106
public UserDao getUserDao() {
102107
return new JdbcUserDao(jdbcTemplate);
@@ -112,6 +117,11 @@ public SuspiciousActivityDao getSuspiciousActivityDao() {
112117
return new JdbcSuspiciousActivityDao(jdbcTemplate);
113118
}
114119

120+
@Bean
121+
public TransactionParticipantDao getTransactionParticipantDao() {
122+
return new JdbcTransactionParticipantDao(jdbcTemplate);
123+
}
124+
115125
@Bean
116126
public StampsCatalogDao getYvertCatalogDao() {
117127
return new JdbcStampsCatalogDao(

src/main/java/ru/mystamps/web/config/ServicesConfig.java

+10
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ public SeriesService getSeriesService() {
114114
);
115115
}
116116

117+
@Bean
118+
public SeriesSalesService getSeriesSalesService() {
119+
return new SeriesSalesServiceImpl(daoConfig.getSeriesSalesDao());
120+
}
121+
117122
@Bean
118123
public SiteService getSiteService() {
119124
return new SiteServiceImpl(daoConfig.getSuspiciousActivityDao());
@@ -149,4 +154,9 @@ public StampsCatalogService getGibbonsCatalogService() {
149154
return new StampsCatalogServiceImpl("Gibbons", daoConfig.getGibbonsCatalogDao());
150155
}
151156

157+
@Bean
158+
public TransactionParticipantService getTransactionParticipantService() {
159+
return new TransactionParticipantServiceImpl(daoConfig.getTransactionParticipantDao());
160+
}
161+
152162
}

src/main/java/ru/mystamps/web/controller/SeriesController.java

+74-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.IOException;
2121
import java.util.Calendar;
2222
import java.util.Collections;
23+
import java.util.Date;
2324
import java.util.GregorianCalendar;
2425
import java.util.HashMap;
2526
import java.util.LinkedHashMap;
@@ -56,15 +57,19 @@
5657
import ru.mystamps.web.controller.converter.annotation.Category;
5758
import ru.mystamps.web.controller.converter.annotation.Country;
5859
import ru.mystamps.web.controller.converter.annotation.CurrentUser;
60+
import ru.mystamps.web.dao.dto.EntityWithIdDto;
5961
import ru.mystamps.web.dao.dto.LinkEntityDto;
6062
import ru.mystamps.web.dao.dto.PurchaseAndSaleDto;
6163
import ru.mystamps.web.dao.dto.SeriesInfoDto;
6264
import ru.mystamps.web.model.AddImageForm;
6365
import ru.mystamps.web.model.AddSeriesForm;
66+
import ru.mystamps.web.model.AddSeriesSalesForm;
6467
import ru.mystamps.web.service.CategoryService;
6568
import ru.mystamps.web.service.CollectionService;
6669
import ru.mystamps.web.service.CountryService;
70+
import ru.mystamps.web.service.SeriesSalesService;
6771
import ru.mystamps.web.service.SeriesService;
72+
import ru.mystamps.web.service.TransactionParticipantService;
6873
import ru.mystamps.web.service.dto.SeriesDto;
6974
import ru.mystamps.web.support.spring.security.Authority;
7075
import ru.mystamps.web.support.spring.security.CustomUserDetails;
@@ -78,7 +83,7 @@
7883

7984
@Controller
8085
@RequiredArgsConstructor
81-
@SuppressWarnings({ "PMD.AvoidDuplicateLiterals", "PMD.TooManyMethods"})
86+
@SuppressWarnings({ "PMD.AvoidDuplicateLiterals", "PMD.TooManyMethods", "PMD.GodClass" })
8287
public class SeriesController {
8388

8489
private static final Integer CURRENT_YEAR = new GregorianCalendar().get(Calendar.YEAR);
@@ -89,6 +94,8 @@ public class SeriesController {
8994
private final CollectionService collectionService;
9095
private final CountryService countryService;
9196
private final SeriesService seriesService;
97+
private final SeriesSalesService seriesSalesService;
98+
private final TransactionParticipantService transactionParticipantService;
9299

93100
static {
94101
YEARS = new LinkedHashMap<>();
@@ -207,6 +214,8 @@ public String showInfo(
207214
Map<String, ?> commonAttrs = prepareCommonAttrsForSeriesInfo(series, currentUserId);
208215
model.addAllAttributes(commonAttrs);
209216

217+
addSeriesSalesFormToModel(model);
218+
210219
AddImageForm form = new AddImageForm();
211220
model.addAttribute("addImageForm", form);
212221

@@ -245,6 +254,8 @@ public String processImage(
245254
Map<String, ?> commonAttrs = prepareCommonAttrsForSeriesInfo(series, currentUserId);
246255
model.addAllAttributes(commonAttrs);
247256

257+
addSeriesSalesFormToModel(model);
258+
248259
// don't try to re-display file upload field
249260
form.setImage(null);
250261

@@ -313,6 +324,49 @@ public String removeFromCollection(
313324
return redirectTo(Url.INFO_COLLECTION_PAGE, collectionSlug);
314325
}
315326

327+
@PostMapping(Url.ADD_SERIES_ASK_PAGE)
328+
public String processAskForm(
329+
@Valid AddSeriesSalesForm form,
330+
BindingResult result,
331+
@PathVariable("id") Integer seriesId,
332+
Model model,
333+
@CurrentUser Integer currentUserId,
334+
Locale userLocale,
335+
HttpServletResponse response)
336+
throws IOException {
337+
338+
if (seriesId == null) {
339+
response.sendError(HttpServletResponse.SC_NOT_FOUND);
340+
return null;
341+
}
342+
343+
String lang = LocaleUtils.getLanguageOrNull(userLocale);
344+
SeriesDto series = seriesService.findFullInfoById(seriesId, lang);
345+
if (series == null) {
346+
response.sendError(HttpServletResponse.SC_NOT_FOUND);
347+
return null;
348+
}
349+
350+
boolean maxQuantityOfImagesExceeded = !isAdmin() && !isAllowedToAddingImages(series);
351+
model.addAttribute("maxQuantityOfImagesExceeded", maxQuantityOfImagesExceeded);
352+
353+
AddImageForm addImageForm = new AddImageForm();
354+
model.addAttribute("addImageForm", addImageForm);
355+
356+
if (result.hasErrors() || maxQuantityOfImagesExceeded) {
357+
Map<String, ?> commonAttrs = prepareCommonAttrsForSeriesInfo(series, currentUserId);
358+
model.addAllAttributes(commonAttrs);
359+
360+
addSeriesSalesFormToModel(model);
361+
362+
return "series/info";
363+
}
364+
365+
seriesSalesService.add(form, series.getId(), currentUserId);
366+
367+
return redirectTo(Url.INFO_SERIES_PAGE, series.getId());
368+
}
369+
316370
@PostMapping(Url.SEARCH_SERIES_BY_CATALOG)
317371
public String searchSeriesByCatalog(
318372
@RequestParam("catalogNumber") String catalogNumber,
@@ -386,6 +440,25 @@ public String searchSeriesByCatalog(
386440
return model;
387441
}
388442

443+
private void addSeriesSalesFormToModel(Model model) {
444+
if (!(Features.ADD_PURCHASES_AND_SALES.isActive()
445+
&& SecurityContextUtils.hasAuthority(Authority.ADD_SERIES_SALES))) {
446+
return;
447+
}
448+
449+
if (!model.containsAttribute("addSeriesSalesForm")) {
450+
AddSeriesSalesForm addSeriesSalesForm = new AddSeriesSalesForm();
451+
addSeriesSalesForm.setDate(new Date());
452+
model.addAttribute("addSeriesSalesForm", addSeriesSalesForm);
453+
}
454+
455+
List<EntityWithIdDto> sellers = transactionParticipantService.findAllSellers();
456+
model.addAttribute("sellers", sellers);
457+
458+
List<EntityWithIdDto> buyers = transactionParticipantService.findAllBuyers();
459+
model.addAttribute("buyers", buyers);
460+
}
461+
389462
private static boolean isAllowedToAddingImages(SeriesDto series) {
390463
return series.getImageIds().size() <= series.getQuantity();
391464
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (C) 2009-2016 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;
19+
20+
import ru.mystamps.web.dao.dto.AddSeriesSalesDbDto;
21+
22+
public interface SeriesSalesDao {
23+
void add(AddSeriesSalesDbDto dto);
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (C) 2009-2016 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;
19+
20+
import java.util.List;
21+
22+
import ru.mystamps.web.dao.dto.EntityWithIdDto;
23+
24+
public interface TransactionParticipantDao {
25+
List<EntityWithIdDto> findAllAsEntityWithIdDto();
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (C) 2009-2016 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+
import java.util.Date;
22+
23+
import lombok.Getter;
24+
import lombok.Setter;
25+
26+
@Getter
27+
@Setter
28+
public class AddSeriesSalesDbDto {
29+
private Integer seriesId;
30+
private Date date;
31+
private Integer sellerId;
32+
private String url;
33+
private BigDecimal price;
34+
private String currency;
35+
private BigDecimal altPrice;
36+
private String altCurrency;
37+
private Integer buyerId;
38+
private Date createdAt;
39+
private Integer createdBy;
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (C) 2009-2016 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 lombok.Getter;
21+
import lombok.RequiredArgsConstructor;
22+
import lombok.ToString;
23+
24+
@Getter
25+
@ToString
26+
@RequiredArgsConstructor
27+
public class EntityWithIdDto {
28+
private final Integer id;
29+
private final String name;
30+
}

0 commit comments

Comments
 (0)