diff --git a/app/Console/Commands/CostCommand.php b/app/Console/Commands/CostCommand.php index 9845050..1e05de4 100644 --- a/app/Console/Commands/CostCommand.php +++ b/app/Console/Commands/CostCommand.php @@ -4,78 +4,60 @@ namespace App\Console\Commands; use Throwable; use Carbon\Carbon; +use App\Models\Cost; use App\Models\Business; use Illuminate\Console\Command; use Morilog\Jalali\CalendarUtils; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Storage; class CostCommand extends Command { - public const USER_FEE = 400; - - public const FILE_FEE = [ - 200 => 0, - 400 => 1000, - 800 => 2000, - ]; - protected $signature = 'cost:work'; protected $description = 'Run the cost worker'; - public function __construct() - { - parent::__construct(); - } - public function handle() { while (true) { - $business = Business::find(221); - if ($business === null) { + $lock = Cache::get('lock', false); + if ($lock) { + $this->info('There is no business for auditing.'); continue; } - $year = jdate()->getYear(); - $month = jdate()->getMonth(); - $day = jdate()->getDay(); - $hour = jdate()->getHour(); - $minute = jdate()->getMinute(); - $second = jdate()->getSecond(); - - if (jdate()->getYear() > jdate($business->calculated_at)->getYear()) { - $year = jdate()->getYear(); - $month = 1; - $day = 1; + $business = Business::orderBy('calculated_at')->first(); + if ($business === null) { + continue; } - if ( - jdate()->getYear() > jdate($business->calculated_at)->getYear() - && - jdate()->getMonth() > jdate($business->calculated_at)->getMonth() - ) { - $year = jdate()->getYear(); - $month = jdate()->getMonth(); - $day = 1; + if ($business->calculated_at->isFuture()) { + continue; } - $gDate = CalendarUtils::toGregorian($year, $month, $day); - $carbon = Carbon::createFromDate($gDate[0], $gDate[1], $gDate[2]); - $carbon->setTime($hour, $minute, $second); + $next_month = jdate($business->calculated_at)->addMonths(); + [$year, $month, $day] = CalendarUtils::toGregorian( + $next_month->getYear(), $next_month->getMonth(), 1 + ); + $now = Carbon::createFromDate($year, $month, $day); + $now->setTime(0, 0, 0); - $now = $carbon; + if ($now->isFuture()) { + $now = Carbon::now(); + } // if calculated_at less than an hour stop - if ($now->diffInMinutes($business->calculated_at)) { + if ($now->diffInMinutes($business->calculated_at) <= 59) { $this->info('Must be one hour after the last audit.'); + Cache::put('lock', true, $now->diffInSeconds($business->calculated_at)); continue; } try { DB::beginTransaction(); // Fixed amounts of expenses - $business->load('users', 'cost'); + $business->load('users', 'files'); $costs = 0; $costs += $this->calculateCostOfBusinessUsers($business, $now); @@ -86,11 +68,13 @@ class CostCommand extends Command // make sure save the calculated_at $business->update([ 'wallet' => $business->wallet - $costs, - 'calculated_at' => Carbon::now(), + 'calculated_at' => $now, ]); DB::commit(); + $this->info("The business #{$business->id} was audited."); } catch (Throwable $throwable) { + throw $throwable; DB::rollback(); report($throwable); continue; @@ -98,16 +82,18 @@ class CostCommand extends Command } } - public function calculateCostOfBusinessUsers($business, $until_now) + public function calculateCostOfBusinessUsers($business, $now) { $user_fee = enum('business.fee.user'); - $calculated_at = $business->calculated_at; $recorded_month = jdate($business->calculated_at)->format("Y-m-01"); + if ($business->users->isEmpty()) { + return 0; + } // get business employee $users_cost = $business->cost - ->where('type', '=', 'users') + ->where('type', '=', Cost::USER_TYPE) ->where('fee', '=', $user_fee) ->where('month', '=', $recorded_month) ->where('amount', '=', $business->users->count()) @@ -115,16 +101,16 @@ class CostCommand extends Command if ($users_cost === null) { $business->cost()->create([ - 'type' => 'users', + 'type' => Cost::USER_TYPE, 'month' => $recorded_month, 'amount' => $business->users->count(), 'fee' => $user_fee, - 'duration' => $duration = $until_now->diffInSeconds($calculated_at), // from the created_at time of the newset fifth user + 'duration' => $duration = $now->diffInMinutes($business->calculated_at), // from the created_at time of the newset fifth user 'additional' => $business->users->pluck('id')->toArray(), ]); } else { $users_cost->update([ - 'duration' => $duration = $until_now->diffInMinutes($calculated_at) + $users_cost->duration, // last calc - (current month - now else last calc - end of the past month), + 'duration' => $duration = $now->diffInMinutes($business->calculated_at) + $users_cost->duration, // last calc - (current month - now else last calc - end of the past month), 'additional' => $business->users->pluck('id')->toArray(), ]); } @@ -132,7 +118,7 @@ class CostCommand extends Command return $user_fee * $duration; } - public function calculateCostOfBusinessFiles($business, $until_now) + public function calculateCostOfBusinessFiles($business, $now) { $file_fee = enum('business.fee.file'); $calculated_at = $business->calculated_at; @@ -140,31 +126,33 @@ class CostCommand extends Command // do the math in php - if (intdiv($business->files_volume, 200) === 0) { - $pads = 0; + $packs = intdiv($business->files_volume, 200); + if ($packs === 0) { + return 0; } else { - $pads = intdiv($business->files_volume, 200) - 1; + $packs--; } - $files = $business->cost - ->where('type', '=', 'files') + ->where('type', '=', Cost::FILE_TYPE) ->where('fee', '=', $file_fee) ->where('month', '=', $recorded_month) - ->where('amount', '=', $business->files_volume) + ->where('amount', '=', $packs) ->first(); if ($files === null) { $business->cost()->create([ - 'type' => 'files', + 'type' => Cost::FILE_TYPE, 'month' => $recorded_month, - 'amount' => $pads, + 'amount' => $packs, 'fee' => $file_fee, - 'duration' => $duration = $until_now->diffInMinutes($calculated_at), // how to determine the file?, + 'duration' => $duration = $now->diffInMinutes($calculated_at), // how to determine the file?, + 'additional' => ['volume' => $business->files_volume], ]); } else { $files->update([ - 'duration' => $duration = $until_now->diffInMinutes($calculated_at) + $files->duration, // last calc - (current month - now else last calc - end of the past month),, + 'duration' => $duration = $now->diffInMinutes($calculated_at) + $files->duration, // last calc - (current month - now else last calc - end of the past month),, + 'additional' => ['volume' => $business->files_volume], ]); } diff --git a/app/Http/Controllers/FileController.php b/app/Http/Controllers/FileController.php index a132732..23b30ca 100644 --- a/app/Http/Controllers/FileController.php +++ b/app/Http/Controllers/FileController.php @@ -9,8 +9,8 @@ use App\Models\Business; use Illuminate\Support\Str; use Illuminate\Http\Request; use Illuminate\Http\UploadedFile; +use App\Http\Resources\FileResource; use Illuminate\Support\Facades\Auth; -use App\HiLib\Resources\FileResource; use Spatie\QueryBuilder\QueryBuilder; use Spatie\QueryBuilder\AllowedFilter; use Illuminate\Support\Facades\Storage; @@ -127,6 +127,10 @@ class FileController extends Controller 'description' => $request->description ]); + $business->update([ + 'files_volume' => $business->files_volume + $file_record->size + ]); + return new FileResource($file_record); } diff --git a/app/Http/Resources/FileResource.php b/app/Http/Resources/FileResource.php index 3b74fb0..bc99db1 100644 --- a/app/Http/Resources/FileResource.php +++ b/app/Http/Resources/FileResource.php @@ -1,9 +1,7 @@ 'boolean', + 'calculated_at' => 'datetime', ]; public function getValueOf(?string $key) diff --git a/app/Models/Cost.php b/app/Models/Cost.php index fa06239..98b2e63 100644 --- a/app/Models/Cost.php +++ b/app/Models/Cost.php @@ -6,6 +6,10 @@ use App\Models\Model; class Cost extends Model { + public const USER_TYPE = 'users'; + + public const FILE_TYPE = 'files'; + public $perPage = 12; protected $fillable = [ diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index c02d1b6..69ff803 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -40,7 +40,7 @@ class AuthServiceProvider extends ServiceProvider 'token' => $request->bearerToken(), 'agent' => $request->getAgent(), 'os' => $request->getOS(), - ])->first(); + ])->firstOrFail(); return $fingerprint->user->setAttribute('token', $fingerprint->token); }); diff --git a/composer.json b/composer.json index a8d0129..6c87a76 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,8 @@ "jenssegers/agent": "^2.6", "laravel/socialite": "^5.1", "laravel/framework": "^8.12", + "laravel/legacy-factories": "^1", + "fruitcake/laravel-cors": "^2.0", "league/flysystem-aws-s3-v3": "~1.0", "spatie/laravel-medialibrary": "^9.0", "spatie/laravel-query-builder": "^3.3",