ECOMMERCE/app/Models/Items.php

330 lines
9.9 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Awobaz\Compoships\Compoships;
use Spatie\Activitylog\LogOptions;
use Illuminate\Support\Facades\Storage;
class Items extends Model
{
use HasFactory, SoftDeletes;
use Compoships;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
// protected $with = ['brands', 'categories'];
protected $table = 'items';
protected $primaryKey = 'id';
protected $guarded = ['id'];
protected $fillable = [
'number',
'name',
'brand_id',
'category_id',
'image',
'description',
'weight',
'is_publish',
// BC data
'type',
'unit',
'display_unit',
'unit_cost',
'costing_method',
'last_direct_cost',
'unit_price',
'price_include_vat',
'sales_blocked',
'purchasing_blocked',
'profit_percent',
'net_weight',
'gross_weight',
'unit_volume',
'net_price',
'ref_id',
// purchase,
'alias_name',
'group_type',
'model_type',
'slug'
];
public function scopeFilter(Builder $query, array $filters)
{
$query->when($filters['search'] ?? false, function ($query, $search) {
return $query
->where('number', 'iLIKE', '%' . $search . '%')
->orWhere('name', 'iLIKE', '%' . $search . '%');
});
}
public function order()
{
return $this->hasMany(SaleOrderDetail::class, 'item_id', 'id');
}
public function dimension()
{
return $this->hasOne(ItemDimension::class,"no","number");
}
public function reference()
{
return $this->hasOne(ItemReference::class,'item_id')
->where(function($query){
$query->whereNull("item_variant_id")->orWhere("item_variant_id",0);
});
}
public function variants()
{
return $this->hasMany(ItemVariant::class,"item_id")->leftJoin("stocks","item_variant_id","=","item_variants.id")
->select("item_variants.id","item_variants.code","item_variants.display_name","item_variants.is_publish", DB::raw("SUM(quantity) as stock"),"description","item_variants.item_id")
->groupBy("item_variants.id","item_variants.code","description","item_variants.item_id","item_variants.display_name","item_variants.is_publish");
}
public function images()
{
return $this->hasMany(ItemImage::class,'item_id')->whereNull('item_variant_id');
}
public function itemVariants()
{
return $this->hasMany(ItemVariant::class,"item_id")->with("reference");
}
public function publishedItemVariants()
{
return $this->hasMany(ItemVariant::class,"item_id")->with("reference")->where('is_publish', true);
}
public function brands()
{
return $this->belongsTo(Brand::class, 'brand_id', 'id');
}
public function categories()
{
return $this->belongsTo(Categories::class, 'categories_id', 'id');
}
public function brand()
{
return $this->belongsTo(Brand::class, 'brand_id', 'id');
}
public function gender()
{
return $this->belongsTo(Gender::class, 'gender_id', 'id');
}
public function category()
{
return $this->belongsTo(Categories::class, 'category_id', 'id');
}
public function discount()
{
$user = auth()->user();
[$location_id, $is_consignment] = Cache::remember(
'employee_user_' . optional($user)->id,
60 * 60 * 24,
function () use ($user) {
if (!$user) {
return [10, false];
}
$employee = $user->employee;
$location = $employee?->location;
return [
$employee?->location_id,
(bool) optional($location)->is_consignment,
];
}
);
// return $this->hasOne(Discount::class,DB::raw("item_reference.item_id"))
// ->leftJoin('discount_items', 'discount_items.discount_id', '=', 'discounts.id')
// ->leftJoin('item_reference', 'item_reference.id', '=', 'discount_items.item_reference_id')
// ->where('discounts.type', 'discount')
// ->where(function ($query) {
// $query->whereNull('valid_at')
// ->orWhere('valid_at', '<=', now());
// })
// ->where(function ($query) {
// $query->whereNull('expired_at')
// ->orWhere('expired_at', '>=', now());
// })
// ->where(function ($query) use ($location_id, $is_consignment) {
// if (!$is_consignment) {
// $query->whereNull('discounts.location_id');
// }
// if ($location_id) {
// $query->orWhere('discounts.location_id', $location_id);
// }
// })
// ->orderByDesc('discounts.created_at')
// ->select([
// 'item_reference.item_id',
// 'discount_items.price',
// ]);
return $this->hasOne(DiscountItem::class, 'item_reference_id', 'id')
->leftJoin('discounts', 'discounts.id', '=', 'discount_items.discount_id')
->leftJoin('item_reference', 'item_reference.id', '=', 'discount_items.item_reference_id')
->where('discounts.type', 'discount')
->where(function ($q) {
$q->whereNull('discounts.valid_at')
->orWhere('discounts.valid_at', '<=', now());
})
->where(function ($q) {
$q->whereNull('discounts.expired_at')
->orWhere('discounts.expired_at', '>=', now());
})
->where(function ($q) use ($location_id, $is_consignment) {
if (!$is_consignment) {
$q->whereNull('discounts.location_id');
}
if ($location_id) {
$q->orWhere('discounts.location_id', $location_id);
}
})
->orderByDesc('discounts.created_at')
->select([
'item_reference.item_id',
'discount_items.price',
]);
}
public function price()
{
$user = auth()->user();
$userId = $user ? $user->id : 0;
list($location_id, $is_consignment) = Cache::remember("employee_user_".$userId, 60 * 60 * 24, function() use ($user){
if ($user == null)
return [10, false];
$employee = @$user->employee;
$location_id = @$employee->location_id;
$location = @$employee->location;
$is_consignment = (boolean) @$location->is_consignment;
return [$location_id, $is_consignment];
});
return $this->hasOne(Discount::class, 'id', 'item_reference_id')
->leftJoin('discount_items', 'discount_items.discount_id', '=', 'discounts.id')
->where('discounts.type', 'price')
->where(function ($query) {
$query->where('valid_at', '<=', now())
->orWhereNull('valid_at');
})
->where(function ($query) {
$query->where('expired_at', '>', now())
->orWhereNull('expired_at');
})
->where(function ($query) use ($location_id, $is_consignment) {
if (!$is_consignment) {
$query->whereNull('discounts.location_id');
}
if ($location_id) {
$query->orWhere('discounts.location_id', $location_id);
}
})
->orderByDesc('discounts.created_at')
->select([
'discount_items.item_reference_id',
'discount_items.price',
]);
}
public function stock()
{
return $this->hasOne(Stock::class,"item_id")
->leftJoin("locations","locations.id","=","location_id")
->whereNotNull("locations.display_name")
->where("locations.display_name","<>","")
->where("quantity",">","0")
->groupBy("item_id")
->select("item_id",DB::raw("SUM(quantity) as quantity"));
}
public function attributes()
{
return $this->hasMany(ItemAttribute::class, 'item_id');
}
public function getImageUrlAttribute()
{
$image = $this->images->first()->filename ?? null;
if (str_contains($image,"http")) {
return $image;
}
return $image ? Storage::disk('wms')->url($image) : null;
}
public function conversion_value()
{
$convertion = 1;
if (($this->display_unit != $this->unit) and ($this->display_unit)){
$convertions = DB::select("select to_qty / from_qty as conv
from item_convertions where from_unit = ? and to_unit = ?",
[$this->display_unit, $this->unit] );
$convertion = max((float) @$convertions[0]->conv,1);
}
return $convertion;
}
public function getDisplayPriceAttribute()
{
$convertion = $this->conversion_value();
$price = @$this->variants->first()->reference->price->price ?? null;
$price = $price ? $price : $this->net_price;
return (float) $price * $convertion;
}
public function getDisplayDiscountPriceAttribute()
{
$convertion = $this->conversion_value();
$discountPrice = @$this->discount->price ?? 0;
return (float) $discountPrice * $convertion;
}
}