PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/app/Console/Commands/CampagneTokensOld.php

https://bitbucket.org/hfab/webservice
PHP | 368 lines | 273 code | 70 blank | 25 comment | 31 complexity | a0a1103466703e8cbec42f17e707c6bc MD5 | raw file
Possible License(s): BSD-2-Clause, Apache-2.0, MIT, GPL-3.0, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. <?php namespace App\Console\Commands;
  2. use App\Models\PlanningFaiVolume;
  3. use Illuminate\Console\Command;
  4. use Symfony\Component\Console\Input\InputArgument;
  5. use Carbon\Carbon;
  6. use App\Models\Campagne;
  7. use App\Models\Destinataire;
  8. use App\Models\Fai;
  9. use App\Models\Planning;
  10. use App\Models\Token;
  11. use Mail;
  12. class CampagneTokensOld extends Command {
  13. protected $max_tries = 5;
  14. protected $name = 'campagne:tokens_old';
  15. protected $description = 'Prepares a campaign (tokens...)';
  16. public function __construct()
  17. {
  18. parent::__construct();
  19. $this->passe = 0;
  20. $this->selected = 0;
  21. $this->fai_selected = 0;
  22. $this->how_many_to_select = 0;
  23. $this->remaining = 0;
  24. $this->total = 0;
  25. $this->chunk_size = 25000;
  26. $this->total_tested = 0;
  27. $this->total_excluded = 0;
  28. $this->to_exclude = [];
  29. }
  30. /**
  31. *
  32. */
  33. public function fire()
  34. {
  35. \DB::disableQueryLog();
  36. $planning = Planning::find($this->argument('planning_id'));
  37. \Log::info("[CampagneTokens][P$planning->id] : Début (Planning $planning->id / Campagne $planning->campagne_id)");
  38. $count = \DB::table('tokens')
  39. ->where('planning_id',$planning->id)
  40. ->count();
  41. if($planning->tokens_at != null or $count > 0){
  42. \DB::statement("UPDATE tokens SET planning_id = 0, campagne_id = NULL WHERE planning_id = $planning->id");
  43. // au cas où le script se relance on ré-initialise les tokens déjà sélectionnés
  44. }
  45. $campagne = Campagne::find($planning->campagne_id);
  46. $today = Carbon::today()->format('Y-m-d');
  47. $this->remaining = $planning->volume;
  48. $done_fais = [];
  49. // on charge les "déja destinataires"
  50. $dateOffset = date('Y-m-d', strtotime("-7 days"));
  51. \DB::table('tokens')
  52. ->where('base_id', $campagne->base_id)
  53. ->where('campagne_id', $campagne->id)
  54. ->where('date_active','>',$dateOffset)
  55. ->chunk($this->chunk_size, function ($already) {
  56. foreach ($already as $historique) {
  57. $this->to_exclude[$historique->destinataire_id] = 1;
  58. }
  59. });
  60. \DB::table('repoussoirs')
  61. ->where('campagne_id', $campagne->id)
  62. ->chunk($this->chunk_size, function ($repoussoirs) {
  63. foreach ($repoussoirs as $r) {
  64. $this->to_exclude[$r->destinataire_id] = 1;
  65. }
  66. });
  67. // echo 'Repoussoirs : '.count($this->to_exclude)."\n";
  68. //Volume par FAI pour la campagne
  69. $planvols = \DB::table('plannings_fais_volumes')
  70. ->select('volume','fai_id')
  71. ->where('planning_id',$planning->id)
  72. ->get();
  73. foreach($planvols as $planvol){
  74. \Log::info("// FAI ID // $planvol->fai_id ");
  75. $getMin = array();
  76. $this->fai_selected = 0;
  77. $done_fais[] = $planvol->fai_id;
  78. $lefai = Fai::find($planvol->fai_id);
  79. if ($this->remaining <= 0) {
  80. break;
  81. }
  82. $total_fai_per_day = \DB::table('fai_sender')
  83. ->selectRaw('sum(quota_left) as total')
  84. ->where('fai_id',$lefai->id)
  85. ->where('quota_left','>',0)
  86. ->first();
  87. $getMin[] = $planvol->volume;
  88. if(!empty($total_fai_per_day)){
  89. $getMin[] = $total_fai_per_day->total;
  90. }
  91. if($lefai->quota_campagne > 0) {
  92. $getMin[] = $lefai->quota_campagne;
  93. }
  94. $how_many = min($getMin);
  95. \Log::info("// HOW MANY // $how_many");
  96. $this->how_many_to_select = $how_many;
  97. $chunk = min($how_many, $this->chunk_size);
  98. if($chunk == 0) {
  99. continue;
  100. }
  101. // echo "Trying to find $how_many tokens \n";
  102. \DB::table('tokens')
  103. ->where('base_id', $campagne->base_id)
  104. ->whereRaw('campagne_id IS null')
  105. ->where('date_active', $today)
  106. ->where('fai_id', $planvol->fai_id)
  107. ->orderBy('priority')
  108. ->orderByRaw('rand()')
  109. ->take($how_many)
  110. ->chunk($chunk, function ($tokens) use ($planning, $planvol) {
  111. if($this->fai_selected < $this->how_many_to_select){
  112. \Log::info("// IF // Fai selected $this->fai_selected -- HowManyToSelect $this->how_many_to_select");
  113. $this->fai_selected += $this->checkTokens($planning, $tokens, ($planvol->volume - $this->fai_selected));
  114. } else {
  115. \Log::info("// ELSE // Fai selected $this->fai_selected -- HowManyToSelect $this->how_many_to_select");
  116. return false;
  117. }
  118. });
  119. }
  120. // d'abord, les FAI à quota
  121. $fais = Fai::where('quota_campagne','>',0)
  122. ->whereNotIn('id',$done_fais)
  123. ->orderBy('quota_campagne')
  124. ->get();
  125. foreach($fais as $fai) {
  126. // echo "\n\nFAI (quota) : $fai->nom ( $fai->quota_campagne ) \n";
  127. $getMin = array();
  128. $this->fai_selected = 0;
  129. $tries = 0;
  130. $done_fais[] = $fai->id;
  131. if ($this->remaining <= 0) {
  132. break;
  133. }
  134. $getMin[] = $this->remaining;
  135. $getMin[] = $fai->quota_campagne;
  136. $planvol = \DB::table('plannings_fais_volumes')
  137. ->select('volume')
  138. ->where('planning_id',$planning->id)
  139. ->where('fai_id',$fai->id)
  140. ->first();
  141. $total_fai_per_day = \DB::table('fai_sender')
  142. ->selectRaw('sum(quota_left) as total')
  143. ->where('fai_id',$fai->id)
  144. ->where('quota_left','>',0)
  145. ->first();
  146. if(!empty($total_fai_per_day)){
  147. $getMin[] = $total_fai_per_day->total;
  148. }
  149. if(!empty($planvol)){
  150. $getMin[] = $planvol->volume;
  151. }
  152. // echo "Trying to find $how_many tokens \n";
  153. $how_many = min($getMin);
  154. $chunk = min($how_many, $this->chunk_size);
  155. $this->how_many_to_select = $how_many;
  156. if($chunk == 0) {
  157. continue;
  158. }
  159. \DB::table('tokens')
  160. ->where('base_id', $campagne->base_id)
  161. ->whereRaw('campagne_id IS null')
  162. ->where('date_active', $today)
  163. ->where('fai_id', $fai->id)
  164. ->orderBy('priority')
  165. ->orderByRaw('rand()')
  166. ->take($how_many)
  167. ->chunk($chunk, function ($tokens) use ($planning, $planvol) {
  168. // $this->checkTokens($planning, $tokens);
  169. if(!empty($planvol)){
  170. if($this->fai_selected < $this->how_many_to_select){
  171. $this->fai_selected += $this->checkTokens($planning, $tokens,($planvol->volume - $this->fai_selected));
  172. }
  173. } else{
  174. $this->checkTokens($planning, $tokens);
  175. }
  176. });
  177. // $this->remaining -= $this->selected;
  178. // echo "REMAINING : " . $this->remaining . "\n";
  179. // die();
  180. }
  181. // die();
  182. // echo "Le reste : Trying to find $this->remaining tokens\n";
  183. $cache_tokens = array();
  184. $pdo = \DB::connection()->getPdo();
  185. $date_active = date('Y-m-d');
  186. if(count($done_fais)>0) {
  187. $query = "SELECT id, destinataire_id, fai_id FROM tokens WHERE base_id = $campagne->base_id and campagne_id is null and date_active = '$date_active' and fai_id not in (" . implode(',', $done_fais) . ") order by priority, rand()";
  188. $stmt = $pdo->prepare($query);
  189. $stmt->execute();
  190. while ($token = $stmt->fetchObject()) {
  191. if ($this->remaining > 0) {
  192. $cache_tokens[] = $token;
  193. }
  194. if (count($cache_tokens) >= 5000) {
  195. $this->checkTokens($planning, $cache_tokens);
  196. $cache_tokens = array();
  197. }
  198. }
  199. } else{
  200. $query = "SELECT id, destinataire_id, fai_id FROM tokens WHERE base_id = $campagne->base_id and campagne_id is null and date_active = '$date_active' order by priority, rand()";
  201. $stmt = $pdo->prepare($query);
  202. $stmt->execute();
  203. while ($token = $stmt->fetchObject()) {
  204. if ($this->remaining > 0) {
  205. $cache_tokens[] = $token;
  206. }
  207. if (count($cache_tokens) >= 5000) {
  208. $this->checkTokens($planning, $cache_tokens);
  209. $cache_tokens = array();
  210. }
  211. }
  212. }
  213. if (count($cache_tokens) >= 0) {
  214. $this->checkTokens($planning, $cache_tokens);
  215. $cache_tokens = array();
  216. }
  217. \Log::info("[CampagneTokens][P$planning->id] : After last checkTokens (Planning $planning->id / Campagne $planning->campagne_id)");
  218. echo "Total : $this->total\n";
  219. echo "Passes : $this->passe \n";
  220. echo "Total Sélectionnés : $this->total \n";
  221. echo "Remaining : $this->remaining \n";
  222. echo "Total tokens testés : ".$this->total_tested."\n";
  223. echo "Total exclus : ".$this->total_excluded."\n";
  224. $planning->tokens_at = date('Y-m-d H:i:s');
  225. $planning->save();
  226. \Log::info("[CampagneTokens][P$planning->id] : C$planning->campagne_id -- terminé (Planning $planning->id / Campagne $planning->campagne_id)");
  227. $idplanning = $this->argument('planning_id');
  228. \Log::info("Lancement du calcul des statistiques pour la plannif n : " . $idplanning);
  229. // \Log::info("Stats off");
  230. \Artisan::call('tokens:stats', ['planning_id' => $idplanning ]);
  231. $resultat_selected = \DB::table('tokens')->where('date_active', date('Y-m-d'))->where('planning_id',$planning->id)->count();
  232. \DB::statement("UPDATE plannings SET volume_selected ='" . $resultat_selected . "' WHERE id = '" . $planning->id ."'");
  233. \Log::info("[CampagneTokens][P$planning->id] : Calcul volume réel selected {".$resultat_selected."} (Planning $planning->id / Campagne $planning->campagne_id)");
  234. // alert info
  235. $controlev = 0.1 * $planning->volume;
  236. if($resultat_selected < $controlev){
  237. $email = 'Un volume de ' . $planning->volume . ' a été demandé pour la campagne ' . $campagne->nom . ' mais le nombre réel de destinataires selectionnés est de : ' . $resultat_selected ;
  238. Mail::raw($email, function ($message, $campagne) {
  239. $destinataires = \App\Models\User::where('is_valid', 1)
  240. ->where('user_group_id', 1)
  241. ->where('email', '!=', "")
  242. ->get();
  243. $message->from('dev@lead-factory.net', 'Tor')->subject('Avertissement : pb sur la sélection de tokens pour '.$campagne->ref.' [' . $campagne->id .'] le ' . date('d-m-Y H:i'));
  244. foreach($destinataires as $d){
  245. $message->to($d->email);
  246. }
  247. return "true";
  248. });
  249. }
  250. \App\Helpers\Profiler::report();
  251. }
  252. function checkTokens($planning, $tokens, $how_many = null) {
  253. $this->selected = 0;
  254. $this->passe++;
  255. if(empty($how_many)){
  256. $how_many = $this->remaining;
  257. }
  258. if ($this->remaining <= 0) {
  259. return;
  260. }
  261. $cache_ids = [];
  262. // echo "Found ".count($tokens)." tokens\t remaining avant : $this->remaining \t";
  263. foreach($tokens as $idx => $token) {
  264. $this->total_tested++;
  265. if (isset($this->to_exclude[$token->destinataire_id])) {
  266. $this->total_excluded++;
  267. continue;
  268. }
  269. $this->to_exclude[$token->destinataire_id] = 1;
  270. if ($this->remaining > 0 && $how_many > 0) {
  271. // echo "Remain : ".$this->remaining."\n";
  272. $this->selected++;
  273. $this->remaining--;
  274. $how_many--;
  275. $this->total++;
  276. $cache_ids[] = $token->id;
  277. //echo "Passe $this->passe \t campagne ".$campagne->id." \t idx ".str_pad($idx,3, ' ', STR_PAD_LEFT) ." \t Reste $this->remaining \t Sélectionnés $this->selected \n";
  278. }
  279. // \t Fai ".$token->fai->id." ($token->fai->quota_campagne) \t Token $token->id \t Reste ".($this->remaining - $this->selected)." \n";
  280. }
  281. if (count($cache_ids) > 0) {
  282. $this->writeUpdates($cache_ids, $planning->campagne_id,$planning->id);
  283. $num = count($cache_ids);
  284. // echo "Exclus $this->total_excluded \t Writing $num - Remaining après : $this->remaining";
  285. }
  286. return $this->selected;
  287. // echo "\n";
  288. }
  289. protected function getArguments()
  290. {
  291. return [
  292. ['planning_id', InputArgument::REQUIRED, 'Planning id.'],
  293. ];
  294. }
  295. private function writeUpdates($ids, $campagne_id, $planning_id) {
  296. \DB::table('tokens')->whereIn('id', $ids)->update(['campagne_id' => $campagne_id, 'planning_id' => $planning_id]);
  297. }
  298. }