Add lot_prefix to products; compose LOT number from prefix + date suffix
Deploy / deploy (push) Successful in 14s
Deploy / deploy (push) Successful in 14s
Products now have a configurable lot_prefix (e.g. "112"). In the batch form the prefix is shown read-only next to the suffix input (JJMMTT), and the full lot_number (e.g. "112-260912") is composed automatically and stored. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
e9734c2590
commit
5c034ec895
6 files changed
+87
-12
No files matched your search
@@ -110,7 +110,7 @@ GET https://api.sms.spices.blue/api/v1/{lot_number}
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"lot_number": "LOT-2024-001",
|
"lot_number": "112-260912",
|
||||||
"produced_at": "2024-10-01",
|
"produced_at": "2024-10-01",
|
||||||
"expires_at": "2026-10-01",
|
"expires_at": "2026-10-01",
|
||||||
"units_produced": 50,
|
"units_produced": 50,
|
||||||
@@ -220,6 +220,7 @@ Table packings {
|
|||||||
Table products {
|
Table products {
|
||||||
id int [pk]
|
id int [pk]
|
||||||
title text
|
title text
|
||||||
|
lot_prefix varchar -- Präfix für Chargennummer, z.B. "112"
|
||||||
images json
|
images json
|
||||||
description text
|
description text
|
||||||
recipes_id int [ref: > recipes.id]
|
recipes_id int [ref: > recipes.id]
|
||||||
|
|||||||
@@ -31,12 +31,6 @@ class BatchResource extends Resource
|
|||||||
{
|
{
|
||||||
return $form->schema([
|
return $form->schema([
|
||||||
Forms\Components\Section::make('Charge')->schema([
|
Forms\Components\Section::make('Charge')->schema([
|
||||||
Forms\Components\TextInput::make('lot_number')
|
|
||||||
->label('LOT-Nummer')
|
|
||||||
->required()
|
|
||||||
->unique(ignoreRecord: true)
|
|
||||||
->maxLength(255),
|
|
||||||
|
|
||||||
Forms\Components\Select::make('product_id')
|
Forms\Components\Select::make('product_id')
|
||||||
->label('Produkt')
|
->label('Produkt')
|
||||||
->relationship('product', 'title')
|
->relationship('product', 'title')
|
||||||
@@ -44,7 +38,7 @@ class BatchResource extends Resource
|
|||||||
->preload()
|
->preload()
|
||||||
->required()
|
->required()
|
||||||
->live()
|
->live()
|
||||||
->afterStateUpdated(function ($state, $set) {
|
->afterStateUpdated(function ($state, $set, $get) {
|
||||||
$set('size_id', null);
|
$set('size_id', null);
|
||||||
$set('recipe_id', null);
|
$set('recipe_id', null);
|
||||||
$set('origins', []);
|
$set('origins', []);
|
||||||
@@ -62,8 +56,41 @@ class BatchResource extends Resource
|
|||||||
])->toArray());
|
])->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$suffix = $get('lot_suffix');
|
||||||
|
if ($suffix && $product?->lot_prefix) {
|
||||||
|
$set('lot_number', $product->lot_prefix . '-' . $suffix);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('lot_suffix')
|
||||||
|
->label('LOT-Nummer')
|
||||||
|
->prefix(fn (Get $get): ?string => Product::find($get('product_id'))?->lot_prefix
|
||||||
|
? Product::find($get('product_id'))->lot_prefix . ' -'
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
->placeholder('JJMMTT')
|
||||||
|
->maxLength(50)
|
||||||
|
->required()
|
||||||
|
->dehydrated(false)
|
||||||
|
->live()
|
||||||
|
->afterStateHydrated(function ($component, $record) {
|
||||||
|
if (! $record?->lot_number) return;
|
||||||
|
$pos = strrpos($record->lot_number, '-');
|
||||||
|
$component->state($pos !== false
|
||||||
|
? substr($record->lot_number, $pos + 1)
|
||||||
|
: $record->lot_number
|
||||||
|
);
|
||||||
|
})
|
||||||
|
->afterStateUpdated(function ($state, $set, $get) {
|
||||||
|
$product = Product::find($get('product_id'));
|
||||||
|
$set('lot_number', $product?->lot_prefix
|
||||||
|
? $product->lot_prefix . '-' . $state
|
||||||
|
: $state
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
|
||||||
|
Forms\Components\Hidden::make('lot_number'),
|
||||||
|
|
||||||
Forms\Components\Select::make('size_id')
|
Forms\Components\Select::make('size_id')
|
||||||
->label('Variante (Verpackung)')
|
->label('Variante (Verpackung)')
|
||||||
->options(fn (Get $get) => ProductSize::with('packing')
|
->options(fn (Get $get) => ProductSize::with('packing')
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ class ProductResource extends Resource {
|
|||||||
Forms\Components\TextInput::make('title')
|
Forms\Components\TextInput::make('title')
|
||||||
->label('Name')
|
->label('Name')
|
||||||
->required(),
|
->required(),
|
||||||
|
Forms\Components\TextInput::make('lot_prefix')
|
||||||
|
->label('Chargen-Präfix')
|
||||||
|
->placeholder('z.B. 112')
|
||||||
|
->unique(ignoreRecord: true)
|
||||||
|
->maxLength(20),
|
||||||
Placeholder::make('shopify_product_id')
|
Placeholder::make('shopify_product_id')
|
||||||
->label('Shopify ID')
|
->label('Shopify ID')
|
||||||
->content(fn ($record) => $record?->shopify_product_id
|
->content(fn ($record) => $record?->shopify_product_id
|
||||||
|
|||||||
+23
-3
@@ -24,11 +24,31 @@ class BatchesRelationManager extends RelationManager
|
|||||||
public function form(Form $form): Form
|
public function form(Form $form): Form
|
||||||
{
|
{
|
||||||
return $form->schema([
|
return $form->schema([
|
||||||
Forms\Components\TextInput::make('lot_number')
|
Forms\Components\TextInput::make('lot_suffix')
|
||||||
->label('LOT-Nummer')
|
->label('LOT-Nummer')
|
||||||
|
->prefix(fn ($livewire): ?string => $livewire->getOwnerRecord()->lot_prefix
|
||||||
|
? $livewire->getOwnerRecord()->lot_prefix . ' -'
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
->placeholder('JJMMTT')
|
||||||
|
->maxLength(50)
|
||||||
->required()
|
->required()
|
||||||
->unique(ignoreRecord: true)
|
->dehydrated(false)
|
||||||
->maxLength(255),
|
->live()
|
||||||
|
->afterStateHydrated(function ($component, $record) {
|
||||||
|
if (! $record?->lot_number) return;
|
||||||
|
$pos = strrpos($record->lot_number, '-');
|
||||||
|
$component->state($pos !== false
|
||||||
|
? substr($record->lot_number, $pos + 1)
|
||||||
|
: $record->lot_number
|
||||||
|
);
|
||||||
|
})
|
||||||
|
->afterStateUpdated(function ($state, $set, $livewire) {
|
||||||
|
$prefix = $livewire->getOwnerRecord()->lot_prefix;
|
||||||
|
$set('lot_number', $prefix ? "{$prefix}-{$state}" : $state);
|
||||||
|
}),
|
||||||
|
|
||||||
|
Forms\Components\Hidden::make('lot_number'),
|
||||||
|
|
||||||
Forms\Components\Select::make('size_id')
|
Forms\Components\Select::make('size_id')
|
||||||
->label('Variante (Verpackung)')
|
->label('Variante (Verpackung)')
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
|
|
||||||
class Product extends Model
|
class Product extends Model
|
||||||
{
|
{
|
||||||
protected $fillable = ['title', 'description', 'images', 'package_content', 'recipes_id', 'shopify_product_id'];
|
protected $fillable = ['title', 'lot_prefix', 'description', 'images', 'package_content', 'recipes_id', 'shopify_product_id'];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'images' => 'array',
|
'images' => 'array',
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('products', function (Blueprint $table) {
|
||||||
|
$table->string('lot_prefix')->nullable()->unique()->after('title');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('products', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('lot_prefix');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in new issue
Block a user