Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 1058
0.00% covered (danger)
0.00%
0 / 20
CRAP
0.00% covered (danger)
0.00%
0 / 1
OngoingJobs
0.00% covered (danger)
0.00%
0 / 1058
0.00% covered (danger)
0.00%
0 / 20
60762
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
20
 list_ongoing_jobs
0.00% covered (danger)
0.00%
0 / 251
0.00% covered (danger)
0.00%
0 / 1
5256
 approve_job
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
42
 reject_job
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
42
 move_to_ongoing_jobs
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 1
30
 send_mail
0.00% covered (danger)
0.00%
0 / 88
0.00% covered (danger)
0.00%
0 / 1
1056
 bulk_update_ongoing_job
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
20
 delete_ongoing_job
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
20
 download_ongoing_jobs
0.00% covered (danger)
0.00%
0 / 129
0.00% covered (danger)
0.00%
0 / 1
306
 update_ongoing_job
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
90
 get_dates
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
12
 get_job
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 list_job_analytics
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 1
600
 get_years
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
12
 list_margin_jobs_analytics
0.00% covered (danger)
0.00%
0 / 136
0.00% covered (danger)
0.00%
0 / 1
1560
 get_total_jobs_in_red
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
12
 get_active_job_dates
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
12
 update_ongoing_jobs_month_change
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 update_ongoing_jobs_month_change_manual
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 get_revenue_per_month
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\TblQuotations;
6use App\Models\TblCompanyUsers;
7use App\Models\TblOngoingJobs;
8use App\Models\TblApprovals;
9use App\Models\TblApprovalBudgetTypes;
10use App\Models\TblProjectTypes;
11use App\Models\TblCompanies;
12use App\Models\TblUsers;
13use App\Models\TblBudgetTypes;
14use App\Models\TblOrdersUpdateLogs;
15use App\Models\TblRevenuePerMonth;
16use App\Http\Controllers\Quotations;
17use Illuminate\Support\Facades\App;
18use Illuminate\Support\Facades\Cache;
19use Illuminate\Http\Request;
20use Illuminate\Support\Facades\DB;
21use PhpOffice\PhpSpreadsheet\Spreadsheet;
22use PhpOffice\PhpSpreadsheet\IOFactory;
23use PhpOffice\PhpSpreadsheet\Style;
24use Illuminate\Support\Facades\Log;
25
26class OngoingJobs extends Controller
27{
28    public function __construct(){
29        $this->locale = @getallheaders()['Locale-ID'];
30        $this->userId = @getallheaders()['User-ID'];
31        $this->region = @getallheaders()['Region'];
32        
33        App::setLocale($this->locale);
34
35        $this->companyIds = array();
36
37        if($this->region != null && $this->region != "" && $this->region != "All"){
38            $this->region = urldecode($this->region);
39
40            $query = "SELECT 
41                        b.company_id
42                    FROM 
43                        tbl_company_users a 
44                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id 
45                    WHERE 
46                        a.user_id = {$this->userId}
47                        AND b.region = '{$this->region}'";
48            
49            $this->companyIds = DB::select($query);
50
51            $this->companyIds = collect($this->companyIds)->pluck('company_id')->toArray();
52        }else{
53            $this->companyIds = TblCompanyUsers::where('user_id', $this->userId)->pluck('company_id')->all();
54        }
55        
56        $this->companyId = implode(',', $this->companyIds);
57    }
58
59    function list_ongoing_jobs(Request $request){
60        
61        try {
62
63            $data = $request->all();
64            $companyId = addslashes($data['company_id']);
65            $userId = addslashes($data['user_id']);
66            $filter = $data['filterModel'];
67            $sort = $data['sortModel'];
68            $result = array();
69            $subquery = "";
70            $where = "";
71            $having = "";
72            $orderBy = "";
73            $start = addslashes($data['start']);
74            $end = addslashes($data['end']);
75            $totalRowCount = 0;
76
77            $filterType = array(
78                'contains' => "LIKE '%[value]%'",
79                'notContains' => "NOT LIKE '%[value]%'",
80                'equals' => "= '[value]'",
81                'notEqual' => "<> '[value]'",
82                'startsWith' => "LIKE '[value]%'",
83                'endsWith' => "LIKE '%[value]'",
84                'blank' => "IS NULL",
85                'notBlank' => "IS NOT NULL",
86                'lessThan' => "< [value]",
87                'lessThanOrEqual' => "<= [value]",
88                'greaterThan' => "> [value]",
89                'greaterThanOrEqual' => ">= [value]",
90                'inRange' => "BETWEEN [value1] AND [value2]"
91            );
92
93            if(isset($data['ids']) && count($data['ids']) > 0){
94                $quoteIds = implode(",", $data['ids']);
95                $where = " a.id IN ({$quoteIds}";
96            }
97
98            if(isset($data['ids_not_in']) && count($data['ids_not_in']) > 0){
99                $quoteIds = implode(",", $data['ids_not_in']);
100                $where = " a.id NOT IN ({$quoteIds}";
101            }
102
103            if($companyId != 0){
104                if($where != ""){
105                    $where .= " AND a.company_id = {$companyId} ";
106                }else{
107                    $where .= " a.company_id = {$companyId} ";
108                }
109            }else{
110                if($where != ""){
111                    $where .= " AND a.company_id IN ({$this->companyId}";
112                }else{
113                    $where .= " a.company_id IN ({$this->companyId}";
114                }
115            }
116
117            if($where != ""){
118                $where = "WHERE {$where}";
119            }
120
121            $matchScoreCol = "";
122            $matchScoreOrderBy = "";
123
124            if(isset($data['searchText']) && $data['searchText'] != null){
125
126                $availableParameters = [
127                    'a.quotation_id', 
128                    'c.name',
129                    's.name',
130                    'd.name',
131                    'a.quote_id', 
132                    'a.company_id',
133                    'a.customer_type_id',
134                    'a.budget_type_id',
135                    'a.order_number',
136                    'a.client',
137                    'a.issue_date',
138                    'a.acceptance_date', 
139                    'a.amount', 
140                    'a.created_by', 
141                    'a.created_at',
142                    'a.updated_by',
143                    'a.updated_at',
144                    'a.invoice_amount',
145                    'a.responsible_for_work',
146                    'a.expected_start_date_of_work',
147                    'a.actual_job_start_date', 
148                    'a.actual_end_date', 
149                    'a.expected_completion_date', 
150                    'a.work_status_id',
151                    'e.name'
152                ];
153
154                $searchText = addslashes($data['searchText']);
155                $searchTextArray = explode(" ", $searchText);
156
157                $searchArray = array();
158                $splitSearchArray = array();
159                $matchScoreArray = array();
160                $sc = 1;
161                foreach ($availableParameters as $field) {
162                    if($field == 'a.client' || $field == 'a.amount' || $field == 'a.created_at'){
163                        $sc = 3;
164                    }elseif($field == 'a.acceptance_date'){
165                        $sc = 2;
166                    }else{
167                        $sc = 1;
168                    }
169
170                    $l = "{$field} LIKE '%{$searchText}%'";
171                    if($field == "a.last_follow_up_comment"){
172                        $l = "{$field} = '{$searchText}'";
173                    }else{
174
175                        $d = "IFNULL((LENGTH(LOWER({$field})) - LENGTH(REPLACE(LOWER({$field}), LOWER('{$searchText}'), ''))) / LENGTH(LOWER('{$searchText}')), 0) * {$sc}";
176
177                        if(count($searchTextArray) > 1){
178                            foreach ($searchTextArray as $word) {
179                                if(!is_numeric($word)){
180                                    $d .= " + IFNULL((LENGTH(LOWER({$field})) - LENGTH(REPLACE(LOWER({$field}), LOWER('{$word}'), ''))) / LENGTH(LOWER('{$word}')), 0) * {$sc}";
181                                }
182                            }   
183                        }
184
185                        array_push($matchScoreArray, $d);
186                    }
187
188                    if(is_numeric($searchText)){
189                        array_push($searchArray, "({$l} OR {$field} = CAST('{$searchText}' AS UNSIGNED))");      
190                    }else{
191                        array_push($searchArray, "({$l} OR DATE_FORMAT({$field}, '%d/%m/%Y') = DATE_FORMAT(STR_TO_DATE('{$searchText}', '%d/%m/%Y'), '%d/%m/%Y'))");      
192                    }
193                    
194                    if(count($searchTextArray) > 1){
195                        foreach ($searchTextArray as $word) {
196
197                            $l = "{$field} LIKE '%{$word}%'";
198                            if($field == "a.last_follow_up_comment"){
199                                $l = "{$field} = '{$word}'";
200                            }
201
202                            if(is_numeric($word)){
203                                array_push($splitSearchArray, "{$l} OR {$field} = CAST('{$word}' AS UNSIGNED)");                             
204                            }else{
205                                array_push($splitSearchArray, "{$l} OR DATE_FORMAT({$field}, '%d/%m/%Y') = DATE_FORMAT(STR_TO_DATE('{$word}', '%d/%m/%Y'), '%d/%m/%Y')"); 
206                            }
207                        }
208                    }
209                    
210                    $sc = 1;
211                }
212
213                if(count($splitSearchArray) > 0){
214                    $splitSearchArray = implode(" OR ", $splitSearchArray);
215                    $splitSearchArray = " OR ({$splitSearchArray}";
216                }else{
217                    $splitSearchArray = "";
218                }
219                
220                $searchArray = implode(" OR ", $searchArray);
221                $matchScoreArray = implode(",", $matchScoreArray);
222                $matchScoreCol = ", GREATEST({$matchScoreArray}) match_score";
223                $matchScoreOrderBy = "match_score DESC,";
224                $where .= " AND ({$searchArray} {$splitSearchArray})";
225            }
226
227            if(count($sort) > 0){
228                $field = $sort[0]['colId'];
229                $sortBy = $sort[0]['sort'];
230                
231                if(strpos($field, "translate") !== false){
232                    $field = str_replace("_translate", "", $field);
233                }else{
234                    if($field == "client_type"){
235                        $field = "c.name";
236                    }elseif($field == "segment"){
237                        $field = "s.name";
238                    }elseif($field == "type"){
239                        $field = "d.name";
240                    }elseif($field == "amount"){
241                        $field = "CAST(a.amount AS DOUBLE)";
242                    }elseif($field == "invoice_amount"){
243                        $field = "CAST(a.invoice_amount AS DOUBLE)";
244                    }elseif($field == "quote_id"){
245                        $field = "CAST(a.quote_id AS DOUBLE)";
246                    }
247                }
248
249                if($matchScoreOrderBy){
250                    $matchScoreOrderBy = ", match_score DESC";
251                }
252
253                $orderBy = " ORDER BY {$field} {$sortBy} {$matchScoreOrderBy}";
254            }else{
255                $orderBy = " ORDER BY {$matchScoreOrderBy} a.id DESC ";
256            }
257
258            foreach ($filter as $key => $data) {                
259                if(strpos($key, "translate") !== false){
260
261                    $field = str_replace("_translate", "", $key);
262
263                    if($field == "created_at"){
264                        $field = "a.created_at";
265                    }
266
267                    $whereDates = "";
268                    $z = 0;
269                    foreach ($data['filters'] as $yearKey => $yearData) {
270                        $yearsMonths = array();
271                        $yearsWeeks = array();
272                        
273                        if($z > 0){
274                            $whereDates .= " OR (YEAR($field) = {$yearKey} ";
275                        }else{
276                            $whereDates .= " (YEAR($field) = {$yearKey} ";
277                        }
278
279                        for ($i = 0; $i < count($yearData['months']); $i++) { 
280                            if($yearData['months'][$i]['isChecked']){
281                                array_push($yearsMonths, $yearData['months'][$i]['value']);
282                            }
283                        }
284
285                        $yearsMonths = implode("','", $yearsMonths);
286                        $whereDates .= " AND (MONTH({$field}) IN ('{$yearsMonths}')";
287
288                        for ($i = 0; $i < count($yearData['weeks']); $i++) { 
289                            if($yearData['weeks'][$i]['isChecked']){
290                                array_push($yearsWeeks, $yearData['weeks'][$i]['value']);
291                            }
292                        }
293
294                        $yearsWeeks = implode("','", $yearsWeeks);
295                        if($yearsWeeks != ''){
296                            $whereDates .= " OR WEEK({$field}) IN ('{$yearsWeeks}') ";
297                        }
298
299                        $whereDates .= ")) ";
300                        $z++;
301                    }
302                    
303                    $where .= " AND ({$whereDates}";
304                }else{
305                    if($data['filterType'] == 'number'){
306                        if(array_key_exists('operator', $data)){
307                            if($data['condition1']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
308                                $data['condition1']['filter'] = addslashes($data['condition1']['filter']);
309                                $data['condition2']['filter'] = addslashes($data['condition2']['filter']);
310
311                                if($data['condition1']['type'] == 'inRange'){
312                                    $data['condition1']['filterTo'] = addslashes($data['condition1']['filterTo']);
313                                    $inRange = str_replace("[value1]", $data['condition1']['filter'], $filterType['inRange']);
314                                    $val1 = str_replace("[value2]", $data['condition1']['filterTo'], $inRange);
315                                }else{
316                                    $val1 = str_replace("[value]", $data['condition1']['filter'], $filterType[$data['condition1']['type']]);
317                                }
318    
319                                if($data['condition2']['type'] == 'inRange'){
320                                    $data['condition2']['filterTo'] = addslashes($data['condition2']['filterTo']);
321                                    $inRange = str_replace("[value1]", $data['condition2']['filter'], $filterType['inRange']);
322                                    $val2 = str_replace("[value2]", $data['condition2']['filterTo'], $inRange);
323                                }else{
324                                    $val2 = str_replace("[value]", $data['condition2']['filter'], $filterType[$data['condition2']['type']]);
325                                }
326    
327                            }else{
328                                $val1 = $filterType[$data['condition1']['type']];
329                                $val2 = $filterType[$data['condition2']['type']];
330                            }
331
332                            $where .= " AND a.{$key} {$val1} {$data['operator']} a.{$key} {$val2} ";
333                        }else{
334                            if($data['type'] != 'blank' && $data['type'] != 'notBlank'){
335                                $data['filter'] = addslashes($data['filter']);
336                                
337                                if($data['type'] == 'inRange'){
338                                    $data['filterTo'] = addslashes($data['filterTo']);
339                                    $inRange = str_replace("[value1]", $data['filter'], $filterType['inRange']);
340                                    $val = str_replace("[value2]", $data['filterTo'], $inRange);
341                                }else{
342                                    $val = str_replace("[value]", $data['filter'], $filterType[$data['type']]);
343                                }
344                            }else{
345                                $val = $filterType[$data['type']];
346                            }
347
348                            $where .= " AND a.{$key} {$val} ";
349                        }
350                    }
351
352                    if($data['filterType'] == 'text'){
353                        if(array_key_exists('operator', $data)){
354                            if($data['condition1']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
355                                $data['condition1']['filter'] = addslashes($data['condition1']['filter']);
356                                $val1 = str_replace("[value]", $data['condition1']['filter'], $filterType[$data['condition1']['type']]);
357                            }
358
359                            if($data['condition2']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
360                                $data['condition2']['filter'] = addslashes($data['condition2']['filter']);
361                                $val2 = str_replace("[value]", $data['condition2']['filter'], $filterType[$data['condition2']['type']]);
362                            }
363
364                            $where .= " AND {$key} {$val1} {$data['operator']} {$key} {$val2} ";
365                        }else{
366                            if($data['type'] != 'blank' && $data['type'] != 'notBlank'){
367                                $data['filter'] = addslashes($data['filter']);
368                                $val = str_replace("[value]", $data['filter'], $filterType[$data['type']]);
369                            }else{
370                                $val = $filterType[$data['type']];
371                            }
372
373                            $where .= " AND {$key} {$val} ";
374                        }                        
375                    }
376
377                    if($data['filterType'] == 'set'){
378                        $statusName = $key;
379
380                        if($key == "client_type"){
381                            $statusName = "c.name";
382                        }elseif($key == "segment"){
383                            $statusName = "s.name";
384                        }elseif($key == "type"){
385                            $statusName = "d.name";
386                        }elseif($key == "work_status"){
387                            $statusName = "e.name";
388                        }elseif($key == "created_by"){
389                            $statusName = "a.created_by";
390                        }
391
392                        $val = implode("','", $data['values']);
393                        
394                        if(in_array(null, $data['values'], true)){
395                            $where .= " AND ({$statusName} IN ('{$val}') OR {$statusName} IS NULL) ";
396                        }else{
397                            $where .= " AND {$statusName} IN ('{$val}') ";    
398                        }
399                    }
400                }
401            }
402
403            $offset = $start;
404            $limit = $end - $start;
405
406            $subquery = ",(SELECT can_write FROM tbl_company_users WHERE company_id = a.company_id AND user_id = {$userId}) can_write";
407
408            $query = "SELECT 
409                        a.id,
410                        a.quotation_id, 
411                        b.name company_name, 
412                        c.name client_type,
413                        s.name segment,
414                        s.segment_id,
415                        d.name 'type',
416                        a.quote_id, 
417                        a.company_id,
418                        a.customer_type_id,
419                        a.budget_type_id,
420                        a.order_number,
421                        a.client,
422                        a.issue_date,
423                        a.acceptance_date, 
424                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
425                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
426                        a.amount, 
427                        a.created_by, 
428                        a.created_at,
429                        a.updated_by,
430                        a.updated_at,
431                        a.invoice_amount,
432                        a.responsible_for_work,
433                        a.expected_start_date_of_work,
434                        a.actual_job_start_date, 
435                        a.actual_end_date, 
436                        a.expected_completion_date, 
437                        a.comments,
438                        DATE_FORMAT(a.expected_start_date_of_work, '%d/%m/%Y') expected_start_date_of_work_translate,
439                        DATE_FORMAT(a.actual_job_start_date, '%d/%m/%Y') actual_job_start_date_translate,
440                        DATE_FORMAT(a.actual_end_date, '%d/%m/%Y') actual_end_date_translate,
441                        DATE_FORMAT(a.expected_completion_date, '%d/%m/%Y') expected_completion_date_translate,
442                        DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate,
443                        CASE 
444                            WHEN 
445                                DATE_FORMAT(a.expected_completion_date, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d') AND a.work_status_id NOT IN (3, 5)
446                            THEN 1
447                            ELSE 0
448                        END is_red_expected_completion_date,
449                        CASE 
450                            WHEN 
451                                DATE_FORMAT(a.expected_start_date_of_work, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d') AND a.work_status_id = 2
452                            THEN 1
453                            ELSE 0
454                        END is_red_expected_start_date_of_work,
455                        CASE 
456                            WHEN 
457                                DATE_FORMAT(a.expected_completion_date, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d')
458                                AND a.work_status_id NOT IN (3, 5) 
459                            THEN 1
460                            ELSE 0
461                        END is_red,
462                        CASE 
463                            WHEN 
464                                (g.amount IS NULL OR g.amount = '')
465                                AND (a.pending_to_be_invoiced IS NOT NULL AND a.pending_to_be_invoiced <> '' AND a.pending_to_be_invoiced <> 0)
466                                AND DATE_FORMAT(NOW(), '%Y-%m-%d') BETWEEN DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_job_start_date ELSE a.expected_start_date_of_work END, '%Y-%m-%d') 
467                                AND DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_end_date ELSE a.expected_completion_date END , '%Y-%m-%d') 
468                            THEN 1
469                            ELSE 0
470                        END is_red_invoiced,
471                        a.work_status_id,
472                        e.name work_status,
473                        a.cost_for_client,
474                        a.people_assigned_to_the_job,
475                        a.duration_of_job_in_days,
476                        a.estimated_cost_of_materials,
477                        a.for_approval,
478                        a.cost_of_labor,
479                        a.total_cost_of_job,
480                        a.invoice_margin,
481                        a.margin_for_the_company,
482                        a.margin_on_invoice_per_day_per_worker,
483                        a.revenue_per_date_per_worked,
484                        a.gross_margin,
485                        a.labor_percentage,
486                        a.pending_to_be_invoiced,
487                        g.amount to_be_invoiced_this_month,
488                        a.to_be_invoiced_after_this_month,
489                        a.approved_at,
490                        a.approved_by
491                        {$matchScoreCol}
492                        {$subquery}
493                    FROM 
494                        tbl_ongoing_jobs a 
495                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
496                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
497                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
498                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
499                        LEFT JOIN tbl_work_status e ON a.work_status_id = e.work_status_id
500                        LEFT JOIN tbl_revenue_per_month g ON a.quotation_id = g.quotation_id AND g.month = MONTH(NOW()) AND g.year = YEAR(NOW())
501                    {$where}
502                    {$orderBy}
503                    LIMIT {$offset}{$limit}
504                    ";
505            
506            $value = Cache::get(base64_encode($query));
507
508            if(!$value){
509                $result = DB::select($query);
510
511                Cache::put(base64_encode($query), $result, 600);
512            }else{
513                $result = $value;
514            }
515
516            $totalQuery = "SELECT 
517                            COUNT(1) totalRowCount
518                        FROM 
519                            tbl_ongoing_jobs a 
520                            LEFT JOIN tbl_companies b ON a.company_id = b.company_id 
521                            LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id 
522                            LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
523                            LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id 
524                            LEFT JOIN tbl_work_status e ON a.work_status_id = e.work_status_id
525                        {$where}";
526
527            $value = Cache::get(base64_encode($totalQuery));
528
529            if(!$value){
530                $countQuery = DB::select($totalQuery);
531
532                Cache::put(base64_encode($totalQuery), $countQuery, 600);
533            }else{                
534                $countQuery = $value;
535            }
536
537            return response([
538                'message' => 'OK', 
539                'data' => $result, 
540                'totalRowCount' => $countQuery[0]->totalRowCount,
541            ]);
542        
543        } catch (\Exception $e) {
544            /** @disregard P1014 */
545            $e->exceptionCode = 'LIST_ONGOING_JOBS_EXCEPTION'; 
546            report($e);
547            return response(['message' => 'KO', 'error' => $e->getMessage()]);
548        } 
549    }
550
551    function approve_job($id){
552
553        try {
554            
555            $id = addslashes($id);
556
557            $result = TblOngoingJobs::where('id', $id)->first();
558            $company = TblCompanies::where('company_id', $result->company_id)->first();
559            $budgetType = TblBudgetTypes::where('budget_type_id', $result->budget_type_id)->first();
560
561            $order = new Quotations();
562
563            if($result->created_by != $result->responsible_for_work){
564                $creatorAndResponsibleForWork = array($result->created_by, $result->responsible_for_work);
565                foreach ($creatorAndResponsibleForWork as $name) {
566                    $user = TblUsers::where('name', $name)->first();
567                    if($user){
568                        $order->send_approved_notification(
569                            $user->id, 
570                            $user->name, 
571                            $user->email, 
572                            $company->name, 
573                            $budgetType->name, 
574                            $result->amount, 
575                            $id, 
576                            $result->quote_id, 
577                            $company->company_id, 
578                            'ongoing-jobs'
579                        );
580                    }
581                }
582            }else{
583                $user = TblUsers::where('name', $result->created_by)->first();
584                if($user){
585                    $order->send_approved_notification(
586                        $user->id, 
587                        $user->name, 
588                        $user->email, 
589                        $company->name, 
590                        $budgetType->name, 
591                        $result->amount, 
592                        $id, 
593                        $result->quote_id, 
594                        $company->company_id,
595                        'ongoing-jobs'
596                    );
597                }
598            }
599
600            TblOngoingJobs::where('id', $id)->update(array('for_approval' => null));
601
602            Cache::flush();
603            return response(['message' => 'OK']);
604
605        } catch (\Exception $e) {
606            /** @disregard P1014 */
607            $e->exceptionCode = 'APROVE_JOB_EXCEPTION'; 
608            report($e);
609            return response(['message' => 'KO', 'error' => $e->getMessage()]);
610        }
611
612    }
613
614    function reject_job($id){
615
616        try {
617            
618            $id = addslashes($id);
619
620            $result = TblOngoingJobs::where('id', $id)->first();
621            $company = TblCompanies::where('company_id', $result->company_id)->first();
622            $budgetType = TblBudgetTypes::where('budget_type_id', $result->budget_type_id)->first();
623
624            $order = new Quotations();
625
626            if($result->created_by != $result->commercial){
627                $creatorAndResponsibleForWork = array($result->created_by, $result->responsible_for_work);
628                foreach ($creatorAndResponsibleForWork as $name) {
629                    $user = TblUsers::where('name', $name)->first();
630                    if($user){
631                        $order->send_rejected_notification(
632                            $user->id, 
633                            $user->name, 
634                            $user->email, 
635                            $company->name, 
636                            $budgetType->name, 
637                            $result->amount, 
638                            $id, 
639                            $result->quote_id, 
640                            $company->company_id,
641                            'ongoing-jobs'
642                        );
643                    }
644                    
645                }
646            }else{
647                $user = TblUsers::where('name', $result->created_by)->first();
648                if($user){
649                    $order->send_rejected_notification(
650                        $user->id, 
651                        $user->name, 
652                        $user->email, 
653                        $company->name, 
654                        $budgetType->name, 
655                        $result->amount, 
656                        $id, 
657                        $result->quote_id, 
658                        $company->company_id,
659                        'ongoing-jobs'
660                    );
661                }
662            }
663
664            TblOngoingJobs::where('id', $id)->update(array('for_approval' => 2));
665
666            Cache::flush();
667            return response(['message' => 'OK']);
668
669        } catch (\Exception $e) {
670            /** @disregard P1014 */
671            $e->exceptionCode = 'REJECCT_JOB_EXCEPTION'; 
672            report($e);
673            return response(['message' => 'KO', 'error' => $e->getMessage()]);
674        }
675
676    }
677
678    function move_to_ongoing_jobs(Request $request, $id){
679
680        try {
681            
682            $id = addslashes($id);
683            $data = $request->all();
684            $userId = addslashes($data['user_id']);
685            unset($data['user_id']);
686
687            $jobId = null;
688
689            $ongoingJob = TblOngoingJobs::where('quotation_id', $id)->first();
690            $quotation = TblQuotations::where('id', $id)->first();
691                            
692            if(empty($quotation->acceptance_date)){
693                $quotation->acceptance_date = date('Y-m-d H:i:s');
694
695                TblQuotations::where('id', $id)->update(
696                    array(
697                        'acceptance_date' => $quotation->acceptance_date,
698                        'budget_status_id' => 3,
699                        'updated_at' => date('Y-m-d H:i:s'),
700                        'updated_by' => $data['created_by']
701                    )
702                );
703            }
704
705            $job = array(
706                'quotation_id' => $id,
707                'quote_id' => $quotation->quote_id,
708                'company_id' => $quotation->company_id,
709                'customer_type_id' => $quotation->customer_type_id,
710                'segment_id' => $quotation->segment_id,
711                'budget_type_id' => $quotation->budget_type_id,
712                'order_number' => $quotation->order_number,
713                'client' => $quotation->client,
714                'issue_date' => $quotation->issue_date,
715                'acceptance_date' => $quotation->acceptance_date,
716                'amount' => $quotation->amount,
717                'cost_for_client' => $quotation->amount,
718                'comments' => $quotation->last_follow_up_comment
719            );
720
721            if($quotation->budget_margin_enabled > 0){
722                $job['people_assigned_to_the_job'] = $quotation->people_assigned_to_the_job;
723                $job['duration_of_job_in_days'] = $quotation->duration_of_job_in_days;
724                $job['estimated_cost_of_materials'] = $quotation->estimated_cost_of_materials;
725                $job['cost_of_labor'] = $quotation->cost_of_labor;
726                $job['total_cost_of_job'] = $quotation->total_cost_of_job;
727                $job['invoice_margin'] = $quotation->invoice_margin;
728                $job['margin_for_the_company'] = $quotation->margin_for_the_company;
729                $job['margin_on_invoice_per_day_per_worker'] = $quotation->margin_on_invoice_per_day_per_worker;
730                $job['revenue_per_date_per_worked'] = $quotation->revenue_per_date_per_worked;
731                $job['gross_margin'] = $quotation->gross_margin;
732                $job['labor_percentage'] = $quotation->labor_percentage;
733            }
734
735            $username = null;
736            $isAdd = 0;
737            if(empty($ongoingJob)){
738                $isAdd = 1;
739                $job['created_by'] = $data['created_by'];
740                $job['to_be_invoiced_this_month'] = $quotation->amount;
741                $job['pending_to_be_invoiced'] = 0;
742                $job['to_be_invoiced_after_this_month'] = 0;
743
744                $result = TblOngoingJobs::create($job);
745                $jobId = $result->id;
746
747                // if(empty($quotation->approved_at)){
748                //     $this->send_mail($quotation, $job, $jobId, $userId, $isAdd, $data['created_by']);
749                // }
750            }else{
751                $jobId = $ongoingJob->id;
752                $job['updated_by'] = $data['created_by'];
753                $job['updated_at'] = date('Y-m-d H:i:s');
754                $result = TblOngoingJobs::where('id', $jobId)->update($job);
755
756                // if(empty($quotation->approved_at) || $ongoingJob->invoice_margin != $quotation->invoice_margin){
757                //     $this->send_mail($quotation, $job, $jobId, $userId, $isAdd, $data['created_by']);
758                // }
759            }
760            
761            Cache::flush();
762            return response(['message' => 'OK', 'id' => $jobId]); 
763        
764        } catch (\Exception $e) {
765            /** @disregard P1014 */
766            $e->exceptionCode = 'MOVE_TO_ONGOING_JOB_EXCEPTION'; 
767            report($e);
768            return response(['message' => 'KO', 'error' => $e->getMessage()]);
769        } 
770    }
771
772    function send_mail($quotation, $data, $jobId, $userId, $isAdd, $createdBy){
773
774        $g = false;
775        if($isAdd == 0){
776            if(isset($data['cost_for_client']) || isset($data['budget_type_id']) || isset($data['customer_type_id']) || isset($data['invoice_margin'])){
777                if($data['cost_for_client'] != $quotation->cost_for_client || $data['budget_type_id'] != $quotation->budget_type_id 
778                || $data['customer_type_id'] != $quotation->customer_type_id || $data['invoice_margin'] != $quotation->invoice_margin){
779                    $g = true;
780                }
781            }
782        }else{
783            $g = true;
784        }
785
786        if($g){
787            $company = TblCompanies::where('company_id', $quotation->company_id)->first();
788    
789            if($company){
790    
791                $n = 0;
792                $invoiceMargin = 0;
793                $minimumMargin = 0;
794    
795                $project = TblProjectTypes::where('company_id', $company->company_id)->where('budget_type_id', $data['budget_type_id'])->first();
796                $customerTypeIds = array();
797
798                if($project){
799                    if(!empty($project->customer_type_ids)){
800                        $customerTypeIds = array_map('intval', explode(',', $project->customer_type_ids));
801                    }
802                    if($project->minimum_order_size != null && in_array($data['customer_type_id'], $customerTypeIds)){
803                        if($data['cost_for_client'] >= $project->minimum_order_size){
804                            $data['for_approval'] = 1;
805                            $n = 1;
806                        }
807                    }    
808                }else{
809                    if(!empty($company->customer_type_ids)){
810                        $customerTypeIds = array_map('intval', explode(',', $company->customer_type_ids));
811                    }
812                    if($company->minimum_order_size != null && in_array($data['customer_type_id'], $customerTypeIds)){
813                        if($data['cost_for_client'] >= $company->minimum_order_size){
814                            $data['for_approval'] = 1;
815                            $n = 1;
816                        }
817                    }
818                }
819
820                $costOfLabor = $data['cost_of_labor'] ?? 0;
821                $totalCostOfJob = $data['total_cost_of_job'] ?? 0;
822
823                if($totalCostOfJob > 0){
824                    $invoiceMargin = $data['invoice_margin'] ?? 0;
825                }
826                
827                $project = TblProjectTypes::where('company_id', $quotation->company_id)->where('budget_type_id', $quotation->budget_type_id)->first();
828                $minimumMargin = $company->minimum_margin;
829                $minimumOrderSize = $company->minimum_order_size;
830
831                if(!empty($company->customer_type_ids)){
832                    $customerTypeIds = array_map('intval', explode(',', $company->customer_type_ids));    
833                }
834
835                if($project){
836                    $minimumMargin = $project->minimum_margin;
837                    $minimumOrderSize = $project->minimum_order_size;
838                    if(!empty($project->customer_type_ids)){
839                        $customerTypeIds = array_map('intval', explode(',', $project->customer_type_ids));
840                    }
841                }
842                
843
844                if($invoiceMargin < $minimumMargin && $invoiceMargin != null && $invoiceMargin != 0){
845                    if(in_array($data['customer_type_id'], $customerTypeIds)){
846                        $data['for_approval'] = 1;
847                        $n = 2;
848                    }
849                }
850    
851                $order = new Quotations();
852    
853                if($n == 1){
854                    $order->send_approval_notification(
855                        $data['cost_for_client'], 
856                        $quotation->budget_type_id, 
857                        $quotation->customer_type_id,
858                        $minimumOrderSize,
859                        $quotation->quote_id, 
860                        $jobId, 
861                        $quotation->name, 
862                        $createdBy, 
863                        $userId, 
864                        $isAdd,
865                        null,
866                        $company->company_id,
867                        'ongoing-jobs',
868                        0,
869                        null
870                    );
871                }
872    
873                if($n == 2){
874                    $order->send_approval_margin_notification(
875                        $data['cost_for_client'], 
876                        $quotation->budget_type_id, 
877                        $quotation->customer_type_id,
878                        $minimumMargin,
879                        $quotation->quote_id, 
880                        $jobId, 
881                        $company->name, 
882                        $createdBy, 
883                        $userId, 
884                        $isAdd,
885                        null,
886                        $invoiceMargin,
887                        $company->company_id,
888                        'ongoing-jobs'
889                    );
890                }
891
892                if(isset($data['for_approval'])){
893                    TblOngoingJobs::where('id', $jobId)->update(
894                        array(
895                            'for_approval' => $data['for_approval']
896                        )
897                    );
898                }
899            }
900        }
901    }
902
903    function bulk_update_ongoing_job(Request $request){
904
905        try {
906
907            $data = $request->all();
908
909            $r = new Request([
910                'filterModel' => $data['filterModel'],
911                'sortModel' => $data['sortModel'],
912                'start' => 0,
913                'end' => 999999999,
914                'company_id' => $data['company_id'],
915                'user_id' => $data['user_id'],
916                'ids' => $data['ids'],
917                'searchText' => $data['searchText'],
918                'ids_not_in' => $data['ids_not_in']
919            ]);
920    
921            $listOngoingJobs = $this->list_ongoing_jobs($r);
922            $d = $listOngoingJobs->original['data'];
923
924            if(count($d) > 0){
925                unset($data['filterModel']);
926                unset($data['sortModel']);
927                unset($data['start']);
928                unset($data['end']);
929                unset($data['company_id']);
930                unset($data['user_id']);
931                unset($data['ids']);
932                unset($data['searchText']);
933                unset($data['ids_not_in']);
934    
935                $result = array();
936                for ($i = 0; $i < count($d); $i++) { 
937                    array_push($result, $d[$i]->id);
938                }
939                
940                TblOngoingJobs::whereIn('id', $result)->update($data);
941                
942                Cache::flush();
943            }
944
945            return response(['message' => 'OK', $data]);
946
947        } catch (\Exception $e) {
948            /** @disregard P1014 */
949            $e->exceptionCode = 'BULK_UPDATE_ONGOING_JOB_EXCEPTION'; 
950            report($e);
951            return response(['message' => 'KO', 'error' => $e->getMessage()]);
952        }
953
954    }
955
956    public function delete_ongoing_job(Request $request){
957
958        try {            
959
960            $data = $request->all();
961            $result = array();
962
963            $r = new Request([
964                'filterModel' => $data['filterModel'],
965                'sortModel' => $data['sortModel'],
966                'start' => 0,
967                'end' => 999999999,
968                'company_id' => $data['company_id'],
969                'user_id' => $data['user_id'],
970                'ids' => $data['ids'],
971                'searchText' => $data['searchText'],
972                'ids_not_in' => $data['ids_not_in']
973            ]);
974    
975            $result = $this->list_ongoing_jobs($r);
976            $result = $result->original['data'];
977
978            $outputArray = array();
979
980            foreach ($result as $item) {
981                if (isset($item->id)) {
982                    $outputArray[] = $item->id;
983                }
984            }
985
986            TblOngoingJobs::whereIn('id', $outputArray)->delete();
987
988            Cache::flush();
989            return response(['message' => 'OK', 'data' => $result]);
990
991        } catch (\Exception $e) {
992            /** @disregard P1014 */
993            $e->exceptionCode = 'DELETE_ONGOING_JOB_EXCEPTION'; 
994            report($e);
995            return response(['message' => 'KO', 'error' => $e->getMessage()]);
996        }
997
998    }
999
1000    function download_ongoing_jobs(Request $request){
1001        ini_set('max_execution_time', 123456);
1002        $data = $request->all();
1003        $companyId = addslashes($data['company_id']);
1004        $userId = addslashes($data['user_id']);
1005
1006        $where = "";
1007        $n = 17;
1008
1009        if($companyId){
1010            $n = 16;
1011        }
1012
1013        $r = new Request([
1014            'filterModel' => $data['filterModel'],
1015            'sortModel' => $data['sortModel'],
1016            'start' => 0,
1017            'end' => 999999999,
1018            'company_id' => $data['company_id'],
1019            'user_id' => $data['user_id'],
1020            'ids' => $data['ids'],
1021            'searchText' => $data['searchText'],
1022            'ids_not_in' => $data['ids_not_in']
1023        ]);
1024
1025        $result = $this->list_ongoing_jobs($r);
1026
1027        $spreadsheet = new Spreadsheet();
1028        $worksheet   = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, "Inputs");
1029        $spreadsheet->addSheet($worksheet, 0);
1030        $col         = range('A', 'Z');
1031        
1032        for($i = 0; $i < 20; $i++){
1033            $worksheet->getColumnDimension($col[$i])->setAutoSize(true);
1034            if($i != 1){
1035                $worksheet->getStyle($col[$i])
1036                    ->getAlignment()
1037                    ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
1038            }
1039        }
1040
1041        $l = 1;
1042        $worksheet->setCellValue('A' . $l, __('language.ID'));
1043        $worksheet->setCellValue('B' . $l, __('language.CLIENT'));
1044        $worksheet->setCellValue('C' . $l, __('language.ISSUE_DATE'));
1045        $worksheet->setCellValue('D' . $l, __('language.ACCEPTANCE_DATE'));
1046        $worksheet->setCellValue('E' . $l, __('language.ORDER_NUMBER'));
1047        $worksheet->setCellValue('F' . $l, __('language.TYPE'));
1048        $worksheet->setCellValue('G' . $l, __('language.AMOUNT'));
1049        $worksheet->setCellValue('H' . $l, __('language.CREATED_BY'));
1050        $worksheet->setCellValue('I' . $l, __('language.RESPONSIBLE_FOR_WORK'));
1051        $worksheet->setCellValue('J' . $l, __('language.CLIENT_TYPE'));
1052        $worksheet->setCellValue('K' . $l, __('language.SEGMENT'));
1053        $worksheet->setCellValue('L' . $l, __('language.INVOICE_AMOUNT'));
1054        $worksheet->setCellValue('M' . $l, __('language.EXPECTED_START_DATE_OF_WORK'));
1055        $worksheet->setCellValue('N' . $l, __('language.ACTUAL_JOB_START_DATE'));
1056        $worksheet->setCellValue('O' . $l, __('language.ACTUAL_END_DATE'));
1057        $worksheet->setCellValue('P' . $l, __('language.EXPECTED_COMPLETION_DATE'));
1058        $worksheet->setCellValue('Q' . $l, __('language.CREATED_AT'));
1059
1060        if($n > 17){
1061            $worksheet->setCellValue('R' . $l, __('language.COMPANY_NAME'));
1062        }
1063
1064        $styleArray = [
1065            'font' => [
1066                'bold' => true,
1067            ]
1068        ];
1069
1070        $worksheet->getStyle('A1:' . (($n > 17) ? 'R1' : 'Q1'))
1071            ->getFill()
1072            ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
1073            ->getStartColor()
1074            ->setARGB('523779');
1075
1076        $worksheet->getStyle('A1:' . (($n > 17) ? 'R1' : 'Q1'))
1077            ->getFont()
1078            ->getColor()
1079            ->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
1080
1081        $worksheet->getStyle('A1:' . (($n > 17) ? 'R1' : 'Q1'))->applyFromArray($styleArray);
1082        
1083        $l = 2;
1084        $result = $result->original['data'];
1085
1086        for ($i = 0; $i < count($result); $i++) { 
1087
1088            if($result[$i]->issue_date){
1089                $result[$i]->issue_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->issue_date);
1090            }
1091
1092            if($result[$i]->acceptance_date){
1093                $result[$i]->acceptance_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->acceptance_date);
1094            }
1095
1096            if($result[$i]->expected_start_date_of_work){
1097                $result[$i]->expected_start_date_of_work = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->expected_start_date_of_work);
1098            }
1099
1100            if($result[$i]->actual_job_start_date){
1101                $result[$i]->actual_job_start_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->actual_job_start_date);
1102            }
1103
1104            if($result[$i]->actual_end_date){
1105                $result[$i]->actual_end_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->actual_end_date);
1106            }
1107
1108            if($result[$i]->expected_completion_date){
1109                $result[$i]->expected_completion_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->expected_completion_date);
1110            }
1111
1112            if($result[$i]->created_at){
1113                $result[$i]->created_at = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->created_at);
1114            }
1115
1116            $worksheet->setCellValue('A' . $l, $result[$i]->quote_id);
1117            $worksheet->setCellValue('B' . $l, $result[$i]->client);
1118            $worksheet->setCellValue('C' . $l, $result[$i]->issue_date);
1119
1120            $worksheet->getStyle('C' . $l)
1121                ->getNumberFormat()
1122                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
1123
1124            $worksheet->setCellValue('D' . $l, $result[$i]->acceptance_date);
1125
1126            $worksheet->getStyle('D' . $l)
1127                ->getNumberFormat()
1128                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
1129
1130            $worksheet->setCellValue('E' . $l, $result[$i]->order_number);
1131            $worksheet->setCellValue('F' . $l, $result[$i]->type);
1132            $worksheet->setCellValue('G' . $l, $result[$i]->amount);
1133            $worksheet->setCellValue('H' . $l, $result[$i]->created_by);
1134            $worksheet->setCellValue('I' . $l, $result[$i]->responsible_for_work);
1135            $worksheet->setCellValue('J' . $l, $result[$i]->client_type);
1136            $worksheet->setCellValue('K' . $l, $result[$i]->segment);
1137            $worksheet->setCellValue('L' . $l, $result[$i]->invoice_amount);
1138            $worksheet->setCellValue('M' . $l, $result[$i]->expected_start_date_of_work);
1139
1140            $worksheet->getStyle('M' . $l)
1141                ->getNumberFormat()
1142                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
1143
1144            $worksheet->setCellValue('N' . $l, $result[$i]->actual_job_start_date);
1145
1146            $worksheet->getStyle('N' . $l)
1147                ->getNumberFormat()
1148                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
1149
1150            $worksheet->setCellValue('O' . $l, $result[$i]->actual_end_date);
1151
1152            $worksheet->getStyle('O' . $l)
1153                ->getNumberFormat()
1154                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
1155
1156            $worksheet->setCellValue('P' . $l, $result[$i]->expected_completion_date);
1157
1158            $worksheet->getStyle('P' . $l)
1159                ->getNumberFormat()
1160                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
1161                
1162            $worksheet->setCellValue('Q' . $l, $result[$i]->created_at);
1163
1164            $worksheet->getStyle('Q' . $l)
1165                ->getNumberFormat()
1166                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
1167
1168            if($n > 17){
1169                $worksheet->setCellValue('R' . $l, $result[$i]->company_name);
1170            }
1171                
1172            $l++;
1173            
1174        }
1175
1176        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
1177        ob_start();
1178        $writer->save('php://output');
1179        $file = ob_get_contents();
1180        ob_end_clean();
1181
1182        return response($file);
1183    }
1184
1185    function update_ongoing_job(Request $request, $id){
1186
1187        try {            
1188
1189            $data = $request->all();
1190            $id = addslashes($id);
1191            $userId = addslashes($data['user_id']);
1192            unset($data['user_id']);
1193
1194            $r = array('amount', 'order_number', 'budget_type_id', 'acceptance_date');
1195            $order = array();
1196
1197            foreach ($data as $key => $value) {
1198                if($value == 'null'){
1199                    $data[$key] = null;
1200                }
1201
1202                if(in_array($key, $r)){
1203                    $order[$key] = $value;
1204                }
1205            }
1206            
1207            $data['updated_at'] = date('Y-m-d H:i:s');
1208            $order['updated_at'] = $data['updated_at'];
1209
1210            $revenuePerMonth = array();
1211            if(isset($data['revenue_per_month'])){
1212                $revenuePerMonth = $data['revenue_per_month'];
1213                unset($data['revenue_per_month']);
1214            }
1215            
1216            $quotation = TblOngoingJobs::where('id', $id)->first();
1217
1218            if(count($revenuePerMonth) > 0){
1219                TblRevenuePerMonth::where('quotation_id', $quotation->quotation_id)->delete();
1220                for ($i = 0; $i < count($revenuePerMonth); $i++) {
1221                    unset($revenuePerMonth[$i]['duplicate']);
1222                    unset($revenuePerMonth[$i]['invoice_date']);
1223                    
1224                    $revenuePerMonth[$i]['created_by'] = $data['updated_by'];
1225                    $revenuePerMonth[$i]['quotation_id'] = $quotation->quotation_id;
1226
1227                    if(date('Yn') == $revenuePerMonth[$i]['year'] . $revenuePerMonth[$i]['month']){
1228                        $data['to_be_invoiced_this_month'] = $revenuePerMonth[$i]['amount'];
1229                    }
1230                }
1231                TblRevenuePerMonth::insert($revenuePerMonth);
1232            }
1233
1234            $result = TblOngoingJobs::where('id', $id)->update($data);
1235            TblQuotations::where('id', $quotation->quotation_id)->update($order);
1236
1237            $this->send_mail($quotation, $data, $id, $userId, 0, $data['updated_by']);
1238
1239            Cache::flush();
1240            return response(['message' => 'OK', 'data' => $result]);
1241
1242        } catch (\Exception $e) {
1243            /** @disregard P1014 */
1244            $e->exceptionCode = 'UPDATE_ONGOING_JOB_EXCEPTION'; 
1245            report($e);
1246            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1247        }
1248    }
1249
1250    public function get_dates(Request $request){
1251
1252        try {
1253
1254            $data = $request->all();
1255            $companyId = addslashes($data['company_id']);
1256
1257            $where = "";
1258            if($companyId != 0){
1259                $where = " a.company_id = {$companyId} ";
1260            }else{
1261                $where = " a.company_id IN ({$this->companyId}";
1262            }
1263            
1264            $query = "SELECT
1265                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
1266                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
1267                        DATE_FORMAT(a.expected_start_date_of_work, '%d/%m/%Y') expected_start_date_of_work_translate,
1268                        DATE_FORMAT(a.actual_job_start_date, '%d/%m/%Y') actual_job_start_date_translate,
1269                        DATE_FORMAT(a.actual_end_date, '%d/%m/%Y') actual_end_date_translate,
1270                        DATE_FORMAT(a.expected_completion_date, '%d/%m/%Y') expected_completion_date_translate,
1271                        DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate
1272                    FROM tbl_ongoing_jobs a
1273                    WHERE {$where}";
1274
1275            $result = DB::select($query);
1276
1277            return response([
1278                'message' => 'OK', 
1279                'data' => $result
1280            ]);
1281
1282        } catch (\Exception $e) {
1283            /** @disregard P1014 */
1284            $e->exceptionCode = 'GET_DATES_EXCEPTION'; 
1285            report($e);
1286            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1287        }
1288
1289    }
1290
1291    function get_job($jobId){
1292
1293        try {
1294
1295            $jobId = addslashes($jobId);
1296
1297            $query = "SELECT 
1298                        a.id,
1299                        a.quotation_id, 
1300                        b.name company_name, 
1301                        c.name client_type,
1302                        s.name segment,
1303                        s.segment_id,
1304                        d.name 'type',
1305                        a.quote_id, 
1306                        a.company_id,
1307                        a.customer_type_id,
1308                        a.budget_type_id,
1309                        a.order_number,
1310                        a.client,
1311                        a.issue_date,
1312                        a.acceptance_date, 
1313                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
1314                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
1315                        a.amount, 
1316                        a.created_by, 
1317                        a.created_at,
1318                        a.updated_by,
1319                        a.updated_at,
1320                        a.invoice_amount,
1321                        a.responsible_for_work,
1322                        a.expected_start_date_of_work,
1323                        a.actual_job_start_date, 
1324                        a.actual_end_date, 
1325                        a.expected_completion_date, 
1326                        DATE_FORMAT(a.expected_start_date_of_work, '%d/%m/%Y') expected_start_date_of_work_translate,
1327                        DATE_FORMAT(a.actual_job_start_date, '%d/%m/%Y') actual_job_start_date_translate,
1328                        DATE_FORMAT(a.actual_end_date, '%d/%m/%Y') actual_end_date_translate,
1329                        DATE_FORMAT(a.expected_completion_date, '%d/%m/%Y') expected_completion_date_translate,
1330                        DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate,
1331                        a.work_status_id,
1332                        e.name work_status,
1333                        a.cost_for_client,
1334                        a.people_assigned_to_the_job,
1335                        a.duration_of_job_in_days,
1336                        a.estimated_cost_of_materials,
1337                        a.for_approval,
1338                        a.cost_of_labor,
1339                        a.total_cost_of_job,
1340                        a.invoice_margin,
1341                        a.margin_for_the_company,
1342                        a.margin_on_invoice_per_day_per_worker,
1343                        a.revenue_per_date_per_worked,
1344                        a.gross_margin,
1345                        a.labor_percentage,
1346                        a.pending_to_be_invoiced,
1347                        g.amount to_be_invoiced_this_month,
1348                        a.to_be_invoiced_after_this_month,
1349                        a.approved_at,
1350                        a.approved_by,
1351                        a.rejected_at,
1352                        a.rejected_by,
1353                        CASE 
1354                            WHEN 
1355                                (g.amount IS NULL OR g.amount = '')
1356                                AND (a.pending_to_be_invoiced IS NOT NULL AND a.pending_to_be_invoiced <> '' AND a.pending_to_be_invoiced <> 0)
1357                                AND DATE_FORMAT(NOW(), '%Y-%m-%d') BETWEEN DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_job_start_date ELSE a.expected_start_date_of_work END, '%Y-%m-%d') 
1358                                AND DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_end_date ELSE a.expected_completion_date END , '%Y-%m-%d') 
1359                            THEN 1
1360                            ELSE 0
1361                        END is_red_invoiced
1362                    FROM 
1363                        tbl_ongoing_jobs a 
1364                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
1365                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
1366                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
1367                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
1368                        LEFT JOIN tbl_work_status e ON a.work_status_id = e.work_status_id
1369                        LEFT JOIN tbl_revenue_per_month g ON a.quotation_id = g.quotation_id AND g.month = MONTH(NOW()) AND g.year = YEAR(NOW())
1370                    WHERE a.id = {$jobId}";
1371
1372            $result = DB::select($query);
1373
1374            Cache::flush();
1375            return response(['message' => 'OK', 'data' => $result]);
1376
1377        } catch (\Exception $e) {
1378            /** @disregard P1014 */
1379            $e->exceptionCode = 'GET_JOB_EXCEPTION'; 
1380            report($e);
1381            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1382        }
1383    }
1384
1385    function list_job_analytics(Request $request){
1386
1387        try {
1388
1389            $data = $request->all();
1390            $companyId = addslashes($data['company_id']);
1391
1392            $where = "";
1393            $whereYears = "";
1394            $whereMonths = "";
1395
1396            if($companyId != 0){
1397                $where .= " AND company_id = {$companyId} ";
1398            }else{
1399                $where .= " AND company_id IN ({$this->companyId}";
1400            }
1401
1402            if(isset($data['start_years']) && $data['start_years'] != null){
1403                $years = implode(',', $data['start_years']);
1404                if(count($data['start_years']) > 0){
1405                    $whereYears = " AND YEAR(expected_start_date_of_work) IN ({$years})";
1406                }
1407            }
1408
1409            if(isset($data['start_months']) && $data['start_months'] != null){
1410                $months = implode(',', $data['start_months']);
1411                if(count($data['start_months']) > 0){
1412                    $whereMonths = " AND MONTH(expected_start_date_of_work) IN ({$months})";
1413                }
1414            }
1415
1416            if(isset($data['end_years']) && $data['end_years'] != null){
1417                $years = implode(',', $data['end_years']);
1418                if(count($data['end_years']) > 0){
1419                    $whereYears .= " AND YEAR(expected_completion_date) IN ({$years})";
1420                }
1421            }
1422
1423            if(isset($data['end_months']) && $data['end_months'] != null){
1424                $months = implode(',', $data['end_months']);
1425                if(count($data['end_months']) > 0){
1426                    $whereMonths .= " AND MONTH(expected_completion_date) IN ({$months})";
1427                }
1428            }
1429
1430            if(isset($data['responsible_for_work']) && $data['responsible_for_work'] != null){
1431                $responsible = implode("','", $data['responsible_for_work']);
1432                if(count($data['responsible_for_work']) > 0){
1433                    $where .= " AND a.responsible_for_work IN ('{$responsible}')";
1434                }
1435            }
1436
1437            if(isset($data['work_status_id']) && $data['work_status_id'] != null){
1438                $work = implode(',', $data['work_status_id']);
1439                if(count($data['work_status_id']) > 0){
1440                    $where .= " AND a.work_status_id IN ({$work})";
1441                }
1442            }
1443
1444            if(isset($data['budget_type_id']) && $data['budget_type_id'] != null){
1445                $budget = implode(',', $data['budget_type_id']);
1446                if(count($data['budget_type_id']) > 0){
1447                    $where .= " AND a.budget_type_id IN ({$budget})";
1448                }
1449            }
1450            
1451            $query = "SELECT
1452                        YEAR 'year',
1453                        MONTH 'month',
1454                        WEEK 'week',
1455                        SUM(acceptance_date) AS totalApproved,
1456                        SUM(expected_start_date_of_work) AS totalJobsExpectedToStart,
1457                        SUM(expected_completion_date) AS totalJobsExpectedToFinalized,
1458                        SUM(actual_job_start_date) AS totalJobsStarted,
1459                        SUM(actual_end_date) AS totalJobsFinalized,
1460                        SUM(revenueExpected) AS revenueExpected,
1461                        SUM(realRevenue) AS realRevenue
1462                    FROM (
1463                        SELECT
1464                            YEAR(acceptance_date) AS YEAR,
1465                            MONTH(acceptance_date) AS MONTH,
1466                            WEEK(acceptance_date) AS WEEK,
1467                            COUNT(*) AS acceptance_date,
1468                            0 AS expected_start_date_of_work,
1469                            0 AS expected_completion_date,
1470                            0 AS actual_job_start_date,
1471                            0 AS actual_end_date,
1472                            0 AS revenueExpected,
1473                            0 AS realRevenue
1474                        FROM
1475                            tbl_ongoing_jobs
1476                        WHERE 
1477                            issue_date IS NOT NULL
1478                            {$where}
1479                            {$whereYears}
1480                            {$whereMonths}
1481                        GROUP BY
1482                            YEAR(acceptance_date),
1483                            MONTH(acceptance_date),
1484                            WEEK(acceptance_date)
1485                    
1486                        UNION ALL
1487
1488                        SELECT
1489                            YEAR(expected_start_date_of_work) AS YEAR,
1490                            MONTH(expected_start_date_of_work) AS MONTH,
1491                            WEEK(expected_start_date_of_work) AS WEEK,
1492                            0 AS acceptance_date,
1493                            COUNT(*) AS expected_start_date_of_work,
1494                            0 AS expected_completion_date,
1495                            0 AS actual_job_start_date,
1496                            0 AS actual_end_date,
1497                            0 AS revenueExpected,
1498                            0 AS realRevenue
1499                        FROM
1500                            tbl_ongoing_jobs
1501                        WHERE 
1502                            issue_date IS NOT NULL
1503                            {$where}
1504                            {$whereYears}
1505                            {$whereMonths}
1506                        GROUP BY
1507                            YEAR(expected_start_date_of_work),
1508                            MONTH(expected_start_date_of_work),
1509                            WEEK(expected_start_date_of_work)
1510                    
1511                        UNION ALL
1512                    
1513                        SELECT
1514                            YEAR(expected_completion_date) AS YEAR,
1515                            MONTH(expected_completion_date) AS MONTH,
1516                            WEEK(expected_completion_date) AS WEEK,
1517                            0 AS acceptance_date,
1518                            0 AS expected_start_date_of_work,
1519                            COUNT(*) AS expected_completion_date,
1520                            0 AS actual_job_start_date,
1521                            0 AS actual_end_date,
1522                            0 AS revenueExpected,
1523                            0 AS realRevenue
1524                        FROM
1525                            tbl_ongoing_jobs
1526                        WHERE 
1527                            issue_date IS NOT NULL
1528                            {$where}
1529                            {$whereYears}
1530                            {$whereMonths}
1531                        GROUP BY
1532                            YEAR(expected_completion_date),
1533                            MONTH(expected_completion_date),
1534                            WEEK(expected_completion_date)
1535                    
1536                        UNION ALL
1537                    
1538                        SELECT
1539                            YEAR(actual_job_start_date) AS YEAR,
1540                            MONTH(actual_job_start_date) AS MONTH,
1541                            WEEK(actual_job_start_date) AS WEEK,
1542                            0 AS acceptance_date,
1543                            0 AS expected_start_date_of_work,
1544                            0 AS expected_completion_date,
1545                            COUNT(*) AS actual_job_start_date,
1546                            0 AS actual_end_date,
1547                            0 AS revenueExpected,
1548                            0 AS realRevenue
1549                        FROM
1550                            tbl_ongoing_jobs
1551                        WHERE 
1552                            issue_date IS NOT NULL
1553                            {$where}
1554                            {$whereYears}
1555                            {$whereMonths}
1556                        GROUP BY
1557                            YEAR(actual_job_start_date),
1558                            MONTH(actual_job_start_date),
1559                            WEEK(actual_job_start_date)
1560                    
1561                        UNION ALL
1562                    
1563                        SELECT
1564                            YEAR(actual_end_date) AS YEAR,
1565                            MONTH(actual_end_date) AS MONTH,
1566                            WEEK(actual_end_date) AS WEEK,
1567                            0 AS acceptance_date,
1568                            0 AS expected_start_date_of_work,
1569                            0 AS expected_completion_date,
1570                            0 AS actual_job_start_date,
1571                            COUNT(*) AS actual_end_date,
1572                            0 AS revenueExpected,
1573                            0 AS realRevenue
1574                        FROM
1575                            tbl_ongoing_jobs
1576                        WHERE 
1577                            issue_date IS NOT NULL
1578                            {$where}
1579                            {$whereYears}
1580                            {$whereMonths}
1581                        GROUP BY
1582                            YEAR(actual_end_date),
1583                            MONTH(actual_end_date),
1584                            WEEK(actual_end_date)
1585                    
1586                        UNION ALL
1587                    
1588                        SELECT
1589                            YEAR(expected_completion_date) AS YEAR,
1590                            MONTH(expected_completion_date) AS MONTH,
1591                            WEEK(expected_completion_date) AS WEEK,
1592                            0 AS acceptance_date,
1593                            0 AS expected_start_date_of_work,
1594                            0 AS expected_completion_date,
1595                            0 AS actual_job_start_date,
1596                            0 AS actual_end_date,
1597                            SUM(CASE WHEN cost_for_client REGEXP '^[0-9]+\\.?[0-9]*$' = 1 THEN cost_for_client END) AS revenueExpected,
1598                            SUM(CASE WHEN invoice_amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1 THEN invoice_amount END) AS realRevenue
1599                        FROM
1600                            tbl_ongoing_jobs
1601                        WHERE 
1602                            issue_date IS NOT NULL
1603                            {$where}
1604                            {$whereYears}
1605                            {$whereMonths}
1606                        GROUP BY
1607                            YEAR(expected_completion_date),
1608                            MONTH(expected_completion_date),
1609                            WEEK(expected_completion_date)
1610                    ) AS subquery
1611                    GROUP BY 
1612                        YEAR, 
1613                        MONTH, 
1614                        WEEK WITH ROLLUP
1615                    HAVING 
1616                        (YEAR IS NOT NULL OR MONTH IS NOT NULL OR WEEK IS NOT NULL)
1617                    ORDER BY
1618                        YEAR, MONTH, WEEK;
1619                    ";
1620            
1621            $result = DB::select($query);
1622
1623            return response([
1624                'message' => 'OK', 
1625                'data' => $result,
1626            ]);
1627            
1628        } catch (\Exception $e) {
1629            /** @disregard P1014 */
1630            $e->exceptionCode = 'LIST_JOB_ANALYTICS_EXCEPTION'; 
1631            report($e);
1632            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1633        }
1634
1635    }
1636
1637    function get_years(Request $request){
1638
1639        try {
1640
1641            $data = $request->all();
1642            $companyId = addslashes($data['company_id']);
1643            $where = "";
1644
1645            if($companyId != 0){
1646                $where = " AND company_id = {$companyId} ";
1647            }else{
1648                $where = " AND company_id IN ({$this->companyId}";
1649            }
1650    
1651            $query = "SELECT 
1652                            DISTINCT YEAR(acceptance_date) AS 'year' 
1653                        FROM 
1654                            tbl_ongoing_jobs 
1655                        WHERE 
1656                            acceptance_date IS NOT NULL 
1657                            {$where}
1658                        UNION 
1659                        SELECT 
1660                            DISTINCT YEAR(actual_job_start_date) AS 'year' 
1661                        FROM 
1662                            tbl_ongoing_jobs 
1663                        WHERE 
1664                            actual_job_start_date IS NOT NULL 
1665                            {$where}
1666                        UNION 
1667                        SELECT 
1668                            DISTINCT YEAR(expected_start_date_of_work) AS 'year' 
1669                        FROM 
1670                            tbl_ongoing_jobs 
1671                        WHERE 
1672                            expected_start_date_of_work IS NOT NULL 
1673                            {$where}
1674                        UNION 
1675                        SELECT 
1676                            DISTINCT YEAR(actual_end_date) AS 'year' 
1677                        FROM 
1678                            tbl_ongoing_jobs 
1679                        WHERE 
1680                            actual_end_date IS NOT NULL 
1681                            {$where}
1682                        UNION 
1683                        SELECT 
1684                            DISTINCT YEAR(expected_completion_date) AS 'year' 
1685                        FROM 
1686                            tbl_ongoing_jobs 
1687                        WHERE 
1688                            expected_completion_date IS NOT NULL 
1689                            {$where}
1690                        ORDER BY 
1691                            YEAR
1692                            ";
1693                            
1694            $result = DB::select($query);
1695
1696            return response([
1697                'message' => 'OK', 
1698                'data' => $result,
1699            ]);
1700
1701
1702        } catch (\Exception $e) {
1703            /** @disregard P1014 */
1704            $e->exceptionCode = 'GET_YEARS_EXCEPTION'; 
1705            report($e);
1706            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1707        }
1708
1709    }
1710
1711    public function list_margin_jobs_analytics(Request $request){
1712
1713        try {
1714
1715            $data = $request->all();
1716            $companyId = addslashes($data['company_id']);
1717            $responsibleForWork = $data['user'];
1718            $where = "";
1719            $whereYear = "";
1720            $whereMonths = "";
1721
1722            if($companyId != 0){
1723                $where .= " AND a.company_id = {$companyId} ";
1724            }else{
1725                $where .= " AND a.company_id IN ({$this->companyId}";
1726            }
1727
1728            if(isset($data['start_years']) && $data['start_years'] != null){
1729                $years = implode(',', $data['start_years']);
1730                if(count($data['start_years']) > 0){
1731                    $whereYear = " AND YEAR(a.expected_start_date_of_work) IN ({$years})";
1732                }
1733            }
1734
1735            if(isset($data['start_months']) && $data['start_months'] != null){
1736                $months = implode(',', $data['start_months']);
1737                if(count($data['start_months']) > 0){
1738                    $whereMonths = " AND MONTH(a.expected_start_date_of_work) IN ({$months})";
1739                }
1740            }
1741
1742            if(isset($data['end_years']) && $data['end_years'] != null){
1743                $years = implode(',', $data['end_years']);
1744                if(count($data['end_years']) > 0){
1745                    $whereYear .= " AND YEAR(a.expected_completion_date) IN ({$years})";
1746                }
1747            }
1748
1749            if(isset($data['end_months']) && $data['end_months'] != null){
1750                $months = implode(',', $data['end_months']);
1751                if(count($data['end_months']) > 0){
1752                    $whereMonths .= " AND MONTH(a.expected_completion_date) IN ({$months})";
1753                }
1754            }
1755
1756            if(isset($data['responsible_for_work']) && $data['responsible_for_work'] != null){
1757                $responsible = implode("','", $data['responsible_for_work']);
1758                if(count($data['responsible_for_work']) > 0){
1759                    $where .= " AND a.responsible_for_work IN ('{$responsible}')";
1760                }
1761            }
1762
1763            if(isset($data['work_status_id']) && $data['work_status_id'] != null){
1764                $work = implode(',', $data['work_status_id']);
1765                if(count($data['work_status_id']) > 0){
1766                    $where .= " AND a.work_status_id IN ({$work})";
1767                }
1768            }
1769
1770            if(isset($data['budget_type_id']) && $data['budget_type_id'] != null){
1771                $budget = implode(',', $data['budget_type_id']);
1772                if(count($data['budget_type_id']) > 0){
1773                    $where .= " AND a.budget_type_id IN ({$budget})";
1774                }
1775            }
1776
1777            $whereInconsistent = "";
1778            if(isset($data['status']) && $data['status'] != null){
1779                if($data['status'] == 1){
1780                    $whereInconsistent = " AND ((DATE_FORMAT(a.expected_start_date_of_work, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d') AND a.work_status_id = 2
1781                        OR DATE_FORMAT(a.expected_completion_date, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d') AND a.work_status_id NOT IN (3, 5))
1782                        ) AND (CASE WHEN a.responsible_for_work IS NULL THEN a.created_by ELSE a.responsible_for_work END) = '{$responsibleForWork}'";
1783                }elseif($data['status'] == 2){
1784                    $whereInconsistent = " AND ((g.amount IS NULL OR g.amount = '')
1785                        AND (CASE WHEN a.responsible_for_work IS NULL THEN a.created_by ELSE a.responsible_for_work END) = '{$responsibleForWork}'
1786                        AND DATE_FORMAT(NOW(), '%Y-%m-%d') BETWEEN DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_job_start_date ELSE a.expected_start_date_of_work END, '%Y-%m-%d') 
1787                        AND DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_end_date ELSE a.expected_completion_date END , '%Y-%m-%d') ) ";
1788                }
1789            }
1790
1791            $activeJobWhere = "";
1792            $activeJob = 0;
1793            
1794            $activeStartDateColumn = "CASE WHEN a.work_status_id IN (1,2,4) THEN expected_start_date_of_work ELSE actual_job_start_date END";    
1795            $activeEndDateColumn = "CASE WHEN a.work_status_id IN (1,2,4) THEN expected_completion_date ELSE actual_end_date END";
1796
1797            if(isset($data['active_year']) && $data['active_year'] != null){
1798                $activeJobWhere = " AND {$data['active_year']} 
1799                    BETWEEN YEAR({$activeStartDateColumn}
1800                    AND YEAR({$activeEndDateColumn}";
1801                $activeJob++;
1802            }
1803
1804            $gMonth = "MONTH(NOW())";
1805            $gYear = "YEAR(NOW())";
1806
1807            if(isset($data['active_month']) && $data['active_month'] != null){
1808                $gMonth = $data['active_month'];
1809                if(empty($data['active_year'])){
1810                    $r = new Request([
1811                        'company_id'=> $companyId
1812                    ]);
1813                    $getYears = $this->get_years($r);
1814                    $years = $getYears->original['data'];
1815
1816                    $activeJobWhereArray = array();
1817                    foreach ($years as $k => $v) {
1818                        $activeJobWhere = " CONCAT('{$years[$k]->year}', '-', LPAD('{$data['active_month']}', 2, 0)) BETWEEN DATE_FORMAT({$activeStartDateColumn}, '%Y-%m') AND DATE_FORMAT({$activeEndDateColumn} , '%Y-%m') ";
1819                        array_push($activeJobWhereArray, $activeJobWhere);
1820                    }
1821
1822                    $activeJobWhere = implode(' OR ', $activeJobWhereArray);
1823                    $activeJobWhere = " AND ({$activeJobWhere}";
1824                }
1825
1826                $activeJob++;
1827            }
1828
1829            if($activeJob == 2){
1830                $gYear = $data['active_year'];
1831                $activeJobWhere = " AND CONCAT('{$data['active_year']}', '-', LPAD('{$data['active_month']}', 2, 0)) BETWEEN DATE_FORMAT({$activeStartDateColumn}, '%Y-%m') AND DATE_FORMAT({$activeEndDateColumn} , '%Y-%m') ";
1832            }
1833
1834            $where .= $activeJobWhere;
1835            
1836            $query = "SELECT
1837                            a.id,
1838                            a.quotation_id, 
1839                            b.name company_name, 
1840                            c.name client_type,
1841                            s.name segment,
1842                            s.segment_id,
1843                            d.name 'type',
1844                            a.quote_id, 
1845                            a.company_id,
1846                            a.customer_type_id,
1847                            a.budget_type_id,
1848                            a.order_number,
1849                            a.client,
1850                            a.issue_date,
1851                            a.acceptance_date, 
1852                            DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
1853                            DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
1854                            a.amount, 
1855                            a.created_by, 
1856                            a.created_at,
1857                            a.updated_by,
1858                            a.updated_at,
1859                            a.invoice_amount,
1860                            a.responsible_for_work,
1861                            a.expected_start_date_of_work,
1862                            a.actual_job_start_date, 
1863                            a.actual_end_date, 
1864                            a.expected_completion_date, 
1865                            DATE_FORMAT(a.expected_start_date_of_work, '%d/%m/%Y') expected_start_date_of_work_translate,
1866                            DATE_FORMAT(a.actual_job_start_date, '%d/%m/%Y') actual_job_start_date_translate,
1867                            DATE_FORMAT(a.actual_end_date, '%d/%m/%Y') actual_end_date_translate,
1868                            DATE_FORMAT(a.expected_completion_date, '%d/%m/%Y') expected_completion_date_translate,
1869                            DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate,
1870                            a.work_status_id,
1871                            e.name work_status,
1872                            CASE 
1873                                WHEN 
1874                                DATE_FORMAT(a.expected_completion_date, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d') AND a.work_status_id NOT IN (3, 5)
1875                                THEN 1
1876                                ELSE 0
1877                            END is_red_expected_completion_date,
1878                            CASE 
1879                                WHEN 
1880                                DATE_FORMAT(a.expected_start_date_of_work, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d') AND a.work_status_id = 2
1881                                THEN 1
1882                                ELSE 0
1883                            END is_red_expected_start_date_of_work,
1884                            CASE 
1885                                WHEN 
1886                                    (g.amount IS NULL OR g.amount = '')
1887                                    AND (a.pending_to_be_invoiced IS NOT NULL AND a.pending_to_be_invoiced <> '' AND a.pending_to_be_invoiced <> 0)
1888                                    AND DATE_FORMAT(NOW(), '%Y-%m-%d') BETWEEN DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_job_start_date ELSE a.expected_start_date_of_work END, '%Y-%m-%d') 
1889                                    AND DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_end_date ELSE a.expected_completion_date END , '%Y-%m-%d') 
1890                                THEN 1
1891                                ELSE 0
1892                            END is_red_invoiced,
1893                            a.cost_for_client,
1894                            a.people_assigned_to_the_job,
1895                            a.duration_of_job_in_days,
1896                            a.estimated_cost_of_materials,
1897                            a.cost_of_labor,
1898                            a.total_cost_of_job,
1899                            a.invoice_margin,
1900                            a.margin_for_the_company,
1901                            a.margin_on_invoice_per_day_per_worker,
1902                            a.revenue_per_date_per_worked,
1903                            a.gross_margin,
1904                            a.labor_percentage,
1905                            a.pending_to_be_invoiced,
1906                            (SELECT amount FROM tbl_revenue_per_month WHERE quotation_id = a.quotation_id AND month = {$gMonth} AND year = {$gYear}) to_be_invoiced_this_month,
1907                            a.to_be_invoiced_after_this_month,
1908                            a.for_approval,
1909                            a.approved_at,
1910                            a.approved_by,
1911                            a.rejected_at,
1912                            a.rejected_by,
1913                            d.color,
1914                            e.color color_work_status,
1915                            CASE 
1916                                WHEN f.budget_type_id IS NULL THEN b.revenue_per_employee_per_day
1917                                ELSE f.revenue_per_employee_per_day
1918                            END revenue_per_employee_per_day,
1919                            CASE 
1920                                WHEN CAST(f.revenue_per_employee_per_day AS DOUBLE) > CAST(a.revenue_per_date_per_worked AS DOUBLE) AND f.budget_type_id IS NOT NULL THEN 1
1921                                WHEN CAST(b.revenue_per_employee_per_day AS DOUBLE) > CAST(a.revenue_per_date_per_worked AS DOUBLE) AND f.budget_type_id IS NULL THEN 1
1922                                ELSE 0
1923                            END is_below_benchmark
1924                        FROM tbl_ongoing_jobs a
1925                            LEFT JOIN tbl_companies b ON a.company_id = b.company_id
1926                            LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
1927                            LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
1928                            LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
1929                            LEFT JOIN tbl_work_status e ON a.work_status_id = e.work_status_id
1930                            LEFT JOIN tbl_project_types f ON a.budget_type_id = f.budget_type_id AND a.company_id = f.company_id
1931                            LEFT JOIN tbl_revenue_per_month g ON a.quotation_id = g.quotation_id AND g.month = MONTH(NOW()) AND g.year = YEAR(NOW())
1932                        WHERE a.issue_date 
1933                        AND a.expected_start_date_of_work IS NOT NULL
1934                        {$where}
1935                        {$whereYear}
1936                        {$whereMonths}
1937                        {$whereInconsistent}
1938                        ORDER BY a.client ASC";
1939            
1940            $result = DB::select($query);
1941
1942            $durationOfJobInDays = 0;
1943            $peopleAssignedToTheJob = 0;
1944            $totaCostForClient = 0;
1945            $totalCostOfLabor = 0;
1946            $totalMaterialCosts = 0;
1947            $revenuePerDayPerWorked = 0;
1948            $toBeInvoiceIn = 0;
1949            $pAndD = 0;
1950
1951            foreach ($result as $item) {
1952                $durationOfJobInDays = $durationOfJobInDays + $item->duration_of_job_in_days;
1953                $peopleAssignedToTheJob = $peopleAssignedToTheJob + $item->people_assigned_to_the_job;
1954                $totaCostForClient = $totaCostForClient + $item->cost_for_client;
1955                $totalCostOfLabor = $totalCostOfLabor + $item->cost_of_labor;
1956                $totalMaterialCosts = $totalMaterialCosts + $item->estimated_cost_of_materials;
1957                $toBeInvoiceIn = $toBeInvoiceIn + $item->to_be_invoiced_this_month;
1958                $pAndD = $pAndD + ($item->people_assigned_to_the_job * $item->duration_of_job_in_days);
1959            }
1960            
1961            $totalCostOfJob = $totalCostOfLabor + $totalMaterialCosts;
1962
1963            $invoiceMargin = 0;
1964            $grossMargin = 0;
1965            $laborPercentage = 0;
1966            $marginForTheCompany = 0;
1967            if($totalCostOfJob > 0){
1968                $invoiceMargin = ($totaCostForClient - $totalCostOfJob) / $totaCostForClient * 100;
1969                $grossMargin = ($totaCostForClient - $totalMaterialCosts) / $totaCostForClient * 100;
1970                $laborPercentage = ($totalCostOfLabor / $totaCostForClient) * 100;
1971
1972                $company = TblCompanies::where('company_id', $companyId)->first();
1973                if($company){
1974                    $marginForTheCompany = $invoiceMargin - $company->hours_per_worker_per_day_percentage;
1975                }
1976            }
1977
1978            if ($pAndD != 0) {
1979                $revenuePerDayPerWorked = $totaCostForClient / $pAndD;
1980            }
1981
1982            $resultTotal = array(
1983                'durationOfJobInDays' => $durationOfJobInDays,
1984                'peopleAssignedToTheJob' => $peopleAssignedToTheJob,
1985                'totalCostForClient' => $totaCostForClient,
1986                'totalCostOfLabor' => $totalCostOfLabor,
1987                'totalMaterialCosts' => $totalMaterialCosts,
1988                'invoiceMargin' => $invoiceMargin,
1989                'marginForTheCompany' => $marginForTheCompany,
1990                'revenuePerDayPerWorked' => $revenuePerDayPerWorked,
1991                'toBeInvoiceIn' => $toBeInvoiceIn,
1992                'grossMargin' => $grossMargin,
1993                'laborPercentage' => $laborPercentage
1994            );
1995
1996            return response([
1997                'message' => 'OK', 
1998                'data' => $result,
1999                'totals' => $resultTotal
2000            ]);
2001
2002
2003        } catch (\Exception $e) {
2004            /** @disregard P1014 */
2005            $e->exceptionCode = 'LIST_MARGIN_JOB_ANALYTICS_EXCEPTION'; 
2006            report($e);
2007            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2008        }
2009    }
2010
2011    function get_total_jobs_in_red(Request $request){
2012
2013        try {
2014            
2015            $data = $request->all();
2016            $companyId = addslashes($data['company_id']);
2017            $responsibleForWork = $data['responsible_for_work'];
2018            $where = "";
2019
2020            if($companyId != 0){
2021                $where .= " AND a.company_id = {$companyId} ";
2022            }else{
2023                $where .= " AND a.company_id IN ({$this->companyId}";
2024            }
2025
2026            $query = "SELECT
2027                        COUNT(1) total
2028                    FROM tbl_ongoing_jobs a
2029                    WHERE 
2030                        a.expected_start_date_of_work IS NOT NULL
2031                        AND (
2032                            DATE_FORMAT(a.expected_start_date_of_work, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d') AND a.work_status_id = 2
2033                            OR DATE_FORMAT(a.expected_completion_date, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d') AND a.work_status_id NOT IN (3, 5)                            
2034                        )
2035                        AND (CASE WHEN responsible_for_work IS NULL THEN created_by ELSE responsible_for_work END) = '{$responsibleForWork}'
2036                        {$where}";
2037            
2038            $result = DB::select($query);
2039
2040            $query = "SELECT
2041                        COUNT(1) total
2042                    FROM tbl_ongoing_jobs a
2043                    LEFT JOIN tbl_revenue_per_month g ON a.quotation_id = g.quotation_id AND g.month = MONTH(NOW()) AND g.year = YEAR(NOW())
2044                    WHERE 
2045                        a.expected_start_date_of_work IS NOT NULL
2046                        AND ((g.amount IS NULL OR g.amount = '')
2047                        AND (CASE WHEN responsible_for_work IS NULL THEN a.created_by ELSE responsible_for_work END) = '{$responsibleForWork}')
2048                        AND DATE_FORMAT(NOW(), '%Y-%m-%d') BETWEEN DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_job_start_date ELSE a.expected_start_date_of_work END, '%Y-%m-%d') 
2049                        AND DATE_FORMAT(CASE WHEN a.work_status_id = 3 OR a.work_status_id = 5 THEN a.actual_end_date ELSE a.expected_completion_date END , '%Y-%m-%d') 
2050                        {$where}";
2051
2052            $invoiced = DB::select($query);
2053
2054            $query = "SELECT COUNT(1) total FROM tbl_quotations a WHERE DATE_FORMAT(a.visit_date, '%Y-%m-%d') < DATE_FORMAT(NOW(), '%Y-%m-%d') AND a.commercial = '{$responsibleForWork}' AND a.budget_status_id = 8 {$where}";            
2055            $countPastVisitDate = DB::select($query);
2056
2057            $query = "SELECT 
2058                            COUNT(1) total
2059                        FROM tbl_quotations a 
2060                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2061                        LEFT JOIN (
2062                                    SELECT
2063                                    a.id,
2064                                    SUBSTRING_INDEX(
2065                                        SUBSTRING_INDEX(a.email, ',', n.digit + 1),
2066                                        ',',
2067                                        -1
2068                                    ) AS email_domain
2069                                    FROM
2070                                    tbl_quotations a
2071                                    INNER JOIN (
2072                                        SELECT
2073                                        0 AS digit
2074                                        UNION ALL
2075                                        SELECT
2076                                        1
2077                                        UNION ALL
2078                                        SELECT
2079                                        2
2080                                        UNION ALL
2081                                        SELECT
2082                                        3
2083                                        UNION ALL
2084                                        SELECT
2085                                        4
2086                                        UNION ALL
2087                                        SELECT
2088                                        5
2089                                        UNION ALL
2090                                        SELECT
2091                                        6
2092                                        UNION ALL
2093                                        SELECT
2094                                        7
2095                                        UNION ALL
2096                                        SELECT
2097                                        8
2098                                        UNION ALL
2099                                        SELECT
2100                                        9
2101                                    ) n ON LENGTH(
2102                                        REPLACE(a.email, ',', '')
2103                                    ) <= LENGTH(a.email)- n.digit
2104                                    GROUP BY a.id
2105                                ) temp ON a.id = temp.id
2106                        WHERE
2107                            a.last_follow_up_date < DATE_SUB(NOW(), INTERVAL 2 DAY)
2108                            AND a.budget_status_id IN (2)
2109                            AND a.email IS NOT NULL
2110                            AND a.email <> ''
2111                            AND NOT EXISTS (
2112                                SELECT
2113                                1
2114                                FROM
2115                                tbl_blocked_domains bd
2116                                WHERE
2117                                temp.email_domain LIKE CONCAT('%', bd.domain, '%')
2118                                AND bd.company_id = a.company_id
2119                            )
2120                            AND a.last_follow_up_date IS NOT NULL
2121                            AND a.reason_for_not_following_up_id IS NULL
2122                            AND a.last_follow_up_date > 0
2123                            AND a.total_sent < b.limit_reminder_emails
2124                            AND a.for_add = 0
2125                            AND a.commercial = '{$responsibleForWork}'
2126                            {$where}";
2127            
2128            $countReminders = DB::select($query);
2129
2130            return response([
2131                'message' => 'OK', 
2132                'data' => $result[0]->total,
2133                'invoiced' => $invoiced[0]->total,
2134                'totalPastVisitDate' => $countPastVisitDate[0]->total,
2135                'totalReminders' => $countReminders[0]->total
2136            ]);
2137
2138
2139        } catch (\Exception $e) {
2140            /** @disregard P1014 */
2141            $e->exceptionCode = 'GET_TOTAL_JOBS_IN_RED_EXCEPTION'; 
2142            report($e);
2143            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2144        }
2145    }
2146
2147    public function get_active_job_dates($companyId){
2148
2149        try {
2150            
2151            $companyId = addslashes($companyId);
2152            $where = "";
2153
2154            if($companyId != 0){
2155                $where .= " AND company_id = {$companyId} ";
2156            }else{
2157                $where .= " AND company_id IN ({$this->companyId}";
2158            }
2159
2160            $query = "SELECT 
2161                        DISTINCT years 
2162                    FROM 
2163                        (
2164                        SELECT 
2165                            YEAR(expected_start_date_of_work) AS years 
2166                        FROM 
2167                            tbl_ongoing_jobs 
2168                        WHERE 
2169                            expected_start_date_of_work IS NOT NULL 
2170                            {$where}
2171                        UNION 
2172                        SELECT 
2173                            YEAR(expected_completion_date) AS years 
2174                        FROM 
2175                            tbl_ongoing_jobs 
2176                        WHERE 
2177                            expected_completion_date IS NOT NULL
2178                            {$where}
2179                        ) AS combined_years 
2180                    ORDER BY 
2181                        years DESC
2182                    ";
2183
2184            $activeYears = DB::select($query);
2185
2186            $query = "SELECT 
2187                        DISTINCT months 
2188                    FROM 
2189                        (
2190                        SELECT 
2191                            MONTH(expected_start_date_of_work) AS months 
2192                        FROM 
2193                            tbl_ongoing_jobs 
2194                        WHERE 
2195                            expected_start_date_of_work IS NOT NULL 
2196                            {$where}
2197                        UNION 
2198                        SELECT 
2199                            MONTH(expected_completion_date) AS months 
2200                        FROM 
2201                            tbl_ongoing_jobs 
2202                        WHERE 
2203                            expected_completion_date IS NOT NULL
2204                            {$where}
2205                        ) AS combined_months
2206                    ORDER BY 
2207                        months ASC
2208                    ";
2209
2210            $activeMonths = DB::select($query);
2211
2212
2213            return response([
2214                'message' => 'OK', 
2215                'data' => array(
2216                    'years' => $activeYears,
2217                    'months' => $activeMonths
2218                ),
2219            ]);
2220
2221
2222        } catch (\Exception $e) {
2223            /** @disregard P1014 */
2224            $e->exceptionCode = 'GET_ACTIVE_JOB_DATES_EXCEPTION'; 
2225            report($e);
2226            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2227        }
2228
2229    }
2230
2231    function update_ongoing_jobs_month_change($companyId = null, $processedBy = "System"){
2232
2233        return response(['message' => 'OK']); 
2234
2235        try {
2236
2237            $startedAt = date('Y-m-d H:i:s');
2238            $where = "";
2239
2240            Cache::flush();
2241            if($companyId != null){
2242                $where = " AND company_id = {$companyId} ";
2243            }else{
2244                $query = "SELECT 
2245                                company_id, 
2246                                COUNT(1) total 
2247                            FROM 
2248                                tbl_ongoing_jobs 
2249                            WHERE 
2250                                DATE_SUB((DATE_SUB(CURDATE(), INTERVAL 1 MONTH)), INTERVAL 4 DAY) BETWEEN DATE_FORMAT(expected_start_date_of_work, '%Y-%m-%d') 
2251                                AND DATE_FORMAT(expected_completion_date, '%Y-%m-%d')
2252                                AND already_invoiced > 0
2253                                AND to_be_invoiced_this_month > 0";
2254
2255                $affectedRowsArr = DB::select($query);
2256            }
2257            
2258            $query = "UPDATE 
2259                        tbl_ongoing_jobs 
2260                    SET 
2261                        already_invoiced = already_invoiced + to_be_invoiced_this_month, 
2262                        to_be_invoiced_this_month = cost_for_client - already_invoiced 
2263                    WHERE 
2264                        DATE_SUB((DATE_SUB(CURDATE(), INTERVAL 1 MONTH)), INTERVAL 4 DAY) BETWEEN DATE_FORMAT(expected_start_date_of_work, '%Y-%m-%d') 
2265                        AND DATE_FORMAT(expected_completion_date, '%Y-%m-%d')
2266                        {$where}
2267                    ";
2268            
2269            $affectedRows = DB::update($query);
2270
2271            if($companyId != null){
2272                TblOrdersUpdateLogs::create(
2273                    array(
2274                        'company_id' => $companyId,
2275                        'to_process' => 'Ongoing Jobs',
2276                        'status' => 'success',
2277                        'month_change_affected_rows' => $affectedRows,
2278                        'processed_by' => $processedBy,
2279                        'started_at' => $startedAt,
2280                        'ended_at' => date('Y-m-d H:i:s')
2281                    )
2282                );
2283
2284                return true;
2285            }else{
2286                $companies = array();
2287                for ($i = 0; $i < count($affectedRowsArr); $i++) { 
2288                    array_push($companies, $affectedRowsArr[$i]);
2289                    TblOrdersUpdateLogs::create(
2290                        array(
2291                            'company_id' => $affectedRowsArr[$i]->company_id,
2292                            'to_process' => 'Ongoing Jobs',
2293                            'status' => 'success',
2294                            'month_change_affected_rows' => $affectedRowsArr[$i]->total,
2295                            'processed_by' => $processedBy,
2296                            'started_at' => $startedAt,
2297                            'ended_at' => date('Y-m-d H:i:s')
2298                        )
2299                    );
2300                }
2301
2302                return response(['message' => 'OK', 'data' => $companies]);
2303            }
2304
2305            return response(['message' => 'OK']);
2306
2307        } catch (\Exception $e) {
2308            /** @disregard P1014 */
2309            $e->exceptionCode = 'UPDATE_ONGOING_JOB_MONTH_CHANGE_MANUAL_EXCEPTION'; 
2310            report($e);
2311            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2312        }
2313
2314    }
2315
2316    function update_ongoing_jobs_month_change_manual(Request $request){
2317
2318        try {
2319
2320            $data = $request->all();
2321            
2322            $update = $this->update_ongoing_jobs_month_change(addslashes($data['company_id']), $data['processed_by']);
2323
2324            if($update){
2325                return response(['message' => 'OK']);
2326            }else{
2327                return response(['message' => 'KO']);
2328            }
2329
2330        } catch (\Exception $e) {
2331            /** @disregard P1014 */
2332            $e->exceptionCode = 'UPDATE_ONGOING_JOB_MONTH_CHANGE_MANUAL_EXCEPTION'; 
2333            report($e);
2334            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2335        }
2336
2337    }
2338
2339    function get_revenue_per_month($quotationId){
2340        
2341        try {
2342
2343            $quotationId = addslashes($quotationId);
2344
2345            $result = TblRevenuePerMonth::where('quotation_id', $quotationId)->orderBy('year', 'ASC')->orderBy('month', 'ASC')->get();
2346
2347            return response(['message' => 'OK', 'data' => $result]);
2348            
2349        } catch (\Exception $e) {
2350            /** @disregard P1014 */
2351            $e->exceptionCode = 'GET_REVENUE_PER_MONTH_EXCEPTION'; 
2352            report($e);
2353            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2354        }
2355    }
2356
2357}