197 lines
7.5 KiB
PHP
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
|
|
)
|
|
),
|
|
];
|
|
});
|
|
};
|
|
}
|
|
}
|