added price_offset_percent
This commit is contained in:
@@ -4,7 +4,8 @@ namespace App\Console\Commands;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use Illuminate\Support\Facades\Http;
|
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);
|
$show = ($current_time >= $product->auto_open_at && $current_time <= $product->auto_close_at);
|
||||||
|
|
||||||
if ($product->reading_method == $RPrice['name']) {
|
if ($product->reading_method == $RPrice['name']) {
|
||||||
$p = Product::where('id', $product->id)->update([
|
ProductPriceService::syncFromReference(
|
||||||
'price' => $RPrice['price'],
|
$product,
|
||||||
'price_profit' => $RPrice['profit'],
|
(int) $RPrice['price'],
|
||||||
]);
|
(int) ($RPrice['profit'] ?? 0)
|
||||||
|
);
|
||||||
|
|
||||||
if($product->bubble== 1){
|
if($product->bubble== 1){
|
||||||
$ReportController = new ReportController();
|
$ReportController = new ReportController();
|
||||||
@@ -63,11 +65,9 @@ class UpdateProductStatus extends Command
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($product->reading_method == 'مس' && $CP){
|
if ($product->reading_method == 'مس' && $CP) {
|
||||||
$p = Product::where('id', $product->id)->update([
|
ProductPriceService::syncFromReference($product, (int) $CP, 0);
|
||||||
'price' => $CP,
|
Product::where('id', $product->id)->update(['show' => $show]);
|
||||||
'show' => $show,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use Illuminate\Support\Facades\Http;
|
|||||||
use \App\Http\Controllers\Customer\FundController;
|
use \App\Http\Controllers\Customer\FundController;
|
||||||
use App\Http\Controllers\Site\ReportController;
|
use App\Http\Controllers\Site\ReportController;
|
||||||
use App\Services\ConfigService;
|
use App\Services\ConfigService;
|
||||||
|
use App\Services\ProductPriceService;
|
||||||
|
|
||||||
|
|
||||||
class ProductController extends SuperController
|
class ProductController extends SuperController
|
||||||
@@ -73,7 +74,7 @@ class ProductController extends SuperController
|
|||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$data = $request->all();
|
$data = $this->filterProductData($request->all());
|
||||||
|
|
||||||
$product = Product::create($data);
|
$product = Product::create($data);
|
||||||
return $this->resultCreate($product->id);
|
return $this->resultCreate($product->id);
|
||||||
@@ -83,9 +84,12 @@ class ProductController extends SuperController
|
|||||||
{
|
{
|
||||||
// return 1;
|
// return 1;
|
||||||
|
|
||||||
$data = $request->all();
|
$data = $this->filterProductData($request->all());
|
||||||
if (isset($data["price"])){
|
if (isset($data["price"])){
|
||||||
$data["reading_method"] = null;
|
$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 (isset($data["auto_close_at"]) and isset($data["auto_close_at"])){
|
||||||
if ($data["auto_close_at"] == $data["auto_open_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_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');
|
// $data['auto_close_at'] = Carbon::parse($data['auto_close_at'])->format('Y-m-d H:i:s');
|
||||||
// Product::find($id)->update($data);
|
$product = Product::findOrFail($id);
|
||||||
Product::find($id)->update($data);
|
$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);
|
return response()->json(true);
|
||||||
}
|
}
|
||||||
@@ -121,8 +140,13 @@ class ProductController extends SuperController
|
|||||||
{
|
{
|
||||||
// $this->getPrice();
|
// $this->getPrice();
|
||||||
// $this->auto_close_open();
|
// $this->auto_close_open();
|
||||||
$product = Product::with(['file'])->where('active', 1)->get();
|
$products = Product::with(['file'])->where('active', 1)->get();
|
||||||
return response()->json($product);
|
|
||||||
|
if (Product::hasPriceOffsetColumn() && str_contains(request()->path(), '/customer/')) {
|
||||||
|
$products->each->makeHidden(['price_offset_percent']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($products);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPrice()
|
public function getPrice()
|
||||||
@@ -159,11 +183,16 @@ class ProductController extends SuperController
|
|||||||
if ($RPrice['name'] == 'گلد دات ای از آبشده - رسمی - نقد فردا') {
|
if ($RPrice['name'] == 'گلد دات ای از آبشده - رسمی - نقد فردا') {
|
||||||
$RPrice['price'] = $RPrice['price'] / 4.3318;
|
$RPrice['price'] = $RPrice['price'] / 4.3318;
|
||||||
}
|
}
|
||||||
$p = Product::where('id', $product->id)->update([
|
ProductPriceService::syncFromReference(
|
||||||
'price' => $RPrice['price'],
|
$product,
|
||||||
'price_profit' => $RPrice['profit'],
|
(int) $RPrice['price'],
|
||||||
]);
|
(int) ($RPrice['profit'] ?? 0)
|
||||||
$productPrice = (float) $RPrice['price'] + (float) ($RPrice['profit'] ?? 0);
|
);
|
||||||
|
$productPrice = (float) ProductPriceService::adjustedTotal(
|
||||||
|
(int) $RPrice['price'],
|
||||||
|
(int) ($RPrice['profit'] ?? 0),
|
||||||
|
ProductPriceService::offsetPercent($product)
|
||||||
|
);
|
||||||
if (
|
if (
|
||||||
$hasExtremeKeys
|
$hasExtremeKeys
|
||||||
&& $mainProductId
|
&& $mainProductId
|
||||||
@@ -183,10 +212,12 @@ class ProductController extends SuperController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($copper) && isset($dollar)) {
|
if (isset($copper) && isset($dollar)) {
|
||||||
$cp = ($copper / 1000000) * $dollar;
|
$cp = (int) round(($copper / 1000000) * $dollar);
|
||||||
$p = Product::where('metal_id', 3)->update([
|
$copperProducts = Product::where('metal_id', 3)->get();
|
||||||
'price' => $cp,
|
foreach ($copperProducts as $copperProduct) {
|
||||||
'price_profit' => 0,
|
ProductPriceService::syncFromReference($copperProduct, $cp, 0);
|
||||||
|
}
|
||||||
|
Product::where('metal_id', 3)->update([
|
||||||
'updated_at' => \Carbon\Carbon::now()->format('Y-m-d H:i:s'),
|
'updated_at' => \Carbon\Carbon::now()->format('Y-m-d H:i:s'),
|
||||||
]);
|
]);
|
||||||
if (
|
if (
|
||||||
@@ -194,7 +225,11 @@ class ProductController extends SuperController
|
|||||||
&& $mainProductId
|
&& $mainProductId
|
||||||
&& Product::where('id', $mainProductId)->where('metal_id', 3)->exists()
|
&& 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
@@ -9,12 +9,49 @@ use Rooyesh\Wallet\models\Transaction;
|
|||||||
use Rooyesh\Wallet\models\Wallet;
|
use Rooyesh\Wallet\models\Wallet;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
|
||||||
class Product extends Model
|
class Product extends Model
|
||||||
{
|
{
|
||||||
use HasFactory,Selector,SoftDeletes;
|
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 = [
|
protected $fillable = [
|
||||||
'title', // The title of the record.
|
'title', // The title of the record.
|
||||||
'price', // The amount 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
|
'cash_fee_sell', // Add cash_fee_sell to fillable
|
||||||
'percent_fee_buy', // Add percent_fee_buy to fillable
|
'percent_fee_buy', // Add percent_fee_buy to fillable
|
||||||
'metal_id', //the material of metal (#gold or #silver)
|
'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 = [
|
protected $casts = [
|
||||||
@@ -54,6 +94,8 @@ class Product extends Model
|
|||||||
'percent_fee_buy' => 'float', // Cast to float.
|
'percent_fee_buy' => 'float', // Cast to float.
|
||||||
'cash_fee_buy' => 'int', // Cast to int or decimal if needed
|
'cash_fee_buy' => 'int', // Cast to int or decimal if needed
|
||||||
'cash_fee_sell' => '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 = [
|
static $METAL_ID = [
|
||||||
|
|||||||
@@ -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
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
|
use App\Services\ProductPriceService;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
@@ -33,19 +34,20 @@ Route::get('/refPricer', function () {
|
|||||||
if ($RPrice['name'] == 'گلد دات ای از آبشده - رسمی - نقد فردا') {
|
if ($RPrice['name'] == 'گلد دات ای از آبشده - رسمی - نقد فردا') {
|
||||||
$RPrice['price'] = $RPrice['price'] / 4.3318;
|
$RPrice['price'] = $RPrice['price'] / 4.3318;
|
||||||
}
|
}
|
||||||
$p = Product::where('id', $product->id)->update([
|
ProductPriceService::syncFromReference(
|
||||||
'price' => $RPrice['price'],
|
$product,
|
||||||
'price_profit' => $RPrice['profit'],
|
(int) $RPrice['price'],
|
||||||
]);
|
(int) ($RPrice['profit'] ?? 0)
|
||||||
|
);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($copper) && isset($dollar)) {
|
if (isset($copper) && isset($dollar)) {
|
||||||
$cp = ($copper / 1000000) * $dollar;
|
$cp = ($copper / 1000000) * $dollar;
|
||||||
$p = Product::where('id', 33)->update([
|
$copperProduct = Product::find(33);
|
||||||
'price' => $cp,
|
if ($copperProduct) {
|
||||||
'price_profit' => 0,
|
ProductPriceService::syncFromReference($copperProduct, (int) round($cp), 0);
|
||||||
]);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json(true);
|
return response()->json(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user