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); } }