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