Skip to content

Commit d6c44d1

Browse files
committed
FullStack Backend
1 parent c9f9fb8 commit d6c44d1

File tree

17 files changed

+574
-22
lines changed

17 files changed

+574
-22
lines changed

Part-9.SpringBoot-React-Projects/Project-2.SpringBoot-React-ShoppingMall/fullstack/backend/pom.xml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@
8686
<groupId>org.springframework.kafka</groupId>
8787
<artifactId>spring-kafka</artifactId>
8888
</dependency>
89+
<dependency>
90+
<groupId>org.mockito</groupId>
91+
<artifactId>mockito-all</artifactId>
92+
<version>1.10.19</version>
93+
<scope>test</scope>
94+
</dependency>
8995

9096
<dependency>
9197
<groupId>org.springframework.kafka</groupId>
@@ -116,6 +122,32 @@
116122
<version>4.5.10</version>
117123
</dependency>
118124

125+
<dependency>
126+
<groupId>com.fasterxml.jackson.core</groupId>
127+
<artifactId>jackson-annotations</artifactId>
128+
<version>2.9.8</version>
129+
</dependency>
130+
<dependency>
131+
<groupId>com.fasterxml.jackson.core</groupId>
132+
<artifactId>jackson-core</artifactId>
133+
<version>2.9.8</version>
134+
</dependency>
135+
<dependency>
136+
<groupId>com.fasterxml.jackson.datatype</groupId>
137+
<artifactId>jackson-datatype-jsr310</artifactId>
138+
<version>2.9.8</version>
139+
</dependency>
140+
<dependency>
141+
<groupId>com.fasterxml.jackson.core</groupId>
142+
<artifactId>jackson-databind</artifactId>
143+
<version>2.9.8</version>
144+
</dependency>
145+
146+
<dependency>
147+
<groupId>javax.inject</groupId>
148+
<artifactId>javax.inject</artifactId>
149+
<version>1</version>
150+
</dependency>
119151
<!---->
120152

121153

Original file line numberDiff line numberDiff line change
@@ -1,15 +1,53 @@
11
package com.urunov;
22

3+
import com.fasterxml.jackson.core.JsonParser;
4+
import com.fasterxml.jackson.databind.DeserializationContext;
5+
import com.fasterxml.jackson.databind.JsonDeserializer;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.urunov.configure.JpaConfig;
38
import org.springframework.boot.SpringApplication;
49
import org.springframework.boot.autoconfigure.SpringBootApplication;
10+
import org.springframework.context.annotation.Bean;
11+
import org.springframework.context.annotation.ComponentScan;
512
import springfox.documentation.swagger2.annotations.EnableSwagger2;
613

