added possibility to get attributes
This commit is contained in:
2025-06-08 14:36:38 +02:00
parent 81cbc1f4b2
commit 00b9f99af5
16 changed files with 180 additions and 121 deletions

View File

@@ -1,17 +1,17 @@
package _11.asktpk.artisanconnectbackend.controller;
import _11.asktpk.artisanconnectbackend.dto.NoticeAdditionDTO;
import _11.asktpk.artisanconnectbackend.dto.NoticeBoostDTO;
import _11.asktpk.artisanconnectbackend.dto.RequestResponseDTO;
import _11.asktpk.artisanconnectbackend.dto.*;
import _11.asktpk.artisanconnectbackend.service.ClientService;
import _11.asktpk.artisanconnectbackend.service.NoticeService;
import _11.asktpk.artisanconnectbackend.dto.NoticeDTO;
import _11.asktpk.artisanconnectbackend.utils.Enums;
import _11.asktpk.artisanconnectbackend.utils.Tools;
import jakarta.persistence.EntityNotFoundException;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@RequestMapping("/api/v1/notices")
@@ -19,14 +19,16 @@ import java.util.List;
public class NoticeController {
private final NoticeService noticeService;
private final ClientService clientService;
private final Tools tools;
public NoticeController(NoticeService noticeService, ClientService clientService) {
public NoticeController(NoticeService noticeService, ClientService clientService, Tools tools) {
this.noticeService = noticeService;
this.clientService = clientService;
this.tools = tools;
}
@GetMapping("/get/all")
public List<NoticeDTO> getAllNotices() {
public List<NoticeResponseDTO> getAllNotices() {
return noticeService.getAllNotices();
}
@@ -40,57 +42,34 @@ public class NoticeController {
}
@PostMapping("/add")
public ResponseEntity<NoticeAdditionDTO> addNotice(@RequestBody NoticeDTO dto) {
if (!clientService.clientExists(dto.getClientId())) {
public ResponseEntity<NoticeAdditionDTO> addNotice(@RequestBody NoticeRequestDTO dto, HttpServletRequest request) {
Long clientId = tools.getClientIdFromRequest(request);
if (!clientService.clientExists(clientId)) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new NoticeAdditionDTO("Nie znaleziono klienta o ID: " + dto.getClientId()));
.body(new NoticeAdditionDTO("Nie znaleziono klienta o ID: " + clientId));
}
if (dto.getCategory() == null) {
dto.setClientId(clientId);
if (dto.getCategory() == null || !Arrays.asList(Enums.Category.values()).contains(dto.getCategory())) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new NoticeAdditionDTO("Nie ma takiej kategorii"));
}
dto.setPublishDate(java.time.LocalDateTime.now());
Long newNoticeId = noticeService.addNotice(dto);
return ResponseEntity.status(HttpStatus.CREATED).body(new NoticeAdditionDTO(newNoticeId ,"Dodano ogłoszenie."));
}
// TODO: zamiast dodawać tutaj pętlą, musi to robić NoticeService, trzeba zaimplementować odpowienią metodę
@PostMapping("/bulk_add")
public ResponseEntity<String> addNotices(@RequestBody List<NoticeDTO> notices_list) {
ResponseEntity<String> response = new ResponseEntity<>(HttpStatus.CREATED);
List<String> errors = new ArrayList<>();
boolean isError = false;
if (notices_list.isEmpty()) {
return response.status(HttpStatus.BAD_REQUEST).body("Lista ogłoszeń jest pusta.");
}
for (NoticeDTO dto : notices_list) {
if (!clientService.clientExists(dto.getClientId())) {
isError = true;
errors.add(dto.getClientId().toString());
} else {
if (!isError) {
noticeService.addNotice(dto);
}
}
}
if (isError) {
return response.status(HttpStatus.BAD_REQUEST).body("Nie znaleziono klientów: " + errors);
}
return response;
}
@PutMapping("/edit/{id}")
public ResponseEntity<Object> editNotice(@PathVariable("id") long id, @RequestBody NoticeDTO dto) {
public ResponseEntity<Object> editNotice(@PathVariable("id") long id, @RequestBody NoticeRequestDTO dto, HttpServletRequest request) {
Long clientIdFromToken = tools.getClientIdFromRequest(request);
if (noticeService.noticeExists(id)) {
if (!noticeService.isNoticeOwnedByClient(id, clientIdFromToken)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new RequestResponseDTO("Nie masz uprawnień do edycji tego ogłoszenia."));
}
try {
return new ResponseEntity<>(noticeService.updateNotice(id, dto), HttpStatus.OK);
return ResponseEntity.status(HttpStatus.OK).body(noticeService.updateNotice(id, dto));
} catch (EntityNotFoundException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
@@ -100,8 +79,13 @@ public class NoticeController {
}
@DeleteMapping("/delete/{id}")
public ResponseEntity<RequestResponseDTO> deleteNotice(@PathVariable("id") long id) {
public ResponseEntity<RequestResponseDTO> deleteNotice(@PathVariable("id") long id, HttpServletRequest request) {
Long clientIdFromToken = tools.getClientIdFromRequest(request);
if (noticeService.noticeExists(id)) {
if (!noticeService.isNoticeOwnedByClient(id, clientIdFromToken)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new RequestResponseDTO("Nie masz uprawnień do usunięcia tego ogłoszenia."));
}
noticeService.deleteNotice(id);
return ResponseEntity.status(HttpStatus.OK).body(new RequestResponseDTO("Pomyślnie usunięto ogłoszenie o ID: " + id));
} else {
@@ -109,9 +93,10 @@ public class NoticeController {
}
}
@PostMapping("/boost/{id}")
public ResponseEntity<RequestResponseDTO> boostNotice(@PathVariable("id") long clientId, @RequestBody NoticeBoostDTO dto) {
if (!noticeService.isNoticeOwnedByClient(dto.getNoticeId(), clientId)) {
@PostMapping("/boost")
public ResponseEntity<RequestResponseDTO> boostNotice(@RequestBody NoticeBoostDTO dto, HttpServletRequest request) {
Long clientId = tools.getClientIdFromRequest(request);
if (noticeService.isNoticeOwnedByClient(dto.getNoticeId(), clientId)) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new RequestResponseDTO("Ogłoszenie nie istnieje lub nie należy do zalogowanego klienta."));
}
noticeService.boostNotice(dto.getNoticeId());

View File

@@ -5,12 +5,12 @@ import _11.asktpk.artisanconnectbackend.entities.Order;
import _11.asktpk.artisanconnectbackend.service.OrderService;
import _11.asktpk.artisanconnectbackend.service.PaymentService;
import _11.asktpk.artisanconnectbackend.utils.Enums;
import _11.asktpk.artisanconnectbackend.utils.Tools;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import static _11.asktpk.artisanconnectbackend.utils.Tools.getClientIdFromRequest;
@RestController
@RequestMapping("/api/v1/orders")
@@ -18,15 +18,17 @@ public class OrderController {
private final OrderService orderService;
private final PaymentService paymentService;
private final Tools tools;
public OrderController(OrderService orderService, PaymentService paymentService) {
public OrderController(OrderService orderService, PaymentService paymentService, Tools tools) {
this.orderService = orderService;
this.paymentService = paymentService;
this.tools = tools;
}
@PostMapping("/add")
public ResponseEntity<?> addClient(@RequestBody OrderDTO orderDTO, HttpServletRequest request) {
orderDTO.setClientId(getClientIdFromRequest(request));
orderDTO.setClientId(tools.getClientIdFromRequest(request));
return ResponseEntity.status(HttpStatus.CREATED).body(orderService.addOrder(orderDTO));
}

View File

@@ -1,10 +1,11 @@
package _11.asktpk.artisanconnectbackend.controller;
import _11.asktpk.artisanconnectbackend.dto.NoticeDTO;
import _11.asktpk.artisanconnectbackend.dto.NoticeResponseDTO;
import _11.asktpk.artisanconnectbackend.dto.RequestResponseDTO;
import _11.asktpk.artisanconnectbackend.service.ClientService;
import _11.asktpk.artisanconnectbackend.service.NoticeService;
import _11.asktpk.artisanconnectbackend.service.WishlistService;
import _11.asktpk.artisanconnectbackend.utils.Tools;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
@@ -12,8 +13,6 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
import static _11.asktpk.artisanconnectbackend.utils.Tools.getClientIdFromRequest;
@Slf4j
@RestController
@RequestMapping("/api/v1/wishlist")
@@ -21,18 +20,20 @@ public class WishlistController {
private final WishlistService wishlistService;
private final ClientService clientService;
private final NoticeService noticeService;
private final Tools tools;
public WishlistController(WishlistService wishlistService, ClientService clientService, NoticeService noticeService) {
public WishlistController(WishlistService wishlistService, ClientService clientService, NoticeService noticeService, Tools tools) {
this.wishlistService = wishlistService;
this.clientService = clientService;
this.noticeService = noticeService;
this.tools = tools;
}
@PostMapping("/toggle/{noticeId}")
public ResponseEntity<RequestResponseDTO> toggleWishlist(@PathVariable Long noticeId, HttpServletRequest request) {
Long clientId = getClientIdFromRequest(request);
NoticeDTO noticeDTO = noticeService.getNoticeById(noticeId);
if (noticeDTO == null) {
Long clientId = tools.getClientIdFromRequest(request);
NoticeResponseDTO noticeResponseDTO = noticeService.getNoticeById(noticeId);
if (noticeResponseDTO == null) {
return ResponseEntity.badRequest().body(new RequestResponseDTO("Notice not found"));
}
boolean added = wishlistService.toggleWishlist(
@@ -54,8 +55,8 @@ public class WishlistController {
// }
@GetMapping("/")
public List<NoticeDTO> getWishlistForClient(HttpServletRequest request) {
Long clientId = getClientIdFromRequest(request);
public List<NoticeResponseDTO> getWishlistForClient(HttpServletRequest request) {
Long clientId = tools.getClientIdFromRequest(request);
return wishlistService.getNoticesInWishlist(clientId);
}
}

View File

@@ -0,0 +1,11 @@
package _11.asktpk.artisanconnectbackend.dto;
import lombok.Getter;
import lombok.Setter;
@Getter @Setter
public class AttributeDto {
private String name;
private String value;
}

View File

@@ -0,0 +1,24 @@
package _11.asktpk.artisanconnectbackend.dto;
import _11.asktpk.artisanconnectbackend.utils.Enums;
import lombok.Getter;
import lombok.Setter;
@Getter @Setter
public class NoticeRequestDTO {
private String title;
private Long clientId;
private String description;
private Double price;
private Enums.Category category;
private Enums.Status status;
public NoticeRequestDTO() {
}
}

View File

@@ -1,6 +1,5 @@
package _11.asktpk.artisanconnectbackend.dto;
import _11.asktpk.artisanconnectbackend.entities.AttributesNotice;
import _11.asktpk.artisanconnectbackend.utils.Enums;
import lombok.Getter;
import lombok.Setter;
@@ -9,7 +8,7 @@ import java.time.LocalDateTime;
import java.util.List;
@Getter @Setter
public class NoticeDTO {
public class NoticeResponseDTO {
private long noticeId;
private String title;
@@ -26,11 +25,9 @@ public class NoticeDTO {
private LocalDateTime publishDate;
private List<AttributesNotice> attributesNotices;
private List<AttributeDto> attributes;
private boolean isWishlisted;
public NoticeDTO() {
public NoticeResponseDTO() {
}
}

View File

@@ -1,9 +1,12 @@
package _11.asktpk.artisanconnectbackend.entities;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "attribute_values")
@Getter @Setter
public class AttributeValues {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -14,6 +17,4 @@ public class AttributeValues {
private Attributes attribute;
private String value;
// Getters, setters, and constructors
}

View File

@@ -1,10 +1,14 @@
package _11.asktpk.artisanconnectbackend.entities;
import jakarta.persistence.*;
import lombok.Setter;
import lombok.Getter;
import java.util.List;
@Entity
@Table(name = "attributes")
@Getter @Setter
public class Attributes {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -12,8 +16,6 @@ public class Attributes {
private String name;
@OneToMany(mappedBy = "attribute", cascade = CascadeType.ALL)
@OneToMany(mappedBy = "attribute")
private List<AttributeValues> attributeValues;
// Getters, setters, and constructors
}

View File

@@ -1,21 +1,20 @@
package _11.asktpk.artisanconnectbackend.entities;
import jakarta.persistence.*;
import lombok.Setter;
import lombok.Getter;
@Entity
@Table(name = "attributes_notice")
@Getter @Setter
public class AttributesNotice {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "id_notice")
private Notice notice;
private Long notice_id;
@ManyToOne
@JoinColumn(name = "id_value")
private AttributeValues attributeValue;
// Getters, setters, and constructors
}

View File

@@ -35,10 +35,10 @@ public class Notice {
private LocalDateTime publishDate;
@OneToMany(mappedBy = "notice", cascade = CascadeType.ALL)
@OneToMany(mappedBy = "notice_id")
private List<AttributesNotice> attributesNotices;
@OneToMany(mappedBy = "notice", cascade = CascadeType.ALL)
@OneToMany(mappedBy = "notice")
private List<Order> orders;
// @OneToMany(mappedBy = "notice", cascade = CascadeType.ALL)

View File

@@ -1,11 +1,9 @@
package _11.asktpk.artisanconnectbackend.repository;
import _11.asktpk.artisanconnectbackend.entities.Notice;
import org.springframework.data.jpa.repository.JpaRepository;
public interface NoticeRepository extends JpaRepository<Notice, Long> {
boolean existsByIdNoticeAndClientId(long noticeId, long clientId);
}

View File

@@ -43,7 +43,7 @@ public class JwtRequestFilter extends OncePerRequestFilter {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
String jsonResponse = "{\"error\": \"Token is invalid or expired. Please login again.\"}";
String jsonResponse = "{\"error\": \"Token is invalid. Please login again.\"}";
response.getWriter().write(jsonResponse);
return;
}
@@ -53,7 +53,7 @@ public class JwtRequestFilter extends OncePerRequestFilter {
} catch (ExpiredJwtException expiredJwtException) {
logger.error(expiredJwtException.getMessage());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(new RequestResponseDTO(expiredJwtException.getMessage()).toJSON());
response.getWriter().write(new RequestResponseDTO("Authentication token is expired. Please login again.").toJSON());
return;
} catch (Exception e) {
logger.error(e.getMessage());

View File

@@ -1,10 +1,13 @@
package _11.asktpk.artisanconnectbackend.service;
import _11.asktpk.artisanconnectbackend.dto.AttributeDto;
import _11.asktpk.artisanconnectbackend.dto.NoticeRequestDTO;
import _11.asktpk.artisanconnectbackend.entities.AttributesNotice;
import _11.asktpk.artisanconnectbackend.entities.Client;
import _11.asktpk.artisanconnectbackend.entities.Notice;
import _11.asktpk.artisanconnectbackend.repository.ClientRepository;
import _11.asktpk.artisanconnectbackend.repository.NoticeRepository;
import _11.asktpk.artisanconnectbackend.dto.NoticeDTO;
import _11.asktpk.artisanconnectbackend.dto.NoticeResponseDTO;
import jakarta.persistence.EntityNotFoundException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -14,7 +17,6 @@ import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
public class NoticeService {
@@ -25,25 +27,21 @@ public class NoticeService {
private final NoticeRepository noticeRepository;
private final ClientRepository clientRepository;
private final WishlistService wishlistService;
private final ImageService imageService;
public NoticeService(NoticeRepository noticeRepository, ClientRepository clientRepository, WishlistService wishlistService, ImageService imageService) {
public NoticeService(NoticeRepository noticeRepository, ClientRepository clientRepository, ImageService imageService) {
this.noticeRepository = noticeRepository;
this.clientRepository = clientRepository;
this.wishlistService = wishlistService;
this.imageService = imageService;
}
public Notice fromDTO(NoticeDTO dto) {
public Notice fromDTO(NoticeRequestDTO dto) {
Notice notice = new Notice();
notice.setTitle(dto.getTitle());
notice.setDescription(dto.getDescription());
notice.setPrice(dto.getPrice());
notice.setCategory(dto.getCategory());
notice.setStatus(dto.getStatus());
notice.setPublishDate(dto.getPublishDate());
notice.setAttributesNotices(dto.getAttributesNotices());
Client client = clientRepository.findById(dto.getClientId())
.orElseThrow(() -> new EntityNotFoundException("Nie znaleziono klienta o ID: " + dto.getClientId()));
@@ -52,15 +50,8 @@ public class NoticeService {
return notice;
}
private NoticeDTO toDTO(Notice notice) {
NoticeDTO dto = new NoticeDTO();
// TODO: To be updated using AuthService after implementing authentication.
Optional<Client> client = clientRepository.findById(1L);
boolean isWishlisted = false;
if (client.isPresent()) {
Client c = client.get();
isWishlisted = wishlistService.isWishlisted(c, notice);
}
private NoticeResponseDTO toDTO(Notice notice) {
NoticeResponseDTO dto = new NoticeResponseDTO();
dto.setNoticeId(notice.getIdNotice());
dto.setTitle(notice.getTitle());
dto.setClientId(notice.getClient().getId());
@@ -69,20 +60,30 @@ public class NoticeService {
dto.setCategory(notice.getCategory());
dto.setStatus(notice.getStatus());
dto.setPublishDate(notice.getPublishDate());
dto.setAttributesNotices(notice.getAttributesNotices());
dto.setWishlisted(isWishlisted);
List<AttributeDto> attributes = new ArrayList<>();
if (notice.getAttributesNotices() != null) {
for (AttributesNotice an : notice.getAttributesNotices()) {
AttributeDto attr = new AttributeDto();
attr.setName(an.getAttributeValue().getAttribute().getName());
attr.setValue(an.getAttributeValue().getValue());
attributes.add(attr);
}
}
dto.setAttributes(attributes);
return dto;
}
public List<NoticeDTO> getAllNotices() {
List<NoticeDTO> result = new ArrayList<>();
public List<NoticeResponseDTO> getAllNotices() {
List<NoticeResponseDTO> result = new ArrayList<>();
for (Notice notice : noticeRepository.findAll()) {
result.add(toDTO(notice));
}
return result;
}
public NoticeDTO getNoticeById(Long id) {
public NoticeResponseDTO getNoticeById(Long id) {
Notice notice = noticeRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("Nie znaleziono ogłoszenia o ID: " + id));
return toDTO(notice);
@@ -93,15 +94,17 @@ public class NoticeService {
.orElseThrow(() -> new EntityNotFoundException("Nie znaleziono ogłoszenia o ID: " + id));
}
public Long addNotice(NoticeDTO dto) {
return noticeRepository.save(fromDTO(dto)).getIdNotice();
public Long addNotice(NoticeRequestDTO dto) {
Notice notice = fromDTO(dto);
notice.setPublishDate(LocalDateTime.now());
return noticeRepository.save(notice).getIdNotice();
}
public boolean noticeExists(Long id) {
return noticeRepository.existsById(id);
}
public NoticeDTO updateNotice(Long id, NoticeDTO dto) {
public NoticeResponseDTO updateNotice(Long id, NoticeRequestDTO dto) {
Notice existingNotice = noticeRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("Nie znaleziono ogłoszenia o ID: " + id));
@@ -110,7 +113,6 @@ public class NoticeService {
existingNotice.setPrice(dto.getPrice());
existingNotice.setCategory(dto.getCategory());
existingNotice.setStatus(dto.getStatus());
existingNotice.setAttributesNotices(dto.getAttributesNotices());
if (dto.getClientId() != null && !dto.getClientId().equals(existingNotice.getClient().getId())) {
Client client = clientRepository.findById(dto.getClientId())

View File

@@ -1,7 +1,7 @@
package _11.asktpk.artisanconnectbackend.service;
import _11.asktpk.artisanconnectbackend.dto.WishlistDTO;
import _11.asktpk.artisanconnectbackend.dto.NoticeDTO;
import _11.asktpk.artisanconnectbackend.dto.NoticeResponseDTO;
import _11.asktpk.artisanconnectbackend.entities.Client;
import _11.asktpk.artisanconnectbackend.entities.Notice;
import _11.asktpk.artisanconnectbackend.entities.Wishlist;
@@ -31,12 +31,6 @@ public class WishlistService {
.toList();
}
public boolean isWishlisted(Client client, Notice notice) {
Optional<Wishlist> existingEntry = wishlistRepository.findByClientAndNotice(client, notice);
return existingEntry.isEmpty();
}
public boolean toggleWishlist(Client client, Notice notice) {
Optional<Wishlist> existingEntry = wishlistRepository.findByClientAndNotice(client, notice);
@@ -61,7 +55,7 @@ public class WishlistService {
return dto;
}
public List<NoticeDTO> getNoticesInWishlist(Long clientId) {
public List<NoticeResponseDTO> getNoticesInWishlist(Long clientId) {
List<Wishlist> wishlistEntries = wishlistRepository.findAllByClientId(clientId);
return wishlistEntries.stream()

View File

@@ -3,20 +3,22 @@ package _11.asktpk.artisanconnectbackend.utils;
import _11.asktpk.artisanconnectbackend.security.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
@Component
public class Tools {
private static JwtUtil jwtUtil = null;
private final JwtUtil jwtUtil;
public Tools(JwtUtil jwtUtil) {
Tools.jwtUtil = jwtUtil;
this.jwtUtil = jwtUtil;
}
static public Long getClientIdFromRequest(HttpServletRequest request) {
public Long getClientIdFromRequest(HttpServletRequest request) {
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
return jwtUtil.extractUserId(authorizationHeader.substring(7));
} else {
return null;
return -1L;
}
}
}

View File

@@ -18,3 +18,44 @@ INSERT INTO notice (title, description, client_id, price, category, status, publ
('Ceramiczna waza', 'Piękna waza ceramiczna, idealna na prezent.', 2, 300.00, 'Ceramics', 'INACTIVE', '2023-08-20'),
('Obraz olejny', 'Obraz olejny przedstawiający krajobraz górski.', 4, 800.00, 'Painting', 'ACTIVE', '2023-07-10'),
('Skórzany portfel', 'Ręcznie wykonany portfel ze skóry naturalnej.', 1, 250.00, 'Leatherwork', 'ACTIVE', '2023-06-05');
insert into attributes (name) values
('Kolor'),
('Materiał');
-- Kolory
insert into attribute_values (value, id_attribute) values
('Zielony', 1),
('Czerwony', 1),
('Niebieski', 1),
('Żółty', 1),
('Biały', 1),
('Czarny', 1),
('Różowy', 1),
('Szary', 1),
('Fioletowy', 1),
('Pomarańczowy', 1),
('Inny', 1);
-- Materiały
insert into attribute_values (value, id_attribute) values
('Bawełna', 2),
('Wełna', 2),
('Syntetyk', 2),
('Skóra', 2),
('Len', 2),
('Jedwab', 2),
('Poliester', 2),
('Akryl', 2),
('Wiskoza', 2),
('Nylon', 2),
('Inny', 2);
insert into attributes_notice (id_value, notice_id) values
(1, 1), -- Ręcznie robiona biżuteria - Zielony
(22, 1),
(2, 2), -- Drewniany stół - Czerwony
(3, 3), -- Ceramiczna waza - Niebieski
(4, 4), -- Obraz olejny - Żółty
(5, 5); -- Skórzany portfel - Biały