feat: implement sorting for lines in purchase and restock create/edit components; enhance user experience
This commit is contained in:
parent
6546e1e3eb
commit
b70a40af4d
@ -39,7 +39,7 @@ protected function formattedName(): Attribute
|
|||||||
protected function statusLabel(): Attribute
|
protected function statusLabel(): Attribute
|
||||||
{
|
{
|
||||||
return Attribute::make(
|
return Attribute::make(
|
||||||
get: fn () => $this->status->label(),
|
get: fn () => $this->status?->label(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Models\Scopes\ProductVariantScope;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||||
|
use Illuminate\Database\Eloquent\Attributes\ScopedBy;
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@ -15,6 +17,7 @@
|
|||||||
|
|
||||||
#[Appends(['formatted_name'])]
|
#[Appends(['formatted_name'])]
|
||||||
#[Guarded(['id'])]
|
#[Guarded(['id'])]
|
||||||
|
#[ScopedBy([ProductVariantScope::class])]
|
||||||
class ProductVariant extends Model implements HasMedia
|
class ProductVariant extends Model implements HasMedia
|
||||||
{
|
{
|
||||||
use HasFactory, InteractsWithMedia, SoftDeletes;
|
use HasFactory, InteractsWithMedia, SoftDeletes;
|
||||||
|
|||||||
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Models\Scopes\RawMaterialPriceScope;
|
||||||
use App\Services\S3PresignedService;
|
use App\Services\S3PresignedService;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||||
|
use Illuminate\Database\Eloquent\Attributes\ScopedBy;
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@ -16,6 +18,7 @@
|
|||||||
|
|
||||||
#[Appends(['formatted_price'])]
|
#[Appends(['formatted_price'])]
|
||||||
#[Guarded(['id'])]
|
#[Guarded(['id'])]
|
||||||
|
#[ScopedBy([RawMaterialPriceScope::class])]
|
||||||
class RawMaterialPrice extends Model implements HasMedia
|
class RawMaterialPrice extends Model implements HasMedia
|
||||||
{
|
{
|
||||||
use HasFactory, InteractsWithMedia, SoftDeletes;
|
use HasFactory, InteractsWithMedia, SoftDeletes;
|
||||||
|
|||||||
15
app/Models/Scopes/ProductVariantScope.php
Normal file
15
app/Models/Scopes/ProductVariantScope.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Scopes;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Scope;
|
||||||
|
|
||||||
|
class ProductVariantScope implements Scope
|
||||||
|
{
|
||||||
|
public function apply(Builder $builder, Model $model): void
|
||||||
|
{
|
||||||
|
$builder->orderBy('name');
|
||||||
|
}
|
||||||
|
}
|
||||||
15
app/Models/Scopes/RawMaterialPriceScope.php
Normal file
15
app/Models/Scopes/RawMaterialPriceScope.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Scopes;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Scope;
|
||||||
|
|
||||||
|
class RawMaterialPriceScope implements Scope
|
||||||
|
{
|
||||||
|
public function apply(Builder $builder, Model $model): void
|
||||||
|
{
|
||||||
|
$builder->orderBy('variant');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,7 +29,9 @@ public function paginated(int $perPage = 25, string $search = '', string $sort =
|
|||||||
'supplier:id,name',
|
'supplier:id,name',
|
||||||
'createdBy:id',
|
'createdBy:id',
|
||||||
'createdBy.userProfile:id,user_id,full_name',
|
'createdBy.userProfile:id,user_id,full_name',
|
||||||
'purchaseItems:id,purchase_id,raw_material_price_id,quantity,unit_price,subtotal',
|
'purchaseItems' => fn ($q) => $q
|
||||||
|
->select('id', 'purchase_id', 'raw_material_price_id', 'quantity', 'unit_price', 'subtotal')
|
||||||
|
->orderByRaw('(SELECT variant FROM raw_material_prices WHERE raw_material_prices.id = purchase_items.raw_material_price_id)'),
|
||||||
'purchaseItems.rawMaterialPrice:id,raw_material_id,variant,price,stock',
|
'purchaseItems.rawMaterialPrice:id,raw_material_id,variant,price,stock',
|
||||||
'purchaseItems.rawMaterialPrice.rawMaterial:id,name,unit',
|
'purchaseItems.rawMaterialPrice.rawMaterial:id,name,unit',
|
||||||
])
|
])
|
||||||
@ -86,6 +88,8 @@ public function getForCreate(): array
|
|||||||
public function getForEdit(Purchase $purchase): array
|
public function getForEdit(Purchase $purchase): array
|
||||||
{
|
{
|
||||||
$purchase->load([
|
$purchase->load([
|
||||||
|
'purchaseItems' => fn ($q) => $q
|
||||||
|
->orderByRaw('(SELECT variant FROM raw_material_prices WHERE raw_material_prices.id = purchase_items.raw_material_price_id)'),
|
||||||
'purchaseItems.rawMaterialPrice.rawMaterial',
|
'purchaseItems.rawMaterialPrice.rawMaterial',
|
||||||
'supplier',
|
'supplier',
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -30,7 +30,9 @@ public function paginated(int $perPage = 25, string $search = '', string $sort =
|
|||||||
->with([
|
->with([
|
||||||
'createdBy:id',
|
'createdBy:id',
|
||||||
'createdBy.userProfile:id,user_id,full_name',
|
'createdBy.userProfile:id,user_id,full_name',
|
||||||
'restockItems:id,restock_id,product_variant_id,quantity,unit_price,subtotal',
|
'restockItems' => fn ($q) => $q
|
||||||
|
->select('id', 'restock_id', 'product_variant_id', 'quantity', 'unit_price', 'subtotal')
|
||||||
|
->orderByRaw('(SELECT name FROM product_variants WHERE product_variants.id = restock_items.product_variant_id)'),
|
||||||
'restockItems.productVariant:id,product_id,name,stock,reject_stock,retail_stock',
|
'restockItems.productVariant:id,product_id,name,stock,reject_stock,retail_stock',
|
||||||
'restockItems.productVariant.product:id,name',
|
'restockItems.productVariant.product:id,name',
|
||||||
])
|
])
|
||||||
@ -89,7 +91,11 @@ public function getForCreate(): array
|
|||||||
|
|
||||||
public function getForEdit(Restock $restock): array
|
public function getForEdit(Restock $restock): array
|
||||||
{
|
{
|
||||||
$restock->load('restockItems.productVariant.product');
|
$restock->load([
|
||||||
|
'restockItems' => fn ($q) => $q
|
||||||
|
->orderByRaw('(SELECT name FROM product_variants WHERE product_variants.id = restock_items.product_variant_id)'),
|
||||||
|
'restockItems.productVariant.product',
|
||||||
|
]);
|
||||||
|
|
||||||
$media = $restock->getFirstMedia('photos');
|
$media = $restock->getFirstMedia('photos');
|
||||||
|
|
||||||
|
|||||||
@ -360,7 +360,7 @@ export default function PurchaseCreate({ data }: Props) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines;
|
return lines.sort((a, b) => a.title.localeCompare(b.title));
|
||||||
}
|
}
|
||||||
|
|
||||||
return variants
|
return variants
|
||||||
|
|||||||
@ -301,7 +301,7 @@ export default function PurchaseEdit({ purchase, data }: Props) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines;
|
return lines.sort((a, b) => a.title.localeCompare(b.title));
|
||||||
}
|
}
|
||||||
|
|
||||||
return variants
|
return variants
|
||||||
|
|||||||
@ -188,7 +188,7 @@ return 0;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines;
|
return lines.sort((a, b) => a.title.localeCompare(b.title));
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function formatQuantity(value: number): string {
|
function formatQuantity(value: number): string {
|
||||||
|
|||||||
@ -162,7 +162,7 @@ return 0;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines;
|
return lines.sort((a, b) => a.title.localeCompare(b.title));
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function formatQuantity(value: number): string {
|
function formatQuantity(value: number): string {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user