Browse Source

solve conflict with mohammad

remotes/origin/mohammad
mahdihty 4 years ago
parent
commit
26e5ac5d1b
  1. 217
      app/Console/Commands/CostCommand.php
  2. 1
      app/Http/Controllers/AuthController.php
  3. 10
      app/Http/Controllers/FileController.php
  4. 10
      app/Http/Controllers/ProjectController.php
  5. 5
      app/Http/Controllers/TaskFileController.php
  6. 2
      app/Http/Resources/FileResource.php
  7. 1
      app/Models/Business.php
  8. 4
      app/Models/Cost.php
  9. 4
      app/Models/Model.php
  10. 2
      app/Providers/AuthServiceProvider.php
  11. 3
      composer.json
  12. 5
      config/app.php
  13. 2
      database/factories/BusinessFactory.php
  14. 4
      database/migrations/2020_08_18_085017_fingerprints.php
  15. 2
      database/migrations/2020_08_18_085018_create_businesses_table.php

217
app/Console/Commands/CostCommand.php

@ -2,135 +2,160 @@
namespace App\Console\Commands;
use DB;
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()
{
// infinte loop
while (true) {
// to baghali ha
$recorded_month = jdate($business->calculated_at)->format("Y-m-01");
$calculated_at = Cache::get('calculated_at');
if ($calculated_at === null) {
$business = Business::orderBy('calculated_at')->first()->load('users', 'cost');
$calculated_at = $business->calculated_at;
$until_now = jdate()->getMonth() > jdate($business->calculated_at)->getMonth()
? jdate($business->calculated_at)->toCarbon()->setTime("00", "00", "00")
: \Carbon\Carbon::now();
Cache::put('calculated_at', $until_now, 60);
$lock = Cache::get('lock', false);
if ($lock) {
$this->info('There is no business for auditing.');
continue;
}
$business = Business::orderBy('calculated_at')->first();
if ($business === null) {
continue;
}
if ($business->calculated_at->isFuture()) {
continue;
}
$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);
if ($now->isFuture()) {
$now = Carbon::now();
}
// if calculated_at less than an hour stop
if (\Carbon\Carbon::now()->diffInMinutes($until_now) <= 60) {
$this->info('nothing to cost');
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', 'files');
// business order by last_calculated_at take first
if (!isset($business)) {
$business = Business::orderBy('calculated_at')->first()->load('users', 'cost');
}
$user_fee = enum('business.fee.user');
// 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), // last calc - (current month - now else last calc - end of the past month),
'additional' => $business->users->pluck('id')->toArray(),
]);
}
$costs = $user_fee * $duration;
// do the math in php
if (intdiv($business->files_volume, 200) === 0) {
$pads = 0;
} else {
$pads = intdiv($business->files_volume, 200) - 1;
}
$file_fee = enum('business.fee.file');
$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), // last calc - (current month - now else last calc - end of the past month),,
]);
}
$costs += $file_fee * $duration;
$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\Carbon::now(),
'calculated_at' => $now,
]);
DB::commit();
} catch (Throwable $thr) {
$this->info("The business #{$business->id} was audited.");
} catch (Throwable $throwable) {
throw $throwable;
DB::rollback();
throw $thr;
report($throwable);
continue;
}
}
}
public function calculateCostOfBusinessUsers($business, $now)
{
$user_fee = enum('business.fee.user');
$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', '=', Cost::USER_TYPE)
->where('fee', '=', $user_fee)
->where('month', '=', $recorded_month)
->where('amount', '=', $business->users->count())
->first();
if ($users_cost === null) {
$business->cost()->create([
'type' => Cost::USER_TYPE,
'month' => $recorded_month,
'amount' => $business->users->count(),
'fee' => $user_fee,
'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 = $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(),
]);
}
return $user_fee * $duration;
}
public function calculateCostOfBusinessFiles($business, $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
$packs = intdiv($business->files_volume, 200);
if ($packs === 0) {
return 0;
} else {
$packs--;
}
$files = $business->cost
->where('type', '=', Cost::FILE_TYPE)
->where('fee', '=', $file_fee)
->where('month', '=', $recorded_month)
->where('amount', '=', $packs)
->first();
if ($files === null) {
$business->cost()->create([
'type' => Cost::FILE_TYPE,
'month' => $recorded_month,
'amount' => $packs,
'fee' => $file_fee,
'duration' => $duration = $now->diffInMinutes($calculated_at), // how to determine the file?,
'additional' => ['volume' => $business->files_volume],
]);
} else {
$files->update([
'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],
]);
}
return $file_fee * $duration;
}
}

1
app/Http/Controllers/AuthController.php

@ -13,7 +13,6 @@ use App\Http\Resources\UserResource;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Cache;
use Laravel\Lumen\Routing\Controller;
use Laravel\Socialite\Facades\Socialite;
use Illuminate\Session\TokenMismatchException;
use Symfony\Component\HttpFoundation\Response;

10
app/Http/Controllers/FileController.php

@ -4,13 +4,13 @@ namespace App\Http\Controllers;
use App\Models\File;
use App\Models\Project;
use App\Rules\maxBound;
use App\Rules\MaxBound;
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;
@ -102,7 +102,7 @@ class FileController extends Controller
$business = Business::findOrFail($business);
$project = Project::findOrFail($project);
// $this->validate($request, ['file' => 'required|file',]);
$this->validate($request, ['file' => 'required|file',]);
$file = $request->file('file');
$file_extension = $file->getClientOriginalExtension();
@ -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);
}

