You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
5.5 KiB
173 lines
5.5 KiB
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Throwable;
|
|
use Carbon\Carbon;
|
|
use App\Models\Business;
|
|
use Illuminate\Console\Command;
|
|
use Morilog\Jalali\CalendarUtils;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
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) {
|
|
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;
|
|
}
|
|
|
|
if (
|
|
jdate()->getYear() > jdate($business->calculated_at)->getYear()
|
|
&&
|
|
jdate()->getMonth() > jdate($business->calculated_at)->getMonth()
|
|
) {
|
|
$year = jdate()->getYear();
|
|
$month = jdate()->getMonth();
|
|
$day = 1;
|
|
}
|
|
|
|
$gDate = CalendarUtils::toGregorian($year, $month, $day);
|
|
$carbon = Carbon::createFromDate($gDate[0], $gDate[1], $gDate[2]);
|
|
$carbon->setTime($hour, $minute, $second);
|
|
|
|
$now = $carbon;
|
|
|
|
// if calculated_at less than an hour stop
|
|
if ($now->diffInMinutes($business->calculated_at)) {
|
|
$this->info('Must be one hour after the last audit.');
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
// Fixed amounts of expenses
|
|
$business->load('users', 'cost');
|
|
|
|
$costs = 0;
|
|
$costs += $this->calculateCostOfBusinessUsers($business, $now);
|
|
$costs += $this->calculateCostOfBusinessFiles($business, $now);
|
|
|
|
// increment and decrement of wallet in php
|
|
// deduct costs from your business wallet
|
|
// make sure save the calculated_at
|
|
$business->update([
|
|
'wallet' => $business->wallet - $costs,
|
|
'calculated_at' => Carbon::now(),
|
|
]);
|
|
|
|
DB::commit();
|
|
} catch (Throwable $throwable) {
|
|
DB::rollback();
|
|
report($throwable);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function calculateCostOfBusinessUsers($business, $until_now)
|
|
{
|
|
$user_fee = enum('business.fee.user');
|
|
$calculated_at = $business->calculated_at;
|
|
$recorded_month = jdate($business->calculated_at)->format("Y-m-01");
|
|
|
|
|
|
// get business employee
|
|
$users_cost = $business->cost
|
|
->where('type', '=', 'users')
|
|
->where('fee', '=', $user_fee)
|
|
->where('month', '=', $recorded_month)
|
|
->where('amount', '=', $business->users->count())
|
|
->first();
|
|
|
|
if ($users_cost === null) {
|
|
$business->cost()->create([
|
|
'type' => 'users',
|
|
'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
|
|
'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),
|
|
'additional' => $business->users->pluck('id')->toArray(),
|
|
]);
|
|
}
|
|
|
|
return $user_fee * $duration;
|
|
}
|
|
|
|
public function calculateCostOfBusinessFiles($business, $until_now)
|
|
{
|
|
$file_fee = enum('business.fee.file');
|
|
$calculated_at = $business->calculated_at;
|
|
$recorded_month = jdate($business->calculated_at)->format("Y-m-01");
|
|
|
|
|
|
// do the math in php
|
|
if (intdiv($business->files_volume, 200) === 0) {
|
|
$pads = 0;
|
|
} else {
|
|
$pads = intdiv($business->files_volume, 200) - 1;
|
|
}
|
|
|
|
|
|
$files = $business->cost
|
|
->where('type', '=', 'files')
|
|
->where('fee', '=', $file_fee)
|
|
->where('month', '=', $recorded_month)
|
|
->where('amount', '=', $business->files_volume)
|
|
->first();
|
|
|
|
if ($files === null) {
|
|
$business->cost()->create([
|
|
'type' => 'files',
|
|
'month' => $recorded_month,
|
|
'amount' => $pads,
|
|
'fee' => $file_fee,
|
|
'duration' => $duration = $until_now->diffInMinutes($calculated_at), // how to determine the file?,
|
|
]);
|
|
} 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),,
|
|
]);
|
|
}
|
|
|
|
return $file_fee * $duration;
|
|
}
|
|
}
|