self::STATUS_UNPAID, self::STATUS_PAID => self::STATUS_PAID, self::STATUS_PARTIALLY_PAID => self::STATUS_PARTIALLY_PAID, self::STATUS_OVERDUE => self::STATUS_OVERDUE, ]; } public static function discountTypes() { return [ self::DISCOUNT_TYPE_NONE => self::DISCOUNT_TYPE_NONE, self::DISCOUNT_TYPE_FIXED => self::DISCOUNT_TYPE_FIXED, self::DISCOUNT_TYPE_PERCENTAGE => self::DISCOUNT_TYPE_PERCENTAGE, ]; } public function items() { return $this->hasMany(InvoiceItem::class)->orderBy('description'); } public function payout() { return $this->hasOne(VendorPayout::class); } public function user() { return $this->belongsTo(StaffPayrollUser::class); } public function getPaidAttribute() { if($this->status = self::STATUS_PAID){ return true; } else { return false; } } public function getStampAttribute() { if ($this->created_at) { return $this->created_at->format('F j, Y g:i A'); } return $this->created_at; } public function getMonthStampAttribute() { /*if ($this->created_at) { return $this->created_at->format('M Y'); }*/ if ($this->issue_date) { return Carbon::parse($this->issue_date)->format('M Y'); } return null; } public function reprocessedItems() { return $this->hasMany(InvoiceReprocessedItem::class, 'invoice_id', 'id')->orderBy('description'); } public function addVideoUploadPayout($video, $mode = 'official') { if ($mode == 'reprocessed') { $item_no = $this->reprocessedItems()->count() + 1; } else { $item_no = $this->items()->count() + 1; } $video->load('asinData','channel.user'); $applied = false; $apply_default_incentive = true; $invoice_service = new InvoiceService(); if($video->videoType->vertical_video){ $incentives = StudioPlusIncentive::whereHas('videoTypes', function ($query) use($video) { $query->where('studio_plus_video_type_id', $video->studio_plus_video_type_id); })->doesntHave('asins')->whereHas('roles', function ($query) use($video) { $query->where('role_id', $video->channel->user->role_id); })->where('target_rule',1)->get(); } else { $incentives = StudioPlusIncentive::whereHas('videoTypes', function ($query) use($video) { $query->where('studio_plus_video_type_id', $video->studio_plus_video_type_id); })->whereHas('asins', function ($query) use($video) { $query->where('studio_plus_asin_id', $video->studio_plus_asin_id); })->whereHas('roles', function ($query) use($video) { $query->where('role_id', $video->channel->user->role_id); })->where('target_rule',1)->where('incentive_category_id','!=',5)->get(); } if (count($incentives) > 0) { $apply_default_incentive = false; } foreach ($incentives as $incentive) { // if ($invoice_service->isIncentiveApplicable($incentive, $video)) { $published_track = $video->tracks()->where('name','Published')->first(); $data = [ 'studio_plus_video_id' => $video->id, 'item_no' => $item_no, 'name' => 'Video upload payout', 'description' => $video->videoType->need_asin ? "ASIN {$video->asin} ({$incentive->description})" : $incentive->description, 'amount' => $incentive->amount_value_earned, 'quantity' => 1, 'issue_date' => $published_track ? $published_track->created_at->toDateString() : $video->created_at->toDateString(), 'type' => InvoiceItem::TYPE_VIDEO_UPLOAD_PAYOUT, 'range_amount' => $video->asinData != null ? $video->asinData->range_amount : null, 'created_at' => $published_track ? $published_track->created_at : $video->created_at ]; if ($mode == 'reprocessed') { $this->reprocessedItems()->create($data); } else { $this->items()->create($data); } $applied = true; // } } if ($apply_default_incentive || !$applied) { $amount = 0; if($video->videoType->need_job_request == 1){ //based on a job incentive $incentive = StudioPlusIncentive::where('incentive_category_id', 15)->where('target_rule',1)->first(); if($incentive){ $amount = $incentive->amount_value_earned; } } elseif(!$video->videoType->vertical_video) { $amount = $video->asinData->payout_amount; } $data = [ 'studio_plus_video_id' => $video->id, 'item_no' => $item_no, 'name' => 'Video upload payout', 'description' => "ASIN {$video->asin}", 'amount' => $amount, 'quantity' => 1, 'issue_date' => $video->created_at->toDateString(), 'type' => InvoiceItem::TYPE_VIDEO_UPLOAD_PAYOUT, 'range_amount' => $video->asinData->range_amount, 'created_at' => $video->created_at ]; if ($mode == 'reprocessed') { $this->reprocessedItems()->create($data); } else { $this->items()->create($data); } } // Add incentive for video with over 5k ratings $rating_bonus = StudioPlusIncentive::where('code', 'asin-ratings')->first(); if ($rating_bonus) { if ($invoice_service->isIncentiveApplicable($rating_bonus, $video)) { if ($video->amazon_total_reviews > $rating_bonus->target_rule) { $data['item_no'] = ++$item_no; $data['studio_plus_video_id'] = $video->id; $data['name'] = 'Rating Incentive Bonus'; $data['description'] = $rating_bonus->description; $data['amount'] = $rating_bonus->amount_value_earned; $data['type'] = 'INCENTIVE BONUS'; $data['studio_plus_incentive_id'] = $rating_bonus->id; if ($mode == 'reprocessed') { $this->reprocessedItems()->create($data); } else { $this->items()->create($data); } } } } } public function addIncentive($incentive, $mode = 'official', $params = null) { if ($mode == 'reprocessed') { $item_no = $this->reprocessedItems()->count() + 1; } else { $item_no = $this->items()->count() + 1; } $data = [ 'item_no' => $item_no, 'name' => $incentive->title, 'description' => $incentive->description, 'amount' => $incentive->amount_value_earned, 'quantity' => 1, 'issue_date' => $this->created_at->toDateString(), 'type' => 'INCENTIVE BONUS', 'created_at' => $this->created_at, 'studio_plus_incentive_id' => $incentive->id ]; if (is_array($params)) { $data = array_merge($data, $params); } if ($mode == 'reprocessed') { $this->reprocessedItems()->create($data); } else { $this->items()->create($data); } } public function applyReprocessedItems() { $reprocessed_items = $this->reprocessedItems; $this->items()->delete(); foreach ($reprocessed_items as $item) { $this->items()->create($item->toArray()); } } }