Files
postshop-backend/app/Nova/Repos/Payouts/PayoutsRepo.php
2026-02-03 15:31:29 +05:00

197 lines
7.5 KiB
PHP

<?php
namespace App\Nova\Repos\Payouts;
use App\Models\Ecommerce\Product\Order\OrderItem;
use App\Models\Ecommerce\Product\Order\Status\OrderStatus;
use Closure;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Laravel\Nova\Http\Requests\NovaRequest;
class PayoutsRepo
{
/**
* Order items ids element "depends on"
*/
public static function orderItemIdsDependsOn(): Closure
{
return function ($field, $request, $formData) {
if (
! $formData->channel_id ||
! $formData->start_date ||
! $formData->end_date ||
$request->isUpdateOrUpdateAttachedRequest()
) {
return;
}
$paid_products = DB::table('payout_items')
->where('channel_id', $formData->channel_id)
->distinct('order_item_id')
->pluck('order_item_id');
$order_items = OrderItem::query()
->with(['product' => ['media']])
->join(
table: 'orders',
first: fn ($join) => $join->on('order_items.order_id', '=', 'orders.id')
->where('orders.status', '=', OrderStatus::COMPLETED)
)
->where('order_items.channel_id', $formData->channel_id)
->whereIntegerNotInRaw('order_items.id', $paid_products)
->whereRaw('(order_items.created_at >= ? AND order_items.created_at <= ?)', [
$formData->start_date.' 00:00:00',
$formData->end_date.' 23:59:59',
])
->orderBy('order_items.order_id')
->get([
'order_items.id',
'order_items.order_id',
'order_items.product_name',
'order_items.product_id',
'order_items.quantity',
'order_items.unit_price_amount',
'order_items.unit_cost_amount',
'order_items.channel_id',
'order_items.created_at',
])->map(fn ($orderItem) => [
'id' => $orderItem->id,
'product_name' => $orderItem->product_name,
'product_id' => $orderItem->product_id,
'order_id' => $orderItem->order_id,
'channel_id' => $orderItem->channel_id,
'quantity' => $orderItem->quantity,
'unit_price_amount' => $orderItem->unit_price_amount,
'product_cost_amount' => $orderItem->unit_cost_amount ?: $orderItem->product->cost_amount,
'created_at' => $orderItem->created_at,
'updated_at' => $orderItem->updated_at,
'product_thumbnail' => $orderItem->product->thumbnail() ?? null,
]);
$field->products($order_items);
};
}
/**
* Total element "depends on"
*/
public static function totalDependsOn(): Closure
{
return function ($field, $request, $formData) {
if (! $formData->order_items_ids || ! $request->prices) {
return;
}
$orderItems = OrderItem::whereIntegerInRaw('id', $formData->order_items_ids)->get();
$products = collect($request->prices)
->map(fn ($product) => is_string($product) ? json_decode($product) : null)
->filter();
$total_sum = 0;
$entrepreneur_total = 0;
$postshop_total = 0;
foreach ($orderItems as $item) {
$percentage_difference =
$item->unit_price_amount - $products->firstWhere('product_id', $item->product_id)->cost_amount;
$total_sum += $item->unit_price_amount * $item->quantity;
$postshop_total += $percentage_difference * $item->quantity;
$entrepreneur_total += $products->firstWhere('product_id', $item->product_id)->cost_amount * $item->quantity;
}
$field->setValue(number_format($total_sum, 2, '.', ''));
cache(['nova.entrepreneur_total' => number_format($entrepreneur_total, 2, '.', '')]);
cache(['nova.postshop_total' => number_format($postshop_total, 2, '.', '')]);
};
}
/**
* Order item ids fill
*/
public static function orderItemIdsFill(NovaRequest $request, Model $model): void
{
$model::withoutEvents(function () use ($request, $model) {
$order_item_ids = [];
$products = collect($request->prices)
->map(fn ($product) => is_string($product) ? json_decode($product) : null)
->filter()
->each(function ($product) {
DB::table('order_items')
->where('id', $product->order_item_id)
->update(['unit_cost_amount' => $product->cost_amount]);
});
if ($request->filled('order_items_ids')) {
foreach ($request->order_items_ids as $id) {
if (! $id) {
continue;
}
$order_item_ids[] = [
'payout_id' => $model->id,
'channel_id' => $model->channel_id,
'order_item_id' => $id,
'created_at' => $model->created_at,
'updated_at' => now(),
];
}
}
if (! empty($order_item_ids)) {
DB::table('payout_items')->insert($order_item_ids);
}
});
}
/**
* Resolve order items
*/
public static function resolveOrderItems($request, $resource): Closure
{
return function () use ($request, $resource) {
if (! $request->isResourceDetailRequest()) {
return;
}
$items = $resource->orderItems;
$media = DB::table('media')
->where('model_type', 'product')
->whereIntegerInRaw('model_id', $items->pluck('product_id'))
->get(['id', 'model_id', 'file_name']);
return $items->map(function ($orderItem) use ($media) {
return [
'id' => $orderItem->id,
'product_name' => $orderItem->product_name,
'product_id' => $orderItem->product_id,
'order_id' => $orderItem->order_id,
'channel_id' => $orderItem->channel_id,
'quantity' => $orderItem->quantity,
'unit_price_amount' => $orderItem->unit_price_amount,
'unit_cost_amount' => $orderItem->unit_cost_amount,
'created_at' => $orderItem->created_at,
'updated_at' => $orderItem->updated_at,
'product_thumbnail' => url(
sprintf(
'storage/%s/%s',
$media->firstWhere(
'model_id',
$orderItem->product_id
)?->id,
$media->firstWhere(
'model_id',
$orderItem->product_id
)?->file_name
)
),
];
});
};
}
}