added price_offset_percent

This commit is contained in:
2026-06-02 16:00:33 +03:30
parent 6cbbde9834
commit c40ac0a3fe
6 changed files with 215 additions and 36 deletions
+10 -10
View File
@@ -4,7 +4,8 @@ namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Product;
use Illuminate\Support\Facades\Http;
use App\Http\Controllers\Site\ReportController ;
use App\Http\Controllers\Site\ReportController;
use App\Services\ProductPriceService;
// مدل محصول خود را ایمپورت کنید
@@ -47,10 +48,11 @@ class UpdateProductStatus extends Command
$show = ($current_time >= $product->auto_open_at && $current_time <= $product->auto_close_at);
if ($product->reading_method == $RPrice['name']) {
$p = Product::where('id', $product->id)->update([
'price' => $RPrice['price'],
'price_profit' => $RPrice['profit'],
]);
ProductPriceService::syncFromReference(
$product,
(int) $RPrice['price'],
(int) ($RPrice['profit'] ?? 0)
);
if($product->bubble== 1){
$ReportController = new ReportController();
@@ -63,11 +65,9 @@ class UpdateProductStatus extends Command
}
}
if($product->reading_method == 'مس' && $CP){
$p = Product::where('id', $product->id)->update([
'price' => $CP,
'show' => $show,
]);
if ($product->reading_method == 'مس' && $CP) {
ProductPriceService::syncFromReference($product, (int) $CP, 0);
Product::where('id', $product->id)->update(['show' => $show]);
}
}
}
@@ -15,6 +15,7 @@ use Illuminate\Support\Facades\Http;
use \App\Http\Controllers\Customer\FundController;
use App\Http\Controllers\Site\ReportController;
use App\Services\ConfigService;
use App\Services\ProductPriceService;
class ProductController extends SuperController
@@ -73,7 +74,7 @@ class ProductController extends SuperController
public function store(Request $request)
{
$data = $request->all();
$data = $this->filterProductData($request->all());
$product = Product::create($data);
return $this->resultCreate($product->id);
@@ -83,9 +84,12 @@ class ProductController extends SuperController
{
// return 1;
$data = $request->all();
$data = $this->filterProductData($request->all());
if (isset($data["price"])){
$data["reading_method"] = null;
if (Product::hasPriceOffsetColumn()) {
$data['price_offset_percent'] = 0;
}
}
if (isset($data["auto_close_at"]) and isset($data["auto_close_at"])){
if ($data["auto_close_at"] == $data["auto_open_at"]){
@@ -103,8 +107,23 @@ class ProductController extends SuperController
// $data['auto_open_at'] = Carbon::parse($data['auto_open_at'])->format('Y-m-d H:i:s');
// $data['auto_close_at'] = Carbon::parse($data['auto_close_at'])->format('Y-m-d H:i:s');
// Product::find($id)->update($data);
Product::find($id)->update($data);
$product = Product::findOrFail($id);
$oldOffsetPercent = (float) ($product->price_offset_percent ?? 0);
if (
Product::hasPriceOffsetColumn()
&& $product->reading_method
&& array_key_exists('price_offset_percent', $data)
) {
ProductPriceService::reapplyOffsetPercent(
$product,
(float) $data['price_offset_percent'],
$oldOffsetPercent
);
unset($data['price'], $data['price_profit']);
}
$product->update($data);
return response()->json(true);
}
@@ -121,8 +140,13 @@ class ProductController extends SuperController
{
// $this->getPrice();
// $this->auto_close_open();
$product = Product::with(['file'])->where('active', 1)->get();
return response()->json($product);
$products = Product::with(['file'])->where('active', 1)->get();
if (Product::hasPriceOffsetColumn() && str_contains(request()->path(), '/customer/')) {
$products->each->makeHidden(['price_offset_percent']);
}
return response()->json($products);
}
public function getPrice()
@@ -159,11 +183,16 @@ class ProductController extends SuperController
if ($RPrice['name'] == 'گلد دات ای از آبشده - رسمی - نقد فردا') {
$RPrice['price'] = $RPrice['price'] / 4.3318;
}
$p = Product::where('id', $product->id)->update([
'price' => $RPrice['price'],
'price_profit' => $RPrice['profit'],
]);
$productPrice = (float) $RPrice['price'] + (float) ($RPrice['profit'] ?? 0);
ProductPriceService::syncFromReference(
$product,
(int) $RPrice['price'],
(int) ($RPrice['profit'] ?? 0)
);
$productPrice = (float) ProductPriceService::adjustedTotal(
(int) $RPrice['price'],
(int) ($RPrice['profit'] ?? 0),
ProductPriceService::offsetPercent($product)
);
if (
$hasExtremeKeys
&& $mainProductId
@@ -183,10 +212,12 @@ class ProductController extends SuperController
}
}
if (isset($copper) && isset($dollar)) {
$cp = ($copper / 1000000) * $dollar;
$p = Product::where('metal_id', 3)->update([
'price' => $cp,
'price_profit' => 0,
$cp = (int) round(($copper / 1000000) * $dollar);
$copperProducts = Product::where('metal_id', 3)->get();
foreach ($copperProducts as $copperProduct) {
ProductPriceService::syncFromReference($copperProduct, $cp, 0);
}
Product::where('metal_id', 3)->update([
'updated_at' => \Carbon\Carbon::now()->format('Y-m-d H:i:s'),
]);
if (
@@ -194,7 +225,11 @@ class ProductController extends SuperController
&& $mainProductId
&& Product::where('id', $mainProductId)->where('metal_id', 3)->exists()
) {
$config->trackDailyPriceExtreme((float) $cp);
$mainCopper = Product::find($mainProductId);
$extremePrice = $mainCopper
? (float) ($mainCopper->price + ($mainCopper->price_profit ?? 0))
: (float) $cp;
$config->trackDailyPriceExtreme($extremePrice);
}
}
@@ -291,4 +326,13 @@ class ProductController extends SuperController
}
private function filterProductData(array $data): array
{
if (!Product::hasPriceOffsetColumn()) {
unset($data['price_offset_percent']);
}
return $data;
}
}
+44 -2
View File
@@ -9,12 +9,49 @@ 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.
@@ -38,6 +75,9 @@ class Product extends Model
'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 = [
@@ -54,6 +94,8 @@ class Product extends Model
'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 = [
+57
View File
@@ -0,0 +1,57 @@
<?php
namespace App\Services;
use App\Models\Product;
class ProductPriceService
{
public static function referenceTotal(int $basePrice, int $baseProfit = 0): int
{
return $basePrice + $baseProfit;
}
public static function adjustedTotal(int $basePrice, int $baseProfit, float $offsetPercent): int
{
$reference = self::referenceTotal($basePrice, $baseProfit);
return (int) round($reference * (1 + ($offsetPercent / 100)));
}
/** مرجع API + درصد محصول → ذخیره در price (سود خرید/فروش جداگانه در سفارش اعمال می‌شود) */
public static function offsetPercent(Product $product): float
{
return Product::hasPriceOffsetColumn()
? (float) ($product->price_offset_percent ?? 0)
: 0.0;
}
public static function syncFromReference(Product $product, int $basePrice, int $baseProfit = 0): void
{
$offsetPercent = self::offsetPercent($product);
Product::where('id', $product->id)->update([
'price' => self::adjustedTotal($basePrice, $baseProfit, $offsetPercent),
'price_profit' => 0,
]);
}
/** وقتی فقط درصد در ادمین عوض می‌شود (بدون sync جدید) */
public static function reapplyOffsetPercent(Product $product, float $newOffsetPercent, ?float $oldOffsetPercent = null): void
{
if (!Product::hasPriceOffsetColumn()) {
return;
}
$oldOffset = $oldOffsetPercent ?? self::offsetPercent($product);
$currentTotal = (int) ($product->price + ($product->price_profit ?? 0));
$reference = $oldOffset != 0.0
? (int) round($currentTotal / (1 + $oldOffset / 100))
: $currentTotal;
Product::where('id', $product->id)->update([
'price' => (int) round($reference * (1 + ($newOffsetPercent / 100))),
'price_profit' => 0,
]);
}
}
@@ -0,0 +1,34 @@
<?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
{
if (!Schema::hasTable('products')) {
return;
}
Schema::table('products', function (Blueprint $table) {
if (!Schema::hasColumn('products', 'price_offset_percent')) {
$table->decimal('price_offset_percent', 8, 2)->default(0)->after('price_profit');
}
});
}
public function down(): void
{
if (!Schema::hasTable('products')) {
return;
}
if (Schema::hasColumn('products', 'price_offset_percent')) {
Schema::table('products', function (Blueprint $table) {
$table->dropColumn('price_offset_percent');
});
}
}
};
+10 -8
View File
@@ -2,6 +2,7 @@
use App\Models\Customer;
use App\Models\Product;
use App\Services\ProductPriceService;
use Carbon\Carbon;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Http;
@@ -33,19 +34,20 @@ Route::get('/refPricer', function () {
if ($RPrice['name'] == 'گلد دات ای از آبشده - رسمی - نقد فردا') {
$RPrice['price'] = $RPrice['price'] / 4.3318;
}
$p = Product::where('id', $product->id)->update([
'price' => $RPrice['price'],
'price_profit' => $RPrice['profit'],
]);
ProductPriceService::syncFromReference(
$product,
(int) $RPrice['price'],
(int) ($RPrice['profit'] ?? 0)
);
// }
}
}
if (isset($copper) && isset($dollar)) {
$cp = ($copper / 1000000) * $dollar;
$p = Product::where('id', 33)->update([
'price' => $cp,
'price_profit' => 0,
]);
$copperProduct = Product::find(33);
if ($copperProduct) {
ProductPriceService::syncFromReference($copperProduct, (int) round($cp), 0);
}
}
return response()->json(true);