feat: implement product and attachment management service with supporting migrations and API controllers
This commit is contained in:
@@ -22,7 +22,8 @@ class ProductService
|
||||
{
|
||||
return DB::transaction(function () use ($tenant, $data) {
|
||||
$attributeIds = $data['attribute_ids'] ?? [];
|
||||
unset($data['attribute_ids']);
|
||||
$images = $data['images'] ?? [];
|
||||
unset($data['attribute_ids'], $data['images']);
|
||||
|
||||
/** @var Product $product */
|
||||
$product = Product::query()->create([
|
||||
@@ -32,7 +33,11 @@ class ProductService
|
||||
|
||||
$product->attributes()->sync($attributeIds);
|
||||
|
||||
return $product->load('attributes');
|
||||
if (! empty($images)) {
|
||||
$this->syncProductImages($product, $images);
|
||||
}
|
||||
|
||||
return $product->load(['attributes', 'attachments']);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -46,7 +51,9 @@ class ProductService
|
||||
return DB::transaction(function () use ($product, $data) {
|
||||
$hasAttributeIds = array_key_exists('attribute_ids', $data);
|
||||
$attributeIds = $data['attribute_ids'] ?? [];
|
||||
unset($data['attribute_ids']);
|
||||
$hasImages = array_key_exists('images', $data);
|
||||
$images = $data['images'] ?? [];
|
||||
unset($data['attribute_ids'], $data['images']);
|
||||
|
||||
// Ensure tenant_codigo cannot be updated/changed
|
||||
unset($data['tenant_codigo']);
|
||||
@@ -57,7 +64,11 @@ class ProductService
|
||||
$product->attributes()->sync($attributeIds);
|
||||
}
|
||||
|
||||
return $product->load('attributes');
|
||||
if ($hasImages) {
|
||||
$this->syncProductImages($product, $images);
|
||||
}
|
||||
|
||||
return $product->load(['attributes', 'attachments']);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,6 +81,14 @@ class ProductService
|
||||
foreach ($product->variants as $variant) {
|
||||
$product->deleteVariant($variant);
|
||||
}
|
||||
|
||||
// Delete product-level attachments from S3 and database
|
||||
$existing = $product->attachments()->get();
|
||||
$product->attachments()->detach();
|
||||
foreach ($existing as $attachment) {
|
||||
$this->attachmentService->delete($attachment);
|
||||
}
|
||||
|
||||
$product->attributes()->detach();
|
||||
$product->delete();
|
||||
});
|
||||
@@ -183,6 +202,32 @@ class ProductService
|
||||
$variant->attachments()->sync($attachmentIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a list of image files/base64 strings and sync them to a product.
|
||||
*
|
||||
* Same logic as syncImages but for products without variants.
|
||||
*
|
||||
* @param array<int, UploadedFile|string> $images
|
||||
*/
|
||||
protected function syncProductImages(Product $product, array $images): void
|
||||
{
|
||||
// Detach pivot record and delete attachment from S3 and database
|
||||
$existing = $product->attachments()->get();
|
||||
$product->attachments()->detach();
|
||||
foreach ($existing as $attachment) {
|
||||
$this->attachmentService->delete($attachment);
|
||||
}
|
||||
|
||||
$attachmentIds = [];
|
||||
|
||||
foreach ($images as $image) {
|
||||
$attachment = $this->attachmentService->store($image, 'products');
|
||||
$attachmentIds[] = $attachment->id;
|
||||
}
|
||||
|
||||
$product->attachments()->sync($attachmentIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an attribute.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user