mirror of
https://gitea.gofwd.group/Forward_Group/ballistic-builder-spring.git
synced 2026-01-20 16:51:03 -05:00
support for filtering and updating caliber
This commit is contained in:
@@ -29,11 +29,12 @@ public class CatalogController {
|
||||
@RequestParam(required = false) String partRole,
|
||||
@RequestParam(required = false) List<String> partRoles,
|
||||
@RequestParam(required = false, name = "brand") List<String> brands,
|
||||
@RequestParam(required = false, name = "caliber") List<String> calibers,
|
||||
@RequestParam(required = false) String q,
|
||||
Pageable pageable
|
||||
) {
|
||||
Pageable safe = sanitizeCatalogPageable(pageable);
|
||||
return catalogQueryService.getOptions(platform, partRole, partRoles, brands, q, safe);
|
||||
return catalogQueryService.getOptions(platform, partRole, partRoles, brands, calibers, q, safe);
|
||||
}
|
||||
|
||||
private Pageable sanitizeCatalogPageable(Pageable pageable) {
|
||||
|
||||
@@ -37,20 +37,22 @@ public class CaliberEnrichmentService {
|
||||
*/
|
||||
@Transactional
|
||||
public RunResult runRules(int limit) {
|
||||
// Adjust Product entity package if needed:
|
||||
// IMPORTANT: Product must be a mapped @Entity named "Product"
|
||||
|
||||
List<Object[]> rows = em.createQuery("""
|
||||
select p.id, p.name, p.description
|
||||
from Product p
|
||||
where p.deletedAt is null
|
||||
and not exists (
|
||||
select 1 from ProductEnrichment e
|
||||
where e.productId = p.id
|
||||
and e.enrichmentType = group.goforward.battlbuilder.enrichment.EnrichmentType.CALIBER
|
||||
and e.status in ('PENDING_REVIEW','APPROVED')
|
||||
)
|
||||
order by p.id desc
|
||||
""", Object[].class)
|
||||
select p.id, p.name, p.description
|
||||
from Product p
|
||||
where p.deletedAt is null
|
||||
and not exists (
|
||||
select 1 from ProductEnrichment e
|
||||
where e.productId = p.id
|
||||
and e.enrichmentType = :etype
|
||||
and e.status in (:s1, :s2)
|
||||
)
|
||||
order by p.id desc
|
||||
""", Object[].class)
|
||||
.setParameter("etype", EnrichmentType.CALIBER)
|
||||
.setParameter("s1", EnrichmentStatus.PENDING_REVIEW)
|
||||
.setParameter("s2", EnrichmentStatus.APPROVED)
|
||||
.setMaxResults(limit)
|
||||
.getResultList();
|
||||
|
||||
|
||||
@@ -77,6 +77,9 @@ public class Product {
|
||||
@Column(name = "classified_at")
|
||||
private Instant classifiedAt;
|
||||
|
||||
@Column(name = "caliber_locked", nullable = false)
|
||||
private Boolean caliberLocked = false;
|
||||
|
||||
@Column(name = "part_role_locked", nullable = false)
|
||||
private Boolean partRoleLocked = false;
|
||||
|
||||
@@ -227,6 +230,9 @@ public class Product {
|
||||
this.platformLocked = platformLocked;
|
||||
}
|
||||
|
||||
public Boolean getCaliberLocked() { return caliberLocked; }
|
||||
public void setCaliberLocked(Boolean caliberLocked) { this.caliberLocked = caliberLocked; }
|
||||
|
||||
public String getRawCategoryKey() { return rawCategoryKey; }
|
||||
public void setRawCategoryKey(String rawCategoryKey) {
|
||||
this.rawCategoryKey = rawCategoryKey;
|
||||
|
||||
@@ -8,6 +8,7 @@ public enum PartRoleSource {
|
||||
MERCHANT_MAP,
|
||||
OVERRIDE,
|
||||
RULES,
|
||||
UNKNOWN
|
||||
UNKNOWN,
|
||||
ADMIN
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import jakarta.persistence.criteria.JoinType;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class CatalogProductSpecifications {
|
||||
|
||||
@@ -39,6 +40,24 @@ public class CatalogProductSpecifications {
|
||||
};
|
||||
}
|
||||
|
||||
public static Specification<Product> caliberIn(List<String> calibers) {
|
||||
return (root, query, cb) -> {
|
||||
if (calibers == null || calibers.isEmpty()) return cb.conjunction();
|
||||
|
||||
// normalize + drop blanks
|
||||
var cleaned = calibers.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::trim)
|
||||
.filter(s -> !s.isBlank())
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
if (cleaned.isEmpty()) return cb.conjunction();
|
||||
|
||||
return root.get("caliber").in(cleaned);
|
||||
};
|
||||
}
|
||||
|
||||
public static Specification<Product> queryLike(String q) {
|
||||
final String like = "%" + q.toLowerCase().trim() + "%";
|
||||
return (root, query, cb) -> {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package group.goforward.battlbuilder.security;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class Authz {
|
||||
|
||||
public UUID requireUserUuid() {
|
||||
Authentication a = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (a == null || !a.isAuthenticated() || a.getPrincipal() == null) {
|
||||
throw new RuntimeException("Unauthorized");
|
||||
}
|
||||
return UUID.fromString(a.getPrincipal().toString()); // principal is UUID string in your filter
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ public interface CatalogQueryService {
|
||||
String partRole,
|
||||
List<String> partRoles,
|
||||
List<String> brands,
|
||||
List<String> calibers,
|
||||
String q,
|
||||
Pageable pageable
|
||||
);
|
||||
|
||||
@@ -8,8 +8,12 @@ import group.goforward.battlbuilder.web.dto.admin.BulkUpdateResult;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
public interface AdminProductService {
|
||||
Page<ProductAdminRowDto> search(AdminProductSearchRequest request, Pageable pageable);
|
||||
import java.util.List;
|
||||
|
||||
public interface AdminProductService {
|
||||
|
||||
Page<ProductAdminRowDto> search(AdminProductSearchRequest request, Pageable pageable);
|
||||
BulkUpdateResult bulkUpdate(ProductBulkUpdateRequest request);
|
||||
List<String> distinctRoles(AdminProductSearchRequest request);
|
||||
List<String> distinctCalibers(AdminProductSearchRequest request);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package group.goforward.battlbuilder.services.admin.impl;
|
||||
|
||||
import group.goforward.battlbuilder.model.Product;
|
||||
import group.goforward.battlbuilder.model.enums.PartRoleSource;
|
||||
import group.goforward.battlbuilder.repos.ProductRepository;
|
||||
import group.goforward.battlbuilder.services.admin.AdminProductService;
|
||||
import group.goforward.battlbuilder.domain.specs.ProductSpecifications;
|
||||
@@ -9,12 +10,27 @@ import group.goforward.battlbuilder.web.dto.admin.BulkUpdateResult;
|
||||
import group.goforward.battlbuilder.web.dto.admin.ProductAdminRowDto;
|
||||
import group.goforward.battlbuilder.web.dto.admin.ProductBulkUpdateRequest;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class AdminProductServiceImpl implements AdminProductService {
|
||||
@@ -70,10 +86,52 @@ public class AdminProductServiceImpl implements AdminProductService {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// --- CALIBER update with lock semantics ---
|
||||
if (request.getCaliber() != null) {
|
||||
boolean calLocked = Boolean.TRUE.equals(p.getCaliberLocked());
|
||||
boolean forceCal = Boolean.TRUE.equals(request.getForceCaliberUpdate());
|
||||
|
||||
if (calLocked && !forceCal) {
|
||||
skippedLocked++;
|
||||
} else {
|
||||
String next = request.getCaliber().trim();
|
||||
if (next.isEmpty()) next = null;
|
||||
|
||||
if ((next == null && p.getCaliber() != null) || (next != null && !next.equals(p.getCaliber()))) {
|
||||
p.setCaliber(next);
|
||||
|
||||
// optional group
|
||||
if (request.getCaliberGroup() != null) {
|
||||
String g = request.getCaliberGroup().trim();
|
||||
p.setCaliberGroup(g.isEmpty() ? null : g);
|
||||
}
|
||||
|
||||
// audit fields (keep consistent with role)
|
||||
p.setClassifierVersion("admin-ui");
|
||||
p.setClassifiedAt(Instant.now());
|
||||
p.setClassificationReason(
|
||||
request.getClassificationReason() != null
|
||||
? request.getClassificationReason()
|
||||
: "Admin bulk override"
|
||||
);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- apply caliberLocked toggle (even if caliber isn't being changed) ---
|
||||
if (request.getCaliberLocked() != null) {
|
||||
if (!request.getCaliberLocked().equals(p.getCaliberLocked())) {
|
||||
p.setCaliberLocked(request.getCaliberLocked());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// --- platform update with lock semantics ---
|
||||
if (request.getPlatform() != null) {
|
||||
boolean isLocked = Boolean.TRUE.equals(p.getPlatformLocked());
|
||||
boolean override = Boolean.TRUE.equals(request.getPlatformLocked()); // request says "I'm allowed to touch locked ones"
|
||||
boolean override = Boolean.TRUE.equals(request.getPlatformLocked()); // caller says "ok to touch locked ones"
|
||||
|
||||
if (isLocked && !override) {
|
||||
skippedLocked++;
|
||||
@@ -93,21 +151,122 @@ public class AdminProductServiceImpl implements AdminProductService {
|
||||
}
|
||||
}
|
||||
|
||||
// --- ROLE update with lock semantics ---
|
||||
if (request.getPartRole() != null) {
|
||||
boolean roleLocked = Boolean.TRUE.equals(p.getPartRoleLocked());
|
||||
boolean force = Boolean.TRUE.equals(request.getForceRoleUpdate());
|
||||
|
||||
if (roleLocked && !force) {
|
||||
skippedLocked++;
|
||||
} else {
|
||||
if (!request.getPartRole().equals(p.getPartRole())) {
|
||||
p.setPartRole(request.getPartRole());
|
||||
p.setPartRoleSource(PartRoleSource.ADMIN);
|
||||
p.setClassifiedAt(Instant.now());
|
||||
p.setClassifierVersion("admin-ui");
|
||||
p.setClassificationReason(
|
||||
request.getClassificationReason() != null
|
||||
? request.getClassificationReason()
|
||||
: "Admin bulk override"
|
||||
);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- apply partRoleLocked toggle (even if partRole isn't being changed) ---
|
||||
if (request.getPartRoleLocked() != null) {
|
||||
if (!request.getPartRoleLocked().equals(p.getPartRoleLocked())) {
|
||||
p.setPartRoleLocked(request.getPartRoleLocked());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) updated++;
|
||||
}
|
||||
|
||||
productRepository.saveAll(products);
|
||||
productRepository.flush(); // ✅ ensures UPDATEs are executed now
|
||||
productRepository.flush();
|
||||
|
||||
var check = productRepository.findAllById(request.getProductIds());
|
||||
for (var p : check) {
|
||||
System.out.println(
|
||||
"AFTER FLUSH id=" + p.getId()
|
||||
+ " platform=" + p.getPlatform()
|
||||
+ " platformLocked=" + p.getPlatformLocked()
|
||||
);
|
||||
System.out.println("AFTER id=" + p.getId()
|
||||
+ " role=" + p.getPartRole()
|
||||
+ " roleLocked=" + p.getPartRoleLocked()
|
||||
+ " source=" + p.getPartRoleSource()
|
||||
+ " reason=" + p.getClassificationReason());
|
||||
}
|
||||
|
||||
return new BulkUpdateResult(updated, skippedLocked);
|
||||
}
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<String> distinctRoles(AdminProductSearchRequest request) {
|
||||
var spec = ProductSpecifications.adminSearch(request);
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<String> cq = cb.createQuery(String.class);
|
||||
Root<Product> root = cq.from(Product.class);
|
||||
|
||||
// Base predicate from your existing admin search spec
|
||||
Predicate base = spec != null ? spec.toPredicate(root, cq, cb) : cb.conjunction();
|
||||
|
||||
// Only real values
|
||||
Predicate notNull = cb.isNotNull(root.get("partRole"));
|
||||
Predicate notBlank = cb.notEqual(cb.trim(root.get("partRole")), "");
|
||||
|
||||
cq.select(root.get("partRole"))
|
||||
.distinct(true)
|
||||
.where(cb.and(base, notNull, notBlank))
|
||||
.orderBy(cb.asc(root.get("partRole")));
|
||||
|
||||
TypedQuery<String> q = em.createQuery(cq);
|
||||
List<String> raw = q.getResultList();
|
||||
|
||||
// Defensive: normalize + de-dupe in case DB has whitespace variants
|
||||
List<String> out = new ArrayList<>();
|
||||
for (String r : raw) {
|
||||
if (r == null) continue;
|
||||
String t = r.trim();
|
||||
if (t.isEmpty()) continue;
|
||||
if (!out.contains(t)) out.add(t);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<String> distinctCalibers(AdminProductSearchRequest request) {
|
||||
var spec = ProductSpecifications.adminSearch(request);
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<String> cq = cb.createQuery(String.class);
|
||||
Root<Product> root = cq.from(Product.class);
|
||||
|
||||
Predicate base = spec != null ? spec.toPredicate(root, cq, cb) : cb.conjunction();
|
||||
|
||||
Predicate notNull = cb.isNotNull(root.get("caliber"));
|
||||
Predicate notBlank = cb.notEqual(cb.trim(root.get("caliber")), "");
|
||||
|
||||
cq.select(root.get("caliber"))
|
||||
.distinct(true)
|
||||
.where(cb.and(base, notNull, notBlank))
|
||||
.orderBy(cb.asc(root.get("caliber")));
|
||||
|
||||
List<String> raw = em.createQuery(cq).getResultList();
|
||||
|
||||
// normalize + de-dupe
|
||||
List<String> out = new ArrayList<>();
|
||||
for (String c : raw) {
|
||||
if (c == null) continue;
|
||||
String t = c.trim();
|
||||
if (t.isEmpty()) continue;
|
||||
if (!out.contains(t)) out.add(t);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@ public class CatalogQueryServiceImpl implements CatalogQueryService {
|
||||
String partRole,
|
||||
List<String> partRoles,
|
||||
List<String> brands,
|
||||
List<String> calibers,
|
||||
String q,
|
||||
Pageable pageable
|
||||
) {
|
||||
@@ -68,6 +69,10 @@ public class CatalogQueryServiceImpl implements CatalogQueryService {
|
||||
spec = spec.and(CatalogProductSpecifications.brandNameIn(brands));
|
||||
}
|
||||
|
||||
if (calibers != null && !calibers.isEmpty()) {
|
||||
spec = spec.and(CatalogProductSpecifications.caliberIn(calibers));
|
||||
}
|
||||
|
||||
if (q != null && !q.isBlank()) {
|
||||
spec = spec.and(CatalogProductSpecifications.queryLike(q));
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ import group.goforward.battlbuilder.web.dto.admin.AdminProductSearchRequest;
|
||||
import group.goforward.battlbuilder.web.dto.admin.ProductBulkUpdateRequest;
|
||||
import group.goforward.battlbuilder.web.dto.admin.BulkUpdateResult;
|
||||
import group.goforward.battlbuilder.web.dto.admin.ProductAdminRowDto;
|
||||
import group.goforward.battlbuilder.web.dto.admin.ProductFacetsDto;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@@ -22,20 +24,21 @@ public class AdminProductController {
|
||||
this.adminProductService = adminProductService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin product list (paged + filterable)
|
||||
*/
|
||||
@GetMapping
|
||||
public Page<ProductAdminRowDto> search(
|
||||
AdminProductSearchRequest request,
|
||||
Pageable pageable
|
||||
) {
|
||||
public Page<ProductAdminRowDto> search(AdminProductSearchRequest request, Pageable pageable) {
|
||||
return adminProductService.search(request, pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk admin actions (disable, hide, lock, etc.)
|
||||
*/
|
||||
@GetMapping("/roles")
|
||||
public List<String> roles(AdminProductSearchRequest request) {
|
||||
return adminProductService.distinctRoles(request);
|
||||
}
|
||||
|
||||
@GetMapping("/calibers")
|
||||
public List<String> calibers(AdminProductSearchRequest request) {
|
||||
return adminProductService.distinctCalibers(request);
|
||||
}
|
||||
|
||||
@PatchMapping("/bulk")
|
||||
public Map<String, Object> bulkUpdate(@RequestBody ProductBulkUpdateRequest request) {
|
||||
BulkUpdateResult result = adminProductService.bulkUpdate(request);
|
||||
@@ -44,4 +47,12 @@ public class AdminProductController {
|
||||
"skippedLockedCount", result.skippedLockedCount()
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping("/facets")
|
||||
public ProductFacetsDto facets(@RequestBody AdminProductSearchRequest request) {
|
||||
return new ProductFacetsDto(
|
||||
adminProductService.distinctRoles(request),
|
||||
adminProductService.distinctCalibers(request)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,10 @@ public class ProductAdminRowDto {
|
||||
private String platform;
|
||||
private String partRole;
|
||||
|
||||
private String caliber;
|
||||
private String caliberGroup;
|
||||
private Boolean caliberLocked;
|
||||
|
||||
private String brandName;
|
||||
|
||||
private ImportStatus importStatus;
|
||||
@@ -45,25 +49,21 @@ public class ProductAdminRowDto {
|
||||
|
||||
dto.id = p.getId();
|
||||
dto.uuid = p.getUuid();
|
||||
|
||||
dto.name = p.getName();
|
||||
dto.slug = p.getSlug();
|
||||
|
||||
dto.platform = p.getPlatform();
|
||||
dto.partRole = p.getPartRole();
|
||||
|
||||
dto.caliber = p.getCaliber();
|
||||
dto.caliberGroup = p.getCaliberGroup();
|
||||
dto.caliberLocked = p.getCaliberLocked();
|
||||
dto.brandName = (p.getBrand() != null) ? p.getBrand().getName() : null;
|
||||
|
||||
dto.importStatus = p.getImportStatus();
|
||||
|
||||
dto.visibility = p.getVisibility();
|
||||
dto.status = p.getStatus();
|
||||
dto.builderEligible = p.getBuilderEligible();
|
||||
dto.adminLocked = p.getAdminLocked();
|
||||
|
||||
dto.adminNote = p.getAdminNote();
|
||||
dto.mainImageUrl = p.getMainImageUrl();
|
||||
|
||||
dto.createdAt = p.getCreatedAt();
|
||||
dto.updatedAt = p.getUpdatedAt();
|
||||
|
||||
@@ -120,6 +120,15 @@ public class ProductAdminRowDto {
|
||||
this.partRole = partRole;
|
||||
}
|
||||
|
||||
public String getCaliber() { return caliber; }
|
||||
public void setCaliber(String caliber) { this.caliber = caliber; }
|
||||
|
||||
public String getCaliberGroup() { return caliberGroup; }
|
||||
public void setCaliberGroup(String caliberGroup) { this.caliberGroup = caliberGroup; }
|
||||
|
||||
public Boolean getCaliberLocked() { return caliberLocked; }
|
||||
public void setCaliberLocked(Boolean caliberLocked) { this.caliberLocked = caliberLocked; }
|
||||
|
||||
public String getBrandName() {
|
||||
return brandName;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,23 @@ public class ProductBulkUpdateRequest {
|
||||
private Set<Integer> productIds;
|
||||
private String platform;
|
||||
private Boolean platformLocked;
|
||||
private String caliber;
|
||||
private Boolean caliberLocked;
|
||||
private String caliberGroup;
|
||||
private Boolean forceCaliberUpdate;
|
||||
private ProductVisibility visibility;
|
||||
private ProductStatus status;
|
||||
|
||||
private String partRole;
|
||||
private Boolean partRoleLocked;
|
||||
private String classificationReason;
|
||||
private Boolean builderEligible;
|
||||
private Boolean adminLocked;
|
||||
|
||||
private String adminNote;
|
||||
private Boolean forceRoleUpdate;
|
||||
|
||||
public Boolean getForceRoleUpdate() { return forceRoleUpdate; }
|
||||
public void setForceRoleUpdate(Boolean forceRoleUpdate) { this.forceRoleUpdate = forceRoleUpdate; }
|
||||
|
||||
|
||||
// --- getters/setters ---
|
||||
|
||||
@@ -43,4 +53,40 @@ public class ProductBulkUpdateRequest {
|
||||
|
||||
public Boolean getPlatformLocked() { return platformLocked; }
|
||||
public void setPlatformLocked(Boolean platformLocked) { this.platformLocked = platformLocked; }
|
||||
|
||||
public String getCaliber() { return caliber; }
|
||||
public void setCaliber(String caliber) { this.caliber = caliber; }
|
||||
|
||||
public String getCaliberGroup() { return caliberGroup; }
|
||||
public void setCaliberGroup(String caliberGroup) { this.caliberGroup = caliberGroup; }
|
||||
|
||||
public Boolean getCaliberLocked() { return caliberLocked; }
|
||||
public void setCaliberLocked(Boolean caliberLocked) { this.caliberLocked = caliberLocked; }
|
||||
|
||||
public Boolean getForceCaliberUpdate() { return forceCaliberUpdate; }
|
||||
public void setForceCaliberUpdate(Boolean forceCaliberUpdate) { this.forceCaliberUpdate = forceCaliberUpdate; }
|
||||
|
||||
public String getPartRole() {
|
||||
return partRole;
|
||||
}
|
||||
|
||||
public void setPartRole(String partRole) {
|
||||
this.partRole = partRole;
|
||||
}
|
||||
|
||||
public Boolean getPartRoleLocked() {
|
||||
return partRoleLocked;
|
||||
}
|
||||
|
||||
public void setPartRoleLocked(Boolean partRoleLocked) {
|
||||
this.partRoleLocked = partRoleLocked;
|
||||
}
|
||||
|
||||
public String getClassificationReason() {
|
||||
return classificationReason;
|
||||
}
|
||||
|
||||
public void setClassificationReason(String classificationReason) {
|
||||
this.classificationReason = classificationReason;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package group.goforward.battlbuilder.web.dto.admin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record ProductFacetsDto(
|
||||
List<String> roles,
|
||||
List<String> calibers
|
||||
) {}
|
||||
Reference in New Issue
Block a user