10
app/Http/Controllers/ProjectController.php

@ -22,7 +22,7 @@ class ProjectController extends Controller
return Business::info($request->route('business'), true);
}
public function update(Request $request,string $project)
public function update(Request $request, int $business, string $project)
{
permit('projectEdit', ['project_id' => $project]);
$project = Project::findOrFail($project);
@ -31,7 +31,7 @@ class ProjectController extends Controller
}
public function delete(Request $request, string $project)
public function delete(Request $request, int $business, string $project)
{
permit('businessProjects');
$project = Project::findOrFail($project);
@ -39,7 +39,7 @@ class ProjectController extends Controller
return Business::info($request->route('business'));
}
public function restore(Request $request, string $project)
public function restore(Request $request, int $business, string $project)
{
$project = Project::onlyTrashed()->findOrFail($project);
$project->restore();
@ -139,7 +139,7 @@ class ProjectController extends Controller
}
}
public function setAvatar(Request $request, string $project)
public function setAvatar(Request $request, int $business, string $project)
{
$project = Project::findOrFail($project);
if ($request->hasFile('avatar')) {
@ -149,7 +149,7 @@ class ProjectController extends Controller
return $project;
}
public function unSetAvatar(Request $request, string $project)
public function unSetAvatar(Request $request,int $business ,string $project)
{
$project = Project::findOrFail($project);
$project->deleteAvatar();

5
app/Http/Controllers/TaskFileController.php

@ -11,7 +11,6 @@ use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\FileResource;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Http\Exceptions\HttpResponseException;
class TaskFileController extends Controller
{
@ -41,7 +40,7 @@ class TaskFileController extends Controller
// guest or de active
// return files as file resource
[$business, $project, $task] = $this->checkBelonging($business, $project, $task);
return FileResource::collection($task->files);
return FileResource::collection($task->files ?? []);
}
public function sync(Request $request,int $business, int $project, int $task)
@ -78,7 +77,7 @@ class TaskFileController extends Controller
// return the file resource or stream it
[$business, $project, $task] = $this->checkBelonging($business, $project, $task);
$file = File::find($file);
$file = File::findOrFail($file);
if ($file->user_id !== Auth::id()) {
abort(Response::HTTP_UNAUTHORIZED);
}

2
app/Http/Resources/FileResource.php

@ -1,9 +1,7 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class FileResource extends JsonResource

1
app/Models/Business.php

@ -42,6 +42,7 @@ class Business extends Model implements HasMedia
protected $casts = [
'has_avatar' => 'boolean',
'calculated_at' => 'datetime',
];
public function getValueOf(?string $key)

4
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 = [

4
app/Models/Model.php

@ -2,11 +2,7 @@
namespace App\Models;
use Anik\Amqp\Exchange;
use Anik\Amqp\Facades\Amqp;
use App\Events\ModelSaved;
use PhpAmqpLib\Wire\AMQPTable;
use Anik\Amqp\PublishableMessage;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;

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

3
composer.json

@ -20,11 +20,8 @@
"jenssegers/agent": "^2.6",
"laravel/socialite": "^5.1",
"laravel/framework": "^8.12",
"guzzlehttp/guzzle": "^7.0.1",
"laravel/legacy-factories": "^1",
"fruitcake/laravel-cors": "^2.0",
"laravel/lumen-framework": "^8.0",
"illuminate/notifications": "^8.0",
"league/flysystem-aws-s3-v3": "~1.0",
"spatie/laravel-medialibrary": "^9.0",
"spatie/laravel-query-builder": "^3.3",

5
config/app.php

@ -12,7 +12,7 @@ return [
'asset_url' => env('ASSET_URL', null),
'timezone' => 'UTC',
'timezone' => 'Asia/Tehran',
'locale' => 'fa',
@ -64,6 +64,7 @@ return [
App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Utilities\Zarinpal\Laravel\ZarinpalServiceProvider::class,
],
'aliases' => [
@ -104,5 +105,7 @@ return [
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'View' => App\Utilities\Zarinpal\Laravel\Facade\Zarinpal::class,
],
];

2
database/factories/BusinessFactory.php

@ -12,6 +12,6 @@ $factory->define(Business::class, function (Faker $faker) {
'slug' => Str::slug($name) . $faker->numberBetween(1, 100),
'wallet' => random_int(111111, 999999),
'color' => $faker->colorName,
'calculated_at' => \Carbon\Carbon::now()->subMinutes(random_int(1, 1000)),
'calculated_at' => \Carbon\Carbon::now()->subDays(random_int(1, 31)),
];
});

4
database/migrations/2020_08_18_085017_fingerprints.php

@ -19,8 +19,8 @@ class Fingerprints extends Migration
$table->string('agent');
$table->ipAddress('ip');
$table->string('os');
$table->decimal('latitude', 10, 2);
$table->decimal('longitude', 11, 2);
$table->decimal('latitude', 10, 4);
$table->decimal('longitude', 11, 4);
$table->char('token', 60)->unique();
$table->timestamps();
});

2
database/migrations/2020_08_18_085018_create_businesses_table.php

@ -23,7 +23,7 @@ class CreateBusinessesTable extends Migration
$table->string('description')->nullable();
$table->json('cache')->nullable();
$table->boolean('has_avatar')->default(false);
$table->timestamp('calculated_at')->nullable();
$table->timestamp('calculated_at')->nullable()->index();
$table->timestamp('created_at')->nullable();
$table->timestamp('updated_at')->nullable();
$table->timestamp('deleted_at')->nullable();

Loading…
Cancel
Save