mirror of
https://github.com/Prominence/car-repair-site.git
synced 2026-01-09 19:56:43 +03:00
Added CRUD for 'Orders' entity, formatters, translations. Removed useless service.
This commit is contained in:
parent
0124899525
commit
5f15555f4e
@ -20,3 +20,4 @@ public class CarRepairApplication {
|
||||
// TODO: i18n
|
||||
// TODO: tests
|
||||
// TODO: big data
|
||||
// TODO: add autocomplete
|
||||
@ -0,0 +1,106 @@
|
||||
package com.github.prominence.carrepair.controller;
|
||||
|
||||
import com.github.prominence.carrepair.enums.OrderStatus;
|
||||
import com.github.prominence.carrepair.model.Order;
|
||||
import com.github.prominence.carrepair.service.ClientService;
|
||||
import com.github.prominence.carrepair.service.MechanicService;
|
||||
import com.github.prominence.carrepair.service.OrderService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Optional;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(value = "/order")
|
||||
public class OrderController {
|
||||
|
||||
private OrderService orderService;
|
||||
private ClientService clientService;
|
||||
private MechanicService mechanicService;
|
||||
|
||||
public OrderController(OrderService orderService, ClientService clientService, MechanicService mechanicService) {
|
||||
this.orderService = orderService;
|
||||
this.clientService = clientService;
|
||||
this.mechanicService = mechanicService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String index(ModelMap modelMap) {
|
||||
Page<Order> orderList = orderService.findAll((Pageable) modelMap.get("pagination"));
|
||||
|
||||
modelMap.addAttribute("orderList", orderList.getContent());
|
||||
modelMap.addAttribute("totalPages", orderList.getTotalPages());
|
||||
|
||||
return "order/index";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/create")
|
||||
public String create(Model model) {
|
||||
model.addAttribute("order", new Order());
|
||||
model.addAttribute("clientIdsList", clientService.getAllClientIds());
|
||||
model.addAttribute("mechanicIdsList", mechanicService.getAllMechanicIds());
|
||||
model.addAttribute("orderStatuses", new OrderStatus[] { OrderStatus.SCHEDULED, OrderStatus.DONE, OrderStatus.ACCEPTED });
|
||||
|
||||
return "order/edit";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/edit/{id}")
|
||||
public String edit(@PathVariable Long id, Model model) {
|
||||
Optional<Order> orderOptional = orderService.findById(id);
|
||||
if (orderOptional.isPresent()) {
|
||||
model.addAttribute("order", orderOptional.get());
|
||||
model.addAttribute("clientIdsList", clientService.getAllClientIds());
|
||||
model.addAttribute("mechanicIdsList", mechanicService.getAllMechanicIds());
|
||||
model.addAttribute("orderStatuses", new OrderStatus[] { OrderStatus.SCHEDULED, OrderStatus.DONE, OrderStatus.ACCEPTED });
|
||||
return "order/edit";
|
||||
} else {
|
||||
// TODO: need to show warning
|
||||
return "redirect:/order";
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value = "/update/{id}")
|
||||
public String update(@Valid Order order, BindingResult bindingResult, @PathVariable long id, Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
order.setId(id); // why should we do this?
|
||||
model.addAttribute("clientIdsList", clientService.getAllClientIds());
|
||||
model.addAttribute("mechanicIdsList", mechanicService.getAllMechanicIds());
|
||||
model.addAttribute("orderStatuses", new OrderStatus[] { OrderStatus.SCHEDULED, OrderStatus.DONE, OrderStatus.ACCEPTED });
|
||||
return "order/edit";
|
||||
}
|
||||
|
||||
orderService.save(order);
|
||||
return "redirect:/order";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/create")
|
||||
public String save(@Valid Order order, BindingResult bindingResult, Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("clientIdsList", clientService.getAllClientIds());
|
||||
model.addAttribute("mechanicIdsList", mechanicService.getAllMechanicIds());
|
||||
model.addAttribute("orderStatuses", new OrderStatus[] { OrderStatus.SCHEDULED, OrderStatus.DONE, OrderStatus.ACCEPTED });
|
||||
return "order/edit";
|
||||
}
|
||||
|
||||
orderService.save(order);
|
||||
return "redirect:/order";
|
||||
}
|
||||
|
||||
@DeleteMapping(value = "/delete/{id}")
|
||||
public ResponseEntity delete(@PathVariable Long id) {
|
||||
boolean deleteSuccess = orderService.deleteOrderById(id);
|
||||
|
||||
if (deleteSuccess) {
|
||||
return ResponseEntity.ok().build();
|
||||
} else {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
package com.github.prominence.carrepair.controller.advice;
|
||||
|
||||
import com.github.prominence.carrepair.service.CarRepairService;
|
||||
import com.github.prominence.carrepair.service.ClientService;
|
||||
import com.github.prominence.carrepair.service.MechanicService;
|
||||
import com.github.prominence.carrepair.service.OrderService;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ -8,16 +10,20 @@ import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
@ControllerAdvice
|
||||
public class GlobalInfoAdvice {
|
||||
|
||||
private final CarRepairService carRepairService;
|
||||
private final ClientService clientService;
|
||||
private final MechanicService mechanicService;
|
||||
private final OrderService orderService;
|
||||
|
||||
public GlobalInfoAdvice(CarRepairService carRepairService) {
|
||||
this.carRepairService = carRepairService;
|
||||
public GlobalInfoAdvice(ClientService clientService, MechanicService mechanicService, OrderService orderService) {
|
||||
this.clientService = clientService;
|
||||
this.mechanicService = mechanicService;
|
||||
this.orderService = orderService;
|
||||
}
|
||||
|
||||
@ModelAttribute("globalInfo")
|
||||
public void addBadgeInfo(Model model) {
|
||||
model.addAttribute("clientsCount", carRepairService.getClientCount());
|
||||
model.addAttribute("mechanicsCount", carRepairService.getMechanicCount());
|
||||
model.addAttribute("ordersCount", carRepairService.getOrderCount());
|
||||
model.addAttribute("clientsCount", clientService.getClientCount());
|
||||
model.addAttribute("mechanicsCount", mechanicService.getMechanicCount());
|
||||
model.addAttribute("ordersCount", orderService.getOrderCount());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,22 +1,31 @@
|
||||
package com.github.prominence.carrepair.demo;
|
||||
|
||||
import com.github.javafaker.Faker;
|
||||
import com.github.prominence.carrepair.enums.OrderStatus;
|
||||
import com.github.prominence.carrepair.model.Client;
|
||||
import com.github.prominence.carrepair.model.Mechanic;
|
||||
import com.github.prominence.carrepair.model.Order;
|
||||
import com.github.prominence.carrepair.service.ClientService;
|
||||
import com.github.prominence.carrepair.service.MechanicService;
|
||||
import com.github.prominence.carrepair.service.OrderService;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Component
|
||||
public class DemoDataPopulator {
|
||||
private static final int COUNT = 10;
|
||||
private static final int COUNT = 100;
|
||||
|
||||
private Faker faker = new Faker();
|
||||
|
||||
@ -32,9 +41,7 @@ public class DemoDataPopulator {
|
||||
return client;
|
||||
}).limit(COUNT).collect(Collectors.toList());
|
||||
|
||||
return args -> {
|
||||
demoClientList.forEach(clientService::save);
|
||||
};
|
||||
return args -> demoClientList.forEach(clientService::save);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ -49,9 +56,46 @@ public class DemoDataPopulator {
|
||||
return mechanic;
|
||||
}).limit(COUNT).collect(Collectors.toList());
|
||||
|
||||
return args -> {
|
||||
demoMechanicList.forEach(mechanicService::save);
|
||||
};
|
||||
return args -> demoMechanicList.forEach(mechanicService::save);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CommandLineRunner orderDemoData(OrderService orderService, ClientService clientService, MechanicService mechanicService) {
|
||||
final OrderStatus[] orderStatuses = OrderStatus.values();
|
||||
long mechanicsCount = mechanicService.getMechanicCount();
|
||||
long clientsCount = clientService.getClientCount();
|
||||
|
||||
List<Order> demoOrderList = Stream.generate(() -> {
|
||||
Order order = new Order();
|
||||
order.setOrderStatus(orderStatuses[RandomUtils.nextInt(0, 3)]);
|
||||
order.setDescription(faker.lorem().characters(10, 1024));
|
||||
order.setTotalPrice(BigDecimal.valueOf(faker.number().randomDouble(4, 100, 9999)));
|
||||
order.setCreatedOn(LocalDateTime.ofInstant(faker.date().past(5, TimeUnit.DAYS).toInstant(), ZoneId.systemDefault()));
|
||||
|
||||
if (order.getOrderStatus() == OrderStatus.ACCEPTED) {
|
||||
order.setFinishedOn(LocalDateTime.ofInstant(faker.date().future(10, TimeUnit.DAYS).toInstant(), ZoneId.systemDefault()));
|
||||
}
|
||||
|
||||
final List<Client> clientListSlice = clientService.findAll(getRandomPageable(clientsCount)).getContent();
|
||||
final Client randomClient = clientListSlice.get(RandomUtils.nextInt(0, clientListSlice.size()));
|
||||
order.setClient(randomClient);
|
||||
|
||||
final List<Mechanic> mechanicListSlise = mechanicService.findAll(getRandomPageable(mechanicsCount)).getContent();
|
||||
final Mechanic randomMechanic = mechanicListSlise.get(RandomUtils.nextInt(0, mechanicListSlise.size()));
|
||||
order.setMechanic(randomMechanic);
|
||||
|
||||
System.out.println(order); // demo output
|
||||
return order;
|
||||
}).limit(COUNT).collect(Collectors.toList());
|
||||
|
||||
return args -> demoOrderList.forEach(orderService::save);
|
||||
}
|
||||
|
||||
private Pageable getRandomPageable(long totalRecords) {
|
||||
final int size = 10;
|
||||
final int totalPages = (int) (totalRecords / size);
|
||||
|
||||
return PageRequest.of(RandomUtils.nextInt(0, totalPages), size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.github.prominence.carrepair.formatter;
|
||||
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
|
||||
@Component
|
||||
public class CustomDateTimeFormatter implements Formatter<LocalDateTime> {
|
||||
@Override
|
||||
public LocalDateTime parse(String text, Locale locale) throws ParseException {
|
||||
return LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String print(LocalDateTime object, Locale locale) {
|
||||
return object.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.github.prominence.carrepair.formatter;
|
||||
|
||||
import com.github.prominence.carrepair.enums.OrderStatus;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
@Component
|
||||
public class OrderStatusFormatter implements Formatter<OrderStatus> {
|
||||
@Override
|
||||
public OrderStatus parse(String text, Locale locale) throws ParseException {
|
||||
return OrderStatus.valueOf(text.toUpperCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String print(OrderStatus object, Locale locale) {
|
||||
return StringUtils.capitalize(object.toString().toLowerCase());
|
||||
}
|
||||
}
|
||||
@ -3,9 +3,12 @@ package com.github.prominence.carrepair.model;
|
||||
import com.github.prominence.carrepair.enums.OrderStatus;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "orders")
|
||||
@ -16,13 +19,14 @@ public class Order {
|
||||
private long id;
|
||||
|
||||
@NotNull
|
||||
@Size(max = 1024)
|
||||
private String description;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@ManyToOne(fetch = FetchType.EAGER) // change to LAZY after DTO implementation
|
||||
@JoinColumn(name = "client_id", nullable = false)
|
||||
private Client client;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@ManyToOne(fetch = FetchType.EAGER) // change to LAZY after DTO implementation
|
||||
@JoinColumn(name = "mechanic_id", nullable = false)
|
||||
private Mechanic mechanic;
|
||||
|
||||
@ -33,6 +37,7 @@ public class Order {
|
||||
@Column(name = "finishedOn")
|
||||
private LocalDateTime finishedOn;
|
||||
|
||||
@Min(value = 0)
|
||||
@Column(name = "totalPrice")
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
@ -116,4 +121,38 @@ public class Order {
|
||||
public void setOrderStatus(OrderStatus orderStatus) {
|
||||
this.orderStatus = orderStatus.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Order)) return false;
|
||||
Order order = (Order) o;
|
||||
return id == order.id &&
|
||||
Objects.equals(description, order.description) &&
|
||||
Objects.equals(client, order.client) &&
|
||||
Objects.equals(mechanic, order.mechanic) &&
|
||||
Objects.equals(createdOn, order.createdOn) &&
|
||||
Objects.equals(finishedOn, order.finishedOn) &&
|
||||
Objects.equals(totalPrice, order.totalPrice) &&
|
||||
Objects.equals(orderStatus, order.orderStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, description, client, mechanic, createdOn, finishedOn, totalPrice, orderStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Order{" +
|
||||
"id=" + id +
|
||||
", description='" + description + '\'' +
|
||||
", client=" + client +
|
||||
", mechanic=" + mechanic +
|
||||
", createdOn=" + createdOn +
|
||||
", finishedOn=" + finishedOn +
|
||||
", totalPrice=" + totalPrice +
|
||||
", orderStatus='" + orderStatus + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,9 +2,14 @@ package com.github.prominence.carrepair.repository;
|
||||
|
||||
import com.github.prominence.carrepair.model.Client;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ClientRepository extends JpaRepository<Client, Long> {
|
||||
|
||||
@Query(value = "select c.id from Client c")
|
||||
public List<Long> findAllClientIds();
|
||||
}
|
||||
|
||||
@ -2,8 +2,14 @@ package com.github.prominence.carrepair.repository;
|
||||
|
||||
import com.github.prominence.carrepair.model.Mechanic;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface MechanicRepository extends JpaRepository<Mechanic, Long> {
|
||||
|
||||
@Query(value = "select m.id from Mechanic m")
|
||||
public List<Long> findAllMechanicIds();
|
||||
}
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
package com.github.prominence.carrepair.service;
|
||||
|
||||
import com.github.prominence.carrepair.repository.ClientRepository;
|
||||
import com.github.prominence.carrepair.repository.MechanicRepository;
|
||||
import com.github.prominence.carrepair.repository.OrderRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CarRepairService {
|
||||
|
||||
private ClientRepository clientRepository;
|
||||
private MechanicRepository mechanicRepository;
|
||||
private OrderRepository orderRepository;
|
||||
|
||||
@Autowired
|
||||
public CarRepairService(ClientRepository clientRepository, MechanicRepository mechanicRepository, OrderRepository orderRepository) {
|
||||
this.clientRepository = clientRepository;
|
||||
this.mechanicRepository = mechanicRepository;
|
||||
this.orderRepository = orderRepository;
|
||||
}
|
||||
|
||||
public long getClientCount() {
|
||||
return clientRepository.count();
|
||||
}
|
||||
|
||||
public long getMechanicCount() {
|
||||
return mechanicRepository.count();
|
||||
}
|
||||
|
||||
public long getOrderCount() {
|
||||
return orderRepository.count();
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,7 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@ -37,4 +38,12 @@ public class ClientService {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public long getClientCount() {
|
||||
return clientRepository.count();
|
||||
}
|
||||
|
||||
public List<Long> getAllClientIds() {
|
||||
return clientRepository.findAllClientIds();
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,4 +58,12 @@ public class MechanicService {
|
||||
|
||||
return statistics;
|
||||
}
|
||||
|
||||
public long getMechanicCount() {
|
||||
return mechanicRepository.count();
|
||||
}
|
||||
|
||||
public List<Long> getAllMechanicIds() {
|
||||
return mechanicRepository.findAllMechanicIds();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
package com.github.prominence.carrepair.service;
|
||||
|
||||
import com.github.prominence.carrepair.model.Order;
|
||||
import com.github.prominence.carrepair.repository.OrderRepository;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class OrderService {
|
||||
|
||||
private OrderRepository orderRepository;
|
||||
|
||||
public OrderService(OrderRepository orderRepository) {
|
||||
this.orderRepository = orderRepository;
|
||||
}
|
||||
|
||||
public Page<Order> findAll(Pageable pageable) {
|
||||
return orderRepository.findAll(pageable);
|
||||
}
|
||||
|
||||
public Optional<Order> findById(Long id) {
|
||||
return orderRepository.findById(id);
|
||||
}
|
||||
|
||||
public Order save(Order client) {
|
||||
return orderRepository.save(client);
|
||||
}
|
||||
|
||||
public boolean deleteOrderById(Long id) {
|
||||
try {
|
||||
orderRepository.deleteById(id);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public long getOrderCount() {
|
||||
return orderRepository.count();
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ home.requirements.label = Requirements
|
||||
|
||||
client.title = Clients
|
||||
mechanic.title = Mechanics
|
||||
order.title = Orders
|
||||
|
||||
firstName.label = First Name
|
||||
middleName.label = Middle Name
|
||||
@ -16,6 +17,12 @@ phoneNo.label = Phone No
|
||||
hourlyPayment.label = Hourly Payment
|
||||
status.label = Status
|
||||
amount.label = Amount
|
||||
client.label = Client
|
||||
mechanic.label = Mechanic
|
||||
description.label = Description
|
||||
createdOn.label = Created On
|
||||
finishedOn.label = Finished On
|
||||
totalPrice.label = Total Price
|
||||
|
||||
showStatistics.button = Statistics
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ home.requirements.label = Requirements
|
||||
|
||||
client.title = Clients
|
||||
mechanic.title = Mechanics
|
||||
order.title = Orders
|
||||
|
||||
firstName.label = First Name
|
||||
middleName.label = Middle Name
|
||||
@ -16,6 +17,12 @@ phoneNo.label = Phone No
|
||||
hourlyPayment.label = Hourly Payment
|
||||
status.label = Status
|
||||
amount.label = Amount
|
||||
client.label = Client
|
||||
mechanic.label = Mechanic
|
||||
description.label = Description
|
||||
createdOn.label = Created On
|
||||
finishedOn.label = Finished On
|
||||
totalPrice.label = Total Price
|
||||
|
||||
showStatistics.button = Statistics
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ home.requirements.label = Требования
|
||||
|
||||
client.title = Клиенты
|
||||
mechanic.title = Механики
|
||||
order.title = Заказы
|
||||
|
||||
firstName.label = Имя
|
||||
middleName.label = Отчество
|
||||
@ -16,6 +17,12 @@ phoneNo.label = Номер телефона
|
||||
hourlyPayment.label = Почасовая оплата
|
||||
status.label = Статус
|
||||
amount.label = Количество
|
||||
client.label = Клиент
|
||||
mechanic.label = Механик
|
||||
description.label = Описание
|
||||
createdOn.label = Дата создания
|
||||
finishedOn.label = Дата окончания
|
||||
totalPrice.label = Итоговая цена
|
||||
|
||||
showStatistics.button = Статистика
|
||||
|
||||
|
||||
@ -4,3 +4,11 @@ body {
|
||||
.fieldError {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.word-breakable {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
display: flex;
|
||||
}
|
||||
@ -16,5 +16,9 @@
|
||||
<li th:each="err : ${#fields.errors(fieldName)}" th:text="${err}"></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<th:block th:fragment="formatDateTime(dateTime)" th:if="${dateTime != null}">
|
||||
<th:block th:value="${dateTime.format(T(java.time.format.DateTimeFormatter).ofPattern('yyyy-MM-dd HH:mm:ss'))}"/>
|
||||
</th:block>
|
||||
</body>
|
||||
</html>
|
||||
@ -21,7 +21,7 @@
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a th:href="@{/client/}"><th:block th:text="#{badge.clients}"/> <span class="badge" th:text="${clientsCount}"></span></a></li>
|
||||
<li><a th:href="@{/mechanic/}"><th:block th:text="#{badge.mechanics}"/> <span class="badge" th:text="${mechanicsCount}"></span></a></li>
|
||||
<li><a href="#"><th:block th:text="#{badge.orders}"/> <span class="badge" th:text="${ordersCount}"></span></a></li>
|
||||
<li><a th:href="@{/order/}"><th:block th:text="#{badge.orders}"/> <span class="badge" th:text="${ordersCount}"></span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
<div class="form-group row">
|
||||
<label for="mechanicHourlyPayment" class="col-sm-2 col-form-label" th:text="#{hourlyPayment.label}"></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" name="phoneNo" class="form-control" id="mechanicHourlyPayment" th:field="*{hourlyPayment}" th:errorclass="fieldError" th:value="${mechanic.hourlyPayment}">
|
||||
<input type="number" name="hourlyPayment" class="form-control" id="mechanicHourlyPayment" th:field="*{hourlyPayment}" th:errorclass="fieldError" th:value="${mechanic.hourlyPayment}">
|
||||
<div th:replace="common::errors('hourlyPayment')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
77
src/main/resources/templates/order/edit.html
Normal file
77
src/main/resources/templates/order/edit.html
Normal file
@ -0,0 +1,77 @@
|
||||
<!doctype html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{main}">
|
||||
<head>
|
||||
<title th:text="#{default.title}"></title>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1 th:text="#{order.title}"></h1>
|
||||
|
||||
<form th:action="'/order/' + ${order.id != null ? 'update/' + order.id : 'create'}" th:object="${order}" method="post">
|
||||
<div class="form-group row">
|
||||
<label for="orderDescription" class="col-sm-2 col-form-label" th:text="#{description.label}"></label>
|
||||
<div class="col-sm-10">
|
||||
<textarea name="description" class="form-control" id="orderDescription" th:field="*{description}" th:errorclass="fieldError" th:value="${order.description}"></textarea>
|
||||
<div th:replace="common::errors('description')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="orderClient" class="col-sm-2 col-form-label" th:text="#{client.label}"></label>
|
||||
<div class="col-sm-10">
|
||||
<select name="client.id" class="form-control" id="orderClient" th:field="*{client.id}" th:errorclass="fieldError" th:value="${order.client.id}">
|
||||
<option th:each="clientId : ${clientIdsList}" th:value="${clientId}" th:text="${clientId}"></option>
|
||||
</select>
|
||||
<div th:replace="common::errors('client')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="orderMechanic" class="col-sm-2 col-form-label" th:text="#{mechanic.label}"></label>
|
||||
<div class="col-sm-10">
|
||||
<select name="mechanic.id" class="form-control" id="orderMechanic" th:field="*{mechanic.id}" th:errorclass="fieldError" th:value="${order.mechanic.id}">
|
||||
<option th:each="mechanicId : ${mechanicIdsList}" th:value="${mechanicId}" th:text="${mechanicId}"></option>
|
||||
</select>
|
||||
<div th:replace="common::errors('mechanic')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="orderCreatedOn" class="col-sm-2 col-form-label" th:text="#{createdOn.label}"></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="datetime-local" name="createdOn" class="form-control" id="orderCreatedOn" th:field="*{createdOn}" th:errorclass="fieldError" th:value="${order.createdOn}">
|
||||
<div th:replace="common::errors('createdOn')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="orderFinishedOn" class="col-sm-2 col-form-label" th:text="#{finishedOn.label}"></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="datetime-local" name="finishedOn" class="form-control" id="orderFinishedOn" th:field="*{finishedOn}" th:errorclass="fieldError" th:value="${order.finishedOn}">
|
||||
<div th:replace="common::errors('finishedOn')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="orderTotalPrice" class="col-sm-2 col-form-label" th:text="#{totalPrice.label}"></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" name="totalPrice" class="form-control" id="orderTotalPrice" th:field="*{totalPrice}" th:errorclass="fieldError" th:value="${order.totalPrice}">
|
||||
<div th:replace="common::errors('totalPrice')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="orderStatus" class="col-sm-2 col-form-label" th:text="#{status.label}"></label>
|
||||
<div class="col-sm-10">
|
||||
<select name="orderStatus" class="form-control" id="orderStatus" th:field="*{orderStatus}" th:errorclass="fieldError" th:value="${order.orderStatus}">
|
||||
<option th:each="orderStatus : ${orderStatuses}" th:value="${orderStatus.toString()}" th:text="${{orderStatus}}"></option>
|
||||
</select>
|
||||
<div th:replace="common::errors('orderStatus')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row pull-right">
|
||||
<div class="col-sm-12">
|
||||
<a href="/order" class="btn btn-default" th:text="#{common.back.button}"></a>
|
||||
<button type="submit" class="btn btn-primary" th:text="#{common.save.button}"></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
67
src/main/resources/templates/order/index.html
Normal file
67
src/main/resources/templates/order/index.html
Normal file
@ -0,0 +1,67 @@
|
||||
<!doctype html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{main}">
|
||||
<head>
|
||||
<title th:text="#{default.title}"></title>
|
||||
|
||||
<script th:inline="javascript">
|
||||
function deleteOrderById(id) {
|
||||
const confirmationResult = confirm("Are you sure to delete?");
|
||||
if (confirmationResult) {
|
||||
const url = /*[[@{/order/delete/}]]*/;
|
||||
|
||||
$.ajax({
|
||||
url: url + id,
|
||||
type: 'DELETE',
|
||||
success: function () {
|
||||
$('#order-row-' + id).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<h1 th:text="#{order.title}"></h1>
|
||||
|
||||
<div class="pull-right">
|
||||
<a class="btn btn-success" th:href="@{/order/create}" th:text="#{common.create.button}"></a>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th th:text="#{client.label}"></th>
|
||||
<th th:text="#{mechanic.label}"></th>
|
||||
<th th:text="#{description.label}"></th>
|
||||
<th th:text="#{createdOn.label}"></th>
|
||||
<th th:text="#{finishedOn.label}"></th>
|
||||
<th th:text="#{status.label}"></th>
|
||||
<th th:text="#{totalPrice.label}"></th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="order : ${orderList}" th:id="'order-row-' + ${order.id}">
|
||||
<td th:text="${order.client.firstName + ' ' + order.client.lastName + '(' + order.client.id + ')'}"></td>
|
||||
<td th:text="${order.mechanic.firstName + ' ' + order.mechanic.lastName + '(' + order.mechanic.id + ')'}"></td>
|
||||
<td class="word-breakable" th:text="${T(org.apache.commons.lang3.StringUtils).abbreviate(order.description, 128)}"></td>
|
||||
<td th:text="${{order.createdOn}}"></td>
|
||||
<td th:text="${{order.finishedOn}}"></td>
|
||||
<td th:text="${{order.orderStatus}}"></td>
|
||||
<td th:text="${{order.totalPrice}}"></td>
|
||||
<td style="break-inside: avoid">
|
||||
<div class="btn-group pull-right">
|
||||
<a th:href="@{/order/edit/{id}(id=${order.id})}" class="btn btn-default" th:text="#{common.edit.button}"></a>
|
||||
<button type="button" class="btn btn-danger" th:onclick="'deleteOrderById(' + ${order.id} + ')'" th:text="#{common.delete.button}"></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div th:replace="common::pagination(@{/order/}, ${page}, ${totalPages})"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user