14+
import java.io.IOException;
15+
716
@SpringBootApplication
817
@EnableSwagger2
18+
@ComponentScan(basePackages = {
19+
"com.urunov.configure",
20+
"com.urunov.controller",
21+
"com.urunov.model",
22+
"com.urunov.exception",
23+
"com.urunov.repository",
24+
"com.urunov.security",
25+
"com.urunov.utils",
26+
"com.urunov.kafkaService",
27+
"com.urunov.service",
28+
"com.urunov.schedule"
29+
})
930
public class ShoppingApplication {
1031

1132
public static void main(String[] args) {
12-
SpringApplication.run(ShoppingApplication.class, args);
33+
SpringApplication.run(new Class<?>[]{ShoppingApplication.class, JpaConfig.class}, args);
34+
}
35+
@Bean
36+
public JsonDeserializer jsonDeserializer()
37+
{
38+
return new JsonDeserializer()
39+
{
40+
@Override
41+
public Object deserialize(JsonParser p, DeserializationContext context) throws IOException
42+
{
43+
return null;
44+
}
45+
};
1346
}
1447

48+
@Bean
49+
public ObjectMapper objectMapper()
50+
{
51+
return new ObjectMapper();
52+
}
1553
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.urunov.configure;
2+
3+
import com.urunov.ShoppingApplication;
4+
import com.zaxxer.hikari.HikariConfig;
5+
import com.zaxxer.hikari.HikariDataSource;
6+
import org.springframework.beans.factory.annotation.Value;
7+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
8+
import org.springframework.context.annotation.Bean;
9+
import org.springframework.context.annotation.Configuration;
10+
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
11+
import org.springframework.orm.jpa.JpaTransactionManager;
12+
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
13+
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
14+
import org.springframework.transaction.PlatformTransactionManager;
15+
import org.springframework.transaction.annotation.EnableTransactionManagement;
16+
17+
import java.util.Properties;
18+
19+
/**
20+
* User: hamdamboy
21+
* Project: Shopping
22+
* Github: @urunov
23+
*/
24+
@Configuration
25+
@EnableAutoConfiguration
26+
@EnableTransactionManagement
27+
@EnableJpaRepositories(basePackageClasses = ShoppingApplication.class)
28+
public class JpaConfig {
29+
@Value("${dataSource.driverClassName}")
30+
private String driver;
31+
@Value("${dataSource.url}")
32+
private String url;
33+
@Value("${dataSource.username}")
34+
private String username;
35+
@Value("${dataSource.password}")
36+
private String password;
37+
@Value("${hibernate.dialect}")
38+
private String dialect;
39+
@Value("${hibernate.hbm2ddl.auto}")
40+
private String hbm2ddlAuto;
41+
@Value("${spring.datasource.maximumPoolSize}")
42+
private int maximumPoolSize;
43+
44+
@Bean
45+
public HikariDataSource configureDataSource()
46+
{
47+
HikariConfig config = new HikariConfig();
48+
config.setDriverClassName(driver);
49+
config.setJdbcUrl(url);
50+
config.setUsername(username);
51+
config.setPassword(password);
52+
config.setMaximumPoolSize(maximumPoolSize);
53+
config.setConnectionTimeout(60000);
54+
config.setIdleTimeout(60000);
55+
config.setLeakDetectionThreshold(60000);
56+
return new HikariDataSource(config);
57+
}
58+
59+
@Bean(name = "entityManagerFactory")
60+
public LocalContainerEntityManagerFactoryBean configureEntityManagerFactory()
61+
{
62+
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
63+
entityManagerFactoryBean.setDataSource(configureDataSource());
64+
entityManagerFactoryBean.setPackagesToScan("com.messager");
65+
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
66+
Properties jpaProperties = new Properties();
67+
jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, dialect);
68+
jpaProperties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, hbm2ddlAuto);
69+
entityManagerFactoryBean.setJpaProperties(jpaProperties);
70+
return entityManagerFactoryBean;
71+
}
72+
73+
@Bean(name = "transactionManager")
74+
public PlatformTransactionManager annotationDrivenTransactionManager()
75+
{
76+
return new JpaTransactionManager();
77+
}
78+
79+
}

Part-9.SpringBoot-React-Projects/Project-2.SpringBoot-React-ShoppingMall/fullstack/backend/src/main/java/com/urunov/controller/OrderController.java

Lines changed: 138 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
package com.urunov.controller;
22

