diff --git a/build.gradle b/build.gradle index 70fee05..c67f153 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,11 @@ + plugins { id 'java' id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' } -group = 'ru.ulstu.is' +group = 'np' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' @@ -14,9 +15,13 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'com.h2database:h2:2.1.210' + implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5' + implementation 'org.springframework.boot:spring-boot-starter-validation' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() -} +} \ No newline at end of file diff --git a/data.mv.db b/data.mv.db new file mode 100644 index 0000000..89e66bd Binary files /dev/null and b/data.mv.db differ diff --git a/src/main/java/ru/ulstu/is/sbapp/SbappApplication.java b/src/main/java/ru/ulstu/is/sbapp/SbappApplication.java index f5b665b..fbf3925 100644 --- a/src/main/java/ru/ulstu/is/sbapp/SbappApplication.java +++ b/src/main/java/ru/ulstu/is/sbapp/SbappApplication.java @@ -2,17 +2,10 @@ package ru.ulstu.is.sbapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; @SpringBootApplication -@RestController public class SbappApplication { - public static void main(String[] args) { SpringApplication.run(SbappApplication.class, args); } - } - diff --git a/src/main/java/ru/ulstu/is/sbapp/client/model/Client.java b/src/main/java/ru/ulstu/is/sbapp/client/model/Client.java new file mode 100644 index 0000000..d949983 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/client/model/Client.java @@ -0,0 +1,86 @@ +package ru.ulstu.is.sbapp.client.model; + +import jakarta.persistence.*; +import ru.ulstu.is.sbapp.purchase.model.Purchase; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Entity +public class Client { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Column() + private String firstName; + private String lastName; + + @OneToMany(fetch = FetchType.EAGER,mappedBy = "client",cascade = CascadeType.ALL) + private List purchases; + + public Client() { + } + + public Client(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + this.purchases = new ArrayList<>(); + } + public void addPurchase(Purchase purchase) + { + this.purchases.add(purchase); + if(purchase.getClient() != this) + { + purchase.setClient(this); + } + } + + public Long getId() { + return id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List getPurchases() + { + return purchases; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Client client = (Client) o; + return Objects.equals(id, client.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "Client{" + + "id=" + id + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + '}'; + } + +} diff --git a/src/main/java/ru/ulstu/is/sbapp/client/service/ClientService.java b/src/main/java/ru/ulstu/is/sbapp/client/service/ClientService.java new file mode 100644 index 0000000..c519cf2 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/client/service/ClientService.java @@ -0,0 +1,80 @@ +package ru.ulstu.is.sbapp.client.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import ru.ulstu.is.sbapp.client.model.Client; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityNotFoundException; +import jakarta.persistence.PersistenceContext; +import ru.ulstu.is.sbapp.purchase.model.Purchase; +import ru.ulstu.is.sbapp.purchase.service.PurchaseService; + +import java.util.Date; +import java.util.List; + +@Service +public class ClientService { + @PersistenceContext + private EntityManager em; + + @Autowired + PurchaseService purchaseService; + + @Transactional + public Client addClient(String firstName, String lastName) { + if (!StringUtils.hasText(firstName) || !StringUtils.hasText(lastName)) { + throw new IllegalArgumentException("Client name is null or empty"); + } + final Client client = new Client(firstName, lastName); + em.persist(client); + return client; + } + @Transactional + public Client addPurchase(Long id, Date DateOfPurchase,double price) + { + final Client curclient = findClient(id); + final Purchase purchase=purchaseService.addPurchase(DateOfPurchase,price); + curclient.addPurchase(purchase); + return em.merge(curclient); + } + @Transactional(readOnly = true) + public Client findClient(Long id) { + final Client client = em.find(Client.class, id); + if (client == null) { + throw new EntityNotFoundException(String.format("Client with id [%s] is not found", id)); + } + return client; + } + + @Transactional(readOnly = true) + public List findAllClients() { + return em.createQuery("select c from Client c", Client.class) + .getResultList(); + } + + @Transactional + public Client updateClient(Long id, String firstName, String lastName) { + if (!StringUtils.hasText(firstName) || !StringUtils.hasText(lastName)) { + throw new IllegalArgumentException("Client name is null or empty"); + } + final Client currentClient = findClient(id); + currentClient.setFirstName(firstName); + currentClient.setLastName(lastName); + return em.merge(currentClient); + } + + @Transactional + public Client deleteClient(Long id) { + final Client currentClient = findClient(id); + em.remove(currentClient); + return currentClient; + } + + @Transactional + public void deleteAllClients() { + em.createQuery("delete from Client").executeUpdate(); + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/purchase/model/Purchase.java b/src/main/java/ru/ulstu/is/sbapp/purchase/model/Purchase.java new file mode 100644 index 0000000..de45d19 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/purchase/model/Purchase.java @@ -0,0 +1,109 @@ +package ru.ulstu.is.sbapp.purchase.model; + +import jakarta.persistence.*; +import ru.ulstu.is.sbapp.client.model.Client; +import ru.ulstu.is.sbapp.technique.model.Technique; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +@Entity +public class Purchase { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column + Date DateOfPurchase; + + double Price; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name ="client_fk") + private Client client; + + @ManyToMany + @JoinTable(name = "purchases_techniques", + joinColumns = @JoinColumn(name = "purchase_fk"), + inverseJoinColumns = @JoinColumn(name = "technique_fk")) + private List techniques; + + + public Purchase() + { + + } + + public Purchase(Date DateOfPurchase,double Price) + { + this.DateOfPurchase=DateOfPurchase; + this.Price = Price; + } + public List getTechnique() { + return techniques; + } + public void setTechnique(Technique technique) { + if (techniques == null){ + techniques = new ArrayList<>(); + } + this.techniques.add(technique); + if (!technique.getPurchases().contains(this)) { // warning this may cause performance issues if you have a large data set since this operation is O(n) + technique.getPurchases().add(this); + } + } + public Long getId() + { + return id; + } + public Date getDateOfPurchase() + { + return DateOfPurchase; + } + public void setDateOfPurchase(Date DateOfPurchase) + { + this.DateOfPurchase=DateOfPurchase; + } + public double getPrice() + { + return Price; + } + public void setPrice(Float Price) + { + this.Price=Price; + } + public Client getClient() + { + return client; + } + public void setClient(Client client) + { + this.client=client; + if (!client.getPurchases().contains(this)) { + client.getPurchases().add(this); + } + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Purchase purchase = (Purchase) o; + return Objects.equals(id, purchase.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public String toString() { + return "Purchase{" + + "id=" + id + + ", DateOfPurchase='" + DateOfPurchase + '\'' + + ", Price ='" + Price + '\'' + + '}'; + } + +} diff --git a/src/main/java/ru/ulstu/is/sbapp/purchase/service/PurchaseService.java b/src/main/java/ru/ulstu/is/sbapp/purchase/service/PurchaseService.java new file mode 100644 index 0000000..20655a8 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/purchase/service/PurchaseService.java @@ -0,0 +1,75 @@ +package ru.ulstu.is.sbapp.purchase.service; + +import org.apache.commons.lang3.time.DateUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import ru.ulstu.is.sbapp.client.model.Client; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityNotFoundException; +import jakarta.persistence.PersistenceContext; +import ru.ulstu.is.sbapp.purchase.model.Purchase; + +import java.util.Date; +import java.util.List; + +@Service +public class PurchaseService { + @PersistenceContext + private EntityManager em; + + @Transactional + public Purchase addPurchase(Date DateOfPurchase, double Price) { + if (DateOfPurchase==null) { + throw new IllegalArgumentException("Date of purchase is null or empty"); + } + if(Price==0){ + throw new IllegalArgumentException("Price is null or empty"); + } + final Purchase purchase = new Purchase(DateOfPurchase, Price); + em.persist(purchase); + return purchase; + } + + @Transactional(readOnly = true) + public Purchase findPurchase(Long id) { + final Purchase purchase = em.find(Purchase.class, id); + if (purchase == null) { + throw new EntityNotFoundException(String.format("Purchase with id [%s] is not found", id)); + } + return purchase; + } + + @Transactional(readOnly = true) + public List findAllPurchases() { + return em.createQuery("select p from Purchase p", Purchase.class) + .getResultList(); + } + + @Transactional + public Purchase updatePurchase(Long id, Date DateOfPurchase, Float Price) { + if (DateOfPurchase==null) { + throw new IllegalArgumentException("Date of purchase is null or empty"); + } + if(Price==null){ + throw new IllegalArgumentException("Price is null or empty"); + } + final Purchase currentPurchase = findPurchase(id); + currentPurchase.setDateOfPurchase(DateOfPurchase); + currentPurchase.setPrice(Price); + return em.merge(currentPurchase); + } + + @Transactional + public Purchase deletePurchase(Long id) { + final Purchase currentPurchase = findPurchase(id); + em.remove(currentPurchase); + return currentPurchase; + } + + @Transactional + public void deleteAllPurchases() { + em.createQuery("delete from Purchase").executeUpdate(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/ulstu/is/sbapp/technique/model/Technique.java b/src/main/java/ru/ulstu/is/sbapp/technique/model/Technique.java new file mode 100644 index 0000000..d8270a0 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/technique/model/Technique.java @@ -0,0 +1,67 @@ +package ru.ulstu.is.sbapp.technique.model; + +import jakarta.persistence.*; +import ru.ulstu.is.sbapp.purchase.model.Purchase; + +import java.util.List; +import java.util.Objects; + +@Entity +public class Technique { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column + String Type; + + double TechPrice; + + + + @ManyToMany(mappedBy = "techniques") + private List purchases; + + public Technique(){} + + public Technique(String Type,double TechPrice) + { + this.Type = Type; + this.TechPrice=TechPrice; + } + public Long getId() + { + return id; + } + public String getType() + { + return Type; + } + public double getTechPrice() + { + return TechPrice; + } + public void setType(String Type){ + this.Type=Type; + } + public void setTechPrice(Float TechPrice) + { + this.TechPrice=TechPrice; + } + public List getPurchases() + { + return purchases; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Technique technique = (Technique) o; + return Objects.equals(id, technique.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } +} diff --git a/src/main/java/ru/ulstu/is/sbapp/technique/service/TechniqueService.java b/src/main/java/ru/ulstu/is/sbapp/technique/service/TechniqueService.java new file mode 100644 index 0000000..33a9c66 --- /dev/null +++ b/src/main/java/ru/ulstu/is/sbapp/technique/service/TechniqueService.java @@ -0,0 +1,74 @@ +package ru.ulstu.is.sbapp.technique.service; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityNotFoundException; +import jakarta.persistence.PersistenceContext; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import ru.ulstu.is.sbapp.client.model.Client; +import ru.ulstu.is.sbapp.technique.model.Technique; + +import java.util.List; + +@Service +public class TechniqueService { + @PersistenceContext + private EntityManager em; + + @Transactional + public Technique addTechnique(String Type, double TechPrice) { + if (!StringUtils.hasText(Type)) { + throw new IllegalArgumentException("Technique type is null or empty"); + } + if(TechPrice == 0) + { + throw new IllegalArgumentException("Technique TechPrice is null or empty"); + } + final Technique technique = new Technique(Type, TechPrice); + em.persist(technique); + return technique; + } + + @Transactional(readOnly = true) + public Technique findTechnique(Long id) { + final Technique technique = em.find(Technique.class, id); + if (technique == null) { + throw new EntityNotFoundException(String.format("Technique with id [%s] is not found", id)); + } + return technique; + } + + @Transactional(readOnly = true) + public List findAllTechniques() { + return em.createQuery("select t from Technique T", Technique.class) + .getResultList(); + } + + @Transactional + public Technique updateTechnique(Long id, String Type, Float TechPrice) { + if (!StringUtils.hasText(Type)){ + throw new IllegalArgumentException("Technique type is null or empty"); + } + if(TechPrice == null) + { + throw new IllegalArgumentException("Technique TechPrice is null or empty"); + } + final Technique currentTechnique = findTechnique(id); + currentTechnique.setType(Type); + currentTechnique.setTechPrice(TechPrice); + return em.merge(currentTechnique); + } + + @Transactional + public Technique deleteTechnique(Long id) { + final Technique currentTechnique = findTechnique(id); + em.remove(currentTechnique); + return currentTechnique; + } + + @Transactional + public void deleteAllTechniques() { + em.createQuery("delete from Technique").executeUpdate(); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..da7b0b1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,11 @@ - +spring.main.banner-mode=off +#server.port=8080 +spring.datasource.url=jdbc:h2:file:./data +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=password +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=update +spring.h2.console.enabled=true +spring.h2.console.settings.trace=false +spring.h2.console.settings.web-allow-others=false diff --git a/src/test/java/ru/ulstu/is/sbapp/TechShopTest.java b/src/test/java/ru/ulstu/is/sbapp/TechShopTest.java new file mode 100644 index 0000000..81597b8 --- /dev/null +++ b/src/test/java/ru/ulstu/is/sbapp/TechShopTest.java @@ -0,0 +1,55 @@ +package ru.ulstu.is.sbapp; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import ru.ulstu.is.sbapp.client.model.Client; +import ru.ulstu.is.sbapp.client.service.ClientService; +import ru.ulstu.is.sbapp.purchase.model.Purchase; +import ru.ulstu.is.sbapp.purchase.service.PurchaseService; +import ru.ulstu.is.sbapp.technique.service.TechniqueService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@SpringBootTest +public class TechShopTest { + private static final Logger log = LoggerFactory.getLogger(TechShopTest.class); + @Autowired + ClientService clientService; + + @Autowired + TechniqueService techniqueService; + + @Autowired + PurchaseService purchaseService; + + @Test + void testClientCreate(){ + clientService.deleteAllClients(); + final Client client = clientService.addClient("Вася","Пупкин"); + log.info(client.toString()); + Assertions.assertNotNull(client.getId()); + } + + @Test + void testPurchaseCreate() + { + purchaseService.deleteAllPurchases(); + clientService.deleteAllClients(); + final Client client = clientService.addClient("Вася","Пупкин"); + Date date = new Date(12121212L); + clientService.addPurchase(client.getId(),date, 3000.0); + log.info(client.getPurchases().toString()); + } + + @Test + void testTecnhiques(){} + + @Test + void testPurchases(){} +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 0000000..81734b8 --- /dev/null +++ b/src/test/resources/application.properties @@ -0,0 +1,6 @@ +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=password +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=create-drop \ No newline at end of file