mirror of
https://github.com/Bigherollc/wticreatorstudio.git
synced 2026-08-03 06:16:14 -04:00
286 lines
9.4 KiB
PHP
286 lines
9.4 KiB
PHP
<?php
|
|
|
|
namespace Modules\StaffPayroll\Entities;
|
|
|
|
use Carbon\Carbon;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Modules\JobPortal\Entities\VendorPayout;
|
|
use Modules\StaffPayroll\Services\InvoiceService;
|
|
use Modules\StudioPlus\Traits\ScopeTrait;
|
|
use Modules\StudioPlus\Traits\ThisMonthTrait;
|
|
use Modules\StudioPlusWtiiabaddon\Entities\StudioPlusIncentive;
|
|
use Modules\StudioPlusWtiiabaddon\Entities\StudioPlusIncentiveCategory;
|
|
|
|
class Invoice extends Model
|
|
{
|
|
use HasFactory;
|
|
use ScopeTrait;
|
|
use ThisMonthTrait;
|
|
|
|
protected $fillable = [
|
|
'invoice_number',
|
|
'user_id',
|
|
'total_amount',
|
|
'issue_date',
|
|
'note',
|
|
'created_by',
|
|
'status',
|
|
'due_date',
|
|
'discount_type',
|
|
'discount',
|
|
'terms',
|
|
'is_approved'
|
|
];
|
|
|
|
protected $appends = [
|
|
'paid',
|
|
'stamp',
|
|
'month_stamp'
|
|
];
|
|
|
|
public const STATUS_UNPAID = 'UNPAID';
|
|
public const STATUS_PAID = 'PAID';
|
|
public const STATUS_PARTIALLY_PAID = 'PARTIALLY PAID';
|
|
public const STATUS_OVERDUE = 'OVERDUE';
|
|
|
|
public const DISCOUNT_TYPE_NONE = 'NONE';
|
|
public const DISCOUNT_TYPE_FIXED = 'FIXED';
|
|
public const DISCOUNT_TYPE_PERCENTAGE = 'PERCENTAGE';
|
|
|
|
public static function statuses()
|
|
{
|
|
return [
|
|
self::STATUS_UNPAID => 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());
|
|
}
|
|
}
|
|
}
|