2026-11-01 12:42:14 +03:30
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
|
|
2026-11-01 13:44:48 +03:30
|
|
|
|
use App\Http\Controllers\Controller;
|
2026-11-01 12:42:14 +03:30
|
|
|
|
use App\Http\Controllers\Single\SingleOrderController;
|
|
|
|
|
|
use App\Models\CopperConvertRequest;
|
|
|
|
|
|
use App\Models\Customer;
|
|
|
|
|
|
use App\Models\Product;
|
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
|
use Illuminate\Support\Collection;
|
|
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
|
|
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
|
|
|
|
|
|
|
|
|
|
|
class CopperConvertRequestService
|
|
|
|
|
|
{
|
|
|
|
|
|
public function submit(Customer $customer, string $source, int $rings15, int $rings25): CopperConvertRequest
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($rings15 < 1 && $rings25 < 1) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('حداقل یک حلقه انتخاب کنید.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$pending = CopperConvertRequest::query()
|
|
|
|
|
|
->where('customer_id', $customer->id)
|
|
|
|
|
|
->where('status', 'pending')
|
|
|
|
|
|
->exists();
|
|
|
|
|
|
if ($pending) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('یک درخواست تبدیل در انتظار تأیید دارید.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$quote = $this->quote($customer, $source, $rings15, $rings25);
|
|
|
|
|
|
|
2026-11-03 13:04:08 +03:30
|
|
|
|
return CopperConvertRequest::query()->create(
|
|
|
|
|
|
$this->quoteAttributes($customer, $source, $rings15, $rings25, $quote)
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function update(Customer $customer, int $id, string $source, int $rings15, int $rings25): CopperConvertRequest
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($rings15 < 1 && $rings25 < 1) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('حداقل یک حلقه انتخاب کنید.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return DB::transaction(function () use ($customer, $id, $source, $rings15, $rings25) {
|
|
|
|
|
|
$row = $this->ownedPending($customer, $id);
|
|
|
|
|
|
$quote = $this->quote($customer, $source, $rings15, $rings25);
|
|
|
|
|
|
$row->fill($this->quoteAttributes($customer, $source, $rings15, $rings25, $quote));
|
|
|
|
|
|
$row->save();
|
|
|
|
|
|
|
|
|
|
|
|
return $row;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function remove(Customer $customer, int $id): void
|
|
|
|
|
|
{
|
|
|
|
|
|
DB::transaction(function () use ($customer, $id) {
|
|
|
|
|
|
$this->ownedPending($customer, $id)->delete();
|
|
|
|
|
|
});
|
2026-11-01 12:42:14 +03:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function listForAdmin(): array
|
|
|
|
|
|
{
|
|
|
|
|
|
return CopperConvertRequest::query()
|
|
|
|
|
|
->with('customer:id,fname,lname,name,mobile')
|
|
|
|
|
|
->orderByDesc('id')
|
|
|
|
|
|
->limit(200)
|
|
|
|
|
|
->get()
|
|
|
|
|
|
->map(function (CopperConvertRequest $row) {
|
|
|
|
|
|
$customer = $row->customer;
|
|
|
|
|
|
$name = trim((string) ($customer->name ?? ''));
|
|
|
|
|
|
if ($name === '') {
|
|
|
|
|
|
$name = trim(((string) ($customer->fname ?? '')).' '.((string) ($customer->lname ?? '')));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
|
'id' => $row->id,
|
|
|
|
|
|
'status' => $row->status,
|
|
|
|
|
|
'source' => $row->source,
|
|
|
|
|
|
'customer_name' => $name !== '' ? $name : 'مشتری',
|
|
|
|
|
|
'customer_mobile' => $customer->mobile ?? '',
|
|
|
|
|
|
'asset_unit' => $row->asset_unit,
|
|
|
|
|
|
'consumed_amount' => $row->consumed_amount,
|
|
|
|
|
|
'leftover_amount' => $row->leftover_amount,
|
|
|
|
|
|
'source_unit_price' => $row->source_unit_price,
|
|
|
|
|
|
'wire15_rings' => $row->wire15_rings,
|
|
|
|
|
|
'wire15_unit_price' => $row->wire15_unit_price,
|
|
|
|
|
|
'wire25_rings' => $row->wire25_rings,
|
|
|
|
|
|
'wire25_unit_price' => $row->wire25_unit_price,
|
|
|
|
|
|
'created_at' => optional($row->created_at)->toDateTimeString(),
|
|
|
|
|
|
];
|
|
|
|
|
|
})
|
|
|
|
|
|
->all();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-03 13:04:08 +03:30
|
|
|
|
public function listForCustomer(Customer $customer): array
|
|
|
|
|
|
{
|
|
|
|
|
|
return CopperConvertRequest::query()
|
|
|
|
|
|
->where('customer_id', $customer->id)
|
|
|
|
|
|
->orderByDesc('id')
|
|
|
|
|
|
->limit(50)
|
|
|
|
|
|
->get()
|
|
|
|
|
|
->map(function (CopperConvertRequest $row) {
|
|
|
|
|
|
return [
|
|
|
|
|
|
'id' => $row->id,
|
|
|
|
|
|
'status' => $row->status,
|
|
|
|
|
|
'source' => $row->source,
|
|
|
|
|
|
'asset_unit' => $row->asset_unit,
|
|
|
|
|
|
'consumed_amount' => $row->consumed_amount,
|
|
|
|
|
|
'leftover_amount' => $row->leftover_amount,
|
|
|
|
|
|
'wire15_rings' => $row->wire15_rings,
|
|
|
|
|
|
'wire25_rings' => $row->wire25_rings,
|
|
|
|
|
|
'created_at' => optional($row->created_at)->toDateTimeString(),
|
|
|
|
|
|
];
|
|
|
|
|
|
})
|
|
|
|
|
|
->all();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-01 12:42:14 +03:30
|
|
|
|
public function approve(int $id, int $adminId): CopperConvertRequest
|
|
|
|
|
|
{
|
2026-11-01 13:44:48 +03:30
|
|
|
|
$row = DB::transaction(function () use ($id, $adminId) {
|
2026-11-01 12:42:14 +03:30
|
|
|
|
$row = CopperConvertRequest::query()->lockForUpdate()->findOrFail($id);
|
|
|
|
|
|
if ($row->status !== 'pending') {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('این درخواست قبلاً تعیینتکلیف شده است.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$customer = Customer::query()->findOrFail($row->customer_id);
|
|
|
|
|
|
$available = $this->availableQuantity($customer, (int) $row->source_product_id);
|
|
|
|
|
|
if ($available + 0.0001 < (float) $row->consumed_amount) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('موجودی مشتری برای این تبدیل کافی نیست.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$note = 'درخواست تبدیل #'.$row->id;
|
|
|
|
|
|
$sellId = $this->placeLeg($customer, (int) $row->source_product_id, 2, (float) $row->consumed_amount, (float) $row->source_unit_price, $note);
|
|
|
|
|
|
$buy15 = (int) $row->wire15_rings > 0
|
|
|
|
|
|
? $this->placeLeg($customer, (int) $row->wire15_product_id, 1, (float) $row->wire15_rings, (float) $row->wire15_unit_price, $note)
|
|
|
|
|
|
: null;
|
|
|
|
|
|
$buy25 = (int) $row->wire25_rings > 0
|
|
|
|
|
|
? $this->placeLeg($customer, (int) $row->wire25_product_id, 1, (float) $row->wire25_rings, (float) $row->wire25_unit_price, $note)
|
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
|
|
$row->status = 'approved';
|
|
|
|
|
|
$row->admin_id = $adminId;
|
|
|
|
|
|
$row->sell_order_id = $sellId;
|
|
|
|
|
|
$row->buy15_order_id = $buy15;
|
|
|
|
|
|
$row->buy25_order_id = $buy25;
|
|
|
|
|
|
$row->save();
|
|
|
|
|
|
|
|
|
|
|
|
return $row;
|
|
|
|
|
|
});
|
2026-11-01 13:44:48 +03:30
|
|
|
|
|
|
|
|
|
|
$this->notifyCustomer($row, true);
|
|
|
|
|
|
|
|
|
|
|
|
return $row;
|
2026-11-01 12:42:14 +03:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function reject(int $id, int $adminId): CopperConvertRequest
|
|
|
|
|
|
{
|
|
|
|
|
|
$row = CopperConvertRequest::query()->findOrFail($id);
|
|
|
|
|
|
if ($row->status !== 'pending') {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('این درخواست قبلاً تعیینتکلیف شده است.');
|
|
|
|
|
|
}
|
|
|
|
|
|
$row->status = 'rejected';
|
|
|
|
|
|
$row->admin_id = $adminId;
|
|
|
|
|
|
$row->save();
|
2026-11-01 13:44:48 +03:30
|
|
|
|
$this->notifyCustomer($row, false);
|
2026-11-01 12:42:14 +03:30
|
|
|
|
|
|
|
|
|
|
return $row;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-01 13:44:48 +03:30
|
|
|
|
private function notifyCustomer(CopperConvertRequest $row, bool $approved): void
|
|
|
|
|
|
{
|
|
|
|
|
|
try {
|
|
|
|
|
|
$customer = Customer::query()->find($row->customer_id);
|
|
|
|
|
|
$mobile = trim((string) ($customer?->mobile ?? ''));
|
|
|
|
|
|
if ($mobile === '') {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$company = trim((string) Controller::Config('name_fa'));
|
|
|
|
|
|
$source = $this->sourceLabel((string) $row->source);
|
|
|
|
|
|
$lines = [$company !== '' ? $company : 'درخواست تبدیل'];
|
|
|
|
|
|
if ($approved) {
|
|
|
|
|
|
$lines[] = 'درخواست تبدیل #'.$row->id.' تأیید شد.';
|
|
|
|
|
|
$lines[] = 'دارایی '.$source.' به مقدار '.$row->consumed_amount.' '.$row->asset_unit.' فروخته شد.';
|
|
|
|
|
|
if ((int) $row->wire15_rings > 0) {
|
|
|
|
|
|
$lines[] = 'حلقه ۱.۵: '.$row->wire15_rings;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ((int) $row->wire25_rings > 0) {
|
|
|
|
|
|
$lines[] = 'حلقه ۲.۵: '.$row->wire25_rings;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$lines[] = 'درخواست تبدیل #'.$row->id.' رد شد.';
|
|
|
|
|
|
$lines[] = 'دارایی '.$source.' شما بدون تغییر ماند.';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Controller::Send($mobile, implode("\n", $lines));
|
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
|
report($e);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-03 13:04:08 +03:30
|
|
|
|
private function ownedPending(Customer $customer, int $id): CopperConvertRequest
|
|
|
|
|
|
{
|
|
|
|
|
|
$row = CopperConvertRequest::query()
|
|
|
|
|
|
->where('customer_id', $customer->id)
|
|
|
|
|
|
->lockForUpdate()
|
|
|
|
|
|
->find($id);
|
|
|
|
|
|
if (!$row) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('درخواست تبدیل پیدا نشد.');
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($row->status !== 'pending') {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('فقط درخواست در انتظار تایید قابل تغییر است.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $row;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function quoteAttributes(Customer $customer, string $source, int $rings15, int $rings25, array $quote): array
|
|
|
|
|
|
{
|
|
|
|
|
|
return [
|
|
|
|
|
|
'customer_id' => $customer->id,
|
|
|
|
|
|
'status' => 'pending',
|
|
|
|
|
|
'source' => $source,
|
|
|
|
|
|
'source_product_id' => $quote['source']->id,
|
|
|
|
|
|
'asset_unit' => $quote['unit'],
|
|
|
|
|
|
'consumed_amount' => $quote['consumed'],
|
|
|
|
|
|
'leftover_amount' => $quote['leftover'],
|
|
|
|
|
|
'source_unit_price' => $quote['source_unit_price'],
|
|
|
|
|
|
'wire15_product_id' => $quote['wire15']?->id,
|
|
|
|
|
|
'wire15_rings' => $rings15,
|
|
|
|
|
|
'wire15_unit_price' => $quote['price15'],
|
|
|
|
|
|
'wire25_product_id' => $quote['wire25']?->id,
|
|
|
|
|
|
'wire25_rings' => $rings25,
|
|
|
|
|
|
'wire25_unit_price' => $quote['price25'],
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-01 13:44:48 +03:30
|
|
|
|
private function sourceLabel(string $source): string
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($source === 'katod') {
|
|
|
|
|
|
return 'کاتد';
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($source === 'maftoul') {
|
|
|
|
|
|
return 'مفتول';
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($source === 'shamsh') {
|
|
|
|
|
|
return 'شمش';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $source;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-11-01 12:42:14 +03:30
|
|
|
|
private function placeLeg(Customer $customer, int $productId, int $direction, float $number, float $unitPrice, string $note): int
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($productId < 1 || $number <= 0 || $unitPrice <= 0) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('اطلاعات سفارش تبدیل ناقص است.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auth('customer')->setUser($customer);
|
|
|
|
|
|
try {
|
|
|
|
|
|
$response = app(SingleOrderController::class)->store(Request::create('/admin/single/order', 'POST', [
|
|
|
|
|
|
'customer_id' => $customer->id,
|
|
|
|
|
|
'product_id' => $productId,
|
|
|
|
|
|
'direction' => $direction,
|
|
|
|
|
|
'number' => $number,
|
|
|
|
|
|
'method' => 'cash',
|
|
|
|
|
|
'price' => $unitPrice,
|
|
|
|
|
|
'difference' => 0,
|
|
|
|
|
|
'quote_unit_price' => $unitPrice,
|
|
|
|
|
|
'description' => $note,
|
|
|
|
|
|
]));
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
auth('customer')->forgetUser();
|
|
|
|
|
|
}
|
|
|
|
|
|
$body = $response->getData(true);
|
|
|
|
|
|
$orderId = (int) ($body[1]['order']['id'] ?? 0);
|
|
|
|
|
|
if ($orderId < 1) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('ثبت سفارش تبدیل انجام نشد.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $orderId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function quote(Customer $customer, string $source, int $rings15, int $rings25): array
|
|
|
|
|
|
{
|
|
|
|
|
|
$products = Product::query()->where('active', 1)->get();
|
|
|
|
|
|
$sourceProduct = $this->findSource($products, $source);
|
|
|
|
|
|
if (!$sourceProduct) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('محصول این دارایی پیدا نشد.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$wire15 = $rings15 > 0 ? $this->findWire($products, '1.5') : null;
|
|
|
|
|
|
$wire25 = $rings25 > 0 ? $this->findWire($products, '2.5') : null;
|
|
|
|
|
|
if ($rings15 > 0 && !$wire15) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('محصول سیم ۱.۵ پیدا نشد.');
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($rings25 > 0 && !$wire25) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('محصول سیم ۲.۵ پیدا نشد.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$prices = app(ProductDisplayPriceService::class);
|
|
|
|
|
|
$sourcePerKg = (float) $prices->resolveOrderTradePrice($sourceProduct, 1);
|
|
|
|
|
|
$price15 = $wire15 ? (int) round((float) $prices->resolveOrderTradePrice($wire15, 1)) : 0;
|
|
|
|
|
|
$price25 = $wire25 ? (int) round((float) $prices->resolveOrderTradePrice($wire25, 1)) : 0;
|
|
|
|
|
|
if ($sourcePerKg <= 0 || ($rings15 > 0 && $price15 <= 0) || ($rings25 > 0 && $price25 <= 0)) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('قیمت تبدیل در دسترس نیست.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$unit = trim((string) ($sourceProduct->unit ?: 'کیلوگرم'));
|
|
|
|
|
|
if ($unit === '') {
|
|
|
|
|
|
$unit = 'کیلوگرم';
|
|
|
|
|
|
}
|
|
|
|
|
|
$available = $this->availableQuantity($customer, (int) $sourceProduct->id);
|
|
|
|
|
|
$availableValue = $this->toKg($available, $unit, $sourceProduct) * $sourcePerKg;
|
|
|
|
|
|
$spent = ($rings15 * $price15) + ($rings25 * $price25);
|
|
|
|
|
|
if ($spent > $availableValue + 1) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('تعداد حلقه از ارزش دارایی بیشتر است.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$consumedKg = $spent / $sourcePerKg;
|
|
|
|
|
|
$consumed = round($this->fromKg($consumedKg, $unit, $sourceProduct), 4);
|
|
|
|
|
|
if ($consumed <= 0) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('مقدار قابل تبدیل صفر است.');
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($consumed > $available + 0.0001) {
|
|
|
|
|
|
throw new UnprocessableEntityHttpException('موجودی این دارایی کافی نیست.');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$leftover = round(max(0, $available - $consumed), 4);
|
|
|
|
|
|
$sourceUnitPrice = (int) ceil($spent / $consumed);
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
|
'source' => $sourceProduct,
|
|
|
|
|
|
'wire15' => $wire15,
|
|
|
|
|
|
'wire25' => $wire25,
|
|
|
|
|
|
'unit' => $unit,
|
|
|
|
|
|
'consumed' => $consumed,
|
|
|
|
|
|
'leftover' => $leftover,
|
|
|
|
|
|
'source_unit_price' => max(1, $sourceUnitPrice),
|
|
|
|
|
|
'price15' => (int) round($price15),
|
|
|
|
|
|
'price25' => (int) round($price25),
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function availableQuantity(Customer $customer, int $productId): float
|
|
|
|
|
|
{
|
|
|
|
|
|
return (float) app(AssetSummaryService::class)->productDisplayQuantity(
|
|
|
|
|
|
(int) $customer->id,
|
|
|
|
|
|
(int) ($customer->type ?? 2),
|
|
|
|
|
|
$productId
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function findSource(Collection $products, string $source): ?Product
|
|
|
|
|
|
{
|
|
|
|
|
|
return $products->first(function (Product $product) use ($source) {
|
|
|
|
|
|
$group = trim((string) $product->group_type);
|
|
|
|
|
|
$title = (string) $product->title;
|
|
|
|
|
|
if ($source === 'katod') {
|
|
|
|
|
|
return $group === 'کاتد مس' || str_contains($title, 'کاتد');
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($source === 'maftoul') {
|
|
|
|
|
|
return $group === 'مفتول مس' || str_contains($title, 'مفتول');
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($source === 'shamsh') {
|
|
|
|
|
|
return str_contains($group, 'شمش') || str_contains($title, 'شمش');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function findWire(Collection $products, string $section): ?Product
|
|
|
|
|
|
{
|
|
|
|
|
|
return $products->first(function (Product $product) use ($section) {
|
|
|
|
|
|
$title = (string) $product->title;
|
|
|
|
|
|
$pattern = $section === '1.5' ? '/1\.5|۱\.۵/u' : '/2\.5|۲\.۵/u';
|
|
|
|
|
|
|
|
|
|
|
|
return preg_match($pattern, $title) === 1;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function toKg(float $quantity, string $unit, Product $product): float
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($quantity <= 0) {
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (str_contains($unit, 'کیلو')) {
|
|
|
|
|
|
return $quantity;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (str_contains($unit, 'گرم')) {
|
|
|
|
|
|
return $quantity / 1000;
|
|
|
|
|
|
}
|
|
|
|
|
|
$perPiece = (float) ($product->amount ?? 0);
|
|
|
|
|
|
if ($perPiece <= 0) {
|
|
|
|
|
|
return $quantity;
|
|
|
|
|
|
}
|
|
|
|
|
|
$pieceUnit = trim((string) $product->unit);
|
|
|
|
|
|
$grams = str_contains($pieceUnit, 'کیلو') ? $perPiece * 1000 : $perPiece;
|
|
|
|
|
|
|
|
|
|
|
|
return ($quantity * $grams) / 1000;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function fromKg(float $kg, string $unit, Product $product): float
|
|
|
|
|
|
{
|
|
|
|
|
|
if ($kg <= 0) {
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (str_contains($unit, 'کیلو')) {
|
|
|
|
|
|
return $kg;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (str_contains($unit, 'گرم')) {
|
|
|
|
|
|
return $kg * 1000;
|
|
|
|
|
|
}
|
|
|
|
|
|
$perPiece = (float) ($product->amount ?? 0);
|
|
|
|
|
|
if ($perPiece <= 0) {
|
|
|
|
|
|
return $kg;
|
|
|
|
|
|
}
|
|
|
|
|
|
$pieceUnit = trim((string) $product->unit);
|
|
|
|
|
|
$grams = str_contains($pieceUnit, 'کیلو') ? $perPiece * 1000 : $perPiece;
|
|
|
|
|
|
if ($grams <= 0) {
|
|
|
|
|
|
return $kg;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ($kg * 1000) / $grams;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|