3+
import com.google.gson.Gson;
4+
import com.urunov.kafkaService.Producer;
5+
import com.urunov.model.Good;
6+
import com.urunov.model.OrderDetails;
7+
import com.urunov.model.Orders;
8+
import com.urunov.model.User;
9+
import com.urunov.model.enumdto.OrderStatus;
10+
import com.urunov.model.retailer.Retailer;
11+
import com.urunov.payload.ApiResponse;
312
import com.urunov.payload.PagedResponse;
13+
import com.urunov.payload.good.GoodOrderDetailsResponse;
14+
import com.urunov.payload.order.OrderRequest;
415
import com.urunov.payload.order.OrderResponse;
16+
import com.urunov.payload.payment.PaymentBtnResponse;
517
import com.urunov.repository.GoodsRepository;
618
import com.urunov.repository.OrderDetailsRepository;
719
import com.urunov.repository.OrderRepository;
@@ -11,13 +23,15 @@
1123
import com.urunov.service.order.OrderService;
1224
import com.urunov.service.order.payment.PaymentService;
1325
import com.urunov.service.taxiMaster.TaxiOrderProcess;
14-
import org.springframework.beans.factory.annotation.Autowired;
15-
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
16-
import org.springframework.web.bind.annotation.GetMapping;
17-
import org.springframework.web.bind.annotation.RequestMapping;
18-
import org.springframework.web.bind.annotation.RequestParam;
19-
import org.springframework.web.bind.annotation.RestController;
2026
import com.urunov.utils.AppConstants;
27+
import org.springframework.beans.factory.annotation.Autowired;
28+
import org.springframework.http.HttpStatus;
29+
import org.springframework.http.ResponseEntity;
30+
import org.springframework.web.bind.annotation.*;
31+
32+
import java.util.Date;
33+
import java.util.List;
34+
2135
/**
2236
* Created by:
2337
* User: hamdamboy
@@ -42,7 +56,7 @@ public class OrderController {
4256
private TaxiOrderProcess taxiOrderProcess;
4357

4458
@Autowired
45-
private KafkaProperties.Producer producer;
59+
private Producer producer;
4660

4761
@Autowired
4862
private OrderService orderService;
@@ -65,5 +79,122 @@ public PagedResponse<OrderResponse> getAllUserOrders(
6579
return orderService.getAllUserOrders(page, size, sortOrder, isActive, userPrincipal, "status", sortBy);
6680
}
6781

82+
@PostMapping("/order/getPayUrl")
83+
public ResponseEntity<?> getPayUrl(@CurrentUser UserPrincipal userPrincipal, @RequestBody OrderResponse orderResponse) throws Exception
84+
{
85+
Gson gson = new Gson();
86+
PaymentBtnResponse paymentBtnResponse = gson.fromJson(paymentService.makeAnonymousPayment(orderResponse), PaymentBtnResponse.class);
87+
if(paymentBtnResponse.getCode() != null && paymentBtnResponse.getCode().equals("1297"))
88+
return new ResponseEntity(new ApiResponse(true, paymentBtnResponse.getUserMessage(), new Date(), paymentBtnResponse), HttpStatus.INTERNAL_SERVER_ERROR);
89+
Orders order = orderRepository.findById(orderResponse.getId()).orElse(null);
90+
if(order != null)
91+
{
92+
order.setPaymentNumber(paymentBtnResponse.getRegPayNum());
93+
orderRepository.save(order);
94+
return new ResponseEntity(new ApiResponse(true, "Запрос на повторное создание заказа успешно создан!", new Date(), paymentBtnResponse), HttpStatus.OK);
95+
}
96+
else
97+
return new ResponseEntity(new ApiResponse(true, "Не удалось оплатить заказ, пожалуйста попробуйте позднее!", new Date(), paymentBtnResponse), HttpStatus.INTERNAL_SERVER_ERROR);
98+
}
99+
100+
@PostMapping("/order/createOrder")
101+
public void createOrder(@CurrentUser UserPrincipal userPrincipal, @RequestBody OrderRequest orderRequest)
102+
{
103+
User user = userRepository.findById(userPrincipal.getId()).orElse(null);
104+
Orders userBucket = orderRepository.findFirstByStatusAndUser(OrderStatus.NEW, user).orElse(null);
105+
Orders order = new Orders();
106+
order.setStatus(OrderStatus.inProgress);
107+
order.setUser(user);
108+
order.setName(orderRequest.getName());
109+
order.setAdditionalPhone(orderRequest.getAdditionalPhone());
110+
order.setDeliveryPrice(orderRequest.getDeliveryPrice());
111+
order.setEmail(orderRequest.getEmail());
112+
order.setAddress(orderRequest.getAddress());
113+
order.setComment(orderRequest.getComment());
114+
List<OrderDetails> orderDetailsList = orderDetailsRepository.findAllByOrder(userBucket);
115+
orderRepository.save(order);
116+
for(OrderDetails orderDetails : orderDetailsList)
117+
{
118+
orderDetails.setOrder(order);
119+
orderDetailsRepository.save(orderDetails);
120+
}
121+
order.setOrderDetailList(orderDetailsList);
122+
producer.sendOrderRequest(order);
123+
}
68124

125+
@PostMapping("/order/getDeliveryPrice")
126+
public ResponseEntity<?> getDeliveryPrice(@RequestBody String address, @CurrentUser UserPrincipal currentUser) throws Exception
127+
{
128+
User user = userRepository.findById(currentUser.getId()).orElse(null);
129+
if(user != null)
130+
{
131+
Orders order = orderRepository.findFirstByStatusAndUser(OrderStatus.NEW, user).orElse(null);
132+
if(order != null)
133+
{
134+
Retailer retailer = order.getOrderDetailsList().stream().map(OrderDetails::getGood).map(Good::getRetailer).findFirst().orElse(null);
135+
if(retailer != null)
136+
//TODO: тут временная заглушка на getTaxiPropertiesList().get(0), т.к не понятно пока какие проперти выбирать
137+
try
138+
{
139+
return new ResponseEntity(new ApiResponse(false, "Указанный адрес успешно найден!", new Date(),
140+
taxiOrderProcess.getDeliveryPrice(retailer.getCity(), address, retailer.getShippingAddress(), retailer.getTaxiPropertiesList().get(0))), HttpStatus.OK);
141+
}
142+
catch(Exception e)
143+
{
144+
return new ResponseEntity(new ApiResponse(false, "Не удалось найти указанный адрес!", new Date(),
145+
taxiOrderProcess.getDeliveryPrice(retailer.getCity(), address, retailer.getShippingAddress(), retailer.getTaxiPropertiesList().get(0))), HttpStatus.INTERNAL_SERVER_ERROR);
146+
}
147+
}
148+
}
149+
return null;
150+
}
151+
152+
@PostMapping("/order/updateOrder")
153+
public ResponseEntity<?> updateOrder(@CurrentUser UserPrincipal userPrincipal, @RequestBody OrderResponse orderResponse)
154+
{
155+
return orderService.statusDelivered(userPrincipal, orderResponse);
156+
}
157+
158+
@PostMapping("/order/repeatOrderRequest")
159+
public ResponseEntity<?> repeatOrder(@CurrentUser UserPrincipal currentUser, @RequestBody List<GoodOrderDetailsResponse> detailsResponseList)
160+
{
161+
boolean isGoodExists = true;
162+
User user = userRepository.findById(currentUser.getId()).orElse(null);
163+
if(user != null)
164+
{
165+
Orders bucket = orderRepository.findFirstByStatusAndUser(OrderStatus.NEW, user).orElse(null);
166+
if(bucket == null)
167+
{
168+
bucket = new Orders();
169+
bucket.setUser(user);
170+
bucket.setStatus(OrderStatus.NEW);
171+
orderRepository.save(bucket);
172+
}
173+
//TODO: если уже есть товары в корзине, то спрашивать перед тем как чистить корзину
174+
List<OrderDetails> bucketGoods = orderDetailsRepository.findAllByOrder(bucket);
175+
for(OrderDetails orderDetails : bucketGoods)
176+
{
177+
orderDetailsRepository.delete(orderDetails);
178+
}
179+
for(GoodOrderDetailsResponse goodOrderDetailsResponse : detailsResponseList)
180+
{
181+
List<Good> goodList = goodsRepository.findAllByInternalCodeAndIsOutdated(goodOrderDetailsResponse.getInternalCode(), false);
182+
if(!goodList.isEmpty())
183+
{
184+
Good good = goodsRepository.findAllByInternalCodeAndIsOutdated(goodOrderDetailsResponse.getInternalCode(), false).get(0);
185+
OrderDetails orderDetails = new OrderDetails();
186+
orderDetails.setOrder(bucket);
187+
orderDetails.setGood(good);
188+
orderDetails.setQuantity(goodOrderDetailsResponse.getQuantity());
189+
orderDetailsRepository.save(orderDetails);
190+
}
191+
else
192+
isGoodExists = false;
193+
}
194+
}
195+
if(!isGoodExists)
196+
return new ResponseEntity(new ApiResponse(false, "Извините, некоторых товаров уже нет в магазине!"), HttpStatus.INTERNAL_SERVER_ERROR);
197+
else
198+
return new ResponseEntity(new ApiResponse(true, "Запрос на повторное создание заказа успешно создан!"), HttpStatus.OK);
199+
}
69200
}

Part-9.SpringBoot-React-Projects/Project-2.SpringBoot-React-ShoppingMall/fullstack/backend/src/main/java/com/urunov/model/Orders.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,12 @@ public class Orders extends DateAudit {
5757

5858
private String phoneDriver;
5959

60-
@Column(name = "status", columnDefinition = "ENUM('awaitingPayment', 'inProgress', 'paid', 'transferredToDeliveryService', 'completed', 'NEW', 'canceled', 'courierSearch', 'courierFound' ,'deliveryInProgress','awaitingConfirmation', 'delivered') NOT NULL DEFAULT 'inProgress'")
60+
@Column(columnDefinition = "ENUM('awaitingPayment', 'inProgress', 'paid', 'transferredToDeliveryService', 'completed', 'NEW', 'canceled', 'courierSearch', 'courierFound' ,'deliveryInProgress','awaitingConfirmation', 'delivered') NOT NULL DEFAULT 'inProgress'")
6161
@Enumerated(EnumType.STRING)
6262
private OrderStatus status;
6363

64+
65+
6466
private Long taxiOrderId;
6567

6668

@@ -77,6 +79,8 @@ public class Orders extends DateAudit {
7779
@OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
7880
private List<OrderDetails> orderDetailsList;
7981

82+
83+
8084
public Orders(String additionalPhone, @NotBlank String address, String name, String comment, List<Good> goodList, Float deliveryPrice)
8185
{
8286
this.additionalPhone = additionalPhone;
@@ -86,5 +90,9 @@ public Orders(String additionalPhone, @NotBlank String address, String name, Str
8690
this.deliveryPrice = deliveryPrice;
8791
}
8892

93+
public void setOrderDetailList(List<OrderDetails> ordersList)
94+
{
95+
this.orderDetailsList = ordersList;
96+
}
8997

9098
}

0 commit comments

Comments
 (0)