mirror of
https://github.com/Bigherollc/wticreatorstudio.git
synced 2026-10-01 09:13:19 -04:00
215 lines
7.6 KiB
PHP
215 lines
7.6 KiB
PHP
<?php
|
|
|
|
namespace Modules\StaffPayroll\Services;
|
|
|
|
use App\Models\User;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Modules\StaffPayroll\Entities\Invoice;
|
|
use Modules\StaffPayroll\Entities\InvoiceSetting;
|
|
use Modules\StaffPayroll\Transformers\InvoiceResource;
|
|
use Modules\StudioPlus\Entities\StudioPlusVideo;
|
|
use Modules\StudioPlusWtiiabaddon\Entities\StudioPlusIncentive;
|
|
|
|
class InvoiceService
|
|
{
|
|
public function getInvoiceAmount(Invoice $invoice): float
|
|
{
|
|
$amount = 0;
|
|
$items = $invoice->items;
|
|
|
|
foreach ($items as $item) {
|
|
$amount += $item->quantity * $item->amount;
|
|
}
|
|
|
|
return $amount;
|
|
}
|
|
|
|
public function getUserInvoiceOfMonth(User $user): Invoice
|
|
{
|
|
$latestInvoice = Invoice::query()
|
|
->where('user_id', $user->id)
|
|
->latest()
|
|
->first();
|
|
|
|
if (!$latestInvoice) {
|
|
$invoiceSetting = InvoiceSetting::query()
|
|
->where('name', 'start_invoice_number')
|
|
->first()
|
|
->value ?? 1;
|
|
}
|
|
|
|
$latestInvoiceNumber = $latestInvoice
|
|
? $latestInvoice->invoice_number
|
|
: $invoiceSetting;
|
|
|
|
return Invoice::query()
|
|
->whereBetween(DB::raw('created_at'), [now()->startOfMonth()->toDateString(), now()->lastOfMonth()->toDateString()])
|
|
->firstOrCreate(
|
|
[
|
|
'user_id' => $user->id,
|
|
],
|
|
[
|
|
'invoice_number' => $latestInvoiceNumber,
|
|
'issue_date' => now()->toDateString(),
|
|
'created_by' => Auth::check() ? auth()->id() : null,
|
|
]
|
|
);
|
|
}
|
|
|
|
public function reprocess($invoice, $apply = false)
|
|
{
|
|
$user = $invoice->user;
|
|
$downlines = $user->downlines;
|
|
//$start_date = $invoice->created_at->firstOfMonth();
|
|
//$end_date = $invoice->created_at->lastOfMonth();
|
|
$start_date = Carbon::parse("{$invoice->issue_date}")->firstOfMonth()->startOfDay();
|
|
$end_date = Carbon::parse("{$invoice->issue_date}")->lastOfMonth()->endOfDay();
|
|
$video_upload_count = 0;
|
|
|
|
/*$videos = StudioPlusVideo::whereHas('channel.user', function($query) use($user) {
|
|
$query->where('id', $user->id);
|
|
})
|
|
->whereBetween('created_at', [$start_date, $end_date])
|
|
->where('status', StudioPlusVideo::STATUS_PUBLISHED_TO_AMAZON)
|
|
->get();*/
|
|
|
|
$videos = $user->getPublishedVideos($start_date, $end_date);
|
|
$invoice->reprocessedItems()->delete();
|
|
|
|
// Add 10/25/50 incentive bonus
|
|
$bonus10_incentive = StudioPlusIncentive::where('code', 'bonus-10')->first();
|
|
$bonus25_incentive = StudioPlusIncentive::where('code', 'bonus-25')->first();
|
|
$bonus50_incentive = StudioPlusIncentive::where('code', 'bonus-50')->first();
|
|
|
|
$video_upload_count_b10 = 0;
|
|
$video_upload_count_b25 = 0;
|
|
$video_upload_count_b50 = 0;
|
|
|
|
foreach ($videos as $video) {
|
|
$video_upload_count++;
|
|
$invoice->addVideoUploadPayout($video, 'reprocessed');
|
|
|
|
if ($this->isIncentiveApplicable($bonus10_incentive, $video) && ($video->videoType->vertical_video || $video->asinData->payout_amount > 0)) {
|
|
$video_upload_count_b10++;
|
|
}
|
|
|
|
if ($this->isIncentiveApplicable($bonus25_incentive, $video) && ($video->videoType->vertical_video || $video->asinData->payout_amount > 0)) {
|
|
$video_upload_count_b25++;
|
|
}
|
|
|
|
if ($this->isIncentiveApplicable($bonus50_incentive, $video) && ($video->videoType->vertical_video || $video->asinData->payout_amount > 0)) {
|
|
$video_upload_count_b50++;
|
|
}
|
|
}
|
|
|
|
if ($bonus10_incentive) {
|
|
if ($video_upload_count_b10 >= $bonus10_incentive->target_rule) {
|
|
$invoice->addIncentive($bonus10_incentive, 'reprocessed');
|
|
}
|
|
}
|
|
|
|
if ($bonus25_incentive) {
|
|
if ($video_upload_count_b25 >= $bonus25_incentive->target_rule) {
|
|
$invoice->addIncentive($bonus25_incentive, 'reprocessed');
|
|
}
|
|
}
|
|
|
|
if ($bonus50_incentive) {
|
|
if ($video_upload_count_b50 >= $bonus50_incentive->target_rule) {
|
|
$invoice->addIncentive($bonus50_incentive, 'reprocessed');
|
|
}
|
|
}
|
|
|
|
$downline_incentive = StudioPlusIncentive::with('roles')->where('code', 'vcm-downline-bonus')->first();
|
|
if ($downline_incentive && in_array($user->role_id, $downline_incentive->roles->pluck('id')->toArray())) {
|
|
foreach ($downlines as $downline) {
|
|
$videos = $downline->getPublishedVideos($start_date, $end_date);
|
|
|
|
foreach ($videos as $video) {
|
|
if ($this->isIncentiveApplicable($downline_incentive, $video)) {
|
|
$invoice->addIncentive($downline_incentive, 'reprocessed', [
|
|
'name' => 'Downline Incentives',
|
|
'description' => "Downline bonus ({$downline->first_name})",
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//add incentives manually added
|
|
foreach($invoice->items()->whereNull('type')->get() as $incentive){
|
|
$invoice->reprocessedItems()->firstOrCreate(
|
|
[
|
|
'description' => $incentive->description
|
|
],
|
|
[
|
|
'item_no' => $invoice->reprocessedItems()->count() + 1,
|
|
'name' => $incentive->name,
|
|
'amount' => $incentive->amount,
|
|
'quantity' => $incentive->quantity,
|
|
'issue_date' => $incentive->created_at->toDateString(),
|
|
'created_at' => $incentive->created_at
|
|
]
|
|
);
|
|
}
|
|
|
|
if ($apply) {
|
|
$invoice->applyReprocessedItems();
|
|
}
|
|
|
|
return response()->json([
|
|
'invoice' => InvoiceResource::make($invoice->load(['payout', 'user', 'items', 'reprocessedItems']))
|
|
]);
|
|
}
|
|
|
|
public function reprocessAllPending()
|
|
{
|
|
$invoices = Invoice::where('is_approved', false)->get();
|
|
|
|
foreach ($invoices as $invoice) {
|
|
$this->reprocess($invoice, true);
|
|
}
|
|
}
|
|
|
|
public function isUserIncentiveQualified($user, $incentive)
|
|
{
|
|
$role = $incentive->roles()->where('id', $user->role->id)->first();
|
|
|
|
if ($role) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function isIncentiveApplicable($incentive, $video)
|
|
{
|
|
if ($incentive) {
|
|
|
|
$video_types = $incentive->videoTypes()->pluck('studio_plus_video_type_id');
|
|
if ($video_types->count() > 0) {
|
|
return $video_types->contains($video->studio_plus_video_type_id);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected function toVideoVariants($variants)
|
|
{
|
|
return array_map(function($variant) {
|
|
if ($variant == 'based-on-a-job') {
|
|
return 'VIDEO BASED ON A JOB';
|
|
} else if ($variant == 'reach-out') {
|
|
return 'REACH OUT';
|
|
} else if ($variant == 'sponsored-product') {
|
|
return 'SPONSORED PRODUCT';
|
|
}
|
|
}, $variants);
|
|
}
|
|
}
|