Files
Malek TellissiandClaude Sonnet 4.6 e959faff8d
Deploy / deploy (push) Successful in 15s
Fix barcode 500 error, GTIN mask formatting, and add price sync
- Wrap barcode generation in try-catch to prevent 500 on invalid GTIN
- Move barcode preview above GTIN input field
- Add input mask (X XXXXXX XXXXXX) and strip non-digits before save/render
- Only render barcode when >= 8 digits present
- shopify:sync now updates price alongside inventory

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 04:59:46 +02:00

89 lines
3.2 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\ProductInventory;
use App\Models\ProductSize;
use App\Services\ShopifyService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class ShopifySync extends Command
{
protected $signature = 'shopify:sync {--dry-run : Änderungen nur anzeigen, nichts speichern}';
protected $description = 'Gleicht lokalen Lagerbestand mit Shopify-Inventar ab';
public function handle(ShopifyService $shopify): int
{
$dryRun = $this->option('dry-run');
$variants = $shopify->getAllVariants();
if (empty($variants)) {
$this->error('Keine Varianten von Shopify erhalten — API-Aufruf fehlgeschlagen (Details im Log).');
return self::FAILURE;
}
$added = 0;
$removed = 0;
$inSync = 0;
DB::transaction(function () use ($variants, $dryRun, &$added, &$removed, &$inSync) {
foreach ($variants as $variant) {
$size = ProductSize::where('shopify_variant_id', $variant['id'])->first();
if (!$size) {
continue; // not mapped yet — run shopify:map first
}
// Preis immer aktualisieren
if (! $dryRun && $size->price != $variant['price']) {
$size->update(['price' => $variant['price']]);
}
$shopifyQty = $variant['inventory_quantity'];
$localQty = ProductInventory::where('size_id', $size->id)
->whereNull('out_at')
->count();
if ($localQty === $shopifyQty) {
$inSync++;
continue;
}
$diff = $shopifyQty - $localQty;
if ($diff > 0) {
// Shopify hat mehr → Einträge hinzufügen
$this->line(" +{$diff} {$variant['product_title']} (SKU {$variant['sku']})");
if (!$dryRun) {
for ($i = 0; $i < $diff; $i++) {
ProductInventory::create([
'product_id' => $size->product_id,
'size_id' => $size->id,
]);
}
}
$added += $diff;
} else {
// Shopify hat weniger → älteste Einträge als ausgebucht markieren
$excess = abs($diff);
$this->line(" -{$excess} {$variant['product_title']} (SKU {$variant['sku']})");
if (!$dryRun) {
ProductInventory::where('size_id', $size->id)
->whereNull('out_at')
->oldest()
->limit($excess)
->update(['out_at' => now()]);
}
$removed += $excess;
}
}
});
$this->info("✓ Sync abgeschlossen" . ($dryRun ? ' (dry-run)' : ''));
$this->info(" In Sync: {$inSync} | Hinzugefügt: {$added} | Ausgebucht: {$removed}");
return self::SUCCESS;
}
}