ChargeServers.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Models\Server;
  4. use App\Notifications\ServersSuspendedNotification;
  5. use Carbon\Carbon;
  6. use Illuminate\Console\Command;
  7. use Illuminate\Support\Facades\DB;
  8. class ChargeServers extends Command
  9. {
  10. /**
  11. * The name and signature of the console command.
  12. *
  13. * @var string
  14. */
  15. protected $signature = 'servers:charge';
  16. /**
  17. * The console command description.
  18. *
  19. * @var string
  20. */
  21. protected $description = 'Charge all users with severs that are due to be charged';
  22. /**
  23. * A list of users that have to be notified
  24. * @var array
  25. */
  26. protected $usersToNotify = [];
  27. /**
  28. * Create a new command instance.
  29. *
  30. * @return void
  31. */
  32. public function __construct()
  33. {
  34. parent::__construct();
  35. }
  36. /**
  37. * Execute the console command.
  38. *
  39. * @return int
  40. */
  41. public function handle()
  42. {
  43. Server::whereNull('suspended')->with('user', 'product')->chunk(10, function ($servers) {
  44. /** @var Server $server */
  45. foreach ($servers as $server) {
  46. /** @var Product $product */
  47. $product = $server->product;
  48. /** @var User $user */
  49. $user = $server->user;
  50. $billing_period = $product->billing_period;
  51. // check if server is due to be charged by comparing its last_billed date with the current date and the billing period
  52. $newBillingDate = null;
  53. switch ($billing_period) {
  54. case 'annually':
  55. $newBillingDate = Carbon::parse($server->last_billed)->addYear();
  56. break;
  57. case 'half-annually':
  58. $newBillingDate = Carbon::parse($server->last_billed)->addMonths(6);
  59. break;
  60. case 'quarterly':
  61. $newBillingDate = Carbon::parse($server->last_billed)->addMonths(3);
  62. break;
  63. case 'monthly':
  64. $newBillingDate = Carbon::parse($server->last_billed)->addMonth();
  65. break;
  66. case 'weekly':
  67. $newBillingDate = Carbon::parse($server->last_billed)->addWeek();
  68. break;
  69. case 'daily':
  70. $newBillingDate = Carbon::parse($server->last_billed)->addDay();
  71. break;
  72. case 'hourly':
  73. $newBillingDate = Carbon::parse($server->last_billed)->addHour();
  74. default:
  75. $newBillingDate = Carbon::parse($server->last_billed)->addHour();
  76. break;
  77. };
  78. if (!($newBillingDate->isPast())) {
  79. continue;
  80. }
  81. // check if the server is canceled or if user has enough credits to charge the server or
  82. if ($server->canceled || $user->credits <= $product->price) {
  83. try {
  84. // suspend server
  85. $this->line("<fg=yellow>{$server->name}</> from user: <fg=blue>{$user->name}</> has been <fg=red>suspended!</>");
  86. $server->suspend();
  87. // add user to notify list
  88. if (!in_array($user, $this->usersToNotify)) {
  89. array_push($this->usersToNotify, $user);
  90. }
  91. } catch (\Exception $exception) {
  92. $this->error($exception->getMessage());
  93. }
  94. return;
  95. }
  96. // charge credits to user
  97. $this->line("<fg=blue>{$user->name}</> Current credits: <fg=green>{$user->credits}</> Credits to be removed: <fg=red>{$product->price}</>");
  98. $user->decrement('credits', $product->price);
  99. // update server last_billed date in db
  100. DB::table('servers')->where('id', $server->id)->update(['last_billed' => $newBillingDate]);
  101. }
  102. return $this->notifyUsers();
  103. });
  104. }
  105. /**
  106. * @return bool
  107. */
  108. public function notifyUsers()
  109. {
  110. if (!empty($this->usersToNotify)) {
  111. /** @var User $user */
  112. foreach ($this->usersToNotify as $user) {
  113. $this->line("<fg=yellow>Notified user:</> <fg=blue>{$user->name}</>");
  114. $user->notify(new ServersSuspendedNotification());
  115. }
  116. }
  117. #reset array
  118. $this->usersToNotify = array();
  119. return true;
  120. }
  121. }