mirror of
https://gitea.gofwd.group/Forward_Group/ballistic-builder-spring.git
synced 2025-12-06 02:56:44 -05:00
small changes. still working
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package group.goforward.ballistic.imports;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
|
||||
import group.goforward.ballistic.model.Brand;
|
||||
import group.goforward.ballistic.model.Merchant;
|
||||
@@ -41,37 +41,37 @@ public class MerchantFeedImportServiceImpl implements MerchantFeedImportService
|
||||
|
||||
// TODO: replace this with real feed parsing:
|
||||
// List<MerchantFeedRow> rows = feedClient.fetch(merchant);
|
||||
// rows.forEach(row -> upsertProduct(merchant, row));
|
||||
// rows.forEach(row -> upsertProduct(merchant, brand, row));
|
||||
MerchantFeedRow row = new MerchantFeedRow(
|
||||
"TEST-SKU-001",
|
||||
"APPG100002",
|
||||
brand.getName(),
|
||||
"Test Product From Import",
|
||||
"This is a long description from AvantLink.",
|
||||
"Short description from AvantLink.",
|
||||
"Rifles",
|
||||
"AR-15 Parts",
|
||||
"Handguards & Rails",
|
||||
"https://example.com/thumb.jpg",
|
||||
"https://example.com/image.jpg",
|
||||
"https://example.com/buy-link",
|
||||
"ar-15, handguard, aero",
|
||||
null,
|
||||
new BigDecimal("199.99"), // retailPrice
|
||||
new BigDecimal("149.99"), // salePrice
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"https://example.com/medium.jpg",
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
"TEST-SKU-001",
|
||||
"APPG100002",
|
||||
brand.getName(),
|
||||
"Test Product From Import",
|
||||
"This is a long description from AvantLink.",
|
||||
"Short description from AvantLink.",
|
||||
"Rifles",
|
||||
"AR-15 Parts",
|
||||
"Handguards & Rails",
|
||||
"https://example.com/thumb.jpg",
|
||||
"https://example.com/image.jpg",
|
||||
"https://example.com/buy-link",
|
||||
"ar-15, handguard, aero",
|
||||
null,
|
||||
new BigDecimal("199.99"), // retailPrice
|
||||
new BigDecimal("149.99"), // salePrice
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"https://example.com/medium.jpg",
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
Product p = createProduct(brand, row);
|
||||
Product p = upsertProduct(merchant, brand, row);
|
||||
|
||||
System.out.println("IMPORT >>> created product id=" + p.getId()
|
||||
System.out.println("IMPORT >>> upserted product id=" + p.getId()
|
||||
+ ", name=" + p.getName()
|
||||
+ ", slug=" + p.getSlug()
|
||||
+ ", platform=" + p.getPlatform()
|
||||
@@ -79,13 +79,54 @@ public class MerchantFeedImportServiceImpl implements MerchantFeedImportService
|
||||
+ ", merchant=" + merchant.getName());
|
||||
}
|
||||
|
||||
private Product createProduct(Brand brand, MerchantFeedRow row) {
|
||||
System.out.println("IMPORT >>> createProduct brand=" + brand.getName()
|
||||
/**
|
||||
* Upsert logic:
|
||||
* - Try Brand+MPN, then Brand+UPC (for now using sku as a stand-in)
|
||||
* - If found, update fields but keep existing slug
|
||||
* - If not found, create a new Product and generate a unique slug
|
||||
*/
|
||||
private Product upsertProduct(Merchant merchant, Brand brand, MerchantFeedRow row) {
|
||||
System.out.println("IMPORT >>> upsertProduct brand=" + brand.getName()
|
||||
+ ", sku=" + row.sku()
|
||||
+ ", productName=" + row.productName());
|
||||
|
||||
Product p = new Product();
|
||||
p.setBrand(brand);
|
||||
String mpn = trimOrNull(row.manufacturerId());
|
||||
String upc = trimOrNull(row.sku()); // later: real UPC column
|
||||
|
||||
java.util.List<Product> candidates = java.util.Collections.emptyList();
|
||||
|
||||
if (mpn != null) {
|
||||
candidates = productRepository.findAllByBrandAndMpn(brand, mpn);
|
||||
}
|
||||
if ((candidates == null || candidates.isEmpty()) && upc != null) {
|
||||
candidates = productRepository.findAllByBrandAndUpc(brand, upc);
|
||||
}
|
||||
|
||||
Product p;
|
||||
boolean isNew = (candidates == null || candidates.isEmpty());
|
||||
|
||||
if (isNew) {
|
||||
p = new Product();
|
||||
p.setBrand(brand);
|
||||
} else {
|
||||
if (candidates.size() > 1) {
|
||||
System.out.println("IMPORT !!! WARNING: multiple existing products found for brand="
|
||||
+ brand.getName() + ", mpn=" + mpn + ", upc=" + upc
|
||||
+ ". Using the first match (id=" + candidates.get(0).getId() + ")");
|
||||
}
|
||||
p = candidates.get(0);
|
||||
}
|
||||
|
||||
updateProductFromRow(p, row, isNew);
|
||||
|
||||
return productRepository.save(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared mapping logic from feed row -> Product entity.
|
||||
* If isNew = true, we generate a slug. Otherwise we leave the slug alone.
|
||||
*/
|
||||
private void updateProductFromRow(Product p, MerchantFeedRow row, boolean isNew) {
|
||||
|
||||
// ---------- NAME ----------
|
||||
String name = coalesce(
|
||||
@@ -100,25 +141,27 @@ public class MerchantFeedImportServiceImpl implements MerchantFeedImportService
|
||||
p.setName(name);
|
||||
|
||||
// ---------- SLUG ----------
|
||||
String baseForSlug = coalesce(
|
||||
trimOrNull(name),
|
||||
trimOrNull(row.sku())
|
||||
);
|
||||
if (baseForSlug == null) {
|
||||
baseForSlug = "product-" + System.currentTimeMillis();
|
||||
}
|
||||
if (isNew || p.getSlug() == null || p.getSlug().isBlank()) {
|
||||
String baseForSlug = coalesce(
|
||||
trimOrNull(name),
|
||||
trimOrNull(row.sku())
|
||||
);
|
||||
if (baseForSlug == null) {
|
||||
baseForSlug = "product-" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
String slug = baseForSlug
|
||||
.toLowerCase()
|
||||
.replaceAll("[^a-z0-9]+", "-")
|
||||
.replaceAll("(^-|-$)", "");
|
||||
if (slug.isBlank()) {
|
||||
slug = "product-" + System.currentTimeMillis();
|
||||
}
|
||||
String slug = baseForSlug
|
||||
.toLowerCase()
|
||||
.replaceAll("[^a-z0-9]+", "-")
|
||||
.replaceAll("(^-|-$)", "");
|
||||
if (slug.isBlank()) {
|
||||
slug = "product-" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// Ensure slug is unique by appending a numeric suffix if needed
|
||||
String uniqueSlug = generateUniqueSlug(slug);
|
||||
p.setSlug(uniqueSlug);
|
||||
// Ensure slug is unique by appending a numeric suffix if needed
|
||||
String uniqueSlug = generateUniqueSlug(slug);
|
||||
p.setSlug(uniqueSlug);
|
||||
}
|
||||
|
||||
// ---------- DESCRIPTIONS ----------
|
||||
p.setShortDescription(trimOrNull(row.shortDescription()));
|
||||
@@ -141,24 +184,19 @@ public class MerchantFeedImportServiceImpl implements MerchantFeedImportService
|
||||
p.setMpn(mpn);
|
||||
|
||||
// Feed doesn’t give us UPC in the header you showed.
|
||||
// We’ll leave UPC null for now.
|
||||
// We’ll leave UPC null for now (or map later).
|
||||
p.setUpc(null);
|
||||
|
||||
// ---------- PLATFORM ----------
|
||||
// For now, hard-code to AR-15 to satisfy not-null constraint.
|
||||
// Later we can infer from row.category()/row.department().
|
||||
String platform = inferPlatform(row);
|
||||
p.setPlatform(platform != null ? platform : "AR-15");
|
||||
|
||||
// ---------- PART ROLE ----------
|
||||
// We can do a tiny heuristic off category/subcategory.
|
||||
String partRole = inferPartRole(row);
|
||||
if (partRole == null || partRole.isBlank()) {
|
||||
partRole = "unknown";
|
||||
}
|
||||
p.setPartRole(partRole);
|
||||
|
||||
return productRepository.save(p);
|
||||
}
|
||||
|
||||
// --- Helpers ----------------------------------------------------------
|
||||
|
||||
@@ -6,15 +6,15 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.List;
|
||||
|
||||
public interface ProductRepository extends JpaRepository<Product, Integer> {
|
||||
|
||||
Optional<Product> findByUuid(UUID uuid);
|
||||
|
||||
Optional<Product> findByBrandAndMpn(Brand brand, String mpn);
|
||||
|
||||
Optional<Product> findByBrandAndUpc(Brand brand, String upc);
|
||||
|
||||
boolean existsBySlug(String slug);
|
||||
|
||||
List<Product> findAllByBrandAndMpn(Brand brand, String mpn);
|
||||
|
||||
List<Product> findAllByBrandAndUpc(Brand brand, String upc);
|
||||
}
|
||||
Reference in New Issue
Block a user