Commit 4f0ea1e4 authored by Vladimir Trubachoff's avatar Vladimir Trubachoff

Initial commit

parent 50af8069
......@@ -19,10 +19,12 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mockito:mockito-core:5.12.0'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
......
package com.example.testj.domain;
import jakarta.persistence.*;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;
@Entity
@Table(name = "goods")
public class Goods {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@NotEmpty
@Column(name = "name")
private String name;
@Digits
@NotEmpty
@Column(name = "price")
private Number price;
@OneToMany(mappedBy = "goods")
List<OrderLine> orderLines;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Number getPrice() {
return price;
}
public void setPrice(Number price) {
this.price = price;
}
}
package com.example.testj.domain;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.List;
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@NotBlank
@Column(name = "client")
private String client;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
@Column(name = "date")
private String date;
@NotBlank
@Column(name = "address")
private String address;
@OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
List<OrderLine> orderLines;
public Order() {
}
public Order(String client, String date, String address) {
this.client = client;
this.address = address;
this.date = date;
}
public List<OrderLine> getOrderLines() {
return orderLines;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getClient() {
return client;
}
public void setClient(String client) {
this.client = client;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
package com.example.testj.domain;
import jakarta.persistence.*;
import org.springframework.format.annotation.NumberFormat;
import java.util.Set;
@Entity
@Table(name = "order_line")
public class OrderLine {
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@ManyToOne
@JoinColumn(name = "order_id", nullable = false)
private Order order;
@ManyToOne
@JoinColumn(name = "goods_id", nullable = false)
private Goods goods;
@Column(name = "count")
@NumberFormat
private int count;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public Goods getGoods() {
return goods;
}
}
package com.example.testj.domain;
public class RestErrorInfo {
public final String detail;
public final String message;
public RestErrorInfo(Exception ex, String detail) {
this.message = ex.getLocalizedMessage();
this.detail = detail;
}
}
package com.example.testj.domain;
\ No newline at end of file
package com.example.testj.dto;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.NotEmpty;
import java.io.Serializable;
/**
* DTO for {@link com.example.testj.domain.Goods}
*/
public class GoodsDto implements Serializable {
private final Long id;
private final String name;
private final Number price;
public GoodsDto(Long id, String name, Number price) {
this.id = id;
this.name = name;
this.price = price;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public Number getPrice() {
return price;
}
@Override
public String toString() {
return getClass().getSimpleName() + "(" +
"id = " + id + ", " +
"name = " + name + ", " +
"price = " + price + ")";
}
}
\ No newline at end of file
package com.example.testj.dto;
import com.example.testj.domain.Order;
import java.io.Serializable;
public class OrderDTO implements Serializable {
public OrderDTO(Order order) {
this.id = order.getId();
this.client = order.getClient();
this.address = order.getAddress();
this.date = order.getDate();
}
private Long id;
private String client;
private String date;
private String address;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getClient() {
return client;
}
public void setClient(String client) {
this.client = client;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
package com.example.testj.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public class BadRequestException extends RuntimeException {
}
package com.example.testj.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
}
package com.example.testj.repository;
import com.example.testj.domain.Goods;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface GoodsRepository extends CrudRepository<Goods, Long> {
}
\ No newline at end of file
package com.example.testj.repository;
import com.example.testj.domain.OrderLine;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderLineRepository extends CrudRepository<OrderLine, Long> {
}
\ No newline at end of file
package com.example.testj.repository;
import com.example.testj.domain.Order;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderRepository extends PagingAndSortingRepository<Order, Long>, CrudRepository<Order, Long> {
}
\ No newline at end of file
package com.example.testj.service;
import com.example.testj.domain.Order;
import com.example.testj.dto.OrderDTO;
import com.example.testj.exception.ResourceNotFoundException;
import com.example.testj.repository.OrderRepository;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PagedModel;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final OrderRepository orderRepository;
public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
public PagedModel<Order> getOrders(Integer page, Integer size, String sortBy, String sortDir) {
return new PagedModel<Order>(orderRepository.findAll(PageRequest.of(page, size, Sort.by(Sort.Direction.fromString(sortDir), sortBy))));
}
public Order getOrder(Long id) throws ResourceNotFoundException {
return orderRepository.findById(id).orElseThrow(ResourceNotFoundException::new);
}
public Order saveOrUpdateOrder(Order order) {
return orderRepository.save(order);
}
public Order patchOrder(Long id, JsonNode patch) throws JsonMappingException {
Order orderData = orderRepository.findById(id).orElseThrow(ResourceNotFoundException::new);
Order patchedOrder = new ObjectMapper().updateValue(orderData, patch);
return orderRepository.save(patchedOrder);
}
public void deleteOrder(Long id) throws ResourceNotFoundException {
orderRepository.findById(id).orElseThrow(ResourceNotFoundException::new);
orderRepository.deleteById(id);
}
}
package com.example.testj.service;
\ No newline at end of file
package com.example.testj.web.rest;
import com.example.testj.domain.Goods;
import com.example.testj.repository.GoodsRepository;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@CrossOrigin(origins = "http://localhost:4200")
public class GoodsController {
private final GoodsRepository goodsRepository;
public GoodsController(GoodsRepository goodsRepository) {
this.goodsRepository = goodsRepository;
}
@GetMapping("/goods")
public List<Goods> goods() {
return (List<Goods>) goodsRepository.findAll();
}
}
package com.example.testj.web.rest;
import com.example.testj.domain.Order;
import com.example.testj.domain.RestErrorInfo;
import com.example.testj.dto.OrderDTO;
import com.example.testj.exception.ResourceNotFoundException;
import com.example.testj.repository.OrderRepository;
import com.example.testj.service.OrderService;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.validation.Valid;
import org.springframework.data.web.PagedModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://localhost:4200")
public class OrderController {
private final OrderRepository orderRepository;
private final OrderService orderService;
public OrderController(OrderRepository orderRepository, OrderService orderService) {
this.orderRepository = orderRepository;
this.orderService = orderService;
}
@GetMapping("/orders")
public PagedModel<Order> getOrders(@RequestHeader(name = "X-Current-Page", defaultValue = "0") Integer page,
@RequestHeader(name = "X-Page-Size", defaultValue = "10") Integer size,
@RequestHeader(name = "X-Sort-By", defaultValue = "id") String sortBy,
@RequestHeader(name = "X-Sort-Direction", defaultValue = "ASC") String sortDir) {
return orderService.getOrders(page, size, sortBy, sortDir);
}
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable Long id) {
return this.orderService.getOrder(id);
}
@PostMapping("/orders")
public Order createOrder(@Valid @RequestBody Order order) {
return orderService.saveOrUpdateOrder(order);
}
@PutMapping("/orders/{id}")
public Order updateOrder(@PathVariable Long id, @RequestBody Order order) {
Order updatedOrder = orderService.getOrder(id);
updatedOrder.setClient(order.getClient());
updatedOrder.setAddress(order.getAddress());
updatedOrder.setDate(order.getDate());
return orderService.saveOrUpdateOrder(updatedOrder);
}
@PatchMapping("/orders/{id}")
public Order patchOrder(@PathVariable Long id, @RequestBody JsonNode patch) throws JsonMappingException {
return orderService.patchOrder(id, patch);
}
@DeleteMapping("/orders/{id}")
public ResponseEntity<HttpStatus> deleteOrder(@PathVariable Long id) throws ResourceNotFoundException {
try {
orderService.deleteOrder(id);
return new ResponseEntity<>(HttpStatus.OK);
} catch (ResourceNotFoundException e) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
}
spring.application.name=testj
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.defer-datasource-initialization=true
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false
logging.level.org.springframework.web=INFO
This diff is collapsed.
import { Subject } from 'rxjs';
import { Injectable, OnDestroy } from '@angular/core';
@Injectable()
export class AbstractBasicComponent implements OnDestroy {
protected destroy$ = new Subject();
public ngOnDestroy(): void {
this.destroy$.next(undefined);
this.destroy$.complete();
}
}
export interface User {
id: number;
name: string;
price: number;
}
export interface OrderLine {
id: number;
order_id: number;
goods_id: number;
count: number;
}
<app-orders-list [orders]="(orders$ | async)!"></app-orders-list>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IndexPageComponent } from './index-page.component';
describe('IndexPageComponent', () => {
let component: IndexPageComponent;
let fixture: ComponentFixture<IndexPageComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [IndexPageComponent]
})
.compileComponents();
fixture = TestBed.createComponent(IndexPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import {Component, OnInit} from '@angular/core';
import {Observable} from "rxjs";
import {Order} from "../../core/model/order.model";
import {OrderService} from "../../core/service/order.service";
import {AbstractBasicComponent} from "../../core/abstract/abstract-component";
@Component({
selector: 'app-index-page',
templateUrl: './index-page.component.html',
styleUrl: './index-page.component.scss'
})
export class IndexPageComponent extends AbstractBasicComponent implements OnInit {
protected orders$!: Observable<Order[]>;
constructor(private orderService: OrderService) {
super();
}
ngOnInit() {
this.orders$ = this.orderService.getOrders();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment