Files
boursecu_server/app/Models/Product.php
T
2026-06-02 16:00:33 +03:30

164 lines
6.0 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Rooyesh\Wallet\models\Transaction;
use Rooyesh\Wallet\models\Wallet;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class Product extends Model
{
use HasFactory,Selector,SoftDeletes;
private static ?bool $priceOffsetColumnExists = null;
protected static function booted(): void
{
static::saving(function (Product $product) {
if (!static::hasPriceOffsetColumn()) {
unset($product->attributes['price_offset_percent']);
}
});
}
public static function hasPriceOffsetColumn(): bool
{
if (static::$priceOffsetColumnExists !== null) {
return static::$priceOffsetColumnExists;
}
try {
static::$priceOffsetColumnExists = Schema::hasColumn(
(new static)->getTable(),
'price_offset_percent'
);
} catch (\Throwable) {
static::$priceOffsetColumnExists = false;
}
return static::$priceOffsetColumnExists;
}
public function getPriceOffsetPercentAttribute($value): float
{
if (!static::hasPriceOffsetColumn()) {
return 0.0;
}
return (float) ($value ?? 0);
}
protected $fillable = [
'title', // The title of the record.
'price', // The amount of the record.
'amount', // The amount of the record.
'unit', // The unit of the item.
'group_type', // The unit of the item.
'file_id', // The ID of the associated file.
'can_canceled', // Whether the record can be canceled (boolean).
'active', // The active status of the record (boolean).
'for_barayand', // Whether it is for Barayand (boolean).
'show', // Whether to show the record (boolean).
'open_sell', // Whether selling is open (boolean).
'auto_open_at', // Whether selling is open (boolean).
'auto_close_at', // Whether selling is open (boolean).
'kalhor_name', // The name of the Kalhor entity.
'default_credit', // Default credit amount.
'reading_method', // The method of reading.
'open_buy', // Whether buying is open (boolean).
'percent_fee_sell', // Add percent_fee_sell to fillable
'cash_fee_buy', // Add cash_fee_buy to fillable
'cash_fee_sell', // Add cash_fee_sell to fillable
'percent_fee_buy', // Add percent_fee_buy to fillable
'metal_id', //the material of metal (#gold or #silver)
'price_offset_percent', // admin only: +/- % vs automatic reference (baked into price on sync)
'price_profit',
'bubble',
];
protected $casts = [
'can_canceled' => 'boolean', // Cast to boolean.
'active' => 'boolean', // Cast to boolean.
'show' => 'boolean', // Cast to boolean.
'for_barayand' => 'boolean', // Cast to boolean.
'open_sell' => 'boolean', // Cast to boolean.
'auto_sell' => 'boolean', // Cast to boolean (you mentioned this in your casts but it's missing in `$fillable`).
'open_buy' => 'boolean', // Cast to boolean.
'auto_buy' => 'boolean', // Cast to boolean.
'price' => 'int', // Cast to float.
'percent_fee_sell' => 'float', // Cast to float.
'percent_fee_buy' => 'float', // Cast to float.
'cash_fee_buy' => 'int', // Cast to int or decimal if needed
'cash_fee_sell' => 'int', // Cast to int or decimal if needed
'price_offset_percent' => 'float',
'price_profit' => 'int',
];
static $METAL_ID = [
1=>'طلا',
2=>'نقره',
];
public function wallet()
{
return $this->hasOne(Wallet::class);
}
public function walletMy()
{
return $this->hasOne(Wallet::class)->where('owner',auth()->user()->id);
}
public function file(){
return $this->belongsTo(File::class);
}
public function price(){
return $this->hasOne(Price::class)->orderBy('id','desc');
}
public function getPrices()
{
$now = Carbon::now();
$lastMonth = Carbon::now()->subMonth();
$subQuery = DB::table('prices')
->select('product_id', 'date_at', 'price')
->whereBetween('date_at', [$lastMonth, $now])
->where('product_id', $this->id)
->orderBy('date_at', 'desc')
->distinct('date_at')
->groupBy('date_at', 'product_id', 'price');
return DB::table(DB::raw("({$subQuery->toSql()}) as sub"))
->mergeBindings($subQuery->getQuery())
->get(['product_id', 'date_at', 'price']);
}
public function prices(){
$now = Carbon::now();
$lastMonth = Carbon::now()->subMonth();
$data = [];
$datas= $this->hasMany(Price::class, 'product_id')
->whereBetween('date_at', [$lastMonth, $now])
->distinct('date_at')
->select(['product_id', 'date_at', 'difference', 'price']);
return $datas;
}
public function default(){
return $this->hasMany(ProductCredit::class);
}
public function sub(){
return $this->hasOne(PackageProduct::class)->where('is_base',true);
}
// public function wallet(){
// return $this->hasOne(Wallet::class);
// }
public function transaction(){
return $this->hasMany(Transaction::class);
}
public function transactionAgentPanel(){
return $this->hasMany(Transaction::class)->where('note','برداشت بابت فروش')->orwhere('note','واریز بابت خرید')->orwhere('note','سند ورود طلا');
}
}