Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
5.12% covered (danger)
5.12%
279 / 5449
2.47% covered (danger)
2.47%
2 / 81
CRAP
0.00% covered (danger)
0.00%
0 / 1
Quotations
5.12% covered (danger)
5.12%
279 / 5449
2.47% covered (danger)
2.47%
2 / 81
1464835.19
0.00% covered (danger)
0.00%
0 / 1
 __construct
60.00% covered (warning)
60.00%
9 / 15
0.00% covered (danger)
0.00%
0 / 1
2.26
 create_quotation
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 1
56
 currency
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 send_approval_notification
0.00% covered (danger)
0.00%
0 / 120
0.00% covered (danger)
0.00%
0 / 1
552
 send_approval_margin_notification
0.00% covered (danger)
0.00%
0 / 105
0.00% covered (danger)
0.00%
0 / 1
272
 approve_quotation
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
240
 send_approved_notification
0.00% covered (danger)
0.00%
0 / 97
0.00% covered (danger)
0.00%
0 / 1
110
 reject_quotation
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
240
 send_rejected_notification
0.00% covered (danger)
0.00%
0 / 97
0.00% covered (danger)
0.00%
0 / 1
110
 update_quotation
31.97% covered (danger)
31.97%
117 / 366
0.00% covered (danger)
0.00%
0 / 1
4578.12
 compareArrays
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
6
 convertValue
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
7.05
 callDeleteQuotation
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 get_quotation
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 get_quotation_log
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 send_notification
0.00% covered (danger)
0.00%
0 / 61
0.00% covered (danger)
0.00%
0 / 1
42
 delete_quotation
41.03% covered (danger)
41.03%
16 / 39
0.00% covered (danger)
0.00%
0 / 1
21.13
 list_quotations
16.71% covered (danger)
16.71%
62 / 371
0.00% covered (danger)
0.00%
0 / 1
8439.86
 get_dates
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
 list_quotation_analytics_by_source
0.00% covered (danger)
0.00%
0 / 118
0.00% covered (danger)
0.00%
0 / 1
1640
 list_quotation_analytics_send_budgets
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
380
 list_quotation_analytics_track_budgets
0.00% covered (danger)
0.00%
0 / 118
0.00% covered (danger)
0.00%
0 / 1
1332
 list_quotation_analytics_types_budgets
0.00% covered (danger)
0.00%
0 / 120
0.00% covered (danger)
0.00%
0 / 1
1056
 download_quotations
0.00% covered (danger)
0.00%
0 / 164
0.00% covered (danger)
0.00%
0 / 1
306
 bulk_upload
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
30
 list_bulk_upload
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 delete_number
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 get_number
81.08% covered (warning)
81.08%
30 / 37
0.00% covered (danger)
0.00%
0 / 1
11.82
 get_years
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
12
 human_filesize
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 get_files
0.00% covered (danger)
0.00%
0 / 126
0.00% covered (danger)
0.00%
0 / 1
1806
 download_file
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
56
 delete_file
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
30
 send_email_to_client
0.00% covered (danger)
0.00%
0 / 246
0.00% covered (danger)
0.00%
0 / 1
3306
 send_email_follow_ups
0.00% covered (danger)
0.00%
0 / 339
0.00% covered (danger)
0.00%
0 / 1
4422
 create_sender_identity
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
56
 get_sender_identity
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
20
 get_all_sender_identity
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 delete_sender_identity
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
20
 create_template
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 1
72
 get_email_files
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
 download_email_template_file
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 delete_email_template_file
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 update_email_template_order
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 update_email_template
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
90
 delete_template
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 get_email_template
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 update_sender_identity
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
20
 resend_verification
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 list_quotation_analytics_by_performance
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
30
 list_orders_update_logs
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 list_g3w_orders_update_logs
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 update_budget_status_rejected_manual
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 update_budget_status_rejected
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
132
 bulk_update_quotation
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
30
 move_budget_and_job
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 1
30
 list_quotation_analytics_by_types_of_budgets_created_per_week
0.00% covered (danger)
0.00%
0 / 191
0.00% covered (danger)
0.00%
0 / 1
3660
 preview_file
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
20
 get_past_added_quotation
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
42
 send_acceptance_notification
0.00% covered (danger)
0.00%
0 / 75
0.00% covered (danger)
0.00%
0 / 1
156
 get_total_quotations_by_budget_status
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 1
72
 sendgrid_webhook_receiver
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
42
 isEmailValid
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 list_email_status
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 list_quotation_analytics_commercial
0.00% covered (danger)
0.00%
0 / 185
0.00% covered (danger)
0.00%
0 / 1
2970
 clear_open_data
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
30
 list_quotation_analytics_order_size
0.00% covered (danger)
0.00%
0 / 193
0.00% covered (danger)
0.00%
0 / 1
4422
 send_email_template_preview
0.00% covered (danger)
0.00%
0 / 105
0.00% covered (danger)
0.00%
0 / 1
306
 list_quotation_analytics_by_types_of_budgets_company_per_week
0.00% covered (danger)
0.00%
0 / 188
0.00% covered (danger)
0.00%
0 / 1
3660
 request_permission_commercial
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 1
72
 confirm_update_commercial
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
 calculateEmailRequestSize
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
56
 list_quotation_analytics_commercial_productivity
0.00% covered (danger)
0.00%
0 / 234
0.00% covered (danger)
0.00%
0 / 1
4422
 list_quotations_deleted
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 delete_sengrid
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
 download_productivity_commercial
0.00% covered (danger)
0.00%
0 / 377
0.00% covered (danger)
0.00%
0 / 1
2450
 update_commercial_numbers
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 list_quotation_analytics_by_service_type
0.00% covered (danger)
0.00%
0 / 165
0.00% covered (danger)
0.00%
0 / 1
1260
 getIdsFromInternalQuoteIds
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 checkQuotationExistByInternalQuoteId
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
72
 addUpdateLog
37.14% covered (danger)
37.14%
13 / 35
0.00% covered (danger)
0.00%
0 / 1
41.05
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\TblCompanies;
6use App\Models\TblCompanyUsers;
7use App\Models\TblCustomerTypes;
8use App\Models\TblG3WOrdersUpdateLogs;
9use App\Models\TblQuotations;
10use App\Models\TblBulkUpload;
11use App\Models\TblFiles;
12use App\Models\TblEmailFiles;
13use App\Models\TblQuotationsLog;
14use App\Models\TblSegments;
15use App\Models\TblSources;
16use App\Models\TblUsers;
17use App\Models\TblEmailConfiguration;
18use App\Models\TblCompanyEmails;
19use App\Models\TblCcBcc;
20use App\Models\TblBudgetStatus;
21use App\Models\TblOrdersUpdateLogs;
22use App\Models\TblBlockedDomains;
23use App\Models\TblNotifications;
24use App\Models\TblBudgetTypes;
25use App\Models\TblBudgetTypeGroups;
26use App\Models\TblProjectTypes;
27use App\Models\TblOngoingJobs;
28use App\Models\TblWorkflowQuestions;
29use App\Models\TblToAcceptanceNotifications;
30use App\Models\TblCcAcceptanceNotifications;
31use App\Models\TblSendgridWebhook;
32use App\Models\TblFollowUpLogs;
33use App\Models\TblBusinessGoals;
34use App\Models\TblVisitTypes;
35use App\Models\TblVisitTypeGroups;
36use App\Models\TblLastFollowUpDate;
37use App\Models\StructureData;
38use PhpOffice\PhpSpreadsheet\Spreadsheet;
39use PhpOffice\PhpSpreadsheet\IOFactory;
40use Illuminate\Support\Facades\App;
41use Illuminate\Support\Facades\Cache;
42use Illuminate\Http\Request;
43use Illuminate\Support\Facades\DB;
44use Illuminate\Support\Facades\Storage;
45use Illuminate\Support\Facades\Log;
46use Illuminate\Support\Facades\File;
47use Illuminate\Support\Facades\Http;
48use SendGrid\Mail\Mail;
49use Illuminate\Support\Facades\Artisan;
50use function PHPUnit\Framework\isEmpty;
51use function PHPUnit\Framework\isNull;
52
53class Quotations extends Controller
54{
55    private $locale;
56    private $userId;
57    private $region;
58    private $companyIds;
59    private $companyId;
60
61    public function __construct(){
62        $this->locale = @getallheaders()['Locale-ID'];
63        $this->userId = @getallheaders()['User-ID'];
64        $this->region = @getallheaders()['Region'];
65
66        App::setLocale($this->locale);
67
68        $this->companyIds = array();
69        
70        $this->region = json_decode($this->region, true);        
71        
72        if (!empty($this->region)) {
73
74            $this->region = implode(',', array_map(fn($r) => "'" . urldecode($r) ."'", $this->region));
75
76            $query = "SELECT
77                        b.company_id
78                    FROM
79                        tbl_company_users a
80                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
81                    WHERE
82                        a.user_id = {$this->userId}
83                        AND b.region IN ({$this->region})";
84
85            $this->companyIds = DB::select($query);
86
87            $this->companyIds = collect($this->companyIds)->pluck('company_id')->toArray();
88        }else{
89            $this->companyIds = TblCompanyUsers::where('user_id', $this->userId)->pluck('company_id')->all();
90        }
91
92        $this->companyId = implode(',', $this->companyIds);
93    }
94
95    public function create_quotation(Request $request){
96
97        try {
98
99            $data = $request->all();
100            $data['updated_at'] = date('Y-m-d H:i:s');
101
102            if(isset($data['request_date']) && isset($data['issue_date'])){
103                $requestDate = strtotime($data['request_date']);
104                $issueDate = strtotime($data['issue_date']);
105                $dateDiff = $issueDate - $requestDate;
106                $data['duration'] = round($dateDiff / (60 * 60 * 24));
107            }
108
109            $r = new Request([
110                'created_by' => $data['created_by'],
111            ]);
112
113            $result = $this->get_number($r, @$data['company_id']);
114            $id = $result->original['id'];
115
116            $files = $request->file('files');
117            if($files){
118                $uploadedFiles = [];
119
120                foreach ($files as $file) {
121                    $filename = time() . '_' . $file->getClientOriginalName();
122                    $fileSize = $file->getSize();
123                    // $fileContent = file_get_contents($file->getRealPath());
124                    // $fileHash = hash('sha256', $fileContent);                    
125
126                    $s3path = Storage::disk('s3')->putFileAs(
127                        'uploads',
128                        $file,
129                        $filename,
130                        [
131                            'ContentType' => $file->getMimeType(),
132                        ]
133                    );
134
135                    TblFiles::create(
136                        array(
137                            'quotation_id' => $id,
138                            'original_name' => $file->getClientOriginalName(),
139                            'filename' => $filename,
140                            'uploaded_by' => $data['updated_by'],
141                            // 'file' => $fileContent,
142                            'file_size' => $file->getSize(),
143                            // 'file_hash' => $fileHash,
144                            'mime_type' => $file->getMimeType(),
145                            'uploaded_at' => now(),
146                        )
147                    );
148                }
149            }
150
151            $query = "SELECT COUNT(*) as count FROM tbl_files WHERE quotation_id = ?";
152            $fileCount = DB::select($query, [$id])[0]->count;
153
154            $data['has_attachment'] = $fileCount > 0 ? 1 : 0;
155
156            $data = array_diff_key($data, array_flip(['files', '_token', 'otros_campos_no_necesarios']));
157
158            $data['for_add'] = 0;
159            TblQuotations::where('id', $id)->update($data);
160
161            $result = TblQuotations::where('id', $id)->first();
162
163            Cache::flush();
164            return response(['message' => 'OK', 'data' => $result]);
165
166        } catch (\Exception $e) {
167            return response(['message' => 'KO', 'error' => $e->getMessage()]);
168        }
169
170    }
171
172    function currency($amount, $withEuro = ''){
173
174        if($withEuro != null){
175            $withEuro = ' â‚¬';
176        }
177
178
179        return number_format($amount, 2, ',', '.') . $withEuro;
180    }
181
182
183    function send_approval_notification($amount, $budgetTypeId, $customerTypeId, $minimumOrderSize, $quoteId, $id, $companyName, $createdBy, $userId, $action, $commercialEmail, $companyId, $endpoint, $isQuestion, $questionIdsNo, $n, $locale = null){
184
185        if(!is_null($locale)){
186            $this->locale = $locale;
187        }
188
189        if($action != 1){
190            if($this->locale == 'es'){
191                $action = "actualizado";
192            }else{
193                $action = "updated";
194            }
195
196        }else{
197            if($this->locale == 'es'){
198                $action = "creado";
199            }else{
200                $action = "created";
201            }
202        }
203
204        $fendpoint = "";
205
206        if($endpoint == 'orders'){
207            if($this->locale == 'es'){
208                $fendpoint = "presupuesto";
209            }else{
210                $fendpoint = "budget";
211            }
212
213        }else{
214            if($this->locale == 'es'){
215                $fendpoint = "trabajo";
216            }else{
217                $fendpoint = "job";
218            }
219        }
220
221        $user = TblUsers::where('id', $userId)->first();
222
223        $query = "SELECT
224                    a.approver_id,
225                    a.user_id,
226                    b.name,
227                    b.email
228                FROM
229                    tbl_approvers a
230                    INNER JOIN tbl_users b ON a.user_id = b.id
231                WHERE a.company_id = {$companyId}
232                ";
233
234        if($n == 3){
235            $query = "SELECT
236                        a.approver_id,
237                        a.user_id,
238                        u.name,
239                        u.email
240                    FROM tbl_approvers a
241                    INNER JOIN tbl_users u ON a.user_id = u.id
242                    WHERE a.company_id = {$companyId}
243
244                    UNION ALL
245
246                    SELECT
247                        c.approver_id,
248                        c.user_id,
249                        u2.name,
250                        u2.email
251                    FROM tbl_approvers_v2 c
252                    INNER JOIN tbl_users u2 ON c.user_id = u2.id
253                    WHERE c.company_id = {$companyId}";
254        }
255
256        $approvers = DB::select($query);
257
258        if(count($approvers) > 0){
259            $amount = $this->currency($amount, 1);
260            $minimumOrderSize = $this->currency($minimumOrderSize, 1);
261
262            $budgetType = TblBudgetTypes::where('budget_type_id', $budgetTypeId)->first();
263            $clientType = TblCustomerTypes::where('customer_type_id', $customerTypeId)->first();
264
265            $imgpath = File::get('fireservicetitan.png');
266            $base64 = "data:image/png;base64,".base64_encode($imgpath);
267
268            $subject = __('language.send_approval_notification.subject');
269            $subject = str_replace('{{type}}', $budgetType->name, $subject);
270            $subject = str_replace('{{amount}}', $amount, $subject);
271            $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
272
273            $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
274            $href = "<a href='{$url}'>{$quoteId}</a>";
275            $cc = false;
276            foreach ($approvers as $item) {
277
278                $toEmail = $item->email;
279
280                $body = __('language.send_approval_notification.body_hello');
281                $body = str_replace('{{approver}}', $item->name, $body);
282
283                $body .= __('language.send_approval_notification.body_message');
284                $body = str_replace('{{endpoint}}', $fendpoint, $body);
285                $body = str_replace('{{creator}}', $createdBy, $body);
286                $body = str_replace('{{action}}', $action, $body);
287                $body = str_replace('{{company}}', $companyName, $body);
288                $body = str_replace('{{type}}', $budgetType->name, $body);
289                $body = str_replace('{{amount}}', $amount, $body);
290                $body = str_replace('{{quote_id}}', $href, $body);
291
292                if($isQuestion == 1){
293                    $body .= __('language.send_approval_notification.note_question');
294                }else{
295                    $body .= __('language.send_approval_notification.note');
296                }
297
298                $body = str_replace('{{company}}', $companyName, $body);
299                $body = str_replace('{{client_type}}', $clientType->name, $body);
300                $body = str_replace('{{project_type}}', $budgetType->name, $body);
301                $body = str_replace('{{amount}}', $minimumOrderSize, $body);
302
303                if($isQuestion == 1){
304                    if($questionIdsNo){
305                        $questions = TblWorkflowQuestions::whereIn('question_id', $questionIdsNo)->where('company_id', $companyId)->get();
306
307                        if($questions){
308                            $ul = "<ul>";
309                            $li = "";
310                            foreach ($questions as $item) {
311                                $li .= "<li>{$item->question}</li>";
312                            }
313                            $ul .= $li . "</ul><br><br>";
314                            $body .= $ul;
315                        }
316                    }
317                }
318
319                $content = $body;
320
321                $body .= "<p>Fire Service Titan</p>";
322                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
323
324                $html = '<!DOCTYPE html>';
325                $html .= '<html>';
326                $html .= '<head>';
327                $html .= '<meta charset="UTF-8">';
328                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
329                $html .= '</head>';
330                $html .= '<body>';
331                $html .= $body;
332                $html .= '</body>';
333                $html .= '</html>';
334
335                if($toEmail != null){
336                    $email = new \SendGrid\Mail\Mail();
337
338                    if(env('SENDGRID_STAGING')){
339                        $toEmail = $user->email;
340                        $item->user_id = $userId;
341                    }
342
343                    if($cc == false){
344                        $cc = true;
345                        if($user->email != $toEmail){
346                            if($user->email != $commercialEmail && $commercialEmail != null){
347                                $email->addBcc($user->email);
348                                $email->addBcc($commercialEmail);
349                            }else{
350                                $email->addBcc($user->email);
351                            }
352                        }
353                    }
354
355                    $email->setFrom('fire@fire.es', 'Fire Service Titan');
356                    $email->setSubject($subject);
357                    $email->addTo($toEmail);
358                    $email->addContent("text/html", $html);
359
360                    $email->addAttachment(
361                        $imgpath,
362                        "image/png",
363                        "fireservicetitan.png",
364                        "inline",
365                        "fireservicetitan"
366                    );
367
368                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
369
370                    $response = $sendgrid->send($email);
371                    if ($response->statusCode() == 202) {
372                        Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - APPROVAL EMAIL NOTIFICATION SENT');
373
374                        TblNotifications::create(
375                            array(
376                                'user_id' => $item->user_id,
377                                'content' => $content,
378                                'is_open' => 1,
379                                'created_by' => 'System',
380                                'link' => $url
381                            )
382                        );
383                    } else {
384                        $error = true;
385                        Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
386                    }
387                }
388
389            }
390        }
391    }
392
393    function send_approval_margin_notification($amount, $budgetTypeId, $customerTypeId, $minimumMargin, $quoteId, $id, $companyName, $createdBy, $userId, $action, $commercialEmail, $invoiceMargin, $companyId, $endpoint){
394
395        if($action != 1){
396            if($this->locale == 'es'){
397                $action = "actualizado";
398            }else{
399                $action = "updated";
400            }
401
402        }else{
403            if($this->locale == 'es'){
404                $action = "creado";
405            }else{
406                $action = "created";
407            }
408        }
409
410        $fendpoint = "";
411
412        if($endpoint == 'orders'){
413            if($this->locale == 'es'){
414                $fendpoint = "presupuesto";
415            }else{
416                $fendpoint = "budget";
417            }
418
419        }else{
420            if($this->locale == 'es'){
421                $fendpoint = "trabajo";
422            }else{
423                $fendpoint = "job";
424            }
425        }
426
427        $invoiceMargin = number_format($invoiceMargin, 2);
428        $minimumMargin = number_format($minimumMargin, 2);
429
430        $user = TblUsers::where('id', $userId)->first();
431
432        $query = "SELECT
433                    a.approver_id,
434                    a.user_id,
435                    b.name,
436                    b.email
437                FROM
438                    tbl_approvers a
439                    INNER JOIN tbl_users b ON a.user_id = b.id
440                WHERE a.company_id = {$companyId}
441                ";
442
443        $approvers = DB::select($query);
444
445        if(count($approvers) > 0){
446
447            $amount = $this->currency($amount, 1);
448
449            $budgetType = TblBudgetTypes::where('budget_type_id', $budgetTypeId)->first();
450            $clientType = TblCustomerTypes::where('customer_type_id', $customerTypeId)->first();
451
452            $imgpath = File::get('fireservicetitan.png');
453            $base64 = "data:image/png;base64,".base64_encode($imgpath);
454
455            $subject = __('language.send_approval_margin_notification.subject');
456            $subject = str_replace('{{type}}', $budgetType->name, $subject);
457            $subject = str_replace('{{amount}}', $amount, $subject);
458            $subject = str_replace('{{margin}}', $invoiceMargin, $subject);
459            $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
460
461            $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
462            $href = "<a href='{$url}'>{$quoteId}</a>";
463            $cc = false;
464            foreach ($approvers as $item) {
465
466                $toEmail = $item->email;
467
468                $body = __('language.send_approval_margin_notification.body_hello');
469                $body = str_replace('{{approver}}', $item->name, $body);
470
471                $body .= __('language.send_approval_margin_notification.body_message');
472                $body = str_replace('{{endpoint}}', $fendpoint, $body);
473                $body = str_replace('{{creator}}', $createdBy, $body);
474                $body = str_replace('{{action}}', $action, $body);
475                $body = str_replace('{{company}}', $companyName, $body);
476                $body = str_replace('{{type}}', $budgetType->name, $body);
477                $body = str_replace('{{amount}}', $amount, $body);
478                $body = str_replace('{{quote_id}}', $href, $body);
479                $body = str_replace('{{margin}}', $invoiceMargin, $body);
480
481                $body .= __('language.send_approval_margin_notification.note');
482                $body = str_replace('{{company}}', $companyName, $body);
483                $body = str_replace('{{client_type}}', $clientType->name, $body);
484                $body = str_replace('{{project_type}}', $budgetType->name, $body);
485                $body = str_replace('{{margin}}', $minimumMargin, $body);
486
487                $content = $body;
488
489                $body .= "<p>Fire Service Titan</p>";
490                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
491
492                $html = '<!DOCTYPE html>';
493                $html .= '<html>';
494                $html .= '<head>';
495                $html .= '<meta charset="UTF-8">';
496                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
497                $html .= '</head>';
498                $html .= '<body>';
499                $html .= $body;
500                $html .= '</body>';
501                $html .= '</html>';
502
503                if($toEmail != null){
504                    $email = new \SendGrid\Mail\Mail();
505
506                    if(env('SENDGRID_STAGING')){
507                        $toEmail = $user->email;
508                        $item->user_id = $userId;
509                    }
510
511                    if($cc == false){
512                        $cc = true;
513
514                        if($user->email != $toEmail){
515                            if($user->email != $commercialEmail && $commercialEmail != null){
516                                $email->addBcc($user->email);
517                                $email->addBcc($commercialEmail);
518                            }else{
519                                $email->addBcc($user->email);
520                            }
521                        }
522                    }
523
524                    $email->setFrom('fire@fire.es', 'Fire Service Titan');
525                    $email->setSubject($subject);
526                    $email->addTo($toEmail);
527                    $email->addContent("text/html", $html);
528
529                    $email->addAttachment(
530                        $imgpath,
531                        "image/png",
532                        "fireservicetitan.png",
533                        "inline",
534                        "fireservicetitan"
535                    );
536
537                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
538
539                    $response = $sendgrid->send($email);
540                    if ($response->statusCode() == 202) {
541                        Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - MARGIN APPROVAL EMAIL NOTIFICATION SENT');
542
543                        TblNotifications::create(
544                            array(
545                                'user_id' => $item->user_id,
546                                'content' => $content,
547                                'is_open' => 1,
548                                'created_by' => 'System',
549                                'link' => $url
550                            )
551                        );
552                    } else {
553                        $error = true;
554                        Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
555                    }
556                }
557
558            }
559        }
560    }
561
562    function approve_quotation($id){
563
564        try {
565
566            $id = addslashes($id);
567
568            $result = TblQuotations::where('id', $id)->first();
569            $company = TblCompanies::where('company_id', $result->company_id)->first();
570            $budgetType = TblBudgetTypes::where('budget_type_id', $result->budget_type_id)->first();
571
572            if($result->created_by != $result->commercial){
573                $creatorAndCommercial = array($result->created_by, $result->commercial);
574                foreach ($creatorAndCommercial as $name) {
575                    $user = TblUsers::where('name', $name)->first();
576                    if($user){
577                        $this->send_approved_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
578                    }
579                }
580            }else{
581                $user = TblUsers::where('name', $result->created_by)->first();
582                if($user){
583                    $this->send_approved_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
584                }
585            }
586
587            if ($result->for_approval == 3) {
588                $result = TblQuotations::where('id', $id)->first();
589
590                $approved = 0;
591                $rejected = 0;
592
593                if ($result->approved_by !== null) {
594                    $approved++;
595                }
596                if ($result->approved_by_v2 !== null) {
597                    $approved++;
598                }
599
600                if ($result->rejected_by !== null) {
601                    $rejected++;
602                }
603                if ($result->rejected_by_v2 !== null) {
604                    $rejected++;
605                }
606
607                if ($approved === 2) {
608                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
609                } elseif ($rejected >= 1 && ($approved + $rejected) === 2) {
610                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
611                }
612            }elseif($result->for_approval == 1){
613                TblQuotations::where('id', $id)->update(['for_approval' => null]);
614            }
615
616
617            Cache::flush();
618            return response(['message' => 'OK']);
619
620        } catch (\Exception $e) {
621            return response(['message' => 'KO', 'error' => $e->getMessage()]);
622        }
623
624    }
625
626    function send_approved_notification($userId, $username, $email, $companyName, $budgetType, $amount, $id, $quoteId, $companyId, $endpoint){
627
628        $fendpoint = "";
629
630        if($endpoint == 'orders'){
631            if($this->locale == 'es'){
632                $fendpoint = "presupuesto";
633            }else{
634                $fendpoint = "budget";
635            }
636
637        }else{
638            if($this->locale == 'es'){
639                $fendpoint = "trabajo";
640            }else{
641                $fendpoint = "job";
642            }
643        }
644
645        $query = "SELECT
646                    u.id AS user_id,
647                    u.name,
648                    u.email,
649                    u.sender_email,
650                    CASE
651                        WHEN a.user_id IS NOT NULL AND c.user_id IS NOT NULL THEN 'both'
652                        WHEN a.user_id IS NOT NULL THEN 'approvers'
653                        WHEN c.user_id IS NOT NULL THEN 'approvers_v2'
654                        ELSE 'none'
655                    END AS exists_in
656                FROM tbl_users u
657                LEFT JOIN tbl_approvers a
658                    ON u.id = a.user_id AND a.company_id = {$companyId}
659                LEFT JOIN tbl_approvers_v2 c
660                    ON u.id = c.user_id AND c.company_id = {$companyId}
661                WHERE u.id = {$this->userId}";
662
663        $user = DB::select($query);
664
665        $user = $user[0] ?? null;
666
667        $toEmail = $email;
668
669        $amount = $this->currency($amount, 1);
670
671        $imgpath = File::get('fireservicetitan.png');
672        $base64 = "data:image/png;base64,".base64_encode($imgpath);
673
674        $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
675        $href = "<a href='{$url}'>{$quoteId}</a>";
676
677        $body = __('language.send_approved_notification.body_hello');
678        $body = str_replace('{{creator}}', $username, $body);
679
680        $body .= __('language.send_approved_notification.body_message');
681        $body = str_replace('{{approver}}', $user->name, $body);
682        $body = str_replace('{{company}}', $companyName, $body);
683        $body = str_replace('{{type}}', $budgetType, $body);
684        $body = str_replace('{{amount}}', $amount, $body);
685        $body = str_replace('{{quote_id}}', $href, $body);
686        $body = str_replace('{{endpoint}}', $fendpoint, $body);
687
688        $content = $body;
689
690        $body .= "<p>Fire Service Titan</p>";
691        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
692
693        $html = '<!DOCTYPE html>';
694        $html .= '<html>';
695        $html .= '<head>';
696        $html .= '<meta charset="UTF-8">';
697        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
698        $html .= '</head>';
699        $html .= '<body>';
700        $html .= $body;
701        $html .= '</body>';
702        $html .= '</html>';
703
704        $subject = __('language.send_approved_notification.subject');
705        $subject = str_replace('{{quote_id}}', $quoteId, $subject);
706        $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
707
708        if($toEmail != null){
709            $email = new \SendGrid\Mail\Mail();
710
711            if(env('SENDGRID_STAGING')){
712                $toEmail = $user->email;
713                $userId = $this->userId;
714            }
715
716            $email->setFrom('fire@fire.es', 'Fire Service Titan');
717            $email->setSubject($subject);
718            $email->addTo($toEmail);
719            $email->addContent("text/html", $html);
720
721            $email->addAttachment(
722                $imgpath,
723                "image/png",
724                "fireservicetitan.png",
725                "inline",
726                "fireservicetitan"
727            );
728
729            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
730
731            $response = $sendgrid->send($email);
732            if ($response->statusCode() == 202) {
733                Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - APPROVED EMAIL NOTIFICATION SENT');
734
735                if($endpoint == 'orders'){
736                    if($user->exists_in == "approvers"){
737                        TblQuotations::where('id', $id)->update(
738                            array(
739                                'approved_at' => date('Y-m-d H:i:s'),
740                                'approved_by' => $user->name
741                            )
742                        );
743                    }elseif($user->exists_in == "approvers_v2"){
744                        TblQuotations::where('id', $id)->update(
745                            array(
746                                'approved_at_v2' => date('Y-m-d H:i:s'),
747                                'approved_by_v2' => $user->name
748                            )
749                        );
750                    }
751                }else{
752                    TblOngoingJobs::where('id', $id)->update(
753                        array(
754                            'approved_at' => date('Y-m-d H:i:s'),
755                            'approved_by' => $user->name
756                        )
757                    );
758                }
759
760                TblNotifications::create(
761                    array(
762                        'user_id' => $userId,
763                        'content' => $content,
764                        'is_open' => 1,
765                        'created_by' => 'System',
766                        'link' => $url
767                    )
768                );
769            } else {
770                $error = true;
771                Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
772            }
773        }
774
775    }
776
777    function reject_quotation($id){
778
779        try {
780
781            $id = addslashes($id);
782
783            $result = TblQuotations::where('id', $id)->first();
784            $company = TblCompanies::where('company_id', $result->company_id)->first();
785            $budgetType = TblBudgetTypes::where('budget_type_id', $result->budget_type_id)->first();
786
787            if($result->created_by != $result->commercial){
788                $creatorAndCommercial = array($result->created_by, $result->commercial);
789                foreach ($creatorAndCommercial as $name) {
790                    $user = TblUsers::where('name', $name)->first();
791                    if($user){
792                        $this->send_rejected_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
793                    }
794                }
795            }else{
796                $user = TblUsers::where('name', $result->created_by)->first();
797                if($user){
798                    $this->send_rejected_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
799                }
800            }
801
802            if ($result->for_approval == 3) {
803                $result = TblQuotations::where('id', $id)->first();
804
805                $approved = 0;
806                $rejected = 0;
807
808                if ($result->approved_by !== null) {
809                    $approved++;
810                }
811                if ($result->approved_by_v2 !== null) {
812                    $approved++;
813                }
814
815                if ($result->rejected_by !== null) {
816                    $rejected++;
817                }
818                if ($result->rejected_by_v2 !== null) {
819                    $rejected++;
820                }
821
822                if ($approved === 2) {
823                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
824                } elseif ($rejected >= 1 && ($approved + $rejected) === 2) {
825                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
826                }
827            }elseif($result->for_approval == 1){
828                TblQuotations::where('id', $id)->update(['for_approval' => null]);
829            }
830
831            Cache::flush();
832            return response(['message' => 'OK']);
833
834        } catch (\Exception $e) {
835            return response(['message' => 'KO', 'error' => $e->getMessage()]);
836        }
837
838    }
839
840    function send_rejected_notification($userId, $username, $email, $companyName, $budgetType, $amount, $id, $quoteId, $companyId, $endpoint){
841
842        $fendpoint = "";
843
844        if($endpoint == 'orders'){
845            if($this->locale == 'es'){
846                $fendpoint = "presupuesto";
847            }else{
848                $fendpoint = "budget";
849            }
850
851        }else{
852            if($this->locale == 'es'){
853                $fendpoint = "trabajo";
854            }else{
855                $fendpoint = "job";
856            }
857        }
858
859        $query = "SELECT
860                    u.id AS user_id,
861                    u.name,
862                    u.email,
863                    u.sender_email,
864                    CASE
865                        WHEN a.user_id IS NOT NULL AND c.user_id IS NOT NULL THEN 'both'
866                        WHEN a.user_id IS NOT NULL THEN 'approvers'
867                        WHEN c.user_id IS NOT NULL THEN 'approvers_v2'
868                        ELSE 'none'
869                    END AS exists_in
870                FROM tbl_users u
871                LEFT JOIN tbl_approvers a
872                    ON u.id = a.user_id AND a.company_id = {$companyId}
873                LEFT JOIN tbl_approvers_v2 c
874                    ON u.id = c.user_id AND c.company_id = {$companyId}
875                WHERE u.id = {$this->userId}";
876
877        $user = DB::select($query);
878
879        $user = $user[0] ?? null;
880
881        $toEmail = $email;
882        $amount = $this->currency($amount, 1);
883
884        $imgpath = File::get('fireservicetitan.png');
885        $base64 = "data:image/png;base64,".base64_encode($imgpath);
886
887        $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
888        $href = "<a href='{$url}'>{$quoteId}</a>";
889
890        $body = __('language.send_rejected_notification.body_hello');
891        $body = str_replace('{{creator}}', $username, $body);
892
893        $body .= __('language.send_rejected_notification.body_message');
894        $body = str_replace('{{approver}}', $user->name, $body);
895        $body = str_replace('{{company}}', $companyName, $body);
896        $body = str_replace('{{type}}', $budgetType, $body);
897        $body = str_replace('{{amount}}', $amount, $body);
898        $body = str_replace('{{quote_id}}', $href, $body);
899        $body = str_replace('{{endpoint}}', $fendpoint, $body);
900
901        $content = $body;
902
903        $body .= "<p>Fire Service Titan</p>";
904        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
905
906        $html = '<!DOCTYPE html>';
907        $html .= '<html>';
908        $html .= '<head>';
909        $html .= '<meta charset="UTF-8">';
910        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
911        $html .= '</head>';
912        $html .= '<body>';
913        $html .= $body;
914        $html .= '</body>';
915        $html .= '</html>';
916
917        $subject = __('language.send_rejected_notification.subject');
918        $subject = str_replace('{{quote_id}}', $quoteId, $subject);
919        $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
920
921        if($toEmail != null){
922            $email = new \SendGrid\Mail\Mail();
923
924            if(env('SENDGRID_STAGING')){
925                $toEmail = $user->email;
926                $userId = $this->userId;
927            }
928
929            $email->setFrom('fire@fire.es', 'Fire Service Titan');
930            $email->setSubject($subject);
931            $email->addTo($toEmail);
932            $email->addContent("text/html", $html);
933
934            $email->addAttachment(
935                $imgpath,
936                "image/png",
937                "fireservicetitan.png",
938                "inline",
939                "fireservicetitan"
940            );
941
942            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
943
944            $response = $sendgrid->send($email);
945            if ($response->statusCode() == 202) {
946                Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - REJECTED EMAIL NOTIFICATION SENT');
947
948                if($endpoint == 'orders'){
949
950                    if($user->exists_in == "approvers"){
951                        TblQuotations::where('id', $id)->update(
952                            array(
953                                'rejected_at' => date('Y-m-d H:i:s'),
954                                'rejected_by' => $user->name
955                            )
956                        );
957                    }elseif($user->exists_in == "approvers_v2"){
958                        TblQuotations::where('id', $id)->update(
959                            array(
960                                'rejected_at_v2' => date('Y-m-d H:i:s'),
961                                'rejected_by_v2' => $user->name
962                            )
963                        );
964                    }
965                }else{
966                    TblOngoingJobs::where('id', $id)->update(
967                        array(
968                            'rejected_at' => date('Y-m-d H:i:s'),
969                            'rejected_by' => $user->name
970                        )
971                    );
972                }
973
974                TblNotifications::create(
975                    array(
976                        'user_id' => $userId,
977                        'content' => $content,
978                        'is_open' => 1,
979                        'created_by' => 'System',
980                        'link' => $url
981                    )
982                );
983            } else {
984                $error = true;
985                Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
986            }
987        }
988
989    }
990
991    public function update_quotation(Request $request, $id){
992        $approvalMinimumOrderSize = null;
993        $approvalIsQuestion = null;
994        $approvalQuestionIdsNo = null;
995        $approvalN = null;
996        $approvalMinimumMargin = null;
997        $approvalId = null;
998        $approvalForAdd = null;
999        $approvalInvoiceMargin = null;
1000        $sendApprovalNotification = false;
1001        $sendApprovalMarginNotification = false;
1002        $needToSendReminder = false;
1003
1004        // try {
1005
1006            $data = $request->all();
1007            $id = addslashes($id);
1008            $userId = addslashes($data['user_id']);
1009            $forApproval = null;
1010            unset($data['user_id']);
1011
1012            $r = array('amount', 'order_number', 'budget_type_id', 'acceptance_date');
1013            $job = array();
1014
1015            foreach ($data as $key => $value) {
1016                if($value == 'null'){
1017                    $data[$key] = null;
1018                }
1019
1020                if(in_array($key, $r)){
1021                    $job[$key] = $value;
1022                }
1023            }
1024
1025            $files = $request->file('files');
1026            unset($data['files']);
1027
1028            $internalFiles = $request->file('internal_files');
1029            unset($data['internal_files']);
1030
1031            $query = "
1032            SELECT
1033                SUM(CASE WHEN is_internal IS NULL THEN 1 ELSE 0 END) as external_count,
1034                SUM(CASE WHEN is_internal = 1 THEN 1 ELSE 0 END) as internal_count
1035            FROM tbl_files
1036            WHERE quotation_id = ?";
1037
1038            $counts = DB::select($query, [$id]);
1039            $fileCount = $counts[0]->external_count;
1040            $internalFileCount = $counts[0]->internal_count;
1041
1042            if($fileCount > 0 || !empty($files)){
1043                $data['has_attachment'] = 1;
1044            }
1045
1046            if($files){
1047                $totalFiles = $fileCount + count($files);
1048                if($totalFiles > 10){
1049                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
1050                }
1051            }
1052
1053            if($internalFileCount > 0 || !empty($internalFiles)){
1054                $data['has_attachment'] = 1;
1055            }
1056
1057            if($internalFiles){
1058                $totalInternalFileCount = $internalFileCount + count($internalFiles);
1059                if($totalInternalFileCount > 10){
1060                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
1061                }
1062            }
1063
1064            if(isset($data['request_date']) && isset($data['issue_date'])){
1065                $requestDate = strtotime($data['request_date']);
1066                $issueDate = strtotime($data['issue_date']);
1067                $dateDiff = $issueDate - $requestDate;
1068                $data['duration'] = round($dateDiff / (60 * 60 * 24));
1069            }
1070
1071            $result = TblQuotations::where('id', $id)->first();
1072
1073            if($result->quote_id != $data['quote_id']){
1074
1075                $c = TblQuotations::where('quote_id', (string) $data['quote_id'])->where('company_id', $result->company_id)->count();
1076
1077                if($c > 0){
1078
1079                    if($result->for_add == 0){
1080                        $latestBudget = TblQuotations::where('company_id', $result->company_id)->orderByRaw('CAST(quote_id AS DOUBLE) DESC')->first();
1081
1082                        $number = $latestBudget->quote_id;
1083                        $x = true;
1084
1085                        while ($x) {
1086
1087                            if(is_numeric(substr($number, -1))) {
1088                                $number++;
1089                            }else{
1090                                $number .= "1";
1091                            }
1092
1093                            $check = 0;
1094
1095                            $check = TblQuotations::where('company_id', $result->company_id)->where('quote_id', (string) $number)->count();
1096
1097                            if($check == 0){
1098                                $x = false;
1099                            }
1100                        }
1101
1102                        return response(['message' => 'KO', 'error' => 'quote_exists', 'number' => $number]);
1103                    }
1104
1105                    return response(['message' => 'KO', 'error' => 'quote_exists']);
1106                }
1107            }
1108
1109            $action = 0;
1110            if($result->created_by == null || $result->for_add == 1){
1111                $action = 1;
1112                $data['created_by'] = $data['updated_by'];
1113                $data['for_add'] = 0;
1114            }
1115
1116            $company = TblCompanies::where('company_id', $result->company_id)->first();
1117            $commercial = TblUsers::where('name', $data['commercial'])->first();
1118            $status = TblBudgetStatus::where('budget_status_id', $data['budget_status_id'])->first();
1119
1120            // $checkQuotation = TblQuotations::where(function($query) use ($data, $result) {
1121            //     $query->where('internal_quote_id', $data['internal_quote_id'])
1122            //         ->orWhere('internal_quote_id', 'O-25/'.$data['internal_quote_id']);
1123            // })
1124            //     ->where('company_id', $result->company_id)
1125            //     ->first();
1126
1127            // if($checkQuotation) {
1128            //     $url = "orders/" . $checkQuotation->id . "?company_id=" . $checkQuotation->company_id;
1129            //     return response([
1130            //         'message' => 'KO',
1131            //         'error' => "Presupuesto ya creado. Puedes verlo <a href='$url' target='_blank'>aquí</a>."
1132            //     ]);
1133            // }
1134
1135            $limitReminderEmails = $company->limit_reminder_emails ?? 3;
1136
1137            if($result->total_sent == $limitReminderEmails){
1138                $data['total_sent'] = 0;
1139            }
1140
1141            if($result->budget_status_id != $data['budget_status_id'] || $result->commercial != $data['commercial']){
1142                if($data['budget_status_id'] == 12){
1143                    if($company && $commercial){
1144                        $inProgressCount = TblQuotations::where('budget_status_id', 12)->where('company_id', $result->company_id)->where('commercial', $data['commercial'])->count();
1145                        if($company->process_limit <= $inProgressCount){
1146                            return response(['message' => 'KO', 'error' => 'in_progress', 'limit' => $company->process_limit]);
1147                        }
1148                    }else{
1149                        return response(['message' => 'KO', 'error' => 'in_progress', 'limit' => 0]);
1150                    }
1151                }
1152            }
1153
1154            $sendNotification = false;
1155            if($result->commercial != $data['commercial']){
1156                if(!empty($commercial)){
1157                    $createdByX = ($result->created_by == null) ? $data['created_by'] : $result->created_by;
1158                    if($createdByX != $data['commercial']){
1159                        $action = 0;
1160                        $sendNotification = true;
1161                    }
1162                }
1163            }
1164
1165            if(isset($data['amount']) || isset($data['budget_type_id']) || isset($data['customer_type_id']) || isset($data['invoice_margin']) || isset($data['question_enabled'])){
1166                if($company){
1167
1168                    $n = 0;
1169                    $invoiceMargin = 0;
1170                    $minimumMargin = 0;
1171                    $minimumOrderSize = 0;
1172
1173                    if($result->amount != $data['amount'] ||
1174                        $result->budget_type_id != $data['budget_type_id'] ||
1175                        $result->customer_type_id != $data['customer_type_id'] ||
1176                        $result->invoice_margin != $data['invoice_margin']
1177                    ){
1178                        $project = TblProjectTypes::where('company_id', $company->company_id)->where('budget_type_id', $data['budget_type_id'])->first();
1179                        $customerTypeIds = array();
1180
1181                        if($project){
1182                            if(!empty($project->customer_type_ids)){
1183                                $customerTypeIds = array_map('intval', explode(',', $project->customer_type_ids));
1184                            }
1185                            if($project->minimum_order_size != null && in_array($data['customer_type_id'], $customerTypeIds)){
1186                                if($data['amount'] >= $project->minimum_order_size){
1187                                    $data['for_approval'] = 1;
1188                                    $n = 1;
1189                                }
1190                            }
1191                            $minimumOrderSize = $project->minimum_order_size;
1192
1193                            if($project->minimum_order_size_v2 != null && in_array($data['customer_type_id'], $customerTypeIds)){
1194                                if($data['amount'] >= $project->minimum_order_size_v2){
1195                                    $data['for_approval'] = 1;
1196                                    if($n == 1){
1197                                        $data['for_approval'] = 3;
1198                                        $n = 3;
1199                                    }
1200                                }
1201                            }
1202
1203                        }else{
1204                            if(!empty($company->customer_type_ids)){
1205                                $customerTypeIds = array_map('intval', explode(',', $company->customer_type_ids));
1206                            }
1207                            if($company->minimum_order_size != null && in_array($data['customer_type_id'], $customerTypeIds)){
1208                                if($data['amount'] >= $company->minimum_order_size){
1209                                    $data['for_approval'] = 1;
1210                                    $n = 1;
1211                                }
1212                            }
1213                            $minimumOrderSize = $company->minimum_order_size;
1214
1215                            if($company->minimum_order_size_v2 != null && in_array($data['customer_type_id'], $customerTypeIds)){
1216                                if($data['amount'] >= $company->minimum_order_size_v2){
1217                                    $data['for_approval'] = 1;
1218                                    if($n == 1){
1219                                        $data['for_approval'] = 3;
1220                                        $n = 3;
1221                                    }
1222                                }
1223                            }
1224                        }
1225
1226                        if($data['budget_margin_enabled'] > 0){
1227                            $costOfLabor = $data['cost_of_labor'];
1228                            $totalCostOfJob = $data['total_cost_of_job'];
1229
1230                            if($totalCostOfJob > 0){
1231                                $invoiceMargin = $data['invoice_margin'] ?? 0;
1232                            }
1233
1234                            $minimumMargin = $company->minimum_margin;
1235                            if(!empty($company->customer_type_ids)){
1236                                $customerTypeIds = array_map('intval', explode(',', $company->customer_type_ids));
1237                            }
1238
1239                            if($project){
1240                                $minimumMargin = $project->minimum_margin;
1241                                $minimumOrderSize = $project->minimum_order_size;
1242                                if(!empty($project->customer_type_ids)){
1243                                    $customerTypeIds = array_map('intval', explode(',', $project->customer_type_ids));
1244                                }
1245                            }
1246
1247                            if($invoiceMargin < $minimumMargin && $invoiceMargin != null && $invoiceMargin != 0){
1248                                if(in_array($data['customer_type_id'], $customerTypeIds)){
1249                                    $data['for_approval'] = 1;
1250                                    $n = 2;
1251                                }
1252                            }
1253                        }
1254                    }
1255
1256                    $isQuestion = 0;
1257                    $questionIdsNo = array();
1258                    if(isset($data['question_enabled'])){
1259                        if($data['question_ids_no'] != $result->question_ids_no
1260                            || $data['budget_type_id'] != $result->budget_type_id
1261                            || $data['customer_type_id'] != $result->customer_type_id
1262                            || $data['amount'] != $result->amount){
1263                            if($data['question_enabled'] > 0 && $n == 0){
1264                                if(!empty($data['question_ids_no'])){
1265                                    $questionIdsNo = array_map('intval', explode(",", $data['question_ids_no']));
1266
1267                                    if(count($questionIdsNo) > 0){
1268                                        if($company->workflow_budget_size != null){
1269                                            if($data['amount'] >= $company->workflow_budget_size){
1270                                                $isQuestion = 1;
1271                                                $data['for_approval'] = 1;
1272                                                $n = 1;
1273                                            }
1274                                        }
1275                                        $minimumOrderSize = $company->workflow_budget_size;
1276                                    }
1277                                }
1278                            }
1279                        }
1280                    }
1281
1282                    if($n == 1 || $n == 3){
1283                        $sendApprovalNotification = true;
1284                        $approvalMinimumOrderSize = $minimumOrderSize;
1285                        $approvalId = $result->id;
1286                        $approvalForAdd = $result->for_add;
1287                        $approvalIsQuestion = $isQuestion;
1288                        $approvalQuestionIdsNo = $questionIdsNo;
1289                        $approvalN = $n;
1290                    }
1291
1292                    if($n == 2){
1293                        $sendApprovalMarginNotification = true;
1294                        $approvalMinimumMargin = $minimumMargin;
1295                        $approvalId = $result->id;
1296                        $approvalForAdd = $result->for_add;
1297                        $approvalInvoiceMargin = $invoiceMargin;
1298                    }
1299                }
1300            }
1301
1302            $data['updated_at'] = date('Y-m-d H:i:s');
1303            $job['updated_at'] = $data['updated_at'];
1304
1305            $data["g3w_warning"] = 0;
1306
1307            if($result->for_add == 1){
1308                TblCompanies::where('company_id', $result->company_id)->update(array('last_id' => $data['quote_id'], 'before_last_id' => $data['quote_id']));
1309            }
1310
1311            $forApproval = @$data['for_approval'] ?? null;
1312
1313            if($forApproval != null){
1314                $data['approved_at'] = null;
1315                $data['approved_by'] = null;
1316                $data['rejected_at'] = null;
1317                $data['rejected_by'] = null;
1318                $data['approved_at_v2'] = null;
1319                $data['approved_by_v2'] = null;
1320                $data['rejected_at_v2'] = null;
1321                $data['rejected_by_v2'] = null;
1322            }
1323
1324            $differences = $this->compareArrays($data, TblQuotations::where('id', $id)->first());
1325            $primaryAprovalsFields = ["budget_type_id", "customer_type_id", "budget_margin_enabled", "amount", "invoice_margin","margin_for_the_company","margin_on_invoice_per_day_per_worker","gross_margin"];
1326
1327            if(is_null(TblQuotations::where('id', $id)->first()->customer_type_id)){
1328                $needToSendReminder = true;
1329            }
1330
1331            foreach ($differences as $field => $value) {
1332                if(in_array($field, $primaryAprovalsFields)){
1333                    $needToSendReminder = true;
1334                };
1335
1336                $this->addUpdateLog($id, $userId, $field, $value["oldData"], $value["newData"]);
1337            }
1338
1339            //check if the quotation are a solicitud and the user write the internal quote id
1340            if(
1341                (TblQuotations::where('id', $id)->first()->budget_status_id == 6 || TblQuotations::where('id', $id)->first()->budget_status_id == 8)
1342                && !is_null($data["internal_quote_id"] ?? null)
1343                && TblQuotations::where('internal_quote_id', $data["internal_quote_id"])->where("company_id", $company->company_id)->exists()
1344                && (!is_null($id) && $id !== "")
1345            ){
1346                $createdAt = TblQuotations::where('id', $id)->first()->created_at;
1347                TblQuotations::where('id', $id)->first()->update(array("internal_quote_id", $data["internal_quote_id"]));
1348
1349                $this->callDeleteQuotation($id, $company->company_id, $userId, $data['updated_by']);
1350                $budget = TblQuotations::where('internal_quote_id', $data["internal_quote_id"])->where("company_id", $company->company_id)->first();
1351
1352                $id = $budget->id;
1353
1354                $dataToChange = array_intersect_key($data, array_flip([
1355                    'internal_quote_id',
1356                    'client',
1357                    'phone_number',
1358                    'email',
1359                    'source_id',
1360                    'created_by',
1361                    'updated_by',
1362                    'updated_at'
1363                ]));
1364
1365                if($data["phone_number"] === null || $data["phone_number"] === "" || empty($dataToChange["phone_number"])){
1366                    unset($dataToChange['phone_number']);
1367                }
1368
1369                $dataToChange['budget_status_id'] = $budget->budget_status_id;
1370                $dataToChange["created_at"] = $createdAt;
1371
1372                $data["g3w_warning"] = 0;
1373
1374                if(
1375                    in_array($budget->budget_status_id, [13, 14]) ||
1376                    !$dataToChange["source_id"] ||
1377                    (!$budget->budget_type_id || $budget->budget_type_id == 0 || $budget->budget_type_id == 16) ||
1378                    empty(trim($dataToChange["client"])) ||
1379                    empty(trim($dataToChange["email"]))
1380                ){
1381                    $data["g3w_warning"] = 1;
1382                }
1383
1384                TblQuotations::where('id', $id)->update($dataToChange);
1385
1386            } else {
1387                TblQuotations::where('id', $id)->update($data);
1388            }
1389
1390            TblOngoingJobs::where('quotation_id', $id)->update($job);
1391
1392            $this->update_commercial_numbers($result->company_id);
1393
1394            if($result->budget_status_id != $data['budget_status_id']
1395                && $data['budget_status_id'] == 3){
1396                $this->send_acceptance_notification($result->id, $result->company_id, $userId, $data['updated_by']);
1397
1398                TblQuotations::where('id', $id)->update(
1399                    array(
1400                        'accepted_at' => $data['updated_at'],
1401                        'accepted_by' => $data['updated_by']
1402                    )
1403                );
1404            }
1405
1406            if($files){
1407
1408                $uploadedFiles = [];
1409                $i = 0;
1410
1411                $combinedFilesSize = 0;
1412                foreach ($files as $file) {
1413                    $i++;
1414                    $origFilename = $file->getClientOriginalName();
1415                    $filename = $result->id . '-' . $result->company_id . '-FC' . time() . '-' . $origFilename;
1416
1417                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
1418
1419                    if($combinedFilesSize > 25000000){
1420                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
1421                    }
1422
1423                    if(in_array($origFilename, $uploadedFiles)){
1424                        $origFilename = $origFilename . $i;
1425                    }
1426
1427                    // $fileContent = file_get_contents($file->getRealPath());
1428                    // $fileHash = hash('sha256', $fileContent);
1429                    
1430                    $s3path = Storage::disk('s3')->putFileAs(
1431                        'uploads',
1432                        $file,
1433                        $filename,
1434                        [
1435                            'ContentType' => $file->getMimeType(),
1436                        ]
1437                    );
1438
1439                    TblFiles::create(
1440                        array(
1441                            'quotation_id' => $id,
1442                            'original_name' => $origFilename,
1443                            'filename' => $filename,
1444                            'uploaded_by' => $data['updated_by'],
1445                            // 'file' => $fileContent,
1446                            'file_size' => $file->getSize(),
1447                            // 'file_hash' => $fileHash,
1448                            'mime_type' => $file->getMimeType(),
1449                            'uploaded_at' => now(),
1450                        )
1451                    );
1452
1453                    $uploadedFiles[] = $file->getClientOriginalName();
1454                }
1455            }
1456
1457            if($internalFiles){
1458
1459                $uploadedFiles = [];
1460                $i = 0;
1461
1462                $combinedFilesSize = 0;
1463                foreach ($internalFiles as $file) {
1464                    $i++;
1465                    $origFilename = $file->getClientOriginalName();
1466                    $filename = $result->id . '-' . $result->company_id . '-FI' . time() . '-' . $origFilename;
1467
1468                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
1469
1470                    if($combinedFilesSize > 25000000){
1471                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
1472                    }
1473
1474                    if(in_array($origFilename, $uploadedFiles)){
1475                        $origFilename = $origFilename . $i;
1476                    }
1477
1478                    // $fileContent = file_get_contents($file->getRealPath());
1479                    // $fileHash = hash('sha256', $fileContent);                    
1480
1481                    $s3path = Storage::disk('s3')->putFileAs(
1482                        'uploads',
1483                        $file,
1484                        $filename,
1485                        [
1486                            'ContentType' => $file->getMimeType(),
1487                        ]
1488                    );
1489
1490                    TblFiles::create(
1491                        array(
1492                            'quotation_id' => $id,
1493                            'original_name' => $origFilename,
1494                            'filename' => $filename,
1495                            'uploaded_by' => $data['updated_by'],
1496                            // 'file' => $fileContent,
1497                            'file_size' => $file->getSize(),
1498                            // 'file_hash' => $fileHash,
1499                            'mime_type' => $file->getMimeType(),
1500                            'uploaded_at' => now(),
1501                            'is_internal' => 1
1502                        )
1503                    );
1504
1505                    $uploadedFiles[] = $file->getClientOriginalName();
1506                }
1507            }
1508
1509            $query = "SELECT
1510                        a.id,
1511                        a.quote_id,
1512                        a.company_id,
1513                        b.name company_name,
1514                        a.client,
1515                        c.name client_type,
1516                        c.customer_type_id,
1517                        a.request_date,
1518                        a.visit_date,
1519                        a.issue_date,
1520                        a.acceptance_date,
1521                        a.internal_quote_id,
1522                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
1523                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
1524                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
1525                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
1526                        -- DATEDIFF(a.issue_date, a.request_date) duration,
1527                        a.phone_number,
1528                        a.email,
1529                        a.duration,
1530                        a.order_number,
1531                        d.name 'type',
1532                        d.budget_type_id,
1533                        e.name 'status',
1534                        e.budget_status_id,
1535                        f.name source,
1536                        f.source_id,
1537                        a.amount,
1538                        g.name reason_for_not_following_up,
1539                        a.reason_for_not_following_up_id,
1540                        a.reason_for_rejection_id,
1541                        a.last_follow_up_date,
1542                        a.last_follow_up_comment,
1543                        CASE WHEN a.reason_for_rejection_id IS NULL THEN a.reason_for_rejection ELSE h.name END reason_for_rejection,
1544                        a.commercial,
1545                        a.created_by,
1546                        a.created_at,
1547                        a.updated_by,
1548                        a.for_approval,
1549                        a.box_work_g3w,
1550                        a.people_assigned_to_the_job,
1551                        a.duration_of_job_in_days,
1552                        a.estimated_cost_of_materials,
1553                        a.budget_margin_enabled,
1554                        a.question_enabled,
1555                        a.cost_of_labor,
1556                        a.total_cost_of_job,
1557                        CASE WHEN a.budget_margin_enabled > 0 THEN a.invoice_margin ELSE NULL END invoice_margin,
1558                        CASE WHEN a.budget_margin_enabled > 0 THEN a.margin_for_the_company ELSE NULL END margin_for_the_company,
1559                        a.margin_on_invoice_per_day_per_worker,
1560                        a.revenue_per_date_per_worked,
1561                        a.commission_cost,
1562                        a.commission_pct,
1563                        a.gross_margin,
1564                        a.labor_percentage,
1565                        a.question_ids,
1566                        a.question_ids_no,
1567                        a.approved_at,
1568                        a.approved_by,
1569                        a.rejected_at,
1570                        a.rejected_by,
1571                        a.approved_at_v2,
1572                        a.approved_by_v2,
1573                        a.rejected_at_v2,
1574                        a.rejected_by_v2,
1575                        a.accepted_at,
1576                        a.accepted_by,
1577                        a.is_validated,
1578                        a.resource_id,
1579                        a.x_status,
1580                        a.likehood,
1581                        a.updated_at
1582                    FROM
1583                        tbl_quotations a
1584                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
1585                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
1586                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
1587                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
1588                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
1589                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
1590                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
1591                    WHERE a.id = {$id}";
1592
1593            $result = DB::select($query);
1594
1595
1596            if($sendNotification){
1597                $this->send_notification(
1598                    $commercial->email,
1599                    $userId,
1600                    $data['quote_id'],
1601                    $id,
1602                    $status->name,
1603                    $commercial->id,
1604                    $company->name,
1605                    0,
1606                    $company->company_id,
1607                    $data['internal_quote_id']
1608                );
1609            }
1610
1611            if($sendApprovalNotification && $needToSendReminder){
1612                $this->send_approval_notification(
1613                    $data['amount'],
1614                    $data['budget_type_id'],
1615                    $data['customer_type_id'],
1616                    $approvalMinimumOrderSize,
1617                    $data['quote_id'],
1618                    $approvalId,
1619                    $company->name,
1620                    @$data['created_by'] ?? @$data['updated_by'],
1621                    $userId,
1622                    $approvalForAdd,
1623                    @$commercial->email ?? null,
1624                    $company->company_id,
1625                    'orders',
1626                    $approvalIsQuestion,
1627                    $approvalQuestionIdsNo,
1628                    $approvalN
1629                );
1630            }
1631
1632            if($sendApprovalMarginNotification && $needToSendReminder){
1633                $this->send_approval_margin_notification(
1634                    $data['amount'],
1635                    $data['budget_type_id'],
1636                    $data['customer_type_id'],
1637                    $approvalMinimumMargin,
1638                    $data['quote_id'],
1639                    $approvalId,
1640                    $company->name,
1641                    @$data['created_by'] ?? @$data['updated_by'],
1642                    $userId,
1643                    $approvalForAdd,
1644                    @$commercial->email ?? null,
1645                    $approvalInvoiceMargin,
1646                    $company->company_id,
1647                    'orders'
1648                );
1649            }
1650
1651            Cache::flush();
1652
1653            return response(['message' => 'OK', 'data' => $result, 'for_approval' => $forApproval]);
1654
1655        // } catch (\Exception $e) {
1656        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
1657        // }
1658
1659    }
1660
1661    private function compareArrays($data, $quotations) {
1662        $differences = [];
1663
1664        foreach ($data as $field => $valueData) {
1665            if (isset($quotations->$field)) {
1666                $valueQuotations = $quotations->$field;
1667
1668                $valueData = $this->convertValue($valueData);
1669                $valueQuotations = $this->convertValue($valueQuotations);
1670                if (
1671                    $valueData !== $valueQuotations &&
1672                    !is_null($valueData) &&
1673                    !is_null($valueQuotations)
1674                ) {
1675                    $differences[$field] = [
1676                        'newData' => $valueData,
1677                        'oldData' => $valueQuotations
1678                    ];
1679                }
1680            } /*else {
1681                $diferences[$field] = [
1682                    'data' => $valueData,
1683                    'quotations' => 'NO_EXISTE'
1684                ];
1685            }*/
1686        }
1687
1688        /*foreach (get_object_vars($quotations) as $field => $valueQuotations) {
1689            if (!array_key_exists($field, $data)) {
1690                $diferences[$field] = [
1691                    'data' => 'NO_EXISTE',
1692                    'quotations' => $valueQuotations
1693                ];
1694            }
1695        }*/
1696
1697        return $differences;
1698    }
1699
1700    private function convertValue($value) {
1701        if ($value === null) {
1702            return null;
1703        }
1704
1705        if (is_numeric($value)) {
1706            return (int)$value;
1707        }
1708
1709        if ($value === 'NULL' || $value === 'null') {
1710            return null;
1711        }
1712
1713        if (is_string($value)) {
1714            if (preg_match('/^(\d{4}-\d{2}-\d{2})( \d{2}:\d{2}:\d{2})?$/', $value, $matches)) {
1715                return $matches[1];
1716            }
1717        }
1718
1719        return $value;
1720    }
1721
1722    protected function callDeleteQuotation($id, $company_id, $userId, $user)
1723    {
1724        $request = new \Illuminate\Http\Request([
1725            'company_id' => $company_id,
1726            'user_id' => $userId,
1727            'updated_by' => $user,
1728            'ids' => [$id],
1729            'filterModel' => [],
1730            'sortModel' => [],
1731            'searchText' => '',
1732            'ids_not_in' => []
1733        ]);
1734
1735        return $this->delete_quotation($request, true);
1736    }
1737
1738    public function get_quotation($id){
1739
1740        try {
1741
1742            $id = addslashes($id);
1743
1744            $query = "SELECT
1745                        a.id,
1746                        a.quote_id,
1747                        a.company_id,
1748                        b.name company_name,
1749                        a.client,
1750                        c.name client_type,
1751                        c.customer_type_id,
1752                        s.name segment,
1753                        s.segment_id,
1754                        a.request_date,
1755                        a.visit_date,
1756                        a.issue_date,
1757                        a.acceptance_date,
1758                        a.internal_quote_id,
1759                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
1760                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
1761                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
1762                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
1763                        a.phone_number,
1764                        a.email,
1765                        a.duration,
1766                        a.order_number,
1767                        d.name 'type',
1768                        d.budget_type_id,
1769                        e.name 'status',
1770                        e.budget_status_id,
1771                        f.name source,
1772                        f.source_id,
1773                        a.amount,
1774                        g.name reason_for_not_following_up,
1775                        a.reason_for_not_following_up_id,
1776                        a.reason_for_rejection_id,
1777                        a.last_follow_up_date,
1778                        a.last_follow_up_comment,
1779                        CASE WHEN a.reason_for_rejection_id IS NULL THEN a.reason_for_rejection ELSE h.name END reason_for_rejection,
1780                        a.commercial,
1781                        a.created_by,
1782                        a.created_at,
1783                        a.updated_by,
1784                        a.updated_at,
1785                        a.for_approval,
1786                        a.box_work_g3w,
1787                        a.people_assigned_to_the_job,
1788                        a.duration_of_job_in_days,
1789                        a.estimated_cost_of_materials,
1790                        a.budget_margin_enabled,
1791                        a.question_enabled,
1792                        a.cost_of_labor,
1793                        a.total_cost_of_job,
1794                        CASE WHEN a.budget_margin_enabled > 0 THEN a.invoice_margin ELSE NULL END invoice_margin,
1795                        CASE WHEN a.budget_margin_enabled > 0 THEN a.margin_for_the_company ELSE NULL END margin_for_the_company,
1796                        a.margin_on_invoice_per_day_per_worker,
1797                        a.revenue_per_date_per_worked,
1798                        a.commission_cost,
1799                        a.commission_pct,
1800                        a.gross_margin,
1801                        a.labor_percentage,
1802                        a.question_ids,
1803                        a.question_ids_no,
1804                        a.approved_at,
1805                        a.approved_by,
1806                        a.rejected_at,
1807                        a.rejected_by,
1808                        a.approved_at_v2,
1809                        a.approved_by_v2,
1810                        a.rejected_at_v2,
1811                        a.rejected_by_v2,
1812                        a.accepted_at,
1813                        a.accepted_by,
1814                        a.is_validated,
1815                        a.resource_id,
1816                        a.sync_import,
1817                        a.sync_import_edited,
1818                        a.g3w_warning,
1819                        a.g3w_warning_fields
1820                    FROM
1821                        tbl_quotations a
1822                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
1823                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
1824                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
1825                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
1826                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
1827                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
1828                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
1829                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
1830                    WHERE a.id = {$id}
1831                    AND a.company_id IN ({$this->companyId})";
1832
1833            $result = DB::select($query);
1834
1835            Cache::flush();
1836            return response(['message' => 'OK', 'data' => $result]);
1837
1838        } catch (\Exception $e) {
1839            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1840        }
1841    }
1842
1843    public function get_quotation_log($id){
1844        return TblQuotationsLog::where("quotation_id", $id)->get();
1845    }
1846
1847    public function send_notification($toEmail = null, $userId, $quoteId, $id, $status, $sendUserId, $companyName, $action, $companyId, $g3wQuoteId){
1848
1849        $user = TblUsers::where('id', $userId)->first();
1850
1851        $imgpath = File::get('fireservicetitan.png');
1852
1853        $url = env('URL') . "orders/{$id}?company_id={$companyId}";
1854        $href = "<a href='{$url}'>{$quoteId}</a>";
1855
1856        $body = "";
1857        $subject = "";
1858
1859        if($g3wQuoteId){
1860            $quoteId = $quoteId . " - G3W #{$g3wQuoteId}";
1861        }
1862
1863        if($action == 1){
1864            $body = __('language.email_notification.body_created');
1865            $body = str_replace('{{creator}}', $user->name, $body);
1866            $subject = str_replace('{{quote_id}}', $quoteId, __('language.email_notification.subject_created'));
1867        }else{
1868            $body = __('language.email_notification.body_assigned');
1869            $body = str_replace('{{assignee}}', $user->name, $body);
1870            $subject = str_replace('{{quote_id}}', $quoteId, __('language.email_notification.subject_assigned'));
1871        }
1872
1873        $body = str_replace('{{quote_id}}', $href, $body);
1874        $body = str_replace('{{company}}', $companyName, $body);
1875        $body = str_replace('{{status}}', $status, $body);
1876
1877        $content = $body;
1878
1879        $body .= "<p>Fire Service Titan</p>";
1880        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
1881
1882        $html = '<!DOCTYPE html>';
1883        $html .= '<html>';
1884        $html .= '<head>';
1885        $html .= '<meta charset="UTF-8">';
1886        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
1887        $html .= '</head>';
1888        $html .= '<body>';
1889        $html .= $body;
1890        $html .= '</body>';
1891        $html .= '</html>';
1892
1893        if($toEmail != null){
1894            $email = new \SendGrid\Mail\Mail();
1895
1896            if(env('SENDGRID_STAGING')){
1897                $toEmail = $user->email;
1898            }
1899
1900            $email->setFrom('fire@fire.es', 'Fire Service Titan');
1901            $email->setSubject($subject);
1902            $email->addTo($toEmail);
1903            $email->addContent("text/html", $html);
1904
1905            $email->addAttachment(
1906                $imgpath,
1907                "image/png",
1908                "fireservicetitan.png",
1909                "inline",
1910                "fireservicetitan"
1911            );
1912
1913            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
1914
1915            $response = $sendgrid->send($email);
1916            if ($response->statusCode() == 202) {
1917                Log::channel('email_log')->info('ID:' . $quoteId . ' : ' . $status . ' : '. $toEmail .' - EMAIL NOTIFICATION SENT');
1918
1919                TblNotifications::create(
1920                    array(
1921                        'user_id' => $sendUserId,
1922                        'content' => $content,
1923                        'is_open' => 1,
1924                        'created_by' => 'System',
1925                        'link' => $url
1926                    )
1927                );
1928            } else {
1929                $error = true;
1930                Log::channel('email_log')->error('ID:' . $quoteId . ' : ' . $status . ' : '. $toEmail .' - ' . $response->body());
1931            }
1932        }
1933
1934    }
1935
1936    public function delete_quotation(Request $request, $isFromDeleteCall = false){
1937
1938        try {
1939
1940            $data = $request->all();
1941            $result = array();
1942
1943            $r = new Request([
1944                'filterModel' => $data['filterModel'],
1945                'sortModel' => $data['sortModel'],
1946                'start' => 0,
1947                'end' => 999999999,
1948                'company_id' => $data['company_id'],
1949                'user_id' => $data['user_id'],
1950                'ids' => $data['ids'],
1951                'searchText' => $data['searchText'],
1952                'ids_not_in' => $data['ids_not_in']
1953            ]);
1954
1955            $result = $this->list_quotations($r);
1956            $result = $result->original['data'];
1957
1958            $outputArray = array();
1959
1960            foreach ($result as $item) {
1961                if (isset($item->id)) {
1962                    $outputArray[] = $item->id;
1963                }
1964            }
1965
1966            $ids = implode(',', $outputArray);
1967
1968            if($outputArray){
1969
1970                TblQuotations::whereIn('id', $outputArray)->update(
1971                    array(
1972                        'updated_at' => date('Y-m-d H:i:s'),
1973                        'updated_by' => $data['updated_by'],
1974                        'for_add' => $isFromDeleteCall ? 2 : ($data['for_add'] ?? 0),
1975                        'reason_id' => (isset($data['reason_id']) ? $data['reason_id'] : null),
1976                        'reason_for_deletion' => (isset($data['reason_for_deletion']) ? $data['reason_for_deletion'] : null),
1977                    )
1978                );
1979
1980                $query = "INSERT INTO tbl_quotations_deleted
1981                        SELECT * FROM tbl_quotations WHERE id IN ({$ids})";
1982
1983                DB::select($query);
1984
1985                TblQuotations::whereIn('id', $outputArray)->delete();
1986                TblFiles::whereIn('quotation_id', $outputArray)->delete();
1987            }
1988
1989            Cache::flush();
1990            return response(['message' => 'OK', 'data' => $result]);
1991
1992        } catch (\Exception $e) {
1993            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1994        }
1995
1996    }
1997
1998    public function list_quotations(Request $request){
1999
2000        // try {
2001
2002            $data = $request->all();
2003            $companyId = addslashes($data['company_id']);
2004            $userId = addslashes($data['user_id']);
2005            $filter = $data['filterModel'];
2006            $sort = $data['sortModel'];
2007            $result = array();
2008            $subquery = "";
2009            $where = "";
2010            $having = "";
2011            $orderBy = "";
2012            $start = addslashes($data['start']);
2013            $end = addslashes($data['end']);
2014            $totalRowCount = 0;
2015            $withFilters = "";
2016            $logFilter = @$data['log_filter'];
2017
2018            $filterType = array(
2019                'contains' => "LIKE '%[value]%'",
2020                'notContains' => "NOT LIKE '%[value]%'",
2021                'equals' => "= '[value]'",
2022                'notEqual' => "<> '[value]'",
2023                'startsWith' => "LIKE '[value]%'",
2024                'endsWith' => "LIKE '%[value]'",
2025                'blank' => "IS NULL",
2026                'notBlank' => "IS NOT NULL",
2027                'lessThan' => "< [value]",
2028                'lessThanOrEqual' => "<= [value]",
2029                'greaterThan' => "> [value]",
2030                'greaterThanOrEqual' => ">= [value]",
2031                'inRange' => "BETWEEN [value1] AND [value2]",
2032                "in" => "IN ([value])"
2033            );
2034            /*if(isset($data['internal_quote_id']) && count($data['internal_quote_id']) > 0){
2035                $internalIds = implode(",", $data['internal_quote_id']);
2036                $where = " AND a.internal_quote_id IN ({$internalIds}) ";
2037            }*/
2038
2039            if(isset($data['ids']) && count($data['ids']) > 0){
2040                $quoteIds = implode(",", $data['ids']);
2041                $where = " AND a.id IN ({$quoteIds}";
2042            }
2043
2044            if(isset($data['ids_not_in']) && count($data['ids_not_in']) > 0){
2045                $quoteIds = implode(",", $data['ids_not_in']);
2046                $where = " AND a.id NOT IN ({$quoteIds}";
2047            }
2048
2049            $lasLeftJoin = "";
2050            $whereBlocked = "";
2051
2052            if(isset($data['last_follow_up_date']) && !empty($data['last_follow_up_date'])){
2053                if($data['last_follow_up_date'] == 1){
2054
2055                    $lasLeftJoin = " LEFT JOIN (
2056                        SELECT
2057                          a.id,
2058                          SUBSTRING_INDEX(
2059                            SUBSTRING_INDEX(a.email, ',', n.digit + 1),
2060                            ',',
2061                            -1
2062                          ) AS email_domain
2063                        FROM
2064                          tbl_quotations a
2065                          INNER JOIN (
2066                            SELECT
2067                              0 AS digit
2068                            UNION ALL
2069                            SELECT
2070                              1
2071                            UNION ALL
2072                            SELECT
2073                              2
2074                            UNION ALL
2075                            SELECT
2076                              3
2077                            UNION ALL
2078                            SELECT
2079                              4
2080                            UNION ALL
2081                            SELECT
2082                              5
2083                            UNION ALL
2084                            SELECT
2085                              6
2086                            UNION ALL
2087                            SELECT
2088                              7
2089                            UNION ALL
2090                            SELECT
2091                              8
2092                            UNION ALL
2093                            SELECT
2094                              9
2095                          ) n ON LENGTH(
2096                            REPLACE(a.email, ',', '')
2097                          ) <= LENGTH(a.email)- n.digit
2098                          GROUP BY a.id
2099                      ) temp ON a.id = temp.id ";
2100
2101                    $whereBlocked = " AND a.last_follow_up_date < NOW()
2102                            AND a.budget_status_id IN (2)
2103                            AND a.email IS NOT NULL
2104                            AND a.email <> ''
2105                            AND NOT EXISTS (
2106                                SELECT
2107                                1
2108                                FROM
2109                                tbl_blocked_domains bd
2110                                WHERE
2111                                temp.email_domain LIKE CONCAT('%', bd.domain, '%')
2112                                AND bd.company_id = a.company_id
2113                            )
2114                            AND a.last_follow_up_date IS NOT NULL
2115                            AND a.reason_for_not_following_up_id IS NULL
2116                            AND a.last_follow_up_date > 0
2117                            AND a.total_sent < b.limit_reminder_emails
2118                            AND a.for_add = 0 ";
2119                }
2120            }
2121
2122            if(isset($data['visit_date']) && !empty($data['visit_date'])){
2123                if($data['visit_date'] == 1){
2124                    $where = " AND DATE_FORMAT(a.visit_date, '%Y-%m-%d') <= DATE_FORMAT(NOW(), '%Y-%m-%d') ";
2125                }
2126            }
2127
2128            $where .= " AND a.company_id IN ({$this->companyId}";
2129
2130            $matchScoreCol = "";
2131            $matchScoreOrderBy = "";
2132
2133            if(isset($data['searchText']) && $data['searchText'] != null){
2134
2135                $availableParameters = [
2136                    'a.quote_id',
2137                    'a.internal_quote_id',
2138                    'a.box_work_g3w',
2139                    's.name',
2140                    'b.name',
2141                    'a.client',
2142                    'c.name',
2143                    'a.phone_number',
2144                    'a.email',
2145                    'a.order_number',
2146                    'a.request_date',
2147                    'a.issue_date',
2148                    'a.acceptance_date',
2149                    'a.created_at',
2150                    'a.updated_at',
2151                    'a.rejected_at',
2152                    'a.accepted_at',
2153                    'd.name',
2154                    'e.name',
2155                    'f.name',
2156                    'a.amount',
2157                    'g.name',
2158                    'a.last_follow_up_comment',
2159                    'a.x_status',
2160                    'h.name',
2161                    'a.commercial',
2162                    'a.user_commercial_by_g3w',
2163                    'a.user_create_by_g3w',
2164                    'a.created_by',
2165                    'a.updated_by',
2166                    'a.approved_by',
2167                    'a.rejected_by',
2168                    'a.accepted_by',
2169                    'a.sync_import',
2170                    'a.sync_import_edited',
2171                    'a.g3w_warning'
2172                ];
2173
2174                $searchText = addslashes($data['searchText']);
2175                $searchTextArray = explode(" ", $searchText);
2176
2177                $searchArray = array();
2178                $splitSearchArray = array();
2179                $matchScoreArray = array();
2180                $sc = 1;
2181                foreach ($availableParameters as $field) {
2182                    if($field == 'a.client' || $field == 'a.amount' || $field == 'a.created_at'){
2183                        $sc = 3;
2184                    }elseif($field == 'a.acceptance_date'){
2185                        $sc = 2;
2186                    }else{
2187                        $sc = 1;
2188                    }
2189
2190                    $l = "{$field} LIKE '%{$searchText}%'";
2191                    if($field == "a.last_follow_up_comment"){
2192                        $l = "{$field} = '{$searchText}'";
2193                    }else{
2194
2195                        $d = "IFNULL((LENGTH(LOWER({$field})) - LENGTH(REPLACE(LOWER({$field}), LOWER('{$searchText}'), ''))) / LENGTH(LOWER('{$searchText}')), 0) * {$sc}";
2196
2197                        if(count($searchTextArray) > 1){
2198                            foreach ($searchTextArray as $word) {
2199                                if(!is_numeric($word)){
2200                                    $d .= " + IFNULL((LENGTH(LOWER({$field})) - LENGTH(REPLACE(LOWER({$field}), LOWER('{$word}'), ''))) / LENGTH(LOWER('{$word}')), 0) * {$sc}";
2201                                }
2202                            }
2203                        }
2204
2205                        array_push($matchScoreArray, $d);
2206                    }
2207
2208                    if(is_numeric($searchText)){
2209                        array_push($searchArray, "({$l} OR {$field} = CAST('{$searchText}' AS UNSIGNED))");
2210                    }else{
2211                        array_push($searchArray, "({$l} OR DATE_FORMAT({$field}, '%d/%m/%Y') = DATE_FORMAT(STR_TO_DATE('{$searchText}', '%d/%m/%Y'), '%d/%m/%Y'))");
2212                    }
2213
2214                    if(count($searchTextArray) > 1){
2215                        foreach ($searchTextArray as $word) {
2216
2217                            $l = "{$field} LIKE '%{$word}%'";
2218                            if($field == "a.last_follow_up_comment"){
2219                                $l = "{$field} = '{$word}'";
2220                            }
2221
2222                            if(is_numeric($word)){
2223                                array_push($splitSearchArray, "{$l} OR {$field} = CAST('{$word}' AS UNSIGNED)");
2224                            }else{
2225                                array_push($splitSearchArray, "{$l} OR DATE_FORMAT({$field}, '%d/%m/%Y') = DATE_FORMAT(STR_TO_DATE('{$word}', '%d/%m/%Y'), '%d/%m/%Y')");
2226                            }
2227                        }
2228                    }
2229
2230                    $sc = 1;
2231                }
2232
2233                if(count($splitSearchArray) > 0){
2234                    $splitSearchArray = implode(" OR ", $splitSearchArray);
2235                    $splitSearchArray = " OR ({$splitSearchArray}";
2236                }else{
2237                    $splitSearchArray = "";
2238                }
2239
2240                $searchArray = implode(" OR ", $searchArray);
2241                $matchScoreArray = implode(",", $matchScoreArray);
2242                $matchScoreCol = ", GREATEST({$matchScoreArray}) match_score";
2243                $matchScoreOrderBy = "match_score DESC,";
2244                $where .= " AND ({$searchArray} {$splitSearchArray})";
2245            }
2246
2247            if(count($sort) > 0){
2248                $field = $sort[0]['colId'];
2249                $sortBy = $sort[0]['sort'];
2250
2251                if(strpos($field, "translate") !== false){
2252                    $field = str_replace("_translate", "", $field);
2253                }else{
2254                    if($field == "client_type"){
2255                        $field = "c.name";
2256                    }elseif($field == "segment"){
2257                        $field = "s.name";
2258                    }elseif($field == "type"){
2259                        $field = "d.name";
2260                    }elseif($field == "status"){
2261                        $field = "e.name";
2262                    }elseif($field == "source"){
2263                        $field = "g.name";
2264                    }elseif($field == "reason_for_not_following_up"){
2265                        $field = "g.name";
2266                    }elseif($field == "reason_for_rejection"){
2267                        $field = "h.name";
2268                    }elseif($field == "amount"){
2269                        $field = "CAST(a.amount AS DOUBLE)";
2270                    }elseif($field == "duration"){
2271                        $field = "CAST(a.duration AS DOUBLE)";
2272                    }elseif($field == "quote_id" || $field == "internal_quote_id"){
2273                        $field = "CAST(a.{$field} AS DOUBLE)";
2274                    }elseif($field == "company_name"){
2275                        $field = "b.name";
2276                    }
2277
2278                }
2279
2280                if($matchScoreOrderBy){
2281                    $matchScoreOrderBy = ", match_score DESC";
2282                }
2283
2284                $orderBy = " ORDER BY {$field} {$sortBy} {$matchScoreOrderBy}";
2285            }else{
2286                $orderBy = " ORDER BY {$matchScoreOrderBy} a.id DESC";
2287            }
2288
2289            foreach ($filter as $key => $data) {      
2290                if(strpos($key, "translate") !== false){
2291
2292                    $field = str_replace("_translate", "", $key);
2293                    if($field == "created_at"){
2294                        $field = "a.created_at";
2295                    }elseif($field == "last_follow_up_date"){
2296                        $field = "a.last_follow_up_date";
2297                    }elseif($field == "issue_date"){
2298                        $field = "a.issue_date";
2299                    }elseif($field == "request_date"){
2300                        $field = "a.request_date";
2301                    }elseif($field == "acceptance_date"){
2302                        $field = "a.acceptance_date";
2303                    }elseif($field == "internal_quote_id"){
2304                        $field = "a.internal_quote_id";
2305                    }
2306
2307                    $whereDates = "";
2308                    $z = 0;
2309
2310                    if(isset($data['filters']) && !empty($data['filters'])){
2311                        foreach ($data['filters'] as $yearKey => $yearData) {
2312                            $yearsMonths = array();
2313                            $yearsWeeks = array();
2314
2315                            if($z > 0){
2316                                $whereDates .= " OR (YEAR($field) = {$yearKey} ";
2317                            }else{
2318                                $whereDates .= " (YEAR($field) = {$yearKey} ";
2319                            }
2320
2321                            for ($i = 0; $i < count($yearData['months']); $i++) {
2322                                if($yearData['months'][$i]['isChecked']){
2323                                    array_push($yearsMonths, $yearData['months'][$i]['value']);
2324                                }
2325                            }
2326
2327                            $yearsMonths = implode("','", $yearsMonths);
2328                            $whereDates .= " AND (MONTH({$field}) IN ('{$yearsMonths}')";
2329
2330                            for ($i = 0; $i < count($yearData['weeks']); $i++) {
2331                                if($yearData['weeks'][$i]['isChecked']){
2332                                    array_push($yearsWeeks, $yearData['weeks'][$i]['value']);
2333                                }
2334                            }
2335
2336                            $yearsWeeks = implode("','", $yearsWeeks);
2337                            if($yearsWeeks != ''){
2338                                $whereDates .= " OR WEEK({$field}) IN ('{$yearsWeeks}') ";
2339                            }
2340
2341                            $whereDates .= ")) ";
2342                            $z++;
2343                        }
2344                    }
2345
2346                    $whereDataUptoToday = "";
2347                    if(isset($data['isDataUptoToday'])){
2348                        if($data['isDataUptoToday']){
2349                            $whereDates = "";
2350                            $whereDataUptoToday .= " AND {$field} < NOW() AND {$field} > 0 ";
2351                        }
2352                    }
2353
2354                    $whereBlanks = "";
2355                    if(isset($data['isBlanks'])){
2356                        if($data['isBlanks']){
2357                            $conj = "OR";
2358                            if($whereDates == ""){
2359                                $conj = "";
2360                            }
2361                            $whereBlanks .= " {$conj} {$field} IS NULL ";
2362                        }else{
2363                            $conj = "AND";
2364                            if($whereDates == ""){
2365                                $conj = "";
2366                            }
2367                            $whereBlanks .= " {$conj} {$field} IS NOT NULL ";
2368                        }
2369                    }
2370
2371                    $where .= " AND ({$whereDates} {$whereBlanks} {$whereDataUptoToday}";
2372                }else{
2373                    if($data['filterType'] == 'number'){
2374                        if(array_key_exists('operator', $data)){
2375                            if($data['condition1']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
2376                                $data['condition1']['filter'] = addslashes($data['condition1']['filter']);
2377                                $data['condition2']['filter'] = addslashes($data['condition2']['filter']);
2378
2379                                if($data['condition1']['type'] == 'inRange'){
2380                                    $data['condition1']['filterTo'] = addslashes($data['condition1']['filterTo']);
2381                                    $inRange = str_replace("[value1]", $data['condition1']['filter'], $filterType['inRange']);
2382                                    $val1 = str_replace("[value2]", $data['condition1']['filterTo'], $inRange);
2383                                }else{
2384                                    $val1 = str_replace("[value]", $data['condition1']['filter'], $filterType[$data['condition1']['type']]);
2385                                }
2386
2387                                if($data['condition2']['type'] == 'inRange'){
2388                                    $data['condition2']['filterTo'] = addslashes($data['condition2']['filterTo']);
2389                                    $inRange = str_replace("[value1]", $data['condition2']['filter'], $filterType['inRange']);
2390                                    $val2 = str_replace("[value2]", $data['condition2']['filterTo'], $inRange);
2391                                }else{
2392                                    $val2 = str_replace("[value]", $data['condition2']['filter'], $filterType[$data['condition2']['type']]);
2393                                }
2394
2395                            }else{
2396                                $val1 = $filterType[$data['condition1']['type']];
2397                                $val2 = $filterType[$data['condition2']['type']];
2398                            }
2399
2400                            $where .= " AND a.{$key} {$val1} {$data['operator']} a.{$key} {$val2} ";
2401                        }else{
2402                            if($data['type'] != 'blank' && $data['type'] != 'notBlank'){
2403                                $data['filter'] = addslashes($data['filter']);
2404
2405                                if($data['type'] == 'inRange'){
2406                                    $data['filterTo'] = addslashes($data['filterTo']);
2407                                    $inRange = str_replace("[value1]", $data['filter'], $filterType['inRange']);
2408                                    $val = str_replace("[value2]", $data['filterTo'], $inRange);
2409                                }else{
2410                                    $val = str_replace("[value]", $data['filter'], $filterType[$data['type']]);
2411                                }
2412                            }else{
2413                                $val = $filterType[$data['type']];
2414                            }
2415
2416                            $where .= " AND a.{$key} {$val} ";
2417                        }
2418                    }
2419
2420                    if($data['filterType'] == 'text'){
2421                        if($key == "id"){
2422                            continue;
2423                        }
2424                        
2425                        if(array_key_exists('operator', $data)){
2426                            if($data['condition1']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
2427                                $data['condition1']['filter'] = addslashes($data['condition1']['filter']);
2428                                $val1 = str_replace("[value]", $data['condition1']['filter'], $filterType[$data['condition1']['type']]);
2429                            }
2430
2431                            if($data['condition2']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
2432                                $data['condition2']['filter'] = addslashes($data['condition2']['filter']);
2433                                $val2 = str_replace("[value]", $data['condition2']['filter'], $filterType[$data['condition2']['type']]);
2434                            }
2435
2436                            $where .= " AND {$key} {$val1} {$data['operator']} {$key} {$val2} ";
2437                        }else{
2438
2439                            $type = $data['type'];
2440                            $filter = $data['filter'];
2441
2442                            if (($type === 'in' || $type === 'contains') && strpos($filter, ',') !== false) {
2443                                $values = explode(',', $filter);
2444                                $escaped = array_map('addslashes', $values);
2445                                $val = "IN ('" . implode("','", $escaped) . "')";
2446                            }
2447
2448                            elseif ($type !== 'blank' && $type !== 'notBlank') {
2449                                $data['filter'] = addslashes($data['filter']);
2450                                $val = str_replace("[value]", $data['filter'], $filterType[$type]);
2451                            }
2452
2453                            else {
2454                                $val = $filterType[$type];
2455                            }
2456
2457                            $where .= " AND {$key} {$val} ";
2458
2459                        }
2460                    }
2461
2462                    if($data['filterType'] == 'set'){
2463                        $statusName = $key;
2464
2465                        if($key == "client_type"){
2466                            $statusName = "c.name";
2467                        }elseif($key == "segment"){
2468                            $statusName = "s.name";
2469                        }elseif($key == "type"){
2470                            $statusName = "d.name";
2471                        }elseif($key == "status"){
2472                            $statusName = "e.name";
2473                        }elseif($key == "source"){
2474                            $statusName = "f.name";
2475                        }elseif($key == "reason_for_not_following_up"){
2476                            $statusName = "g.name";
2477                        }elseif($key == "reason_for_rejection"){
2478                            $statusName = "h.name";
2479                        }elseif($key == "created_by"){
2480                            $statusName = "a.created_by";
2481                        }elseif($key == "has_attachment"){
2482                            $statusName = "a.has_attachment";
2483                            if($data['values']){
2484                                foreach ($data['values'] as $k => $v) {
2485                                    if($v == "No"){
2486                                        $data['values'][$k] = 0;
2487                                    }else{
2488                                        $data['values'][$k] = 1;
2489                                    }
2490                                }
2491                            }
2492                        }elseif($key == "for_approval"){
2493                            $statusName = "a.for_approval";
2494                            if($data['values']){
2495                                foreach ($data['values'] as $k => $v) {
2496                                    if($v == "No"){
2497                                        $data['values'][$k] = 0;
2498                                    }else{
2499                                        $data['values'][$k] = 1;
2500                                    }
2501                                }
2502                            }
2503                        }elseif($key == "sync_import"){
2504                            $statusName = "a.sync_import";
2505                            if($data['values']){
2506                                foreach ($data['values'] as $k => $v) {
2507                                    if($v == "Manual"){
2508                                        $data['values'][$k] = 0;
2509                                    }else{
2510                                        $data['values'][$k] = 1;
2511                                    }
2512                                }
2513                            }
2514                        }elseif($key == "g3w_warning"){
2515                            $statusName = "a.g3w_warning";
2516                            if($data['values']){
2517                                foreach ($data['values'] as $k => $v) {
2518                                    if($v == "No"){
2519                                        $data['values'][$k] = 0;
2520                                    }else{
2521                                        $data['values'][$k] = 1;
2522                                    }
2523                                }
2524                            }
2525                        }elseif($key == "company_name"){
2526                            $statusName = "b.name";
2527                        }
2528
2529                        $val = implode("','", $data['values']);
2530
2531                        if(in_array(null, $data['values'], true)){
2532                            $where .= " AND ({$statusName} IN ('{$val}') OR {$statusName} IS NULL) ";
2533                        }else{
2534                            $where .= " AND {$statusName} IN ('{$val}') ";
2535                        }
2536                    }
2537                }
2538            }
2539
2540            $whereSendToClient = $where;
2541            $where;
2542
2543            $offset = $start;
2544            $limit = $end - $start;
2545
2546            $subquery = ",(SELECT can_write FROM tbl_company_users WHERE company_id = a.company_id AND user_id = {$userId}) can_write";
2547
2548            // Quotations accepted without acceptance_date
2549            // Quotations with state "No encontrado" or "Estado no reconocido en FST"
2550            // Quotations with not comercial in out database
2551            // Phone number on null
2552            // Source on null
2553            // Client name on null
2554            // Budget Type on null
2555            if (isset($request['g3w_warning'])) {
2556                $g3w_warning = $request['g3w_warning'] == "No" ? 0 : 1;
2557                /*$where .= "
2558                AND a.sync_import = 1
2559                    AND (
2560                        a.budget_status_id IN (13, 14)
2561                        OR (
2562                            a.commercial IS NULL
2563                            OR NOT EXISTS (
2564                                SELECT 1 FROM tbl_users u WHERE u.name = a.commercial
2565                            )
2566                            OR a.phone_number IS NULL
2567                            OR a.source_id IS NULL
2568                            OR a.budget_type_id IS NULL
2569                            OR (a.client IS NULL OR TRIM(a.client) = '')
2570                            OR (a.email IS NULL OR TRIM(a.email) = '')
2571                        )
2572                    )
2573                 ";*/
2574                $where .= "
2575                AND (a.sync_import = 1 OR a.sync_import_edited = 1)
2576                AND a.g3w_warning = " . $g3w_warning;
2577            }
2578
2579
2580            $query = "SELECT
2581                        a.id,
2582                        a.quote_id,
2583                        a.internal_quote_id,
2584                        a.company_id,
2585                        b.name company_name,
2586                        a.client,
2587                        c.name client_type,
2588                        c.customer_type_id,
2589                        s.name segment,
2590                        s.segment_id,
2591                        a.request_date,
2592                        a.visit_date,
2593                        a.issue_date,
2594                        a.acceptance_date,
2595                        a.internal_quote_id,
2596                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
2597                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
2598                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
2599                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
2600                        DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate,
2601                        DATE_FORMAT(a.accepted_at, '%d/%m/%Y') accepted_at_translate,
2602                        a.phone_number,
2603                        a.email,
2604                        a.duration,
2605                        a.order_number,
2606                        d.name 'type',
2607                        d.budget_type_id,
2608                        e.name 'status',
2609                        e.budget_status_id,
2610                        f.name as source,
2611                        f.source_id,
2612                        a.amount,
2613                        g.name reason_for_not_following_up,
2614                        a.reason_for_not_following_up_id,
2615                        a.reason_for_rejection_id,
2616                        a.last_follow_up_date,
2617                        a.last_follow_up_comment,
2618                        CASE WHEN a.reason_for_rejection_id IS NULL THEN a.reason_for_rejection ELSE h.name END reason_for_rejection,
2619                        a.commercial,
2620                        a.user_commercial_by_g3w,
2621                        a.user_create_by_g3w,
2622                        a.created_by,
2623                        a.created_at,
2624                        a.updated_by,
2625                        a.updated_at,
2626                        a.total_sent,
2627                        a.has_attachment,
2628                        a.for_approval,
2629                        a.box_work_g3w,
2630                        a.people_assigned_to_the_job,
2631                        a.duration_of_job_in_days,
2632                        a.estimated_cost_of_materials,
2633                        a.budget_margin_enabled,
2634                        a.question_enabled,
2635                        a.cost_of_labor,
2636                        a.total_cost_of_job,
2637                        CASE WHEN a.budget_margin_enabled > 0 THEN a.invoice_margin ELSE NULL END invoice_margin,
2638                        CASE WHEN a.budget_margin_enabled > 0 THEN a.margin_for_the_company ELSE NULL END margin_for_the_company,
2639                        a.margin_on_invoice_per_day_per_worker,
2640                        a.revenue_per_date_per_worked,
2641                        a.commission_cost,
2642                        a.commission_pct,
2643                        a.gross_margin,
2644                        a.labor_percentage,
2645                        a.question_ids,
2646                        a.question_ids_no,
2647                        a.approved_at,
2648                        a.approved_by,
2649                        a.rejected_at,
2650                        a.rejected_by,
2651                        a.approved_at_v2,
2652                        a.approved_by_v2,
2653                        a.rejected_at_v2,
2654                        a.rejected_by_v2,
2655                        a.accepted_at,
2656                        a.accepted_by,
2657                        a.is_validated,
2658                        a.resource_id,
2659                        a.x_status,
2660                        a.likehood,
2661                        a.sync_import,
2662                        a.sync_import_edited,
2663                        a.g3w_warning,
2664                        a.g3w_warning_fields,
2665                        SUBSTRING_INDEX(a.email, '@', -1) domain
2666                        {$matchScoreCol}
2667                        {$subquery}
2668                    FROM
2669                        tbl_quotations a
2670                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2671                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2672                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2673                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2674                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2675                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2676                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2677                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2678                        {$lasLeftJoin}
2679                    WHERE a.for_add = 0 {$where} {$whereBlocked}
2680                    GROUP BY a.id
2681                    {$orderBy}
2682                    LIMIT {$offset}{$limit}
2683                    ";            
2684
2685            $value = Cache::get(base64_encode($query));
2686
2687            if(!$value){
2688                $result = DB::select($query);
2689
2690                Cache::put(base64_encode($query), $result, 600);
2691            }else{
2692                $result = $value;
2693            }
2694
2695            $totalQuery = "SELECT
2696                            COUNT(a.id) totalRowCount,
2697                            SUM(CAST(a.amount AS DECIMAL(10,2))) totalAmount
2698                        FROM
2699                            tbl_quotations a
2700                            LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2701                            LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2702                            LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2703                            LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2704                            LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2705                            LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2706                            LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2707                            LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2708                            {$lasLeftJoin}
2709                        WHERE a.for_add = 0
2710                        {$where} {$whereBlocked}";
2711
2712            $value = Cache::get(base64_encode($totalQuery));
2713
2714            if(!$value){
2715                $countQuery = DB::select($totalQuery);
2716
2717                Cache::put(base64_encode($totalQuery), $countQuery, 600);
2718            }else{
2719                $countQuery = $value;
2720            }
2721
2722            $totalToFollowUpQuery = "SELECT
2723                                        COUNT(DISTINCT a.id) totalRowCount
2724                                    FROM
2725                                        tbl_quotations a
2726                                    LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2727                                    LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2728                                    LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2729                                    LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2730                                    LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2731                                    LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2732                                    LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2733                                    LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2734                                    LEFT JOIN (
2735                                        SELECT
2736                                        a.id,
2737                                        SUBSTRING_INDEX(
2738                                            SUBSTRING_INDEX(a.email, ',', n.digit + 1),
2739                                            ',',
2740                                            -1
2741                                        ) AS email_domain
2742                                        FROM
2743                                        tbl_quotations a
2744                                        INNER JOIN (
2745                                            SELECT
2746                                            0 AS digit
2747                                            UNION ALL
2748                                            SELECT
2749                                            1
2750                                            UNION ALL
2751                                            SELECT
2752                                            2
2753                                            UNION ALL
2754                                            SELECT
2755                                            3
2756                                            UNION ALL
2757                                            SELECT
2758                                            4
2759                                            UNION ALL
2760                                            SELECT
2761                                            5
2762                                            UNION ALL
2763                                            SELECT
2764                                            6
2765                                            UNION ALL
2766                                            SELECT
2767                                            7
2768                                            UNION ALL
2769                                            SELECT
2770                                            8
2771                                            UNION ALL
2772                                            SELECT
2773                                            9
2774                                        ) n ON LENGTH(
2775                                            REPLACE(a.email, ',', '')
2776                                        ) <= LENGTH(a.email)- n.digit
2777                                        GROUP BY a.id
2778                                    ) temp ON a.id = temp.id
2779                                    WHERE
2780                                    a.last_follow_up_date < NOW()
2781                                    AND a.budget_status_id IN (2)
2782                                    AND a.email IS NOT NULL
2783                                    AND a.email <> ''
2784                                    AND NOT EXISTS (
2785                                        SELECT
2786                                        1
2787                                        FROM
2788                                        tbl_blocked_domains bd
2789                                        WHERE
2790                                        temp.email_domain LIKE CONCAT('%', bd.domain, '%')
2791                                        AND bd.company_id = a.company_id
2792                                    )
2793                                    AND a.last_follow_up_date IS NOT NULL
2794                                    AND a.reason_for_not_following_up_id IS NULL
2795                                    AND a.last_follow_up_date > 0
2796                                    AND a.total_sent < b.limit_reminder_emails
2797                                    AND a.for_add = 0
2798                                    {$where}";
2799
2800            $value = Cache::get(base64_encode($totalToFollowUpQuery));
2801
2802            if(!$value){
2803                $countToFollowUpQuery = DB::select($totalToFollowUpQuery);
2804
2805                Cache::put(base64_encode($totalToFollowUpQuery), $countToFollowUpQuery, 600);
2806            }else{
2807                $countToFollowUpQuery = $value;
2808            }
2809
2810            $query = "SELECT
2811                            COUNT(1) as count,
2812                            SUM(a.amount) as total_amount
2813                        FROM tbl_quotations a
2814                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2815                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2816                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2817                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2818                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2819                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2820                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2821                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2822                        WHERE a.budget_status_id = 11
2823                        AND a.email IS NOT NULL
2824                        {$whereSendToClient}
2825                        ";
2826
2827
2828
2829            $value = Cache::get(base64_encode($query));
2830
2831            if(!$value){
2832                $totalSendToClient = DB::select($query);
2833
2834                Cache::put(base64_encode($query), $totalSendToClient, 600);
2835            }else{
2836                $totalSendToClient = $value;
2837            }
2838
2839            return response([
2840                'message' => 'OK',
2841                'data' => $result,
2842                'totalAmount' => $countQuery[0]->totalAmount,
2843                'totalRowCount' => $countQuery[0]->totalRowCount,
2844                'totalToFollowUpRowCount' => $countToFollowUpQuery[0]->totalRowCount,
2845                'totalSendToClient' => $totalSendToClient[0]->count,
2846                'totalSendToClientAmount' => $totalSendToClient[0]->total_amount
2847            ]);
2848
2849        // } catch (\Exception $e) {
2850        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
2851        // }
2852
2853    }
2854
2855    public function get_dates(Request $request){
2856
2857        try {
2858
2859            $data = $request->all();
2860            $companyId = addslashes($data['company_id']);
2861
2862            $where = " AND a.company_id IN ({$this->companyId})";
2863
2864            $query = "SELECT
2865                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
2866                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
2867                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
2868                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
2869                        DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate,
2870                        DATE_FORMAT(a.accepted_at, '%d/%m/%Y') accepted_at_translate
2871                    FROM tbl_quotations a
2872                    WHERE a.for_add = 0 {$where}";
2873
2874            $result = DB::select($query);
2875
2876            return response([
2877                'message' => 'OK',
2878                'data' => $result
2879            ]);
2880
2881        } catch (\Exception $e) {
2882            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2883        }
2884
2885    }
2886
2887    public function list_quotation_analytics_by_source(Request $request){
2888
2889        try {
2890
2891            $data = $request->all();
2892            $companyId = addslashes($data['company_id']);
2893
2894            $where = "";
2895            $whereYear = "";
2896
2897            $dateLflArray = array();
2898            $companyIds = $this->companyIds;
2899
2900            if($companyId != 0){
2901                $companyIds = array($companyId);
2902            }
2903
2904            $field = "issue_date";
2905
2906            if(isset($data['years']) && $data['years'] != null){
2907                $years = implode(',', $data['years']);
2908                if(count($data['years']) > 0){
2909                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
2910                }
2911            }
2912
2913            foreach ($companyIds as $v) {
2914
2915                $lflWhere = " AND q.company_id = {$v} ";
2916
2917                $query = "SELECT
2918                            CONCAT(
2919                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
2920                                ' - ',
2921                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
2922                            ) AS date_like,
2923                            YEAR(q.{$field}) 'year',
2924                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
2925                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
2926                            {$v} 'company_id'
2927                        FROM
2928                            tbl_quotations q
2929                        WHERE
2930                            q.{$field} IS NOT NULL
2931                            AND q.for_add != 1
2932                            {$lflWhere}
2933                            {$whereYear}
2934                        GROUP BY YEAR(q.{$field})
2935                        ORDER BY YEAR(q.{$field}) DESC";
2936
2937                $dateLike = DB::select($query);
2938
2939                $dateLflArray[$v] = $dateLike;
2940            }
2941
2942            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
2943
2944            $isFy = true;
2945
2946            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
2947                $isFy = false;
2948                $ytdArray = array();
2949                $ytdAcceptanceArray = array();
2950                $lflCompanyIds = array();
2951                $lflCompanyIdsAcc = array();
2952                foreach ($dateLflArray as $k => $v) {
2953                    foreach ($dateLflArray[$k] as $item) {
2954                        $year = $item->year;
2955                        $now = date('m-d');
2956                        array_push($ytdAcceptanceArray, "DATE_FORMAT(q.acceptance_date, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}' AND YEAR(q.acceptance_date) = YEAR(issue_date)");
2957                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
2958                    }
2959
2960                    $ytdArray = implode(' OR ', $ytdArray);
2961                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
2962                    $ytdArray = array();
2963
2964                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
2965                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
2966                    $ytdAcceptanceArray = array();
2967                }
2968
2969                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
2970                $where .= " AND ({$lflCompanyIds}";
2971
2972                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
2973                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
2974            }
2975
2976            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
2977                $isFy = false;
2978                $lflArray = array();
2979                $ytdAcceptanceArray = array();
2980                $lflCompanyIds = array();
2981                $lflCompanyIdsAcc = array();
2982                foreach ($dateLflArray as $k => $v) {
2983                    foreach ($dateLflArray[$k] as $item) {
2984                        $year = $item->year;
2985                        $min_date_like = $item->min_date_like;
2986                        $max_date_like = $item->max_date_like;
2987                        array_push($ytdAcceptanceArray, "DATE_FORMAT(q.acceptance_date, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND YEAR(q.acceptance_date) = YEAR(issue_date)");
2988                        array_push($lflArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}')");
2989                    }
2990
2991                    $lflArray = implode(' OR ', $lflArray);
2992                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
2993                    $lflArray = array();
2994
2995                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
2996                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
2997                    $ytdAcceptanceArray = array();
2998                }
2999
3000                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3001                $where .= " AND ({$lflCompanyIds}";
3002
3003                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3004                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3005            }
3006
3007            if($isFy){
3008                if($companyId != 0){
3009                    $where .= " AND q.company_id = {$companyId} ";
3010                }else{
3011                    $where .= " AND q.company_id IN ({$this->companyId})";
3012                }
3013            }
3014
3015            if(isset($data['source']) && $data['source'] != null){
3016                $where .= " AND s.name = '{$data['source']}'";
3017            }
3018
3019            if(isset($data['month']) && $data['month'] != null){
3020                $where .= " AND MONTH(q.issue_date) = '{$data['month']}'";
3021            }
3022
3023            if(isset($data['week']) && $data['week'] != null){
3024                $where .= " AND WEEK(q.issue_date) = '{$data['week']}'";
3025            }
3026
3027            if(isset($data['commercial']) && $data['commercial'] != null){
3028                $where .= " AND q.commercial = '{$data['commercial']}'";
3029            }
3030
3031            if(isset($data['created_by']) && $data['created_by'] != null){
3032                $where .= " AND q.created_by = '{$data['created_by']}'";
3033            }
3034
3035            if(isset($data['budget_type']) && $data['budget_type'] != null){
3036                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
3037            }
3038
3039            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3040                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3041            }
3042
3043            if(isset($data['budget_status']) && $data['budget_status'] != null){
3044                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3045            }
3046
3047            if(isset($data['client_type']) && $data['client_type'] != null){
3048                $where .= " AND ct.customer_type_id = {$data['client_type']}";
3049            }
3050
3051            if(isset($data['segment_id']) && $data['segment_id'] != null){
3052                $where .= " AND q.segment_id = {$data['segment_id']}";
3053            }
3054
3055            $query = "SELECT
3056                        YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) AS 'year',
3057                        LPAD(MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'month',
3058                        LPAD(WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'week',
3059                        DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') issue_date,
3060                        COUNT(
3061                            CASE WHEN q.issue_date IS NOT NULL
3062                            THEN 1 END
3063                        ) AS totalIssue,
3064                        GROUP_CONCAT(
3065                            CASE WHEN q.issue_date IS NOT NULL
3066                            THEN q.id END
3067                        ) AS groupConcatIds,
3068                        SUM(
3069                            CASE WHEN q.issue_date IS NOT NULL THEN q.amount END
3070                        ) AS revenueIssue,
3071                        COUNT(
3072                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN 1 END
3073                        ) AS totalAcceptance,
3074                        SUM(
3075                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN q.amount END
3076                        ) AS revenueAcceptance,
3077                        SUM(
3078                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN q.amount END
3079                        ) / SUM(
3080                            CASE WHEN q.issue_date IS NOT NULL THEN q.amount END
3081                        ) * 100 AS revenueAcceptanceIssuedPercentage,
3082                        COUNT(
3083                            CASE WHEN bs.name = 'Rechazado' THEN 1 END
3084                        ) AS totalRejected,
3085                        SUM(
3086                            CASE WHEN bs.name = 'Rechazado' THEN q.amount END
3087                        ) AS revenueRejected,
3088                        COUNT(
3089                            CASE WHEN bs.name = 'Rechazado - automaticamente' THEN 1 END
3090                        ) AS totalRejectedAutomatic,
3091                        SUM(
3092                            CASE WHEN bs.name = 'Rechazado - automaticamente' THEN q.amount END
3093                        ) AS revenueRejectedAutomatic
3094                    FROM
3095                        tbl_quotations q
3096                        LEFT JOIN tbl_sources s ON s.source_id = q.source_id
3097                        LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3098                        LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3099                        LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
3100                    WHERE
3101                        q.issue_date IS NOT NULL
3102                        AND q.budget_type_id != 7
3103                        AND q.budget_type_id IS NOT NULL
3104                        AND q.for_add != 1
3105                        AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3106                        {$where}
3107                        {$whereYear}
3108                        AND YEAR(q.issue_date) NOT IN (2021, 2022)
3109                    GROUP BY
3110                        YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3111                        MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3112                        WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) WITH ROLLUP
3113                    ORDER BY
3114                        YEAR DESC,
3115                        MONTH ASC,
3116                        WEEK ASC,
3117                        DATE_FORMAT(q.issue_date, '%e') ASC";
3118
3119            $value = Cache::get(base64_encode($query));
3120
3121            if(!$value){
3122                $result = DB::select($query);
3123
3124                Cache::put(base64_encode($query), $result, 600);
3125            }else{
3126                $result = $value;
3127            }
3128
3129            return response([
3130                'message' => 'OK',
3131                'data' => $result
3132            ]);
3133
3134        } catch (\Exception $e) {
3135            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3136        }
3137    }
3138
3139    public function list_quotation_analytics_send_budgets(Request $request){
3140
3141        try {
3142
3143            $data = $request->all();
3144            $companyId = addslashes($data['company_id']);
3145
3146            $where = "";
3147            $whereYear = "";
3148
3149            if($companyId != 0){
3150                $where = " AND q.company_id = {$companyId} ";
3151            }else{
3152                $where = " AND q.company_id IN ({$this->companyId}";
3153            }
3154
3155            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3156                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3157            }
3158
3159            if(isset($data['budget_status']) && $data['budget_status'] != null){
3160                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3161            }
3162
3163            if(isset($data['years']) && $data['years'] != null){
3164                $years = implode(',', $data['years']);
3165                if(count($data['years']) > 0){
3166                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3167                }
3168            }
3169
3170            $query = "SELECT
3171                            YEAR(q.issue_date) AS 'year',
3172                            MONTH(q.issue_date) AS 'month',
3173                            SUM(
3174                                CASE WHEN MONTH(request_date) = MONTH(issue_date) THEN 1 ELSE 0 END
3175                            ) totalRequest,
3176                            COUNT(
3177                                CASE WHEN q.issue_date IS NOT NULL THEN 1 END
3178                            ) AS totalIssue,
3179                            GROUP_CONCAT(
3180                                CASE WHEN q.issue_date IS NOT NULL
3181                                THEN q.id END
3182                            ) AS groupConcatIds,
3183                            SUM(
3184                                CASE WHEN MONTH(request_date) = MONTH(issue_date) THEN 1 ELSE 0 END
3185                            ) /
3186                            COUNT(
3187                                CASE WHEN q.issue_date IS NOT NULL THEN 1 END
3188                            ) * 100 issuePercentage,
3189                            AVG(
3190                                COALESCE(q.duration, 0)
3191                            ) AS averageDurationIssue,
3192                            COALESCE(
3193                                AVG(
3194                                    CASE WHEN bt.name = 'Mantenimiento' THEN COALESCE(q.duration, 0) ELSE NULL END
3195                                ), 0
3196                            ) AS averageDurationMaintenance,
3197                            COALESCE(
3198                                AVG(
3199                                    CASE WHEN bt.name = 'Nuevos' THEN COALESCE(q.duration, 0) ELSE NULL END
3200                                ), 0
3201                            ) AS averageDurationNew,
3202                            COALESCE(
3203                                AVG(
3204                                    CASE WHEN bt.name = 'Correctivos' THEN COALESCE(q.duration, 0) ELSE NULL END
3205                                ), 0
3206                            ) AS averageDurationCorretive,
3207                            COALESCE(
3208                                AVG(
3209                                    CASE WHEN bt.name = 'Anomalías' THEN COALESCE(q.duration, 0) ELSE NULL END
3210                                ), 0
3211                            ) AS averageDurationAnomalies,
3212                            COALESCE(
3213                                AVG(
3214                                    CASE WHEN bt.name = 'Precios Unitarios' THEN COALESCE(q.duration, 0) ELSE NULL END
3215                                ), 0
3216                            ) AS averageDurationUnitPrice,
3217                            COALESCE(
3218                                AVG(
3219                                    CASE WHEN bt.name = 'Instalaciones' THEN COALESCE(q.duration, 0) ELSE NULL END
3220                                ), 0
3221                            ) AS averageDurationFacilities,
3222                            COALESCE(
3223                                AVG(
3224                                    CASE WHEN bt.name = 'Alquiler' THEN COALESCE(q.duration, 0) ELSE NULL END
3225                                ), 0
3226                            ) AS averageDurationRent,
3227                            COALESCE(
3228                                AVG(
3229                                    CASE WHEN bt.name = 'OCA visita' THEN COALESCE(q.duration, 0) ELSE NULL END
3230                                ), 0
3231                            ) AS averageDurationOCA,
3232                            COALESCE(
3233                                AVG(
3234                                    CASE WHEN bt.name = 'Retirada y gestion de residuos' THEN COALESCE(q.duration, 0) ELSE NULL END
3235                                ), 0
3236                            ) AS averageDurationWRM,
3237                            COALESCE(
3238                                AVG(
3239                                    CASE WHEN bt.name = 'Formación' THEN COALESCE(q.duration, 0) ELSE NULL END
3240                                ), 0
3241                            ) AS averageDurationTraining,
3242                            COALESCE(
3243                                AVG(
3244                                    CASE WHEN bt.name = 'Anomalías de facilities' THEN COALESCE(q.duration, 0) ELSE NULL END
3245                                ), 0
3246                            ) AS averageDurationFacilityAnomalies
3247                        FROM
3248                            tbl_quotations q
3249                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3250                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_id = btg.budget_type_id
3251                        WHERE
3252                            q.issue_date IS NOT NULL
3253                            AND q.budget_type_id != 7
3254                            AND q.budget_type_id IS NOT NULL
3255                            AND q.for_add != 1
3256                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3257                            {$where}
3258                            {$whereYear}
3259                        GROUP BY
3260                            YEAR(q.issue_date),
3261                            MONTH(q.issue_date) WITH ROLLUP
3262                        ORDER BY
3263                            YEAR(q.issue_date) DESC,
3264                            MONTH(q.issue_date) ASC";
3265
3266            $sendBudgets = array();
3267            $sendBudgetsTotals = array();
3268
3269            $value = Cache::get(base64_encode($query));
3270
3271            if(!$value){
3272                $result = DB::select($query);
3273
3274                Cache::put(base64_encode($query), $result, 600);
3275            }else{
3276                $result = $value;
3277            }
3278
3279            if(count($result) > 0){
3280                for ($i = 0; $i < count($result); $i++) {
3281
3282                    if($result[$i]->year == null && $result[$i]->month == null){
3283                        $result[$i]->month = "totalGeneral";
3284                        $sendBudgetsTotals["totalGeneral"] = $result[$i];
3285                        continue;
3286                    }elseif($result[$i]->month == null && $result[$i]->year != null){
3287                        if(count($data['years']) > 0 || $whereYear == ""){
3288                            $result[$i]->month = "totalSub";
3289                        }else{
3290                            continue;
3291                        }
3292                    }else{
3293                        $result[$i]->month = sprintf("%02d", $result[$i]->month);
3294                    }
3295
3296                    $sendBudgets[$result[$i]->year][$result[$i]->month] = $result[$i];
3297                }
3298            }
3299
3300            return response([
3301                'message' => 'OK',
3302                'data' => $sendBudgets,
3303                'totals' => $sendBudgetsTotals
3304            ]);
3305
3306        } catch (\Exception $e) {
3307            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3308        }
3309    }
3310
3311    public function list_quotation_analytics_track_budgets(Request $request){
3312
3313        try {
3314
3315            $data = $request->all();
3316            $companyId = addslashes($data['company_id']);
3317
3318            $where = "";
3319            $whereYear = "";
3320            $isBetween = false;
3321
3322            $dateLflArray = array();
3323            $companyIds = $this->companyIds;
3324
3325            if($companyId != 0){
3326                $companyIds = array($companyId);
3327            }
3328
3329            if(isset($data['years']) && $data['years'] != null){
3330                $years = implode(',', $data['years']);
3331                if(count($data['years']) > 0){
3332                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3333                }
3334            }
3335
3336            $field = "issue_date";
3337
3338            foreach ($companyIds as $v) {
3339
3340                $lflWhere = " AND q.company_id = {$v} ";
3341
3342                $query = "SELECT
3343                            CONCAT(
3344                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
3345                                ' - ',
3346                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
3347                            ) AS date_like,
3348                            YEAR(q.{$field}) 'year',
3349                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
3350                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
3351                            {$v} 'company_id'
3352                        FROM
3353                            tbl_quotations q
3354                        WHERE
3355                            q.{$field} IS NOT NULL
3356                            AND q.for_add != 1
3357                            {$lflWhere}
3358                            {$whereYear}
3359                        GROUP BY YEAR(q.{$field})
3360                        ORDER BY YEAR(q.{$field}) DESC";
3361
3362                $dateLike = DB::select($query);
3363
3364                $dateLflArray[$v] = $dateLike;
3365            }
3366
3367            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
3368
3369            $isFy = true;
3370
3371            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
3372                $isFy = false;
3373                $ytdArray = array();
3374                $ytdAcceptanceArray = array();
3375                $lflCompanyIds = array();
3376                $lflCompanyIdsAcc = array();
3377                foreach ($dateLflArray as $k => $v) {
3378                    foreach ($dateLflArray[$k] as $item) {
3379                        $year = $item->year;
3380                        $now = date('m-d');
3381                        array_push($ytdAcceptanceArray, "DATE_FORMAT(q.acceptance_date, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}' AND YEAR(q.acceptance_date) = YEAR(issue_date)");
3382                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
3383                    }
3384
3385                    $ytdArray = implode(' OR ', $ytdArray);
3386                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
3387                    $ytdArray = array();
3388
3389                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3390                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3391                    $ytdAcceptanceArray = array();
3392                }
3393
3394                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3395                $where .= " AND ({$lflCompanyIds}";
3396
3397                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3398                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3399            }
3400
3401            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
3402                $isFy = false;
3403                $lflArray = array();
3404                $ytdAcceptanceArray = array();
3405                $lflCompanyIds = array();
3406                $lflCompanyIdsAcc = array();
3407                foreach ($dateLflArray as $k => $v) {
3408                    foreach ($dateLflArray[$k] as $item) {
3409                        $year = $item->year;
3410                        $min_date_like = $item->min_date_like;
3411                        $max_date_like = $item->max_date_like;
3412                        array_push($ytdAcceptanceArray, "DATE_FORMAT(q.acceptance_date, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND YEAR(q.acceptance_date) = YEAR(issue_date)");
3413                        array_push($lflArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}')");
3414                    }
3415
3416                    $lflArray = implode(' OR ', $lflArray);
3417                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
3418                    $lflArray = array();
3419
3420                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3421                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3422                    $ytdAcceptanceArray = array();
3423                }
3424
3425                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3426                $where .= " AND ({$lflCompanyIds}";
3427
3428                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3429                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3430            }
3431
3432            if($isFy){
3433                if($companyId != 0){
3434                    $where .= " AND q.company_id = {$companyId} ";
3435                }else{
3436                    $where .= " AND q.company_id IN ({$this->companyId})";
3437                }
3438            }
3439
3440            if(isset($data['source']) && $data['source'] != null){
3441                $where .= " AND s.name = '{$data['source']}'";
3442            }
3443
3444            if(isset($data['commercial']) && $data['commercial'] != null){
3445                $where .= " AND q.commercial = '{$data['commercial']}'";
3446            }
3447
3448            if(isset($data['created_by']) && $data['created_by'] != null){
3449                $where .= " AND q.created_by = '{$data['created_by']}'";
3450            }
3451
3452            if(isset($data['budget_type']) && $data['budget_type'] != null){
3453                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
3454            }
3455
3456            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3457                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3458            }
3459
3460            if(isset($data['budget_status']) && $data['budget_status'] != null){
3461                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3462            }
3463
3464            if(isset($data['client_type']) && $data['client_type'] != null){
3465                $where .= " AND ct.customer_type_id = {$data['client_type']}";
3466            }
3467
3468            if(isset($data['segment_id']) && $data['segment_id'] != null){
3469                $where .= " AND q.segment_id = {$data['segment_id']}";
3470            }
3471
3472            $query = "SELECT
3473                            YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) AS 'year',
3474                            LPAD(MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'month',
3475                            LPAD(WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'week',
3476                            DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') issue_date,
3477                            COUNT(
3478                                CASE WHEN q.issue_date IS NOT NULL
3479                                THEN 1 END
3480                            ) AS totalIssue,
3481                            GROUP_CONCAT(
3482                                CASE WHEN q.issue_date IS NOT NULL
3483                                THEN q.id END
3484                            ) AS groupConcatIds,
3485                            COUNT(
3486                                CASE WHEN {$whereAcceptanceDate}
3487                                AND bs.name = 'Aceptado' THEN 1 END) totalAccept,
3488                            COUNT(
3489                                CASE WHEN q.acceptance_date IS NOT NULL
3490                                AND {$whereAcceptanceDate}
3491                                AND bs.name = 'Aceptado'
3492                                AND DATEDIFF(q.acceptance_date, q.issue_date) <= 10 THEN 1 END
3493                            ) / COUNT(
3494                                CASE WHEN q.issue_date IS NOT NULL
3495                                THEN 1 END
3496                            ) * 100 AS percentageOfacceptanceLessThan10,
3497                            COUNT(
3498                                CASE WHEN q.acceptance_date IS NOT NULL
3499                                AND {$whereAcceptanceDate}
3500                                AND bs.name = 'Aceptado'
3501                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 10
3502                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 30 THEN 1 END
3503                            ) / COUNT(
3504                                CASE WHEN q.issue_date IS NOT NULL
3505                                THEN 1 END
3506                            ) * 100 AS percentageOfacceptanceLessThan30,
3507                            COUNT(
3508                                CASE WHEN q.acceptance_date IS NOT NULL
3509                                AND {$whereAcceptanceDate}
3510                                AND bs.name = 'Aceptado'
3511                                AND DATEDIFF(q.acceptance_date, q.issue_date) >= 30 THEN 1 END
3512                            ) / COUNT(
3513                                CASE WHEN q.issue_date IS NOT NULL
3514                                THEN 1 END
3515                            ) * 100 AS percentageOfacceptanceMoreThan30,
3516                            COUNT(CASE WHEN
3517                                {$whereAcceptanceDate} THEN 1 END
3518                            ) / COUNT(
3519                                CASE WHEN q.issue_date IS NOT NULL
3520                                THEN 1 END
3521                            ) * 100 acceptedPercentage,
3522                            COALESCE(
3523                                AVG(
3524                                    CASE WHEN q.issue_date IS NOT NULL
3525                                    AND q.acceptance_date IS NOT NULL
3526                                    AND {$whereAcceptanceDate}
3527                                    AND bs.name = 'Aceptado'
3528                                    THEN DATEDIFF(q.acceptance_date, q.issue_date) ELSE NULL END
3529                                ), 0
3530                            )
3531                            AS averageAcceptedDuration,
3532                            COALESCE(
3533                                AVG(
3534                                    CASE WHEN q.issue_date IS NOT NULL
3535                                    AND q.request_date IS NOT NULL
3536                                    THEN DATEDIFF(q.issue_date, q.request_date) ELSE NULL END
3537                                ), 0
3538                            )
3539                            AS averageRequestedDays
3540                        FROM
3541                            tbl_quotations q
3542                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3543                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3544                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
3545                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
3546                        WHERE
3547                            q.issue_date IS NOT NULL
3548                            AND q.budget_type_id != 7
3549                            AND q.budget_type_id IS NOT NULL
3550                            AND q.for_add != 1
3551                            {$where}
3552                            {$whereYear}
3553                        GROUP BY
3554                            YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3555                            MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3556                            WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) WITH ROLLUP
3557                        ORDER BY
3558                            YEAR DESC,
3559                            MONTH ASC,
3560                            WEEK ASC,
3561                            DATE_FORMAT(q.issue_date, '%e') ASC";
3562
3563            $value = Cache::get(base64_encode($query));
3564
3565            if(!$value){
3566                $result = DB::select($query);
3567
3568                Cache::put(base64_encode($query), $result, 600);
3569            }else{
3570                $result = $value;
3571            }
3572
3573            return response([
3574                'message' => 'OK',
3575                'data' => $result
3576            ]);
3577
3578        } catch (\Exception $e) {
3579            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3580        }
3581    }
3582
3583    public function list_quotation_analytics_types_budgets(Request $request){
3584
3585        try {
3586
3587            $data = $request->all();
3588            $companyId = addslashes($data['company_id']);
3589
3590            $where = "";
3591            $whereYear = "";
3592            $isBetween = false;
3593
3594            $dateLflArray = array();
3595            $companyIds = $this->companyIds;
3596
3597            if($companyId != 0){
3598                $companyIds = array($companyId);
3599            }
3600
3601            if(isset($data['years']) && $data['years'] != null){
3602                $years = implode(',', $data['years']);
3603                if(count($data['years']) > 0){
3604                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3605                }
3606            }
3607
3608            $field = "issue_date";
3609
3610            foreach ($companyIds as $v) {
3611
3612                $lflWhere = " AND q.company_id = {$v} ";
3613
3614                $query = "SELECT
3615                            CONCAT(
3616                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
3617                                ' - ',
3618                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
3619                            ) AS date_like,
3620                            YEAR(q.{$field}) 'year',
3621                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
3622                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
3623                            {$v} 'company_id'
3624                        FROM
3625                            tbl_quotations q
3626                        WHERE
3627                            q.{$field} IS NOT NULL
3628                            AND q.for_add != 1
3629                            {$lflWhere}
3630                            {$whereYear}
3631                        GROUP BY YEAR(q.{$field})
3632                        ORDER BY YEAR(q.{$field}) DESC";
3633
3634                $dateLike = DB::select($query);
3635
3636                $dateLflArray[$v] = $dateLike;
3637            }
3638
3639            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
3640
3641            $isFy = true;
3642
3643            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
3644                $isFy = false;
3645                $ytdArray = array();
3646                $ytdAcceptanceArray = array();
3647                $lflCompanyIds = array();
3648                $lflCompanyIdsAcc = array();
3649                foreach ($dateLflArray as $k => $v) {
3650                    foreach ($dateLflArray[$k] as $item) {
3651                        $year = $item->year;
3652                        $now = date('m-d');
3653                        array_push($ytdAcceptanceArray, "DATE_FORMAT(q.acceptance_date, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}' AND YEAR(q.acceptance_date) = YEAR(issue_date)");
3654                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
3655                    }
3656
3657                    $ytdArray = implode(' OR ', $ytdArray);
3658                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
3659                    $ytdArray = array();
3660
3661                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3662                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3663                    $ytdAcceptanceArray = array();
3664                }
3665
3666                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3667                $where .= " AND ({$lflCompanyIds}";
3668
3669                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3670                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3671            }
3672
3673            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
3674                $isFy = false;
3675                $lflArray = array();
3676                $ytdAcceptanceArray = array();
3677                $lflCompanyIds = array();
3678                $lflCompanyIdsAcc = array();
3679                foreach ($dateLflArray as $k => $v) {
3680                    foreach ($dateLflArray[$k] as $item) {
3681                        $year = $item->year;
3682                        $min_date_like = $item->min_date_like;
3683                        $max_date_like = $item->max_date_like;
3684                        array_push($ytdAcceptanceArray, "DATE_FORMAT(q.acceptance_date, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND YEAR(q.acceptance_date) = YEAR(issue_date)");
3685                        array_push($lflArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}')");
3686                    }
3687
3688                    $lflArray = implode(' OR ', $lflArray);
3689                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
3690                    $lflArray = array();
3691
3692                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3693                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3694                    $ytdAcceptanceArray = array();
3695                }
3696
3697                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3698                $where .= " AND ({$lflCompanyIds}";
3699
3700                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3701                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3702            }
3703
3704            if($isFy){
3705                if($companyId != 0){
3706                    $where .= " AND q.company_id = {$companyId} ";
3707                }else{
3708                    $where .= " AND q.company_id IN ({$this->companyId})";
3709                }
3710            }
3711
3712            if(isset($data['budget_status']) && $data['budget_status'] != null){
3713                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3714            }
3715
3716            if(isset($data['segment_id']) && $data['segment_id'] != null){
3717                $where .= " AND q.segment_id = {$data['segment_id']}";
3718            }
3719
3720            $query = "SELECT
3721                            YEAR(q.issue_date) AS 'year',
3722                            bt.name,
3723                            COUNT(
3724                                CASE WHEN q.issue_date IS NOT NULL
3725                                THEN 1 END
3726                            ) AS totalIssue,
3727                            GROUP_CONCAT(
3728                                CASE WHEN q.issue_date IS NOT NULL
3729                                THEN q.id END
3730                            ) AS groupConcatIds,
3731                            COUNT(CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN 1 END) totalAccept,
3732                            COUNT(
3733                                CASE WHEN q.acceptance_date IS NOT NULL
3734                                AND {$whereAcceptanceDate}
3735                                AND bs.name = 'Aceptado'
3736                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 10 THEN 1 END
3737                            ) / COUNT(
3738                                CASE WHEN q.issue_date IS NOT NULL
3739                                THEN 1 END
3740                            ) * 100 AS percentageOfacceptanceLessThan10,
3741                            COUNT(
3742                                CASE WHEN q.acceptance_date IS NOT NULL
3743                                AND {$whereAcceptanceDate}
3744                                AND bs.name = 'Aceptado'
3745                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 10
3746                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 30 THEN 1 END
3747                            ) / COUNT(
3748                                CASE WHEN q.issue_date IS NOT NULL
3749                                THEN 1 END
3750                            ) * 100 AS percentageOfacceptanceLessThan30,
3751                            COUNT(
3752                                CASE WHEN q.acceptance_date IS NOT NULL
3753                                AND {$whereAcceptanceDate}
3754                                AND bs.name = 'Aceptado'
3755                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 30 THEN 1 END
3756                            ) / COUNT(
3757                                CASE WHEN q.issue_date IS NOT NULL
3758                                THEN 1 END
3759                            ) * 100 AS percentageOfacceptanceMoreThan30,
3760                            COUNT(CASE WHEN {$whereAcceptanceDate} THEN 1 END) / COUNT(
3761                                CASE WHEN q.issue_date IS NOT NULL
3762                                THEN 1 END
3763                            ) * 100 acceptedPercentage,
3764                            COALESCE(
3765                                AVG(
3766                                    CASE WHEN q.issue_date IS NOT NULL
3767                                    AND q.acceptance_date IS NOT NULL
3768                                    AND {$whereAcceptanceDate}
3769                                    AND bs.name = 'Aceptado'
3770                                    THEN DATEDIFF(q.acceptance_date, q.issue_date) ELSE NULL END
3771                                ), 0
3772                            )
3773                            AS averageAcceptedDuration,
3774                            COALESCE(
3775                                AVG(
3776                                    CASE WHEN q.issue_date IS NOT NULL
3777                                    AND q.request_date IS NOT NULL
3778                                    AND q.issue_date > q.request_date
3779                                    THEN DATEDIFF(q.issue_date, q.request_date) ELSE NULL END
3780                                ), 0
3781                            )
3782                            AS averageRequestedDays
3783                        FROM
3784                            tbl_quotations q
3785                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3786                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3787                        WHERE
3788                            q.issue_date IS NOT NULL
3789                            AND q.budget_type_id != 7
3790                            AND q.budget_type_id IS NOT NULL
3791                            AND q.for_add != 1
3792                            {$where}
3793                            {$whereYear}
3794                        GROUP BY
3795                            YEAR(q.issue_date),
3796                            bt.name WITH ROLLUP";
3797
3798            $value = Cache::get(base64_encode($query));
3799
3800            if(!$value){
3801                $result = DB::select($query);
3802
3803                Cache::put(base64_encode($query), $result, 600);
3804            }else{
3805                $result = $value;
3806            }
3807
3808            $typesBudgets = array();
3809            $typesBudgetsTotals = array();
3810
3811            if(count($result) > 0){
3812                for ($i = 0; $i < count($result); $i++) {
3813
3814                    if($result[$i]->year == null && $result[$i]->name == null){
3815                        $result[$i]->name = "totalGeneral";
3816                        $typesBudgetsTotals["totalGeneral"] = $result[$i];
3817                        continue;
3818                    }elseif($result[$i]->name == null && $result[$i]->year != null){
3819                        if(count($data['years']) > 0 || $whereYear == ""){
3820                            $result[$i]->name = "totalSub";
3821                        }else{
3822                            continue;
3823                        }
3824                    }
3825
3826                    $typesBudgets[$result[$i]->year][$result[$i]->name] = $result[$i];
3827                }
3828            }
3829
3830            return response([
3831                'message' => 'OK',
3832                'data' => $typesBudgets,
3833                'totals' => $typesBudgetsTotals
3834            ]);
3835
3836        } catch (\Exception $e) {
3837            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3838        }
3839    }
3840
3841    function download_quotations(Request $request){
3842        ini_set('max_execution_time', 123456);
3843        $data = $request->all();
3844        $companyId = addslashes($data['company_id']);
3845        $userId = addslashes($data['user_id']);
3846
3847        $where = "";
3848
3849        $query = "SELECT
3850                b.name
3851            FROM tbl_users a
3852            LEFT JOIN tbl_roles b
3853                ON a.role_id = b.role_id
3854            WHERE a.id = {$userId}";
3855
3856        $role = DB::select($query);
3857
3858        $r = new Request([
3859            'filterModel' => $data['filterModel'],
3860            'sortModel' => $data['sortModel'],
3861            'start' => 0,
3862            'end' => 999999999,
3863            'company_id' => $data['company_id'],
3864            'user_id' => $data['user_id'],
3865            'ids' => $data['ids'],
3866            'searchText' => $data['searchText'],
3867            'ids_not_in' => $data['ids_not_in']
3868        ]);
3869
3870        $result = $this->list_quotations($r);
3871
3872        $spreadsheet = new Spreadsheet();
3873        $worksheet   = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, "Inputs");
3874        $spreadsheet->addSheet($worksheet, 0);
3875        $col         = range('A', 'Z');
3876
3877        for($i = 0; $i < 26; $i++){
3878            $worksheet->getColumnDimension($col[$i])->setAutoSize(true);
3879            if($i != 1){
3880                $worksheet->getStyle($col[$i])
3881                    ->getAlignment()
3882                    ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
3883            }
3884        }
3885
3886        $worksheet->getColumnDimension("AB")->setAutoSize(true);
3887        $worksheet->getStyle("AB")
3888            ->getAlignment()
3889            ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
3890
3891        $l = 1;
3892        $worksheet->setCellValue('A' . $l, __('language.ID'));
3893        $worksheet->setCellValue('B' . $l, __('language.INTERNAL_ID'));
3894        $worksheet->setCellValue('C' . $l, __('language.CLIENT'));
3895        $worksheet->setCellValue('D' . $l, __('language.AMOUNT'));
3896        $worksheet->setCellValue('E' . $l, __('language.INVOICE_MARGIN'));
3897        $worksheet->setCellValue('F' . $l, __('language.MARGIN_FOR_THE_COMPANY'));
3898        $worksheet->setCellValue('G' . $l, __('language.TYPE'));
3899        $worksheet->setCellValue('H' . $l, __('language.STATUS'));
3900        $worksheet->setCellValue('I' . $l, __('language.CREATED_BY'));
3901        $worksheet->setCellValue('J' . $l, __('language.COMMERCIAL'));
3902        $worksheet->setCellValue('K' . $l, __('language.CREATED_AT'));
3903        $worksheet->setCellValue('L' . $l, __('language.ACCEPTANCE_DATE'));
3904        $worksheet->setCellValue('M' . $l, __('language.REQUEST_DATE'));
3905        $worksheet->setCellValue('N' . $l, __('language.ISSUE_DATE'));
3906        $worksheet->setCellValue('O' . $l, __('language.DURATION'));
3907        $worksheet->setCellValue('P' . $l, __('language.CLIENT_TYPE'));
3908        $worksheet->setCellValue('Q' . $l, __('language.SEGMENT'));
3909        $worksheet->setCellValue('R' . $l, __('language.LIKEHOOD'));
3910        $worksheet->setCellValue('S' . $l, __('language.SOURCE'));
3911        $worksheet->setCellValue('T' . $l, __('language.LAST_FOLLOW_UP_DATE'));
3912        $worksheet->setCellValue('U' . $l, __('language.REASON_FOR_NOT_FOLLOWING_UP'));
3913        $worksheet->setCellValue('V' . $l, __('language.REASON_FOR_REJECTION'));
3914        $worksheet->setCellValue('W' . $l, __('language.EMAIL'));
3915        $worksheet->setCellValue('X' . $l, __('language.EMAIL_STATUS'));
3916        $worksheet->setCellValue('Y' . $l, __('language.PHONE_NUMBER'));
3917        $worksheet->setCellValue('Z' . $l, __('language.ORDER_NUMBER'));
3918        $worksheet->setCellValue('AA' . $l, __('language.BOX_WORK_G3W'));
3919        $worksheet->setCellValue('AB' . $l, __('language.APPROVAL_REQUIRED'));
3920        $worksheet->setCellValue('AC' . $l, __('language.FILES_COUNT'));
3921        $worksheet->setCellValue('AD' . $l, __('language.ACCEPTED_BY'));
3922        $worksheet->setCellValue('AE' . $l, __('language.ACCEPTED_AT'));
3923        $worksheet->setCellValue('AF' . $l, "Origen");
3924        $worksheet->setCellValue('AG' . $l, "Origen Edit");
3925        $worksheet->setCellValue('AH' . $l, __('language.G3W_WARNING'));
3926        $worksheet->setCellValue('AI' . $l, __('language.COMPANY_NAME'));
3927
3928        $styleArray = [
3929            'font' => [
3930                'bold' => true,
3931            ]
3932        ];
3933
3934        $worksheet->getStyle('A1:AH1')
3935            ->getFill()
3936            ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
3937            ->getStartColor()
3938            ->setARGB('523779');
3939
3940        $worksheet->getStyle('A1:AH1')
3941            ->getFont()
3942            ->getColor()
3943            ->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
3944
3945        $worksheet->getStyle('A1:AH1')->applyFromArray($styleArray);
3946
3947        $l = 2;
3948        $result = $result->original['data'];
3949
3950        for ($i = 0; $i < count($result); $i++) {
3951
3952            if($result[$i]->request_date){
3953                $result[$i]->request_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->request_date);
3954            }
3955
3956            if($result[$i]->issue_date){
3957                $result[$i]->issue_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->issue_date);
3958            }
3959
3960            if($result[$i]->acceptance_date){
3961                $result[$i]->acceptance_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->acceptance_date);
3962            }
3963
3964            if($result[$i]->last_follow_up_date){
3965                $result[$i]->last_follow_up_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->last_follow_up_date);
3966            }
3967
3968            if($result[$i]->created_at){
3969                $result[$i]->created_at = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->created_at);
3970            }
3971
3972            if($result[$i]->accepted_at){
3973                $result[$i]->accepted_at = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->accepted_at);
3974            }
3975
3976            $worksheet->setCellValue('A' . $l, $result[$i]->quote_id);
3977            $worksheet->setCellValue('B' . $l, $result[$i]->internal_quote_id);
3978            $worksheet->setCellValue('C' . $l, $result[$i]->client);
3979            $worksheet->setCellValue('D' . $l, $result[$i]->amount);
3980            $worksheet->setCellValue('E' . $l, $result[$i]->invoice_margin);
3981            $worksheet->setCellValue('F' . $l, $result[$i]->margin_for_the_company);
3982            $worksheet->setCellValue('G' . $l, $result[$i]->type);
3983            $worksheet->setCellValue('H' . $l, $result[$i]->status);
3984            $worksheet->setCellValue('I' . $l, $result[$i]->created_by);
3985            $worksheet->setCellValue('J' . $l, $result[$i]->commercial);
3986            $worksheet->setCellValue('K' . $l, $result[$i]->created_at);
3987
3988            $worksheet->getStyle('K' . $l)
3989                ->getNumberFormat()
3990                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
3991
3992            $worksheet->setCellValue('L' . $l, $result[$i]->acceptance_date);
3993
3994            $worksheet->getStyle('L' . $l)
3995                ->getNumberFormat()
3996                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
3997
3998            $worksheet->setCellValue('M' . $l, $result[$i]->request_date);
3999
4000            $worksheet->getStyle('M' . $l)
4001                ->getNumberFormat()
4002                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4003
4004            $worksheet->setCellValue('N' . $l, $result[$i]->issue_date);
4005
4006            $worksheet->getStyle('N' . $l)
4007                ->getNumberFormat()
4008                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4009
4010            $worksheet->setCellValue('O' . $l, '=DATEDIF(J'.$l.',K'.$l.',"d")');
4011            $worksheet->setCellValue('P' . $l, $result[$i]->client_type);
4012            $worksheet->setCellValue('Q' . $l, $result[$i]->segment);
4013            $worksheet->setCellValue('R' . $l, $result[$i]->likehood);
4014            $worksheet->setCellValue('S' . $l, $result[$i]->source);
4015            $worksheet->setCellValue('T' . $l, $result[$i]->last_follow_up_date);
4016
4017            $worksheet->getStyle('T' . $l)
4018                ->getNumberFormat()
4019                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4020
4021            $worksheet->setCellValue('U' . $l, $result[$i]->reason_for_not_following_up);
4022            $worksheet->setCellValue('V' . $l, $result[$i]->reason_for_rejection);
4023            $worksheet->setCellValue('W' . $l, $result[$i]->email);
4024            $worksheet->setCellValue('X' . $l, $result[$i]->x_status);
4025            $worksheet->setCellValue('Y' . $l, $result[$i]->phone_number);
4026            $worksheet->setCellValue('Z' . $l, $result[$i]->order_number);
4027            $worksheet->setCellValue('AA' . $l, $result[$i]->box_work_g3w);
4028            $worksheet->setCellValue('AB' . $l, ($result[$i]->for_approval == 1 || $result[$i]->for_approval == 3) ? __('language.YES') : __('language.NO'));
4029            $worksheet->setCellValue('AC' . $l, $result[$i]->has_attachment == 1 ? __('language.YES') : __('language.NO'));
4030            $worksheet->setCellValue('AD' . $l, $result[$i]->accepted_by);
4031            $worksheet->setCellValue('AE' . $l, $result[$i]->accepted_at);
4032
4033            $worksheet->getStyle('AE' . $l)
4034                ->getNumberFormat()
4035                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4036
4037            $worksheet->setCellValue('AF' . $l, $result[$i]->sync_import == 1 ? 'G3W' : 'Manual');
4038            $worksheet->setCellValue('AG' . $l, $result[$i]->sync_import_edited == 1 ? 'G3W' : 'Manual');
4039            $worksheet->setCellValue('AH' . $l, $result[$i]->g3w_warning == 1 ? 'Sí' : 'No');
4040            $worksheet->setCellValue('AI' . $l, $result[$i]->company_name);
4041            $l++;
4042
4043        }
4044
4045        if($role[0]->name == 'Regular'){
4046            $worksheet->removeColumn('D');
4047            $worksheet->removeColumn('W');
4048            $worksheet->removeColumn('X');
4049        }
4050
4051        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
4052        ob_start();
4053        $writer->save('php://output');
4054        $file = ob_get_contents();
4055        ob_end_clean();
4056
4057        return response($file);
4058    }
4059
4060    function bulk_upload(Request $request){
4061
4062        try {
4063
4064            $data = $request->all();
4065            $file = $request->file('file');
4066            $exte = 'Xlsx';
4067            $companyId = $data['company_id'];
4068
4069            if($file->getMimeType() == 'application/vnd.ms-excel'){
4070                $exte = 'Xls';
4071            }
4072
4073            $destination_path = env('BULK_UPLOAD_FILE_DESTINATION', 'E:/bulk_upload/');
4074            $filename         = $file->getClientOriginalName();
4075
4076            if(file_exists($destination_path . $filename)){
4077                $filename = pathinfo($filename, PATHINFO_FILENAME) . '-' . uniqid() . '.' . pathinfo($filename, PATHINFO_EXTENSION);
4078            }
4079
4080            $file->move($destination_path, $filename);
4081
4082            TblBulkUpload::create(
4083                array(
4084                    'company_id' => $companyId,
4085                    'filename' => $filename,
4086                    'status' => 'Uploading...',
4087                    'is_running' => 1,
4088                    'uploaded_by' => $data['created_by']
4089                )
4090            );
4091
4092            $command = "php BulkUploadQuotations.php '{$data['created_by']}' '{$exte}' '{$destination_path}' '{$filename}{$companyId}";
4093            exec($command . ' > /dev/null &');
4094
4095            $query = "";
4096            $isRunning = 0;
4097
4098            if($companyId == 0){
4099                $query = "SELECT * FROM tbl_bulk_upload ORDER BY started_at DESC";
4100                $isRunning = TblBulkUpload::where('is_running', 1)->count();
4101            }else{
4102                $query = "SELECT * FROM tbl_bulk_upload WHERE company_id = {$companyId} ORDER BY started_at DESC";
4103                $isRunning = TblBulkUpload::where('is_running', 1)->where('company_id', $companyId)->count();
4104            }
4105
4106            $result = DB::select($query);
4107
4108            return response(['message' => 'OK', 'data' => $result, 'is_running' => $isRunning]);
4109
4110        } catch (\Exception $e) {
4111            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4112        }
4113    }
4114
4115    function list_bulk_upload($companyId){
4116
4117        try {
4118
4119            $companyId = addslashes($companyId);
4120            $query = "";
4121            $isRunning = 0;
4122
4123            if($companyId == 0){
4124                $query = "SELECT * FROM tbl_bulk_upload ORDER BY started_at DESC";
4125                $isRunning = TblBulkUpload::where('is_running', 1)->count();
4126            }else{
4127                $query = "SELECT * FROM tbl_bulk_upload WHERE company_id = {$companyId} ORDER BY started_at DESC";
4128                $isRunning = TblBulkUpload::where('is_running', 1)->where('company_id', $companyId)->count();
4129            }
4130
4131            $result = DB::select($query);
4132
4133            return response(['message' => 'OK', 'data' => $result, 'is_running' => $isRunning]);
4134
4135        } catch (\Exception $e) {
4136            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4137        }
4138
4139    }
4140
4141    function delete_number(Request $request, $id){
4142
4143        try {
4144
4145            $id = addslashes($id);
4146            $data = $request->all();
4147
4148            $r = TblQuotations::where('id', $id)->first();
4149            $updatedAt = date('Y-m-d H:i:s');
4150            $query = "INSERT INTO tbl_quotations_deleted (id, quote_id, company_id, for_add, created_by, updated_by, updated_at)
4151                        SELECT id, quote_id, company_id, 1, created_by, '{$data['updated_by']}', '{$updatedAt}' FROM tbl_quotations WHERE id = {$id}";
4152
4153            DB::select($query);
4154
4155            TblQuotations::where('id', $id)->delete();
4156
4157            $latestBudget = TblQuotations::where('company_id', $r->company_id)->orderByRaw('id DESC')->pluck('quote_id')->first();
4158
4159            $query = "UPDATE tbl_companies SET last_id = '{$latestBudget}' WHERE company_id = {$r->company_id}";
4160            DB::select($query);
4161
4162            return response(['message' => 'OK']);
4163
4164        } catch (\Exception $e) {
4165            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4166        }
4167
4168    }
4169
4170    function get_number(Request $request, $companyId, $n = null){
4171
4172        try {
4173
4174            $companyId = addslashes($companyId);
4175            $data = $request->all();
4176            $latestBudget = array();
4177            $number = 0;
4178            $beforeLastId = null;
4179
4180            $x = true;
4181
4182            if($companyId == 0){
4183                $latestBudget = TblQuotations::orderByRaw('CAST(quote_id AS DOUBLE) DESC')->pluck('quote_id')->first();
4184            }else{
4185                $latestBudget = TblCompanies::where('company_id', $companyId)->pluck('last_id')->first();
4186
4187                if($latestBudget == null){
4188                    $latestBudget = TblQuotations::where('company_id', $companyId)->orderByRaw('id DESC')->pluck('quote_id')->first();
4189                    $beforeLastId = $latestBudget;
4190                }
4191            }
4192
4193            $number = $latestBudget;
4194
4195            while ($x) {
4196
4197                if(is_numeric(substr($number, -1))) {
4198                    $number++;
4199                }else{
4200                    $number .= "1";
4201                }
4202
4203                $check = 0;
4204
4205                if($companyId == 0){
4206                    $check = TblQuotations::where('quote_id', (string) $number)->count();
4207                }else{
4208                    $check = TblQuotations::where('company_id', $companyId)->where('quote_id', (string) $number)->count();
4209                }
4210
4211                if($check == 0){
4212                    $x = false;
4213                }
4214            }
4215
4216            $result = null;
4217
4218            if($n == null){
4219                $result = TblQuotations::create(array('quote_id' => $number, 'company_id' => $companyId, 'for_add' => 1, 'created_by' => $data['created_by']));
4220            }
4221
4222            if($beforeLastId == null){
4223                $beforeLastId = $number;
4224            }
4225
4226            $query = "UPDATE tbl_companies SET last_id = '{$number}', before_last_id = CASE WHEN before_last_id IS NULL THEN '{$beforeLastId}' ELSE before_last_id END WHERE company_id = {$companyId}";
4227            DB::select($query);
4228
4229            return response([
4230                'message' => 'OK',
4231                'number' => $number,
4232                'id' => ($result !=  null) ? $result->id : null
4233            ]);
4234
4235
4236        } catch (\Exception $e) {
4237            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4238        }
4239
4240    }
4241
4242    function get_years(Request $request){
4243
4244        try {
4245
4246            $data = $request->all();
4247            $companyId = addslashes($data['company_id']);
4248            $where = "";
4249
4250            if($companyId != 0){
4251                $where = " AND company_id = {$companyId} ";
4252            }else{
4253                $where = " AND company_id IN ({$this->companyId}";
4254            }
4255
4256            $query = "SELECT
4257                        CONCAT(
4258                            DATE_FORMAT((SELECT MIN(issue_date) FROM tbl_quotations WHERE issue_date IS NOT NULL {$where}), '%c/%e/'), YEAR(issue_date),
4259                            ' - ',
4260                            DATE_FORMAT((SELECT MAX(issue_date) FROM tbl_quotations WHERE issue_date IS NOT NULL {$where}), '%c/%e/'), YEAR(issue_date)
4261                        ) AS date_like,
4262                        YEAR(issue_date) 'year'
4263                        FROM tbl_quotations
4264                        WHERE issue_date IS NOT NULL {$where}
4265                        GROUP BY YEAR(issue_date)
4266                        ORDER BY YEAR(issue_date) DESC";
4267
4268            $issueDate = DB::select($query);
4269
4270            $query = "SELECT
4271                        CONCAT(
4272                            DATE_FORMAT((SELECT MIN(created_at) FROM tbl_quotations WHERE created_at IS NOT NULL {$where}), '%c/%e/'), YEAR(created_at),
4273                            ' - ',
4274                            DATE_FORMAT((SELECT MAX(created_at) FROM tbl_quotations WHERE created_at IS NOT NULL {$where}), '%c/%e/'), YEAR(created_at)
4275                        ) AS date_like,
4276                        YEAR(created_at) 'year'
4277                        FROM tbl_quotations
4278                        WHERE created_at IS NOT NULL {$where}
4279                        GROUP BY YEAR(created_at)
4280                        ORDER BY YEAR(created_at) DESC";
4281
4282            $createdAt = DB::select($query);
4283
4284            $query = "SELECT
4285                        CONCAT(
4286                            DATE_FORMAT((SELECT MIN(acceptance_date) FROM tbl_quotations WHERE acceptance_date IS NOT NULL {$where}), '%c/%e/'), YEAR(acceptance_date),
4287                            ' - ',
4288                            DATE_FORMAT((SELECT MAX(acceptance_date) FROM tbl_quotations WHERE acceptance_date IS NOT NULL {$where}), '%c/%e/'), YEAR(acceptance_date)
4289                        ) AS date_like,
4290                        YEAR(acceptance_date) 'year'
4291                        FROM tbl_quotations
4292                        WHERE acceptance_date IS NOT NULL {$where}
4293                        GROUP BY YEAR(acceptance_date)
4294                        ORDER BY YEAR(acceptance_date) DESC";
4295
4296            $acceptanceDate = DB::select($query);
4297
4298            return response([
4299                'message' => 'OK',
4300                'data' => $issueDate,
4301                'created_at' => $createdAt,
4302                'acceptance_date' => $acceptanceDate
4303            ]);
4304
4305
4306        } catch (\Exception $e) {
4307            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4308        }
4309
4310    }
4311
4312    function human_filesize($bytes, $decimals = 2) {
4313        $size = ['B', 'KB', 'MB'];
4314
4315        $factor = floor((strlen($bytes) - 1) / 3);
4316        return number_format($bytes / pow(1024, $factor), 2, ',', '.') . $size[$factor];
4317    }
4318
4319    function get_files($quoteId){
4320
4321        try {
4322
4323            $quoteId = addslashes($quoteId);
4324
4325            $quoteId = (int)$quoteId;
4326            $query = "
4327            SELECT
4328                file_id,
4329                quotation_id,
4330                quote_id,
4331                original_name,
4332                filename,
4333                uploaded_by,
4334                uploaded_at,
4335                is_internal,
4336                file_size,
4337                file_hash,
4338                mime_type
4339            FROM tbl_files
4340            WHERE quotation_id = ?
4341            AND is_internal IS NULL";
4342
4343            $result = DB::select($query, [$quoteId]);
4344
4345            foreach ($result as $file) {
4346                if($file->file_size > 0) {
4347                    $file->filesize = $this->human_filesize($file->file_size);
4348                } else {            
4349                    $path = "uploads/" . $file->filename;
4350
4351                    if (Storage::disk('s3')->exists($path)) {
4352                        $fileSizeBytes = Storage::disk('s3')->size($path);
4353                    } else {
4354                        $fileSizeBytes = 0;
4355                    }
4356
4357                    $file->filesize = $this->human_filesize($fileSizeBytes);
4358                }
4359
4360                $file->original_name = $file->original_name . " ({$file->filesize})";
4361            }
4362
4363            $query = "
4364            SELECT
4365                file_id,
4366                quotation_id,
4367                quote_id,
4368                original_name,
4369                filename,
4370                uploaded_by,
4371                uploaded_at,
4372                is_internal,
4373                file_size,
4374                file_hash,
4375                mime_type
4376            FROM tbl_files
4377            WHERE quotation_id = ?
4378            AND is_internal = 1";
4379
4380            $internal = DB::select($query, [$quoteId]);
4381
4382            foreach ($internal as $file) {
4383                if($file->file_size > 0) {
4384                    $file->filesize = $this->human_filesize($file->file_size);
4385                } else {
4386                    $path = "uploads/" . $file->filename;
4387
4388                    if (Storage::disk('s3')->exists($path)) {
4389                        $fileSizeBytes = Storage::disk('s3')->size($path);
4390                    } else {
4391                        $fileSizeBytes = 0;
4392                    }
4393
4394                    $file->filesize = $this->human_filesize($fileSizeBytes);
4395                }
4396
4397                $file->original_name = $file->original_name . " ({$file->filesize})";
4398            }
4399
4400            $job = TblOngoingJobs::where('quotation_id', $quoteId)->first();
4401            $order = TblQuotations::where('id', $quoteId)->first();
4402
4403            $emails = explode(",", str_replace(" ", "", $order->email));
4404
4405            $sendGrid = TblSendgridWebhook::where('quotation_id', $quoteId)->where('x_message_id', $order->x_message_id)->first();
4406
4407            $uniqueEvents = array();
4408            $currentEvents = array();
4409            $status = 2;
4410
4411            $xStatus = "processed";
4412
4413            if($sendGrid){
4414                $emailErrors = array('deferred', 'bounce', 'dropped', 'spamreport', 'invalid');
4415                $events = json_decode($sendGrid->json_body, true);
4416                $xMessageId = $sendGrid->x_message_id;
4417                $isDelivered = 0;
4418                $isProcessed = 0;
4419                $isError = 0;
4420
4421                foreach ($emails as $email) {
4422
4423                    $emailEvents = array_filter($events, fn($event) => strtolower($event['email']) === strtolower($email));
4424
4425                    $statuses = array_unique(array_column($emailEvents, 'event'));
4426                    $eventCount = count($statuses);
4427
4428                    if ($eventCount === 1 && in_array('processed', $statuses)) {
4429                        $xStatus = "processed";
4430                    }
4431
4432                    if ($eventCount == 2) {
4433                        if (in_array('processed', $statuses) && in_array('delivered', $statuses)) {
4434                            $xStatus = "delivered";
4435                        }
4436
4437                        foreach ($emailErrors as $e) {
4438                            if (in_array('processed', $statuses) && in_array($e, $statuses)) {
4439                                $xStatus = $e;
4440                            }
4441                        }
4442
4443                    }elseif($eventCount > 2){
4444                        if (in_array('processed', $statuses) && in_array('delivered', $statuses)) {
4445                            $xStatus = "delivered";
4446                        }
4447
4448                        if($xStatus != "delivered"){
4449                            foreach ($emailErrors as $e) {
4450                                if (in_array('processed', $statuses) && in_array($e, $statuses)) {
4451                                    $xStatus = $e;
4452                                }
4453                            }
4454                        }
4455                    }
4456
4457
4458                    if($xStatus == "processed"){
4459                        $isProcessed++;
4460                    }elseif($xStatus == "delivered"){
4461                        $isDelivered++;
4462                    }else{
4463                        $isError++;
4464                    }
4465
4466                    foreach ($emailEvents as $event) {
4467                        $key = strtolower($event['email']) . '|' . $event['event'];
4468                        if (!isset($uniqueEvents[$key])) {
4469                            $uniqueEvents[$key] = $event;
4470                        }
4471                    }
4472                }
4473
4474                if($uniqueEvents){
4475                    foreach (array_values($uniqueEvents) as $d) {
4476                        $d['created_at'] = date('Y-m-d H:i:s', $d['timestamp']);
4477
4478                        if(isset($d['response'])){
4479                            $d['error'] = $d['response'];
4480                        }
4481
4482                        if(isset($d['reason'])){
4483                            $d['error'] = $d['reason'];
4484                        }
4485
4486                        array_push($currentEvents, $d);
4487                    }
4488                }
4489
4490
4491
4492                if(count($emails) == $isDelivered){
4493                    $status = 1;
4494                    $xStatus = "Completed";
4495                }elseif($isProcessed > 0){
4496                    $status = 2;
4497                    $xStatus = "Processing";
4498                }elseif($isError > 0){
4499                    $status = 3;
4500
4501                    if($xStatus == "bounce"){
4502                        $xStatus = "Error - Bounce";
4503                    }else{
4504                        $xStatus = "Error";
4505                    }
4506                }
4507            }
4508
4509            $z = 0;
4510
4511            if($order->x_status != $xStatus){
4512                TblQuotations::where('id', $order->id)->update(
4513                    array(
4514                        'x_status' => $xStatus
4515                    )
4516                );
4517                $z = 1;
4518                Cache::flush();
4519            }
4520
4521            if(empty($currentEvents)){
4522                $status = 0;
4523            }
4524
4525            $followUpLogs = TblFollowUpLogs::where('quotation_id', $quoteId)->orderBy('created_at', 'desc')->get();
4526
4527            $projectTypes = TblProjectTypes::where('company_id', $order->company_id)->get();
4528
4529            $sendgridFollowUpLogs = array();
4530
4531            if($order->y_message_id){
4532                $sendgridFollowUpLogs = TblSendgridWebhook::where('x_message_id', $order->y_message_id)->first();
4533
4534                if($sendgridFollowUpLogs){
4535                    $sendgridFollowUpLogs = json_decode($sendgridFollowUpLogs->json_body, true);
4536                    foreach ($sendgridFollowUpLogs as &$item) {
4537                        $item['created_at'] = date("Y-m-d H:i:s", $item['timestamp']);
4538                    }
4539                }
4540            }
4541
4542            return response([
4543                'message' => 'OK',
4544                'data' => $result,
4545                'followUpLogs' => $followUpLogs,
4546                'sendgridFollowUpLogs' => $sendgridFollowUpLogs,
4547                'internal' => $internal,
4548                'projectTypes' => $projectTypes,
4549                'currentEvents' => array(
4550                    'status' => $status,
4551                    'email' => $currentEvents,
4552                    $uniqueEvents,
4553                    $xStatus
4554                ),
4555                'job' => $job,
4556                'isUpdated' => $z
4557            ]);
4558
4559        } catch (\Exception $e) {
4560            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4561        }
4562
4563    }
4564
4565    public function download_file($fileId) {
4566        try {
4567            $fileId = addslashes($fileId);
4568            $file = TblFiles::where('file_id', $fileId)->first();
4569
4570            if (!$file) {
4571                return response()->json([
4572                    'message' => 'KO',
4573                    'error' => 'Archivo no encontrado'
4574                ], 404);
4575            }
4576
4577            if (!is_null($file->file_hash) && !empty($file->file)) {
4578                $fileContent = $file->file;
4579                $mimeType = $file->mime_type ?? 'application/octet-stream';
4580                $filename = $file->original_name ?? $file->filename ?? 'download';
4581
4582                return response($fileContent)
4583                    ->header('Content-Type', $mimeType)
4584                    ->header('Content-Disposition', 'attachment; filename="' . $filename . '"')
4585                    ->header('Content-Length', strlen($fileContent))
4586                    ->header('Cache-Control', 'no-cache, no-store, must-revalidate');
4587
4588            }
4589            else {
4590                $filePath = Storage::disk('s3')->get("uploads/" . $file->filename);
4591                // $filePath = storage_path('app/public/uploads/' . $file->filename);                
4592
4593                if (!Storage::disk('s3')->exists("uploads/" . $file->filename)) {
4594                    return response()->json([
4595                        'message' => 'KO',
4596                        'error' => 'Archivo físico no encontrado: ' . $file->filename
4597                    ], 404);
4598                }
4599
4600                $fileSize = filesize($filePath);
4601                $mimeType = mime_content_type($filePath) ?: 'application/octet-stream';
4602                $filename = $file->original_name ?? $file->filename;
4603
4604                $fileContent = file_get_contents($filePath);
4605
4606                return response($fileContent)
4607                    ->header('Content-Type', $mimeType)
4608                    ->header('Content-Disposition', 'attachment; filename="' . $filename . '"')
4609                    ->header('Content-Length', $fileSize)
4610                    ->header('Cache-Control', 'no-cache, no-store, must-revalidate');
4611            }
4612
4613        } catch (\Exception $e) {
4614            \Log::error('Error downloading file: ' . $e->getMessage());
4615            return response()->json([
4616                'message' => 'KO',
4617                'error' => 'Error interno del servidor: ' . $e->getMessage()
4618            ], 500);
4619        }
4620    }
4621
4622    function delete_file($fileId){
4623
4624        try {
4625
4626            $fileId = addslashes($fileId);
4627            $file = TblFiles::where('file_id', $fileId)->first();
4628            $result = TblFiles::where('file_id', $fileId)->first();
4629
4630            if($result){
4631                TblFiles::where('file_id', $fileId)->delete();
4632                $path = storage_path('app/public/uploads/' . $result->filename);
4633                Storage::disk('public')->delete('uploads/' . $result->filename);
4634
4635                if(!env('SENDGRID_STAGING')){
4636                    Storage::disk('s3')->delete('uploads/' . $result->filename);
4637                }
4638            }
4639
4640            $fileCount = TblFiles::where('quotation_id', $file->quotation_id)->count();
4641            $data = array();
4642            if($fileCount > 0){
4643                $data['has_attachment'] = 1;
4644            }else{
4645                $data['has_attachment'] = 0;
4646            }
4647
4648            TblQuotations::where('quote_id', $file->quote_id)->update($data);
4649
4650            return response(['message' => 'OK']);
4651
4652        } catch (\Exception $e) {
4653            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4654        }
4655    }
4656
4657    function send_email_to_client(Request $request){
4658
4659        try {
4660
4661            $data = $request->all();
4662
4663            // $id = addslashes($data['id']);
4664            $userId = addslashes($data['user_id']);
4665            $companyId = addslashes($data['company_id']);
4666
4667            $isResend = null;
4668
4669            if(isset($data['is_resend'])){
4670                $isResend = 1;
4671                unset($data['is_resend']);
4672            }
4673
4674            // $result = TblQuotations::where('id', $id)->first();
4675
4676            $where = "";
4677            $emailTemplateId = addslashes($data['email_template_id']);
4678            unset($data['email_template_id']);
4679
4680            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
4681            $limit = 0;
4682
4683            if($companyId == 0){
4684                $limit = 20;
4685            }else{
4686                $emailCompany = TblCompanies::where('company_id', $companyId)->first();
4687
4688                if($emailCompany->limit_send != null){
4689                    $limit = $emailCompany->limit_send;
4690                }
4691            }
4692
4693            if(isset($data['ids']) && count($data['ids']) > 0){
4694                $quoteIds = implode(",", $data['ids']);
4695                $where = " a.id IN ({$quoteIds}) AND ";
4696            }
4697
4698            if(isset($data['ids_not_in']) && count($data['ids_not_in']) > 0){
4699                $quoteIds = implode(",", $data['ids_not_in']);
4700                $where = " a.id NOT IN ({$quoteIds}) AND ";
4701            }
4702
4703            $r = new Request([
4704                'filterModel' => $data['filterModel'],
4705                'sortModel' => $data['sortModel'],
4706                'start' => 0,
4707                'end' => 999999999,
4708                'company_id' => $data['company_id'],
4709                'user_id' => $data['user_id'],
4710                'ids' => $data['ids'],
4711                'searchText' => $data['searchText'],
4712                'ids_not_in' => $data['ids_not_in']
4713            ]);
4714
4715            $listQuotations = $this->list_quotations($r);
4716            $d = $listQuotations->original['data'];
4717            $result = array();
4718
4719            for ($i = 0; $i < count($d); $i++) {
4720                if($d[$i]->email != null
4721                    && ($d[$i]->budget_status_id == 11 || $isResend == 1)
4722                ){
4723                    array_push($result, $d[$i]);
4724                }
4725            }
4726
4727            if(count($result) == 0){
4728                return response(['message' => 'OK', $d]);
4729            }
4730
4731            $user   = TblUsers::where('id', $userId)->first();
4732            $error  = false;
4733
4734            $availableParameters = [
4735                'quote_id',
4736                'company_id',
4737                'client',
4738                'client_type',
4739                'phone_number',
4740                'email',
4741                'issue_date',
4742                'request_date',
4743                'duration',
4744                'invoice_number',
4745                'type',
4746                'acceptance_date',
4747                'status',
4748                'source',
4749                'amount',
4750                'reason_for_not_following_up',
4751                'last_follow_up_date',
4752                'last_follow_up_comment',
4753                'reason_for_rejection_id',
4754                'reason_for_rejection',
4755                'commercial',
4756                'created_at',
4757                'created_by',
4758                'updated_at',
4759                'updated_by'
4760            ];
4761
4762            $dateParameters = [
4763                'issue_date',
4764                'request_date',
4765                'acceptance_date',
4766                'last_follow_up_date',
4767                'created_at',
4768                'updated_at',
4769            ];
4770
4771            if($this->locale == 'es'){
4772                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
4773            }
4774
4775            if($this->locale == 'es'){
4776                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
4777            }
4778
4779            for ($i = 0; $i < count($result); $i++) {
4780
4781                $body = $emailTemplate->html;
4782                if(isset($data['html'])){
4783                    $body = $data['html'];
4784                }
4785                $subject = $emailTemplate->subject;
4786                $commercialUser = $result[$i]->commercial;
4787
4788                if($result[$i]->email != null){
4789
4790                    if(env('SENDGRID_STAGING')){
4791                        $toEmail = $user->email;
4792                    }else{
4793                        $toEmail = $result[$i]->email;
4794                    }
4795
4796                    preg_match_all('/{{(.*?)}}/', $body, $matches);
4797
4798                    $parameters = $matches[1];
4799
4800                    foreach ($parameters as $parameter) {
4801
4802                        if(in_array($parameter, $dateParameters)){
4803                            if($result[$i]->{$parameter}){
4804                                $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
4805                            }
4806                        }
4807
4808                        if(in_array($parameter, $availableParameters)){
4809                            $body = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $body);
4810                        }
4811                    }
4812
4813                    preg_match_all('/{{(.*?)}}/', $subject, $matches);
4814
4815                    $parameters = $matches[1];
4816
4817                    foreach ($parameters as $parameter) {
4818
4819                        if(in_array($parameter, $dateParameters)){
4820                            if($result[$i]->{$parameter}){
4821                                $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
4822                            }
4823                        }
4824
4825                        if(in_array($parameter, $availableParameters)){
4826                            $subject = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $subject);
4827                        }
4828                    }
4829
4830                    $email = new \SendGrid\Mail\Mail();
4831
4832                    // $imgpath = \File::get('fireservicetitan.png');
4833                    // $base64 = "data:image/png;base64,".base64_encode($imgpath);
4834                    // $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
4835
4836                    // $email->addAttachment(
4837                    //     $imgpath,
4838                    //     "image/png",
4839                    //     "fireservicetitan.png",
4840                    //     "inline",
4841                    //     "fireservicetitan"
4842                    // );
4843
4844                    $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
4845
4846                    foreach ($templateFiles as $item) {
4847                        $f = storage_path('app/public/uploads/' . $item->filename);
4848
4849                        if (file_exists($f)) {
4850                            $imgpath = file_get_contents($f);
4851                            $base64 = "data:image/png;base64," . base64_encode($imgpath);
4852                            $mimeType = mime_content_type($f);
4853
4854                            $email->addAttachment(
4855                                $imgpath,
4856                                $mimeType,
4857                                str_replace(' ', '', $item->original_name),
4858                                "inline",
4859                                str_replace(' ', '', $item->original_name),
4860                            );
4861
4862                            $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
4863                        } else {
4864                            Log::channel('email_failed_log')->error("File not found: " . $f);
4865                        }
4866                    }
4867
4868                    $html = '<!DOCTYPE html>';
4869                    $html .= '<html>';
4870                    $html .= '<head>';
4871                    $html .= '<meta charset="UTF-8">';
4872                    $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
4873                    $html .= '</head>';
4874                    $html .= '<body>';
4875                    $html .= $body;
4876                    $html .= '</body>';
4877                    $html .= '</html>';
4878
4879                    if($toEmail != null){
4880
4881                        $toEmail = explode(",", $toEmail);
4882                        $toEmail = array_map('trim', $toEmail);
4883
4884                        $companyEmail = null;
4885
4886                        $queryUsers = "SELECT sender_email AS from_email, `name` AS from_name FROM tbl_users WHERE sender_enabled = 1 AND response_id IS NOT NULL AND verified = 1 AND `name` = '{$commercialUser}'";
4887                        $commercialEmail = DB::select($queryUsers);
4888
4889                        if(count($commercialEmail) > 0){
4890                            $companyEmail = $commercialEmail[0];
4891                        }else{
4892                            if($emailTemplate->from_id != null){
4893                                $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
4894                            }else{
4895                                $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result[$i]->company_id)->first();
4896                            }
4897                        }
4898
4899                        if(!$companyEmail){
4900                            return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
4901                        }
4902
4903                        $ccBcc = TblCcBcc::where('company_id', $result[$i]->company_id)->get();
4904
4905                        $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
4906                        $email->setSubject($subject);
4907
4908                        foreach ($toEmail as $clientEmail) {
4909                            $isValid = $this->isEmailValid($clientEmail);
4910                            if($isValid){
4911                                $email->addTo($clientEmail);
4912                            }
4913                        }
4914
4915                        if(env('SENDGRID_STAGING')){
4916
4917                        }else{
4918                            if(!in_array($user->email, $toEmail)){
4919                                $email->addCc($user->email);
4920                            }
4921
4922                            if(count($ccBcc) > 0){
4923                                foreach ($ccBcc as $data) {
4924                                    if(!in_array($data->email, $toEmail) && $user->email != $data->email){
4925                                        $email->addBcc($data->email);
4926                                    }
4927                                }
4928                            }
4929                        }
4930
4931                        $email->addContent("text/html", $html);
4932
4933                        $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
4934
4935                        $files = TblFiles::where('quotation_id', $result[$i]->id)->where('is_internal', null)->get();
4936                        $requestSize = $this->calculateEmailRequestSize($email);
4937
4938                        foreach ($files as $key => $value) {
4939                            $fileContent = null;
4940                            $fileSize = 0;
4941                            $fileName = null;
4942
4943                            if (Storage::disk('s3')->exists("uploads/" . $files[$key]->filename)) {                                
4944                                $fileContent = Storage::disk('s3')->get("uploads/" . $files[$key]->filename);                                
4945                                $fileSize = (int) ceil(strlen($fileContent) / 1048576);                                
4946                                $fileName = $files[$key]->original_name;                                                            
4947                            }
4948                            else if ($files[$key]->file) {
4949                                $fileContent = $files[$key]->file;
4950
4951                                if (is_string($fileContent) && base64_decode($fileContent, true)) {
4952                                    $fileContent = base64_decode($fileContent);
4953                                }
4954
4955                                $fileSize = strlen($fileContent) / 1048576;
4956                                $fileSize = (int) ceil($fileSize);
4957                                $fileName = $files[$key]->original_name ?: $files[$key]->file_name ?: 'file';
4958                            }
4959
4960                            if ($fileContent && $fileSize > 0) {
4961                                if ($requestSize + $fileSize < 25) {
4962                                    $attachment = new \SendGrid\Mail\Attachment();
4963                                    $attachment->setFilename($fileName);
4964                                    $attachment->setDisposition("attachment");
4965
4966                                    $attachment->setContent(base64_encode($fileContent));
4967
4968                                    $email->addAttachment($attachment);
4969                                    $requestSize = $this->calculateEmailRequestSize($email);
4970                                }
4971                            }
4972                        }
4973
4974                        $response = $sendgrid->send($email);
4975                        if ($response->statusCode() == 202) {
4976                            $messageId = null;
4977
4978                            foreach ($response->headers() as $header) {
4979                                if (strpos(strtolower($header), 'x-message-id:') === 0) {
4980                                    $messageId = trim(substr($header, strpos($header, ':') + 1));
4981                                    break;
4982                                }
4983                            }
4984
4985                            $comment = "Se ha enviado la orden por correo electrónico manualmente al cliente el " . date('Y-m-d H:i:s') . " por el usuario " . $user->name;
4986                            $result[$i]->last_follow_up_comment = $result[$i]->last_follow_up_comment . "\n" . $comment;
4987
4988                            TblQuotations::where('id', $result[$i]->id)->update(
4989                                array(
4990                                    'last_follow_up_comment' => $result[$i]->last_follow_up_comment,
4991                                    'budget_status_id' => 2,
4992                                    'x_message_id' => $messageId,
4993                                    'x_status' => 'Processing',
4994                                    'updated_by' => $user->name,
4995                                    'updated_at' => date('Y-m-d H:i:s')
4996                                )
4997                            );
4998
4999                            $jsonBody = array();
5000
5001                            foreach ($toEmail as $clientEmail) {
5002                                $isValid = $this->isEmailValid($clientEmail);
5003                                $eventStatus = "processed";
5004                                $eventResponse = "";
5005                                if(!$isValid){
5006                                    $eventStatus = "invalid";
5007                                    $eventResponse = "Invalid email address";
5008                                }
5009
5010                                array_push(
5011                                    $jsonBody,
5012                                    array(
5013                                        'email' =>  $clientEmail,
5014                                        'event' => $eventStatus,
5015                                        'sg_message_id' => $messageId,
5016                                        'smtp-id' => $messageId,
5017                                        'timestamp' => strtotime(date('Y-m-d H:i:s')),
5018                                        'response' => $eventResponse
5019                                    )
5020                                );
5021                            }
5022
5023                            TblSendgridWebhook::create(
5024                                array(
5025                                    'quotation_id' => $result[$i]->id,
5026                                    'type' => 'sendToClient',
5027                                    'json_body' => json_encode($jsonBody),
5028                                    'x_message_id' => $messageId
5029                                )
5030                            );
5031
5032                            Log::channel('email_log')->info("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - EMAIL MANUALLY SENT');
5033                        } else {
5034                            $error = true;
5035                            Log::channel('email_failed_log')->error("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - ' . $response->body());
5036                        }
5037                    }
5038                }
5039            }
5040
5041            $this->update_commercial_numbers($companyId);
5042
5043            Cache::flush();
5044            return response(['message' => 'OK', $result]);
5045
5046        } catch (\Exception $e) {
5047            Log::channel('email_failed_log')->error($e->getMessage());
5048            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5049        }
5050
5051    }
5052
5053    function send_email_follow_ups(Request $request, $automaticSendLimit = null){
5054
5055        try {
5056
5057            $data = $request->all();
5058
5059            $startedAt = date('Y-m-d H:i:s');
5060            $toEmail = "";
5061            $userId = addslashes($data['user_id']);
5062            $companyId = addslashes($data['company_id']);
5063            $emailTemplateId = addslashes($data['email_template_id']);
5064            unset($data['email_template_id']);
5065
5066            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
5067            $limit = 0;
5068
5069            $blockedDomains = array();
5070            $workingDays = 10;
5071            $limitReminderEmails = 3;
5072
5073            if($companyId == 0){
5074                $limit = 20;
5075            }else{
5076                $emailCompany = TblCompanies::where('company_id', $companyId)->first();
5077                $workingDays = $emailCompany->last_follow_up_date ?? 10;
5078                $limitReminderEmails = $emailCompany->limit_reminder_emails ?? 3;
5079
5080                if($emailCompany->limit_send != null){
5081                    $limit = $emailCompany->limit_send;
5082                }
5083            }
5084
5085            $r = new Request([
5086                'filterModel' => $data['filterModel'],
5087                'sortModel' => $data['sortModel'],
5088                'start' => 0,
5089                'end' => 999999999,
5090                'company_id' => $data['company_id'],
5091                'user_id' => $data['user_id'],
5092                'ids' => $data['ids'],
5093                'searchText' => $data['searchText'],
5094                'ids_not_in' => $data['ids_not_in'],
5095                'last_follow_up_date' => 1
5096            ]);
5097
5098            $listQuotations = $this->list_quotations($r);
5099            $d = $listQuotations->original['data'];
5100            $result = array();
5101
5102            if($automaticSendLimit != null){
5103                $limit = $automaticSendLimit;
5104            }
5105
5106            $l = 0;
5107            for ($i = 0; $i < count($d); $i++) {
5108                if($d[$i]->email != null
5109                    && $d[$i]->budget_status_id == 2
5110                    && $d[$i]->reason_for_not_following_up_id == null
5111                    && $d[$i]->total_sent < $limitReminderEmails
5112                    && $d[$i]->last_follow_up_date != null
5113                    && $d[$i]->last_follow_up_date < date('Y-m-d H:i:s')
5114                    && $d[$i]->last_follow_up_date > 0
5115                ){
5116                    if($l == $limit){
5117                        break;
5118                    }
5119                    array_push($result, $d[$i]);
5120                    $l++;
5121                }
5122            }
5123
5124            if(count($result) == 0){
5125                return response(['message' => 'OK']);
5126            }
5127
5128            $user   = TblUsers::where('id', $userId)->first();
5129            $error  = false;
5130
5131            $sentBy = $user->name;
5132
5133            $availableParameters = [
5134                'quote_id',
5135                'company_id',
5136                'client',
5137                'client_type',
5138                'phone_number',
5139                'email',
5140                'issue_date',
5141                'request_date',
5142                'duration',
5143                'invoice_number',
5144                'type',
5145                'acceptance_date',
5146                'status',
5147                'source',
5148                'amount',
5149                'reason_for_not_following_up',
5150                'last_follow_up_date',
5151                'last_follow_up_comment',
5152                'reason_for_rejection_id',
5153                'reason_for_rejection',
5154                'commercial',
5155                'created_at',
5156                'created_by',
5157                'updated_at',
5158                'updated_by'
5159            ];
5160
5161            $dateParameters = [
5162                'issue_date',
5163                'request_date',
5164                'acceptance_date',
5165                'last_follow_up_date',
5166                'created_at',
5167                'updated_at',
5168            ];
5169
5170
5171
5172            if($this->locale == 'es'){
5173                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
5174            }
5175
5176            $totalSent = 0;
5177            $totalSentIds = array();
5178            $totalFailedIds = array();
5179            $totalErrorIds = array();
5180            $currentQuotationId = null;
5181
5182            for ($i = 0; $i < count($result); $i++) {$budgetTypeId = $result[$i]->budget_type_id;
5183                $currentQuotationId = $result[$i]->quote_id;
5184                $body = $emailTemplate->html;
5185                if(isset($data['html'])){
5186                    $body = $data['html'];
5187                }
5188                $subject = $emailTemplate->subject;
5189                $commercialUser = $result[$i]->commercial;
5190
5191                $blockedDomains = TblBlockedDomains::where('company_id', $result[$i]->company_id)->pluck('domain')->toArray();
5192
5193                if(env('SENDGRID_STAGING')){
5194                    $toEmail = $user->email;
5195                }else{
5196                    $toEmail = $result[$i]->email;
5197                }
5198
5199                preg_match_all('/{{(.*?)}}/', $body, $matches);
5200
5201                $parameters = $matches[1];
5202
5203                foreach ($parameters as $parameter) {
5204
5205                    if(in_array($parameter, $dateParameters)){
5206                        if($result[$i]->{$parameter}){
5207                            $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
5208                        }
5209                    }
5210
5211                    if(in_array($parameter, $availableParameters)){
5212                        $body = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $body);
5213                    }
5214                }
5215
5216                preg_match_all('/{{(.*?)}}/', $subject, $matches);
5217
5218                $parameters = $matches[1];
5219
5220                foreach ($parameters as $parameter) {
5221
5222                    if(in_array($parameter, $dateParameters)){
5223                        if($result[$i]->{$parameter}){
5224                            $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
5225                        }
5226                    }
5227
5228                    if(in_array($parameter, $availableParameters)){
5229                        $subject = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $subject);
5230                    }
5231                }
5232
5233                $email = new \SendGrid\Mail\Mail();
5234
5235                $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
5236
5237                foreach ($templateFiles as $item) {
5238                    $f = storage_path('app/public/uploads/' . $item->filename);
5239
5240                    if (file_exists($f)) {
5241                        $imgpath = file_get_contents($f);
5242                        $base64 = "data:image/png;base64," . base64_encode($imgpath);
5243                        $mimeType = mime_content_type($f);
5244
5245                        $email->addAttachment(
5246                            $imgpath,
5247                            $mimeType,
5248                            str_replace(' ', '', $item->original_name),
5249                            "inline",
5250                            str_replace(' ', '', $item->original_name),
5251                        );
5252
5253                        $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
5254                    } else {
5255                        Log::channel('email_failed_log')->error("File not found: " . $f);
5256                    }
5257                }
5258
5259                $html = '<!DOCTYPE html>';
5260                $html .= '<html>';
5261                $html .= '<head>';
5262                $html .= '<meta charset="UTF-8">';
5263                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
5264                $html .= '</head>';
5265                $html .= '<body>';
5266                $html .= $body;
5267                $html .= '</body>';
5268                $html .= '</html>';
5269
5270                if($automaticSendLimit != null){
5271                    $sentBy = "System";
5272                }
5273
5274                if($toEmail != null){
5275
5276                    $toEmail = explode(",", $toEmail);
5277                    $toEmail = array_map('trim', $toEmail);
5278
5279                    $companyEmail = null;
5280
5281                    $queryUsers = "SELECT sender_email AS from_email, `name` AS from_name FROM tbl_users WHERE sender_enabled = 1 AND response_id IS NOT NULL AND verified = 1 AND `name` = '{$commercialUser}'";
5282                    $commercialEmail = DB::select($queryUsers);
5283
5284                    if(count($commercialEmail) > 0){
5285                        $companyEmail = $commercialEmail[0];
5286                    }else{
5287                        if($emailTemplate->from_id != null){
5288                            $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
5289                        }else{
5290                            $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result[$i]->company_id)->first();
5291                        }
5292                    }
5293
5294                    if(!$companyEmail){
5295                        return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
5296                    }
5297
5298                    $ccBcc = TblCcBcc::where('company_id', $result[$i]->company_id)->get();
5299
5300                    $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
5301                    $email->setSubject($subject);
5302
5303                    $s = 0;
5304                    $addTo = array();
5305                    foreach ($toEmail as $clientEmail) {
5306                        $isValid = $this->isEmailValid($clientEmail);
5307                        if($isValid){
5308                            $domain = substr($clientEmail, strpos($clientEmail, '@') + 1);
5309
5310                            if(!in_array($domain, $blockedDomains)){
5311                                $email->addTo($clientEmail);
5312                                array_push($addTo, $clientEmail);
5313                                $s++;
5314                            }
5315                        }else{
5316                            TblFollowUpLogs::create(
5317                                array(
5318                                    'quotation_id' => $result[$i]->id,
5319                                    'email' => $clientEmail,
5320                                    'sent_by' => $sentBy,
5321                                    'status' => 'Invalid email'
5322                                )
5323                            );
5324                        }
5325                    }
5326
5327                    if($s == 0){
5328                        array_push($totalFailedIds, $result[$i]->id);
5329                        Log::channel('email_failed_log')->error($s. 'ID:' . $result[$i]->id . ' - ' . json_encode($toEmail));
5330                        continue;
5331                    }
5332
5333                    if(env('SENDGRID_STAGING')){
5334
5335                    }else{
5336                        if(count($ccBcc) > 0){
5337                            foreach ($ccBcc as $data) {
5338                                if(!in_array($data->email, $toEmail)){
5339                                    $email->addBcc($data->email);
5340                                }
5341                            }
5342                        }
5343                    }
5344
5345                    $email->addContent("text/html", $html);
5346
5347                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5348
5349                    $files = TblFiles::where('quotation_id', $result[$i]->id)->where('is_internal', null)->get();
5350                    $requestSize = $this->calculateEmailRequestSize($email);
5351
5352                    foreach ($files as $key => $value) {
5353                        if ($files[$key]->filename && Storage::disk('s3')->exists("uploads/" . $files[$key]->filename)) {
5354                                                        
5355                            $fileContent = Storage::disk('s3')->get("uploads/" . $files[$key]->filename);
5356                            $fileSize = strlen($fileContent) / 1048576;
5357                            $fileSize = (int) ceil($fileSize);
5358
5359                            $originalName = $files[$key]->original_name ?: basename($files[$key]->filename);
5360                        }
5361                        else if ($files[$key]->file) {
5362                            $fileContent = $files[$key]->file;
5363
5364                            if (is_string($fileContent) && base64_decode($fileContent, true)) {
5365                                $fileContent = base64_decode($fileContent);
5366                            }
5367
5368                            $fileSize = strlen($fileContent) / 1048576;
5369                            $fileSize = (int) ceil($fileSize);
5370
5371                            $originalName = $files[$key]->original_name ?: ($files[$key]->file_name ?: 'file');
5372                        }
5373                        else {
5374                            continue;
5375                        }
5376
5377                        if($fileSize > 0){
5378                            if($requestSize + $fileSize < 25){
5379                                $attachment = new \SendGrid\Mail\Attachment();
5380                                $attachment->setFilename($originalName);
5381                                $attachment->setDisposition("attachment");
5382
5383                                $attachment->setContent(base64_encode($fileContent));
5384
5385                                if ($files[$key]->mime_type) {
5386                                    $attachment->setType($files[$key]->mime_type);
5387                                }
5388
5389                                $email->addAttachment($attachment);
5390                                $requestSize = $this->calculateEmailRequestSize($email);
5391                            } else {
5392                                Log::warning("File omitted due to size limit: " . $originalName);
5393                            }
5394                        }
5395                    }
5396
5397                    $response = $sendgrid->send($email);
5398                    if ($response->statusCode() == 202) {
5399
5400                        $messageId = null;
5401
5402                        foreach ($response->headers() as $header) {
5403                            if (strpos(strtolower($header), 'x-message-id:') === 0) {
5404                                $messageId = trim(substr($header, strpos($header, ':') + 1));
5405                                break;
5406                            }
5407                        }
5408
5409                        $lastFollowUp = TblLastFollowUpDate::where('company_id', $companyId)->where('budget_type_id', $budgetTypeId)->first();
5410                        $workingDaysN = $workingDays;
5411                        if($lastFollowUp != null){
5412                            if($lastFollowUp->last_follow_up_date){
5413                                $workingDaysN = $lastFollowUp->last_follow_up_date;
5414                            }
5415                        }
5416
5417                        $comment = "Email automático enviado el " . date('Y-m-d H:i:s') . " por usuario " . $sentBy;
5418                        $result[$i]->last_follow_up_comment = $result[$i]->last_follow_up_comment . "\n" . $comment;
5419                        $date = strtotime("{$workingDaysN} weekdays");
5420                        $result[$i]->last_follow_up_date = date('Y-m-d H:i:s', $date);
5421                        $totalSentQ = $result[$i]->total_sent + 1;
5422
5423                        array_push($totalSentIds, $result[$i]->id);
5424
5425                        foreach ($addTo as $addToEmail) {
5426                            TblFollowUpLogs::create(
5427                                array(
5428                                    'quotation_id' => $result[$i]->id,
5429                                    'email' => $addToEmail,
5430                                    'sent_by' => $sentBy,
5431                                    'status' => 'OK'
5432                                )
5433                            );
5434                        }
5435
5436                        if($totalSentQ >= $limitReminderEmails){
5437                            $result[$i]->reason_for_not_following_up_id = 3;
5438                            $result[$i]->last_follow_up_date = null;
5439                        }
5440
5441                        TblQuotations::where('id', $result[$i]->id)->update(
5442                            array(
5443                                'last_follow_up_comment' => $result[$i]->last_follow_up_comment,
5444                                'last_follow_up_date' => $result[$i]->last_follow_up_date,
5445                                'total_sent' => $result[$i]->total_sent + 1,
5446                                'y_message_id' => $messageId,
5447                                'y_status' => 'Processing',
5448                                'reason_for_not_following_up_id' => $result[$i]->reason_for_not_following_up_id,
5449                                'updated_by' => $sentBy,
5450                                'updated_at' => date('Y-m-d H:i:s')
5451                            )
5452                        );
5453
5454                        $jsonBody = array();
5455
5456                        foreach ($toEmail as $clientEmail) {
5457                            $isValid = $this->isEmailValid($clientEmail);
5458                            $eventStatus = "processed";
5459                            $eventResponse = "";
5460                            if(!$isValid){
5461                                $eventStatus = "invalid";
5462                                $eventResponse = "Invalid email address";
5463                            }
5464
5465                            array_push(
5466                                $jsonBody,
5467                                array(
5468                                    'email' =>  $clientEmail,
5469                                    'event' => $eventStatus,
5470                                    'sg_message_id' => $messageId,
5471                                    'smtp-id' => $messageId,
5472                                    'timestamp' => strtotime(date('Y-m-d H:i:s')),
5473                                    'response' => $eventResponse
5474                                )
5475                            );
5476                        }
5477
5478                        TblSendgridWebhook::create(
5479                            array(
5480                                'quotation_id' => $result[$i]->id,
5481                                'type' => 'followUps',
5482                                'json_body' => json_encode($jsonBody),
5483                                'x_message_id' => $messageId
5484                            )
5485                        );
5486
5487                        Log::channel('email_log')->info("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - EMAIL SENT');
5488                        $totalSent++;
5489                        $workingDays = 10;
5490                    } else {
5491                        $error = true;
5492                        array_push($totalErrorIds, $result[$i]->id);
5493                        Log::channel('email_failed_log')->error("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - ' . $response->body());
5494
5495                        foreach ($addTo as $addToEmail) {
5496                            TblFollowUpLogs::create(
5497                                array(
5498                                    'quotation_id' => $result[$i]->id,
5499                                    'email' => $addToEmail,
5500                                    'sent_by' => $sentBy,
5501                                    'status' => $response->body()
5502                                )
5503                            );
5504                        }
5505                    }
5506
5507                    $body = "";
5508                    $subject = "";
5509                }
5510            }
5511            Cache::flush();
5512
5513            Log::channel('send_email_follow_ups')->info(
5514                json_encode(
5515                    array(
5516                        "success" => $totalSentIds,
5517                        "failed" => $totalFailedIds,
5518                        "error" => $totalErrorIds
5519                    )
5520                )
5521            );
5522
5523            $this->update_commercial_numbers($companyId);
5524
5525            if($error){
5526                return response(['message' => 'KO']);
5527            }else{
5528
5529                if($automaticSendLimit != null){
5530                    TblOrdersUpdateLogs::create(
5531                        array(
5532                            'company_id' => $companyId,
5533                            'to_process' => 'Orders',
5534                            'status' => 'success',
5535                            'follow_ups_affected_rows' => $totalSent,
5536                            'processed_by' => $sentBy,
5537                            'started_at' => $startedAt,
5538                            'ended_at' => date('Y-m-d H:i:s')
5539                        )
5540                    );
5541                }
5542
5543                return response(['message' => 'OK', 'data' => $totalSent . ' ' . __('language.total_follow_up_sent')]);
5544            }
5545
5546        } catch (\Throwable $e) {
5547            Log::channel('email_failed_log')->error($e->getMessage());
5548            return response(['message' => 'KO', 'error' => $e->getMessage(), 'quotation_id' => $currentQuotationId]);
5549        }
5550    }
5551
5552    function create_sender_identity(Request $request){
5553
5554        try {
5555
5556            $data = $request->all();
5557            $sData = $data;
5558            $companyId = $data['company_id'];
5559            $createdBy = $data['created_by'];
5560            unset($data['company_id']);
5561            unset($data['created_by']);
5562
5563            $sender = TblCompanyEmails::where('from_email', $data['from_email'])->where('verified', 1)->count();
5564
5565            if($sender > 0){
5566                TblCompanyEmails::create($sData);
5567                return response(['message' => 'OK', 'data' => $data, 'is_verified' => 'yes']);
5568            }
5569
5570            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5571            $data['reply_to'] = $data['from_email'];
5572            $data['reply_to_name'] = $data['from_name'];
5573            $requestBody = $data;
5574            $error  = false;
5575
5576            $response = $sendgrid->client->verified_senders()->post($requestBody);
5577
5578            if ($response->statusCode() == 201) {
5579                $x = json_decode($response->body());
5580
5581                $data['company_id'] = $companyId;
5582                $data['created_by'] = $createdBy;
5583                $data['response_id'] = $x->id;
5584                TblCompanyEmails::create($data);
5585                Log::channel('email_log')->info('EMAIL: ' . $data['from_email'] . ' - VERIFICATION SENT');
5586            } else {
5587                $error = true;
5588                Log::channel('email_log')->error('REQUEST BODY: - ' . $response->body());
5589            }
5590
5591            $response = json_decode($response->body());
5592
5593            if($error){
5594                if($response->errors[0]->message == "already exists" && $response->errors[0]->field == "from_email"){
5595                    TblCompanyEmails::create($sData);
5596                    return response(['message' => 'OK', 'data' => $data, 'is_verified' => 'yes']);
5597                }
5598
5599                $errMessage = $response->errors[0]->field . ': ' . $response->errors[0]->message;
5600                return response(['message' => 'KO', 'error' => $errMessage]);
5601            }else{
5602                return response(['message' => 'OK', 'data' => $response, 'is_verified' => 'no']);
5603            }
5604
5605        } catch (\Exception $e) {
5606            Log::channel('email_log')->error('EMAIL:' . $data['from_email'] . ' - ' . $e->getMessage());
5607            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5608        }
5609    }
5610
5611    function get_sender_identity($companyId){
5612
5613        try {
5614
5615            $companyId = addslashes($companyId);
5616
5617            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5618
5619            $response = $sendgrid->client->verified_senders()->get();
5620
5621            if ($response->statusCode() == 200) {
5622                $x = json_decode($response->body())->results;
5623
5624                foreach ($x as $item) {
5625                    TblCompanyEmails::where('from_email', $item->from_email)->update(array(
5626                        'verified' => $item->verified,
5627                        'reply_to' => $item->reply_to,
5628                        'response_id' => $item->id
5629                    ));
5630                }
5631            }
5632
5633            $companyEmails = TblCompanyEmails::where('company_id', $companyId)->get();
5634
5635            return response(['message' => 'OK', 'data' => $companyEmails]);
5636
5637        } catch (\Exception $e) {
5638            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5639        }
5640    }
5641
5642    function get_all_sender_identity($companyId){
5643
5644        try {
5645
5646            $companyId = addslashes($companyId);
5647
5648            $query = "SELECT
5649                        id,
5650                        response_id,
5651                        nickname,
5652                        CONCAT(nickname, ' - ', from_email) from_email,
5653                        from_name,
5654                        reply_to,
5655                        reply_to_name,
5656                        address,
5657                        address2,
5658                        state,
5659                        city,
5660                        country,
5661                        zip,
5662                        verified,
5663                        locked,
5664                        is_active,
5665                        created_by,
5666                        created_at,
5667                        updated_by,
5668                        updated_at
5669                    FROM
5670                        tbl_company_emails
5671                    WHERE
5672                        company_id != {$companyId}
5673                        AND from_email NOT IN (
5674                        SELECT
5675                            from_email
5676                        FROM
5677                            tbl_company_emails
5678                        WHERE
5679                            company_id = {$companyId}
5680                        )
5681                    ";
5682
5683            $companyEmails = DB::select($query);
5684
5685            return response(['message' => 'OK', 'data' => $companyEmails]);
5686
5687        } catch (\Exception $e) {
5688            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5689        }
5690    }
5691
5692    function delete_sender_identity(Request $request){
5693
5694        try {
5695
5696            $data = $request->all();
5697            $responseId = addslashes($data['response_id']);
5698            $id = addslashes($data['id']);
5699
5700            $sender = TblCompanyEmails::where('response_id', $responseId)->count();
5701
5702            if($sender > 1){
5703                TblCompanyEmails::where('id', $id)->delete();
5704            }else{
5705                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5706
5707                $response = $sendgrid->client->verified_senders()->_($responseId)->delete();
5708
5709                if ($response->statusCode() == 204) {
5710                    TblCompanyEmails::where('response_id', $responseId)->delete();
5711                }
5712            }
5713
5714
5715            return response(['message' => 'OK']);
5716
5717        } catch (\Exception $e) {
5718            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5719        }
5720    }
5721
5722    function create_template(Request $request){
5723
5724        try {
5725
5726            $data = $request->all();
5727
5728            $files = $request->file('files');
5729            unset($data['files']);
5730
5731            if($files){
5732                $totalFileCount = count($files);
5733                if($totalFileCount > 2){
5734                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
5735                }
5736            }
5737
5738            $result = TblEmailConfiguration::create($data);
5739            $id = $result->id;
5740
5741            $directory = 'public/uploads';
5742            $origFilename = 'fireservicetitan.png';
5743            $file = 'public/uploads/fireservicetitan.png';
5744
5745            $sourcePath = public_path($origFilename);
5746            $destinationPath = 'public/uploads/' . $origFilename;
5747
5748            $filename = $id . '-EI' . time() . '-' . $origFilename;
5749
5750            Storage::putFileAs($directory, new \Illuminate\Http\File($sourcePath), $filename);
5751            Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5752
5753            TblEmailFiles::create(
5754                array(
5755                    'email_template_id' => $id,
5756                    'original_name' => $origFilename,
5757                    'filename' => $filename,
5758                    'uploaded_by' => $data['created_by']
5759                )
5760            );
5761
5762            if($files){
5763
5764                $uploadedFiles = [];
5765                $i = 0;
5766
5767                $combinedFilesSize = 0;
5768
5769                foreach ($files as $file) {
5770                    $i++;
5771
5772                    $origFilename = str_replace(" ", "", $file->getClientOriginalName());
5773
5774                    $filename = $id . '-EI' . time() . '-' . $origFilename;
5775
5776                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
5777
5778                    if($combinedFilesSize > 25000000){
5779                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
5780                    }
5781
5782                    Storage::putFileAs($directory, $file, $filename);
5783                    Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5784
5785                    if(in_array($origFilename, $uploadedFiles)){
5786                        $origFilename = $origFilename . $i;
5787                    }
5788
5789                    TblEmailFiles::create(
5790                        array(
5791                            'email_template_id' => $id,
5792                            'original_name' => $origFilename,
5793                            'filename' => $filename,
5794                            'uploaded_by' => $data['created_by']
5795                        )
5796                    );
5797
5798                    $uploadedFiles[] = $file->getClientOriginalName();
5799                }
5800            }
5801
5802            return response(['message' => 'OK']);
5803
5804        } catch (\Exception $e) {
5805            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5806        }
5807    }
5808
5809    function get_email_files($emailTemplateId){
5810
5811        try {
5812
5813            $emailTemplateId = addslashes($emailTemplateId);
5814
5815            $result = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
5816
5817            foreach ($result as $key => $value) {
5818                $path = storage_path('app/public/uploads/' . $result[$key]->filename);
5819
5820                if (File::exists($path)) {
5821                    $fileSizeBytes = File::size($path);
5822                    $result[$key]->filesize = $this->human_filesize($fileSizeBytes);
5823                    $result[$key]->original_name = $result[$key]->original_name . " ({$result[$key]->filesize})";
5824                    $result[$key]->img = "data:image/png;base64,".base64_encode(file_get_contents($path));
5825                }
5826            }
5827
5828            return response(['message' => 'OK', 'data' => $result]);
5829
5830        } catch (\Exception $e) {
5831            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5832        }
5833    }
5834
5835    function download_email_template_file($fileId){
5836
5837        try {
5838
5839            $fileId = addslashes($fileId);
5840
5841            $result = TblEmailFiles::where('file_id', $fileId)->first();
5842
5843            if($result){
5844                $path = storage_path('app/public/uploads/' . $result->filename);
5845
5846                if (!Storage::disk('public')->exists('uploads/' . $result->filename)) {
5847                    return response(['message' => 'KO']);
5848                }
5849
5850                return response()->download($path);
5851            }
5852
5853            return response(['message' => 'KO']);
5854
5855        } catch (\Exception $e) {
5856            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5857        }
5858
5859    }
5860
5861    function delete_email_template_file($fileId){
5862
5863        try {
5864
5865            $fileId = addslashes($fileId);
5866            $file = TblEmailFiles::where('file_id', $fileId)->first();
5867            $result = TblEmailFiles::where('file_id', $fileId)->first();
5868
5869            if($result){
5870                TblEmailFiles::where('file_id', $fileId)->delete();
5871                $path = storage_path('app/public/uploads/' . $result->filename);
5872                Storage::disk('public')->delete('uploads/' . $result->filename);
5873            }
5874
5875            return response(['message' => 'OK']);
5876
5877        } catch (\Exception $e) {
5878            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5879        }
5880    }
5881
5882    function update_email_template_order(Request $request, $id){
5883
5884        try {
5885
5886            $id = addslashes($id);
5887            $data = $request->all();
5888
5889            foreach ($data as $item) {
5890                TblEmailFiles::where('file_id', $item['file_id'])->update(array('order' => $item['order']));
5891            }
5892
5893        } catch (\Exception $e) {
5894            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5895        }
5896
5897    }
5898
5899
5900    function update_email_template(Request $request, $id){
5901
5902        try {
5903
5904            $data = $request->all();
5905
5906            $id = addslashes($id);
5907
5908            $files = $request->file('files');
5909            unset($data['files']);
5910
5911            $fileCount = TblEmailFiles::where('email_template_id', $id)->count();
5912
5913            if($files){
5914                $totalFileCount = $fileCount + count($files);
5915                if($totalFileCount > 3){
5916                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
5917                }
5918            }
5919
5920            if(isset($data['cron_default'])){
5921                TblEmailConfiguration::where('company_id', $data['company_id'])->where('cron_default', 1)->update(array('cron_default' => 0));
5922            }
5923
5924            $data['updated_at'] = date('Y-m-d H:i:s');
5925            TblEmailConfiguration::where('id', $id)->update($data);
5926
5927            if($files){
5928
5929                $directory = 'public/uploads';
5930                $uploadedFiles = [];
5931                $i = 0;
5932
5933                $combinedFilesSize = 0;
5934                foreach ($files as $file) {
5935                    $i++;
5936                    $origFilename = str_replace(" ", "", $file->getClientOriginalName());
5937                    $filename = $id . '-EI' . time() . '-' . $origFilename;
5938
5939                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
5940
5941                    if($combinedFilesSize > 25000000){
5942                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
5943                    }
5944
5945                    Storage::putFileAs($directory, $file, $filename);
5946                    Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5947
5948                    if(in_array($origFilename, $uploadedFiles)){
5949                        $origFilename = $origFilename . $i;
5950                    }
5951
5952                    TblEmailFiles::create(
5953                        array(
5954                            'email_template_id' => $id,
5955                            'original_name' => $origFilename,
5956                            'filename' => $filename,
5957                            'uploaded_by' => $data['updated_by']
5958                        )
5959                    );
5960
5961                    $uploadedFiles[] = $file->getClientOriginalName();
5962                }
5963            }
5964
5965            return response(['message' => 'OK']);
5966
5967        } catch (\Exception $e) {
5968            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5969        }
5970
5971    }
5972
5973    function delete_template($id){
5974
5975        try {
5976
5977            $id = addslashes($id);
5978
5979            TblEmailConfiguration::where('id', $id)->delete();
5980
5981            return response(['message' => 'OK']);
5982
5983        } catch (\Exception $e) {
5984            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5985        }
5986
5987    }
5988
5989    function get_email_template($companyId){
5990
5991        try {
5992
5993            $companyId = addslashes($companyId);
5994            
5995            $where = " a.company_id IN ({$this->companyId}";
5996
5997            $query = "SELECT
5998                        a.id,
5999                        a.from_id,
6000                        CASE
6001                            WHEN a.type = 'followUps' THEN 'Follow-ups'
6002                            WHEN a.type = 'sendToClient' THEN 'Send to client'
6003                        END types,
6004                        (SELECT from_email FROM tbl_company_emails WHERE id = a.from_id) from_email,
6005                        CASE WHEN {$companyId} = 0 THEN CONCAT(b.name, ' - ', a.name) ELSE a.name END `name`,
6006                        a.subject,
6007                        a.html,
6008                        a.is_active,
6009                        a.type,
6010                        a.created_by,
6011                        a.created_at,
6012                        a.updated_by,
6013                        a.updated_at,
6014                        a.cron_default
6015                    FROM tbl_email_configuration a
6016                    LEFT JOIN tbl_companies b
6017                        ON b.company_id = a.company_id
6018                    WHERE {$where}
6019                    ORDER BY a.id DESC";
6020
6021            $result = DB::select($query);
6022
6023            return response(['message' => 'OK', 'data' => $result]);
6024
6025        } catch (\Exception $e) {
6026            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6027        }
6028
6029    }
6030
6031    function update_sender_identity(Request $request, $responseId){
6032
6033        try {
6034
6035            $data = $request->all();
6036            $companyId = $data['company_id'];
6037            $updatedBy = $data['updated_by'];
6038            $active = $data['is_active'];
6039            $id = addslashes($data['id']);
6040            unset($data['id']);
6041            unset($data['company_id']);
6042            unset($data['updated_by']);
6043            unset($data['is_active']);
6044
6045            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
6046            $data['reply_to'] = $data['from_email'];
6047            $data['reply_to_name'] = $data['from_name'];
6048            $requestBody = $data;
6049            $error  = false;
6050
6051            $response = $sendgrid->client->verified_senders()->_($responseId)->patch($requestBody);
6052
6053            if ($response->statusCode() == 200) {
6054                $x = json_decode($response->body());
6055
6056                $data['updated_by'] = $updatedBy;
6057                $data['updated_at'] = date('Y-m-d H:i:s');
6058                $data['is_active'] = $active;
6059
6060                TblCompanyEmails::where('company_id', $companyId)->update(array('is_active' => 0));
6061                TblCompanyEmails::where('id', $id)->update($data);
6062
6063                Log::channel('email_log')->info('EMAIL: ' . $data['from_email'] . ' - UPDATED');
6064            } else {
6065                $error = true;
6066                Log::channel('email_log')->error('REQUEST BODY: - ' . $response->body());
6067            }
6068
6069            $response = json_decode($response->body());
6070
6071            if($error){
6072                $errMessage = @$response->errors[0]->field . ': ' . @$response->errors[0]->message;
6073                return response(['message' => 'KO', 'error' => $errMessage]);
6074            }else{
6075                return response(['message' => 'OK', 'data' => $response]);
6076            }
6077
6078        } catch (\Exception $e) {
6079            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6080        }
6081
6082    }
6083
6084    function resend_verification($id){
6085
6086        try {
6087
6088            $id = addslashes($id);
6089
6090            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
6091
6092            $response = $sendgrid->client->verified_senders()->resend()->_($id)->post();
6093
6094            if ($response->statusCode() == 204) {
6095                return response(['message' => 'OK']);
6096            }else{
6097                $response = json_decode($response->body());
6098                $errMessage = $response->errors[0]->error_id . ': ' . $response->errors[0]->message;
6099                return response(['message' => 'KO', 'error' => $errMessage]);
6100            }
6101
6102        } catch (\Exception $e) {
6103            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6104        }
6105    }
6106
6107    function list_quotation_analytics_by_performance(Request $request){
6108
6109        try {
6110
6111            $data = $request->all();
6112            $companyId = addslashes($data['company_id']);
6113            $where  = "";
6114
6115            if($companyId != 0){
6116                $where .= " AND company_id = {$companyId} AND for_add = 0 ";
6117            }else{
6118                $where .= " AND company_id IN ({$this->companyId}) AND for_add = 0 ";
6119            }
6120
6121            if(isset($data['budget_status']) && $data['budget_status'] != null){
6122                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
6123            }
6124
6125            $latestYear = TblQuotations::max(DB::raw('YEAR(issue_date)'));
6126            $md = date('m-d');
6127
6128            $query = "SELECT
6129                        q.years,
6130                        q.totalIssue,
6131                        (q.total_acceptance_percentage - q.totalAcceptancePercentage) / q.totalAcceptancePercentage * 100 totalAcceptancePercentage,
6132                        q.totalAccept
6133                    FROM
6134                        (
6135                        SELECT
6136                            YEAR(a.issue_date) years,
6137                            (b.total_issued - COUNT(a.issue_date)) / COUNT(a.issue_date) * 100 totalIssue,
6138                            COUNT(
6139                                CASE WHEN a.acceptance_date IS NOT NULL
6140                                AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6141                                AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6142                                AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6143                                AND a.budget_status_id = 3 THEN 1 END
6144                            ) / COUNT(a.issue_date) * 100 totalAcceptancePercentage,
6145                            b.total_acceptance_percentage,
6146                            (b.total_acceptance -
6147                                COUNT(
6148                                    CASE WHEN a.acceptance_date IS NOT NULL
6149                                    AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6150                                    AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6151                                    AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6152                                    AND a.budget_status_id = 3 THEN 1 END)
6153                                    ) / COUNT(
6154                                            CASE WHEN a.acceptance_date IS NOT NULL
6155                                            AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6156                                            AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6157                                            AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6158                                            AND a.budget_status_id = 3 THEN 1 END
6159                            ) * 100 totalAccept
6160                        FROM
6161                            tbl_quotations a
6162                            JOIN (
6163                            SELECT
6164                                YEAR(issue_date) current_year,
6165                                COUNT(issue_date) total_issued,
6166                                COUNT(
6167                                    CASE WHEN acceptance_date IS NOT NULL
6168                                    AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6169                                    AND CONCAT(YEAR(acceptance_date), '-{$md}')
6170                                    AND YEAR(acceptance_date) = YEAR(issue_date)
6171                                    AND budget_status_id = 3 THEN 1 END
6172                                ) total_acceptance,
6173                                COUNT(
6174                                    CASE WHEN acceptance_date IS NOT NULL
6175                                    AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6176                                    AND CONCAT(YEAR(acceptance_date), '-{$md}')
6177                                    AND YEAR(acceptance_date) = YEAR(issue_date)
6178                                    AND budget_status_id = 3 THEN 1 END
6179                                ) / COUNT(issue_date) * 100 total_acceptance_percentage
6180                            FROM
6181                                tbl_quotations
6182                            WHERE
6183                                issue_date IS NOT NULL
6184                                AND YEAR(issue_date) = {$latestYear}
6185                                AND DATE_FORMAT(issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(issue_date), '-01-01')
6186                                AND CONCAT(YEAR(issue_date), '-{$md}')
6187                                {$where}
6188                            GROUP by
6189                                1
6190                            ) b
6191                        WHERE
6192                            a.issue_date IS NOT NULL
6193                            AND a.budget_type_id != 7
6194                            AND a.budget_type_id IS NOT NULL
6195                            AND {$latestYear} > YEAR(a.issue_date)
6196                            AND DATE_FORMAT(a.issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.issue_date), '-01-01')
6197                            AND CONCAT(YEAR(a.issue_date), '-{$md}')
6198                        GROUP BY
6199                            1
6200                        ORDER BY
6201                            YEAR(issue_date) DESC
6202                        ) q
6203                    ";
6204
6205            $resultYtd = DB::select($query);
6206
6207            $query = "SELECT
6208                        YEAR(issue_date) years,
6209                        COUNT(issue_date) totalIssue,
6210                        COUNT(
6211                            CASE WHEN acceptance_date IS NOT NULL
6212                            AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6213                            AND CONCAT(YEAR(acceptance_date), '-{$md}')
6214                            AND YEAR(acceptance_date) = YEAR(issue_date)
6215                            AND budget_status_id = 3 THEN 1 END
6216                        ) totalAccept,
6217                        COUNT(
6218                            CASE WHEN acceptance_date IS NOT NULL
6219                            AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6220                            AND CONCAT(YEAR(acceptance_date), '-{$md}')
6221                            AND YEAR(acceptance_date) = YEAR(issue_date)
6222                            AND budget_status_id = 3 THEN 1 END
6223                        ) / COUNT(issue_date) * 100 totalAcceptancePercentage
6224                    FROM
6225                        tbl_quotations
6226                    WHERE
6227                        issue_date IS NOT NULL
6228                        AND budget_type_id != 7
6229                        AND budget_type_id IS NOT NULL
6230                        AND DATE_FORMAT(issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(issue_date), '-01-01')
6231                        AND CONCAT(YEAR(issue_date), '-{$md}')
6232                        {$where}
6233                    GROUP BY
6234                        1
6235                    ORDER BY
6236                        YEAR(issue_date) DESC
6237                    ";
6238
6239            $resultYears = DB::select($query);
6240
6241            return response(['message' => 'OK', 'ytdData' => $resultYtd, 'yearsData' => $resultYears]);
6242
6243        } catch (\Exception $e) {
6244            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6245        }
6246    }
6247
6248    function list_orders_update_logs($companyId){
6249
6250        try {
6251
6252            $where = "";
6253
6254            if($companyId != 0){
6255                $where .= " a.company_id = {$companyId}";
6256            }else{
6257                $where .= " a.company_id IN ({$this->companyId})";
6258            }
6259
6260            $query = "SELECT
6261                        a.id,
6262                        b.name company,
6263                        a.to_process,
6264                        a.rejected_affected_rows,
6265                        a.for_add_deleted_affected_rows,
6266                        a.month_change_affected_rows,
6267                        a.follow_ups_affected_rows,
6268                        a.sync_succesfull,
6269                        a.sync_error,
6270                        a.sync_error_message,
6271                        a.sync_success_ids,
6272                        a.cleared_email_errors,
6273                        a.remaining_email_errors,
6274                        CASE
6275                            WHEN a.rejected_affected_rows IS NOT NULL THEN a.rejected_affected_rows
6276                            WHEN a.for_add_deleted_affected_rows IS NOT NULL THEN a.for_add_deleted_affected_rows
6277                            WHEN a.month_change_affected_rows IS NOT NULL THEN a.month_change_affected_rows
6278                            WHEN a.follow_ups_affected_rows IS NOT NULL THEN a.follow_ups_affected_rows
6279                        END totals,
6280                        a.status,
6281                        a.processed_by,
6282                        a.started_at,
6283                        a.ended_at,
6284                        a.rejected_automatically_ids
6285                    FROM `tbl_orders_update_logs` a
6286                    LEFT JOIN tbl_companies b
6287                        ON a.company_id = b.company_id
6288                    WHERE {$where}
6289                    ORDER BY started_at DESC";
6290
6291            $result = DB::select($query);
6292
6293            return response(['message' => 'OK', 'data' => $result]);
6294
6295        } catch (\Exception $e) {
6296            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6297        }
6298
6299    }
6300
6301    function list_g3w_orders_update_logs($companyId){
6302
6303        try {
6304            $result = TblG3WOrdersUpdateLogs::where("company_id", $companyId)->get();
6305
6306            return response(['message' => 'OK', 'data' => $result]);
6307
6308        } catch (\Exception $e) {
6309            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6310        }
6311
6312    }
6313
6314    function update_budget_status_rejected_manual(Request $request){
6315
6316        try {
6317
6318            $data = $request->all();
6319
6320            $update = $this->update_budget_status_rejected($data['company_id'], $data['processed_by']);
6321
6322            if($update){
6323                return response(['message' => 'OK']);
6324            }else{
6325                return response(['message' => 'KO']);
6326            }
6327
6328        } catch (\Exception $e) {
6329            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6330        }
6331    }
6332
6333    function update_budget_status_rejected($companyId = null, $processedBy = "System"){
6334
6335        try {
6336
6337            $startedAt = date('Y-m-d H:i:s');
6338            $companyId = addslashes($companyId);
6339            $where = "";
6340
6341            $budgetTypes = TblBudgetTypes::get();
6342
6343            if(count($budgetTypes) > 0){
6344
6345                $companies = array();
6346
6347                if($companyId != 0){
6348                    $companies = TblCompanies::where('company_id', $companyId)->get();
6349                    $where = "AND company_id = {$companyId}";
6350                }else{
6351                    $companies = TblCompanies::get();
6352                }
6353
6354                for ($i = 0; $i < count($budgetTypes); $i++) {
6355
6356                    $days = $budgetTypes[$i]->duration;
6357                    $id = $budgetTypes[$i]->budget_type_id;
6358
6359                    if($days == null || $days == 0){
6360                        continue;
6361                    }
6362
6363                    for ($c = 0; $c < count($companies); $c++) {
6364                        $companyId = $companies[$c]->company_id;
6365
6366                        $query = "SELECT
6367                                    GROUP_CONCAT(id) ids
6368                                FROM
6369                                    tbl_quotations
6370                                WHERE
6371                                    budget_type_id = {$id}
6372                                AND budget_status_id IN (1, 2, 11)
6373                                AND DATEDIFF(NOW(), issue_date) >= {$days}
6374                                AND for_add = 0
6375                                {$where}";
6376
6377                        $result = DB::select($query);
6378
6379                        if(count($result) > 0){
6380
6381                            $ids = $result[0]->ids;
6382
6383                            if($ids != null || $ids != ""){
6384                                $query = "UPDATE
6385                                            tbl_quotations
6386                                        SET
6387                                            budget_status_id = 7
6388                                        WHERE
6389                                            id IN ({$ids})";
6390
6391                                DB::select($query);
6392
6393                                TblOrdersUpdateLogs::create(
6394                                    array(
6395                                        'company_id' => $companyId,
6396                                        'to_process' => 'Orders',
6397                                        'status' => 'success',
6398                                        'rejected_automatically_ids' => $ids,
6399                                        'processed_by' => $processedBy,
6400                                        'started_at' => $startedAt,
6401                                        'ended_at' => date('Y-m-d H:i:s')
6402                                    )
6403                                );
6404                            }
6405                        }
6406                    }
6407                }
6408            }
6409
6410            Cache::flush();
6411
6412            return response(['message' => 'OK']);
6413
6414        } catch (\Exception $e) {
6415
6416            TblOrdersUpdateLogs::create(
6417                array(
6418                    'company_id' => $companyId,
6419                    'to_process' => 'Orders',
6420                    'status' => $e->getMessage(),
6421                    'processed_by' => $processedBy,
6422                    'started_at' => $startedAt,
6423                    'ended_at' => date('Y-m-d H:i:s')
6424                )
6425            );
6426
6427            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6428        }
6429
6430    }
6431
6432    function bulk_update_quotation(Request $request){
6433
6434        // try {
6435
6436            $data = $request->all();
6437
6438            $r = new Request([
6439                'filterModel' => $data['filterModel'],
6440                'sortModel' => $data['sortModel'],
6441                'start' => 0,
6442                'end' => 999999999,
6443                'company_id' => $data['company_id'],
6444                'user_id' => $data['user_id'],
6445                'ids' => $data['ids'],
6446                'searchText' => $data['searchText'],
6447                'ids_not_in' => $data['ids_not_in']
6448            ]);
6449
6450            $listQuotations = $this->list_quotations($r);
6451            $d = $listQuotations->original['data'];
6452
6453            if(count($d) > 0){
6454                if(isset($data['last_follow_up_date']) && $data['last_follow_up_date'] == 1){
6455                    unset($data['last_follow_up_date']);
6456                }
6457                // unset($data['last_follow_up_date']);
6458                unset($data['filterModel']);
6459                unset($data['sortModel']);
6460                unset($data['start']);
6461                unset($data['end']);
6462                unset($data['company_id']);
6463                unset($data['user_id']);
6464                unset($data['ids']);
6465                unset($data['searchText']);
6466                unset($data['ids_not_in']);
6467
6468                $result = array();
6469                for ($i = 0; $i < count($d); $i++) {
6470                    array_push($result, $d[$i]->id);
6471                }
6472
6473                TblQuotations::whereIn('id', $result)->update($data);
6474
6475                Cache::flush();
6476            }
6477
6478            return response(['message' => 'OK', $data]);
6479
6480        // } catch (\Exception $e) {
6481        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
6482        // }
6483
6484    }
6485
6486    function move_budget_and_job(Request $request){
6487
6488        try {
6489
6490            $data = $request->all();
6491            $id = addslashes($data['id']);
6492            $companyId = addslashes($data['company_id']);
6493
6494            unset($data['id']);
6495            unset($data['company_id']);
6496
6497            $budget = TblQuotations::where('id', $id)->first();
6498
6499            $quotationId = $budget->id;
6500            $companyIdJob = $budget->company_id;
6501
6502            $query = "SELECT
6503                        COUNT(1) total
6504                    FROM tbl_company_users a
6505                    LEFT JOIN tbl_users b
6506                        ON a.user_id = b.id
6507                    WHERE a.company_id = {$companyId}
6508                    AND b.name = '{$budget->commercial}'
6509                    ORDER BY b.name ASC";
6510
6511            $result = DB::select($query);
6512
6513            $commercial = $budget->commercial;
6514
6515            if($result[0]->total == 0){
6516                $commercial = $data['created_by'];
6517            }
6518
6519            $r = new Request([
6520                'created_by' => $commercial,
6521            ]);
6522
6523            $result = $this->get_number($r, $companyId, 1);
6524            $newNumber = $result->original['number'];
6525
6526            TblQuotations::where('id', $id)->update(
6527                array(
6528                    'quote_id' => $newNumber,
6529                    'company_id' => $companyId,
6530                    'from_company_id' => $budget->company_id,
6531                    'commercial' => $commercial,
6532                )
6533            );
6534
6535            $job = TblOngoingJobs::where('quotation_id', $quotationId)->first();
6536
6537            $jobId = null;
6538
6539            if($job){
6540                $jobId = $job->id;
6541
6542                $query = "SELECT
6543                            COUNT(1) total
6544                        FROM tbl_company_users a
6545                        LEFT JOIN tbl_users b
6546                            ON a.user_id = b.id
6547                        WHERE a.company_id = {$companyId}
6548                        AND b.name = '{$job->responsible_for_work}'
6549                        ORDER BY b.name ASC";
6550
6551                $result = DB::select($query);
6552
6553                $responsibleForWork = $job->responsible_for_work;
6554
6555                if($result[0]->total == 0){
6556                    $responsibleForWork = $data['created_by'];
6557                }
6558
6559                TblOngoingJobs::where('quotation_id', $id)->update(
6560                    array(
6561                        'quote_id' => $newNumber,
6562                        'company_id' => $companyId,
6563                        'responsible_for_work' => $responsibleForWork,
6564                    )
6565                );
6566            }
6567
6568            Cache::flush();
6569
6570            return response([
6571                'message' => 'OK',
6572                'quotation_id' => $quotationId,
6573                'job_id' => $jobId
6574            ]);
6575
6576        } catch (\Exception $e) {
6577            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6578        }
6579    }
6580
6581    function list_quotation_analytics_by_types_of_budgets_created_per_week(Request $request){
6582
6583        try {
6584
6585            $data = $request->all();
6586            $companyId = addslashes($data['company_id']);
6587            $field = $data['field'];
6588
6589            $where = "";
6590            $whereYear = "";
6591            $dateLflArray = array();
6592            $companyIds = $this->companyIds;
6593
6594            if($companyId != 0){
6595                $companyIds = array($companyId);
6596            }
6597
6598            $acc = "";
6599            if($field == 'acceptance_date'){
6600                $acc = " AND q.acceptance_date IS NOT NULL ";
6601                // $field = 'created_at';
6602
6603                if(@$data['data_to_display'] == 4){
6604                    $field = 'created_at';
6605                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
6606                }
6607            }else{
6608                $field = 'created_at';
6609                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
6610            }
6611
6612            if(isset($data['years']) && $data['years'] != null){
6613                $years = implode(',', $data['years']);
6614                if(count($data['years']) > 0){
6615                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
6616                }
6617            }
6618
6619            foreach ($companyIds as $v) {
6620
6621                $lflWhere = " AND q.company_id = {$v} ";
6622
6623                $query = "SELECT
6624                            CONCAT(
6625                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
6626                                ' - ',
6627                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
6628                            ) AS date_like,
6629                            YEAR(q.{$field}) 'year',
6630                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
6631                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
6632                            {$v} 'company_id'
6633                        FROM
6634                            tbl_quotations q
6635                        WHERE
6636                            q.{$field} IS NOT NULL
6637                            AND q.for_add != 1
6638                            {$lflWhere}
6639                            {$whereYear}
6640                        GROUP BY YEAR(q.{$field})
6641                        ORDER BY YEAR(q.{$field}) DESC";
6642
6643                $dateLike = DB::select($query);
6644
6645                $dateLflArray[$v] = $dateLike;
6646            }
6647
6648            $isFy = true;
6649
6650            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
6651                $isFy = false;
6652                $ytdArray = array();
6653                $ytdAcceptanceArray = array();
6654                $lflCompanyIds = array();
6655                foreach ($dateLflArray as $k => $v) {
6656                    foreach ($dateLflArray[$k] as $item) {
6657                        $year = $item->year;
6658                        $now = date('m-d');
6659                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
6660                    }
6661
6662                    $ytdArray = implode(' OR ', $ytdArray);
6663                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
6664                    $ytdArray = array();
6665                }
6666
6667                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
6668                $where .= " AND ({$lflCompanyIds}";
6669            }
6670
6671            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
6672                $isFy = false;
6673                $lflArray = array();
6674                $ytdAcceptanceArray = array();
6675                $lflCompanyIds = array();
6676                foreach ($dateLflArray as $k => $v) {
6677                    foreach ($dateLflArray[$k] as $item) {
6678                        $year = $item->year;
6679                        $min_date_like = $item->min_date_like;
6680                        $max_date_like = $item->max_date_like;
6681                        array_push($lflArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}')");
6682                    }
6683
6684                    $lflArray = implode(' OR ', $lflArray);
6685                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
6686                    $lflArray = array();
6687                }
6688
6689                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
6690                $where .= " AND ({$lflCompanyIds}";
6691            }
6692
6693            if($isFy){
6694                if($companyId != 0){
6695                    $where .= " AND q.company_id = {$companyId} ";
6696                }else{
6697                    $where .= " AND q.company_id IN ({$this->companyId})";
6698                }
6699            }
6700
6701            if(isset($data['source']) && $data['source'] != null){
6702                $where .= " AND s.name = '{$data['source']}'";
6703            }
6704
6705            if(isset($data['month']) && $data['month'] != null){
6706                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
6707            }
6708
6709            if(isset($data['week']) && $data['week'] != null){
6710                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
6711            }
6712
6713            if(isset($data['commercial']) && $data['commercial'] != null){
6714                $where .= " AND q.commercial = '{$data['commercial']}'";
6715            }
6716
6717            if(isset($data['created_by']) && $data['created_by'] != null){
6718                $where .= " AND q.created_by = '{$data['created_by']}'";
6719            }
6720
6721            if(isset($data['budget_type']) && $data['budget_type'] != null){
6722                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
6723            }
6724
6725            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
6726                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
6727            }
6728
6729            if(isset($data['budget_status']) && $data['budget_status'] != null){
6730                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
6731            }
6732
6733            if(isset($data['client_type']) && $data['client_type'] != null){
6734                $where .= " AND ct.customer_type_id = {$data['client_type']}";
6735            }
6736
6737
6738            if(isset($data['segment_id']) && $data['segment_id'] != null){
6739                $where .= " AND q.segment_id = {$data['segment_id']}";
6740            }
6741
6742            $col = "1";
6743
6744            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
6745                if($data['data_to_display'] == 1){
6746                    $col = "1";
6747                }
6748
6749                if($data['data_to_display'] == 2){
6750                    $col = "q.amount";
6751                }
6752            }
6753
6754            $budgetTypes = TblBudgetTypes::orderByRaw("ISNULL(priority), priority ASC")->get();
6755            $cols = "";
6756            foreach ($budgetTypes as $item) {
6757                if($item->name == '' || $item->name == null){
6758                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} ELSE 0 END), 0) AS 'Otros'";
6759                }else{
6760                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN {$col} ELSE 0 END), 0) AS '{$item->name}'";
6761                }
6762            }
6763
6764            $budgetTypeGroups = TblBudgetTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
6765
6766            $colsGroups = ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} END), 0) AS Otros";
6767
6768            foreach ($budgetTypeGroups as $item) {
6769                $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6770                $colsGroups .= ",GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.id END) AS 'groupConcatIds{$budgetTypeGroupName}'";
6771                $colsGroups .= ",COALESCE(SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN {$col} END), 0) AS '{$budgetTypeGroupName}'";
6772            }
6773
6774            $colsGroups .= ",COALESCE(SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN {$col} END), 0) AS total";
6775
6776            $col = $colsGroups . $cols;
6777
6778            if(@$data['data_to_display'] == 3){
6779
6780                $cols = "";
6781                foreach ($budgetTypes as $item) {
6782                    if($item->name == '' || $item->name == null){
6783                        $cols .= ",COALESCE(
6784                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount ELSE 0 END) /
6785                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 ELSE 0 END) * 100 , 0
6786                                    ) AS 'Otros'";
6787                    }else{
6788                        $cols .= ",COALESCE(
6789                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN q.amount ELSE 0 END) /
6790                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN 1 ELSE 0 END), 0
6791                                    ) AS '{$item->name}'";
6792                    }
6793                }
6794
6795                $colsGroups = ",COALESCE(
6796                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount END)) /
6797                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 END))
6798                            , 0) Otros";
6799
6800                foreach ($budgetTypeGroups as $item) {
6801                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6802                    $colsGroups .= ",GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.id END) AS 'groupConcatIds{$budgetTypeGroupName}'";
6803                    $colsGroups .= ",COALESCE(
6804                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.amount END)) /
6805                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN 1 END))
6806                                    , 0) '{$budgetTypeGroupName}'";
6807                }
6808
6809                $colsGroups .= ",COALESCE(
6810                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.amount END)) /
6811                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END))
6812                                , 0) total";
6813
6814                $col = $colsGroups . $cols;
6815            }
6816
6817            if(@$data['data_to_display'] == 4){
6818
6819                $cols = "";
6820
6821                foreach ($budgetTypes as $item) {
6822
6823                    if($item->name == '' || $item->name == null){
6824                        $cols .= ",COALESCE(
6825                                        SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) /
6826                                        SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 ELSE 0 END) * 100 , 0
6827                                ) AS 'Otros'";
6828                    }else{
6829                        $cols .= ", COALESCE(
6830                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.acceptance_date IS NOT NULL THEN 1 END) /
6831                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.created_at IS NOT NULL THEN 1 END) * 100, 0
6832                                ) AS '{$item->name}'";
6833                    }
6834                }
6835
6836                $colsGroups = ",COALESCE(
6837                                    (SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 END)) /
6838                                    (SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 END)) * 100
6839                                    , 0) Otros";
6840
6841                foreach ($budgetTypeGroups as $item) {
6842                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6843                    $colsGroups .= ",GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.id END) AS 'groupConcatIds{$budgetTypeGroupName}'";
6844                    $colsGroups .= ",COALESCE(
6845                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) AND q.acceptance_date IS NOT NULL THEN 1 END)) /
6846                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) AND q.created_at IS NOT NULL THEN 1 END)) * 100
6847                                    , 0) '{$budgetTypeGroupName}'";
6848                }
6849
6850                $colsGroups .= ",COALESCE(
6851                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) AND q.acceptance_date IS NOT NULL THEN 1 END)) /
6852                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) AND q.created_at IS NOT NULL THEN 1 END)) * 100
6853                                    , 0) total";
6854
6855                $col = $colsGroups . $cols;
6856            }
6857
6858            $query  = "SELECT
6859                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
6860                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
6861                            LPAD(WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'week',
6862                            DATE_FORMAT(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY), '%W, %M %e') 'namedate',
6863                            GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.id END) groupConcatIds
6864                            {$col}
6865                        FROM
6866                            tbl_quotations q
6867                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
6868                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
6869                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
6870                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
6871                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
6872                        WHERE
6873                            q.{$field} IS NOT NULL
6874                            AND q.for_add != 1
6875                            AND q.budget_type_id IS NOT NULL
6876                            AND q.budget_type_id != 7
6877                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
6878                            AND q.acceptance_date != '0000-00-00 00:00:00'
6879                            {$where}
6880                            {$whereYear}
6881                        GROUP BY
6882                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
6883                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
6884                            WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) WITH ROLLUP
6885                        ORDER BY
6886                            YEAR DESC,
6887                            MONTH ASC,
6888                            WEEK ASC,
6889                            DATE_FORMAT(q.{$field}, '%e') ASC";
6890            // return $query;
6891            $result = DB::select($query);
6892
6893            $query = "SELECT
6894                        btg.budget_type_group_id,
6895                        btg.name,
6896                        (
6897                            SELECT
6898                                GROUP_CONCAT(COALESCE(bt.name, '') ORDER BY ISNULL(bt.priority), bt.priority ASC SEPARATOR '|')
6899                            FROM
6900                                tbl_budget_types bt
6901                            WHERE
6902                                bt.budget_type_group_id = btg.budget_type_group_id
6903                        ) budget_types
6904                        FROM
6905                            tbl_budget_type_groups btg
6906                        ORDER BY
6907                            ISNULL(btg.priority),
6908                            btg.priority ASC";
6909
6910            $budgetTypeGroups = DB::select($query);
6911
6912            foreach ($budgetTypeGroups as $item) {
6913                $item->group_key_name = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6914                $item->budget_types = explode("|", $item->budget_types);
6915            }
6916
6917            return response([
6918                'message' => 'OK',
6919                'data' => $result,
6920                'budgetTypeGroups' => $budgetTypeGroups
6921            ]);
6922
6923        } catch (\Exception $e) {
6924            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6925        }
6926    }
6927
6928    public function preview_file($id){
6929        
6930        try {
6931
6932            $file = TblFiles::where("file_id", $id)->first();
6933            
6934            if (!$file) {
6935                return response()->json([
6936                    'message' => 'KO',
6937                    'error' => __('language.file_not_found')
6938                ], 404);
6939            }                                
6940                        
6941            if (!Storage::disk('s3')->exists("uploads/" . $file->filename)) {                
6942                return response()->json(['message' => 'File not found'], 404);
6943            }
6944            
6945            $url = Storage::disk('s3')->temporaryUrl(
6946                "uploads/" . $file->filename,
6947                now()->addMinutes(5)
6948            );
6949
6950            return response()->json([
6951                'filename' => $file->filename,
6952                'url' => $url,
6953                'uploaded_by' => $file->uploaded_by,
6954                'uploaded_at' => $file->uploaded_at
6955            ]);
6956
6957        } catch (\Exception $e) {
6958            return response()->json([
6959                'message' => 'KO',
6960                'error' => $e->getMessage()
6961            ], 500);
6962        }
6963    }
6964
6965    function get_past_added_quotation(Request $request){
6966
6967        try {
6968
6969            $data = $request->all();
6970            $keyword = addslashes($data['keyword']);
6971            $result = array();
6972
6973            if(isset($keyword) && !empty($keyword)){
6974                $array = explode(' ', $keyword);
6975
6976                $where = "";
6977
6978                $availableParameters = array('client', 'email');
6979
6980                $searchTextArray = explode(" ", $keyword);
6981
6982                $searchArray = array();
6983                $matchScoreArray = array();
6984                foreach ($availableParameters as $field) {
6985                    foreach ($searchTextArray as $word) {
6986                        array_push($searchArray, "({$field} LIKE '%{$word}%')");
6987                        array_push($matchScoreArray, "CASE WHEN {$field} LIKE '%{$word}%' THEN 1 ELSE 0 END");
6988                    }
6989                }
6990
6991                $searchArray = implode(" OR ", $searchArray);
6992                $matchScoreArray = implode(" + ", $matchScoreArray);
6993                $matchScoreCol = "({$matchScoreArray})";
6994                $where .= " AND ({$searchArray}";
6995
6996                $query = "SELECT
6997                            id,
6998                            client,
6999                            segment_id,
7000                            CONCAT(`client`, ' - ', email) `client_email`,
7001                            email,
7002                            phone_number,
7003                            customer_type_id,
7004                            {$matchScoreCol} match_score
7005                        FROM tbl_quotations
7006                        WHERE for_add = 0
7007                        AND email IS NOT NULL AND phone_number IS NOT NULL
7008                        {$where}
7009                        GROUP BY client, email
7010                        ORDER BY match_score DESC, client ASC
7011                        ";
7012
7013                $result = DB::select($query);
7014            }
7015
7016            return response(['message' => 'OK', 'data' => $result]);
7017
7018        } catch (\Exception $e) {
7019            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7020        }
7021    }
7022
7023    function send_acceptance_notification($quotationId, $companyId, $userId, $updatedBy){
7024
7025        $budget = TblQuotations::where('id', $quotationId)->first();
7026
7027        if($budget != null){
7028            $to = TblToAcceptanceNotifications::where('company_id', $companyId)->get();
7029            $cc = TblCcAcceptanceNotifications::where('company_id', $companyId)->get();
7030
7031            if(count($to) > 0 && count($cc) > 0){
7032
7033                $company = TblCompanies::where('company_id', $companyId)->first();
7034
7035                $quoteId = $budget->quote_id;
7036                $amount = $this->currency($budget->amount, 1);
7037
7038                $url = env('URL') . "orders/{$quotationId}?company_id={$companyId}";
7039                $href = "<a href='{$url}'>{$quoteId}</a>";
7040
7041                $imgpath = File::get('fireservicetitan.png');
7042                $base64 = "data:image/png;base64,".base64_encode($imgpath);
7043
7044                $body = __('language.send_acceptance_notification.body_hello');
7045                $body .= __('language.send_acceptance_notification.body_message');
7046
7047                $body = str_replace('{{client}}', $budget->client, $body);
7048                $body = str_replace('{{username}}', $updatedBy, $body);
7049                $body = str_replace('{{company}}', $company->name, $body);
7050                $body = str_replace('{{amount}}', $amount, $body);
7051                $body = str_replace('{{quote_id}}', $href, $body);
7052
7053                $body .= "<p>Fire Service Titan</p>";
7054                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
7055
7056                $html = '<!DOCTYPE html>';
7057                $html .= '<html>';
7058                $html .= '<head>';
7059                $html .= '<meta charset="UTF-8">';
7060                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
7061                $html .= '</head>';
7062                $html .= '<body>';
7063                $html .= $body;
7064                $html .= '</body>';
7065                $html .= '</html>';
7066
7067
7068                $subject = __('language.send_acceptance_notification.subject');
7069                $subject = str_replace('{{quote_id}}', $quoteId, $subject);
7070
7071                $email = new \SendGrid\Mail\Mail();
7072
7073                $user = TblUsers::where('id', $userId)->first();
7074
7075                if(env('SENDGRID_STAGING')){
7076                    $email->addTo($user->email);
7077                }else{
7078
7079                    $emails = array();
7080
7081                    foreach ($to as $item) {
7082                        if(!in_array($item->email, $emails)){
7083                            array_push($emails, $item->email);
7084                            $email->addTo($item->email);
7085                        }
7086                    }
7087
7088                    foreach ($cc as $item) {
7089                        if(!in_array($item->email, $emails)){
7090                            array_push($emails, $item->email);
7091                            $email->addCc($item->email);
7092                        }
7093                    }
7094
7095                    $email->addCc($user->email);
7096                    array_push($emails, $user->email);
7097
7098                    $ccUser = TblUsers::where('name', $budget->commercial)->first();
7099
7100                    if($ccUser){
7101                        if(!in_array($ccUser->email, $emails)){
7102                            $email->addCc($ccUser->email);
7103                        }
7104                    }
7105                }
7106
7107                $email->setFrom('fire@fire.es', 'Fire Service Titan');
7108                $email->setSubject($subject);
7109                $email->addContent("text/html", $html);
7110
7111                $email->addAttachment(
7112                    $imgpath,
7113                    "image/png",
7114                    "fireservicetitan.png",
7115                    "inline",
7116                    "fireservicetitan"
7117                );
7118
7119                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
7120
7121                $response = $sendgrid->send($email);
7122                if ($response->statusCode() == 202) {
7123
7124                    $comment = "Email de aprobación automática enviada al equipo de opearciones el " . date('Y-m-d H:i:s');
7125                    $budget->last_follow_up_comment = $budget->last_follow_up_comment . "\n" . $comment;
7126
7127                    TblQuotations::where('id', $quotationId)->update(
7128                        array(
7129                            'last_follow_up_comment' => $budget->last_follow_up_comment
7130                        )
7131                    );
7132
7133                    Log::channel('email_log')->info('ID:' . $quoteId . ' - ACCEPTANCE EMAIL NOTIFICATION SENT');
7134                } else {
7135                    $error = true;
7136                    Log::channel('email_log')->error('ID:' . $quoteId . ' - ' . $response->body());
7137                }
7138
7139            }
7140        }
7141    }
7142
7143    function get_total_quotations_by_budget_status(Request $request){
7144
7145        try {
7146
7147            $data = $request->all();            
7148
7149            $companyId = addslashes($data['company_id']);
7150            
7151            $where = " AND a.company_id IN ({$this->companyId}";
7152            
7153            $user = null;
7154
7155            if(isset($data['commercial'])){
7156                if($data['commercial'] != 'All'){
7157                    $user = TblUsers::where('name', $data['commercial'])->first();
7158                }
7159            }else{
7160                $user = TblUsers::where('id', $this->userId)->first();
7161            }
7162
7163            $totalPendingFollowUps = 0;
7164            $totalRequestAndVisit = 0;
7165            $totalError = 0;
7166            $totalG3WError = 0;
7167
7168            $d = false;
7169
7170            if($user != null){
7171                $where .= " AND a.commercial = '{$user->name}";
7172                $d = true;
7173            }
7174
7175            if($data['commercial'] == 'All'){
7176                $d = true;
7177            }
7178
7179            if($d){
7180                $query = "SELECT
7181                            COUNT(DISTINCT a.id) total
7182                        FROM
7183                            tbl_quotations a
7184                            LEFT JOIN (
7185                                SELECT
7186                                a.id,
7187                                SUBSTRING_INDEX(
7188                                    SUBSTRING_INDEX(a.email, ',', n.digit + 1),
7189                                    ',',
7190                                    -1
7191                                ) AS email_domain
7192                                FROM
7193                                tbl_quotations a
7194                                INNER JOIN (
7195                                    SELECT
7196                                    0 AS digit
7197                                    UNION ALL
7198                                    SELECT
7199                                    1
7200                                    UNION ALL
7201                                    SELECT
7202                                    2
7203                                    UNION ALL
7204                                    SELECT
7205                                    3
7206                                    UNION ALL
7207                                    SELECT
7208                                    4
7209                                    UNION ALL
7210                                    SELECT
7211                                    5
7212                                    UNION ALL
7213                                    SELECT
7214                                    6
7215                                    UNION ALL
7216                                    SELECT
7217                                    7
7218                                    UNION ALL
7219                                    SELECT
7220                                    8
7221                                    UNION ALL
7222                                    SELECT
7223                                    9
7224                                ) n ON LENGTH(
7225                                    REPLACE(a.email, ',', '')
7226                                ) <= LENGTH(a.email)- n.digit
7227                                GROUP BY a.id
7228                            ) temp ON a.id = temp.id
7229                            LEFT JOIN tbl_companies b
7230                                ON a.company_id = b.company_id
7231                        WHERE
7232                            a.last_follow_up_date < NOW()
7233                            AND a.budget_status_id IN (2)
7234                            AND a.email IS NOT NULL
7235                            AND a.email <> ''
7236                            AND NOT EXISTS (
7237                                SELECT
7238                                1
7239                                FROM
7240                                tbl_blocked_domains bd
7241                                WHERE
7242                                temp.email_domain LIKE CONCAT('%', bd.domain, '%')
7243                                AND bd.company_id = a.company_id
7244                            )
7245                            AND a.last_follow_up_date IS NOT NULL
7246                            AND a.reason_for_not_following_up_id IS NULL
7247                            AND a.last_follow_up_date > 0
7248                            AND a.total_sent < b.limit_reminder_emails
7249                            AND a.for_add = 0 {$where}";
7250
7251                    $result = DB::select($query);
7252
7253                    $totalPendingFollowUps = $result[0]->total;
7254
7255                    $query = "SELECT
7256                                COUNT(1) total
7257                            FROM
7258                                tbl_quotations a
7259                            WHERE
7260                                a.budget_status_id IN (6, 8, 12)
7261                                {$where}
7262                            ";
7263
7264                    $result = DB::select($query);
7265
7266                    $totalRequestAndVisit = $result[0]->total;
7267
7268                    $query = "SELECT
7269                                COUNT(1) total
7270                            FROM
7271                                tbl_quotations a
7272                            WHERE
7273                                a.x_status LIKE '%Error%'
7274                                {$where}
7275                            ";
7276
7277                    $result = DB::select($query);
7278
7279                    $totalError = $result[0]->total;
7280
7281                    $query = "SELECT
7282                                COUNT(1) total
7283                                FROM
7284                                    tbl_quotations a
7285                                WHERE
7286                                    a.g3w_warning = 1
7287                                    AND a.sync_import = 1
7288                                    {$where}
7289                                ";
7290
7291                    $result = DB::select($query);
7292
7293                    $totalG3WError = $result[0]->total;
7294            }
7295
7296            return response([
7297                'message' => 'OK',
7298                'userId' => ($user) ? $user->id : null,
7299                'totalPendingFollowUps' => $totalPendingFollowUps,
7300                'totalRequestAndVisit' => $totalRequestAndVisit,
7301                'totalError' => $totalError,
7302                'totalG3WError' => $totalG3WError
7303            ]);
7304
7305
7306        } catch (\Exception $e) {
7307            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7308        }
7309
7310    }
7311
7312    function sendgrid_webhook_receiver(Request $request){
7313
7314        try {
7315
7316            $data = $request->all();
7317
7318            $jsonBody = array();
7319            $order = array();
7320            $orderEmails = array();
7321
7322            Log::channel('email_log')->info('WEBHOOK: ' . json_encode($data));
7323
7324            $quoteId = null;
7325
7326            foreach ($data as $item) {
7327                $matches = explode(".", $item['sg_message_id']);
7328                $messageId = $matches[0];
7329
7330                Log::channel('email_log')->info('MESSAGE-ID: ' . $messageId);
7331
7332                $result = TblSendgridWebhook::where('x_message_id', $messageId)->first();
7333                $quoteId = $result->quotation_id;
7334                Log::channel('email_log')->info('SENDGRID-BODY: ' . json_encode($result));
7335
7336                if(empty($order)){
7337                    $order = TblQuotations::where('x_message_id', $messageId)->first();
7338                    $quoteId = $order->id;
7339                    // if(env('SENDGRID_STAGING')){
7340                    //     $user = TblUsers::where('name', $order->updated_by)->first();
7341
7342                    //     $orderEmails = array($user->email);
7343                    // }else{
7344                        $orderEmails = explode(",", $order->email);
7345                    // }
7346                }
7347
7348                // if(in_array($item['email'], $orderEmails)){
7349                    if($result->json_body == null){
7350                        array_push($jsonBody, $item);
7351                    }else{
7352                        $jsonBody = json_decode($result->json_body);
7353                        array_push($jsonBody, $item);
7354                    }
7355                // }
7356
7357                Log::channel('email_log')->info('JSON-BODY: ' . json_encode($jsonBody));
7358
7359                TblSendgridWebhook::where('x_message_id', $messageId)->update(
7360                    array(
7361                        'json_body' => json_encode($jsonBody),
7362                        'updated_at' => date('Y-m-d H:i:s')
7363                    )
7364                );
7365
7366                if($quoteId != null){
7367                    $this->get_files($quoteId);
7368                }
7369
7370                Cache::flush();
7371            }
7372
7373        } catch (\Exception $e) {
7374            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7375        }
7376
7377    }
7378
7379    function isEmailValid($email) {
7380        // Regular expression pattern for email validation
7381        $pattern = '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/';
7382
7383        // Check if the email matches the pattern
7384        if (preg_match($pattern, $email)) {
7385            return true; // Valid email
7386        } else {
7387            return false; // Invalid email
7388        }
7389    }
7390
7391    function list_email_status($companyId){
7392
7393        try {
7394
7395            $companyId = addslashes($companyId);
7396
7397            $where = " company_id IN ({$this->companyId})";
7398
7399            $query = "SELECT DISTINCT x_status FROM tbl_quotations WHERE {$where} AND x_status IS NOT NULL";
7400            $result = DB::select($query);
7401
7402            return response([
7403                'message' => 'OK',
7404                'data' => $result,
7405            ]);
7406
7407
7408        } catch (\Exception $e) {
7409            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7410        }
7411
7412    }
7413
7414    function list_quotation_analytics_commercial(Request $request){
7415
7416        try {
7417
7418            $data = $request->all();
7419            $companyId = addslashes($data['company_id']);
7420            $field = $data['field'];
7421
7422            $where = "";
7423            $whereYear = "";
7424            $dateLflArray = array();
7425            $companyIds = $this->companyIds;
7426            $whereQ = "";
7427
7428            $acc = "";
7429            if($field == 'acceptance_date'){
7430                $acc = " AND q.acceptance_date IS NOT NULL ";
7431                // $field = 'created_at';
7432
7433                if(@$data['data_to_display'] == 4){
7434                    $field = 'created_at';
7435                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7436                    $whereQ .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7437                }
7438            }else{
7439                $field = 'created_at';
7440                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7441                $whereQ .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7442            }
7443
7444            if(isset($data['years']) && $data['years'] != null){
7445                $years = implode(',', $data['years']);
7446                if(count($data['years']) > 0){
7447                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
7448                }
7449            }
7450
7451            if($companyId != 0){
7452                $companyIds = array($companyId);
7453            }
7454
7455            foreach ($companyIds as $v) {
7456
7457                $lflWhere = " AND q.company_id = {$v} ";
7458
7459                $query = "SELECT
7460                            CONCAT(
7461                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
7462                                ' - ',
7463                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
7464                            ) AS date_like,
7465                            YEAR(q.{$field}) 'year',
7466                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
7467                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
7468                            {$v} 'company_id'
7469                        FROM
7470                            tbl_quotations q
7471                        WHERE
7472                            q.{$field} IS NOT NULL
7473                            AND q.for_add != 1
7474                            {$lflWhere}
7475                            {$whereYear}
7476                        GROUP BY YEAR(q.{$field})
7477                        ORDER BY YEAR(q.{$field}) DESC";
7478
7479                $dateLike = DB::select($query);
7480
7481                $dateLflArray[$v] = $dateLike;
7482            }
7483
7484            $isFy = true;
7485
7486            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
7487                $isFy = false;
7488                $ytdArray = array();
7489                $ytdAcceptanceArray = array();
7490                $lflCompanyIds = array();
7491                foreach ($dateLflArray as $k => $v) {
7492                    foreach ($dateLflArray[$k] as $item) {
7493                        $year = $item->year;
7494                        $now = date('m-d');
7495                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
7496                    }
7497
7498                    $ytdArray = implode(' OR ', $ytdArray);
7499                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
7500                    $ytdArray = array();
7501                }
7502
7503                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7504                $where .= " AND ({$lflCompanyIds}";
7505                $whereQ .= " AND ({$lflCompanyIds}";
7506            }
7507
7508            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
7509                $isFy = false;
7510                $lflArray = array();
7511                $ytdAcceptanceArray = array();
7512                $lflCompanyIds = array();
7513                foreach ($dateLflArray as $k => $v) {
7514                    foreach ($dateLflArray[$k] as $item) {
7515                        $year = $item->year;
7516                        $min_date_like = $item->min_date_like;
7517                        $max_date_like = $item->max_date_like;
7518                        array_push($lflArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}')");
7519                    }
7520
7521                    $lflArray = implode(' OR ', $lflArray);
7522                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
7523                    $lflArray = array();
7524                }
7525
7526                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7527                $where .= " AND ({$lflCompanyIds}";
7528                $whereQ .= " AND ({$lflCompanyIds}";
7529            }
7530
7531            if($isFy){
7532                if($companyId != 0){
7533                    $where .= " AND q.company_id = {$companyId} ";
7534                    $whereQ .= " AND q.company_id = {$companyId} ";
7535                }else{
7536                    $where .= " AND q.company_id IN ({$this->companyId})";
7537                    $whereQ .= " AND q.company_id IN ({$this->companyId})";
7538                }
7539            }
7540
7541            if(isset($data['source']) && $data['source'] != null){
7542                $where .= " AND s.name = '{$data['source']}'";
7543            }
7544
7545            if(isset($data['month']) && $data['month'] != null){
7546                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
7547            }
7548
7549            if(isset($data['week']) && $data['week'] != null){
7550                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
7551            }
7552
7553            if(isset($data['commercial']) && $data['commercial'] != null){
7554                $where .= " AND q.commercial = '{$data['commercial']}'";
7555            }
7556
7557            if(isset($data['created_by']) && $data['created_by'] != null){
7558                $where .= " AND q.created_by = '{$data['created_by']}'";
7559            }
7560
7561            if(isset($data['budget_type']) && $data['budget_type'] != null){
7562                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
7563            }
7564
7565            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
7566                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
7567            }
7568
7569            if(isset($data['budget_status']) && $data['budget_status'] != null){
7570                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
7571            }
7572
7573            if(isset($data['client_type']) && $data['client_type'] != null){
7574                $where .= " AND ct.customer_type_id = {$data['client_type']}";
7575            }
7576
7577            if(isset($data['segment_id']) && $data['segment_id'] != null){
7578                $where .= " AND q.segment_id = {$data['segment_id']}";
7579            }
7580
7581            $col = "1";
7582
7583            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
7584                if($data['data_to_display'] == 1){
7585                    $col = "1";
7586                }
7587
7588                if($data['data_to_display'] == 2){
7589                    $col = "q.amount";
7590                }
7591            }
7592
7593            $query = "SELECT
7594                        q.commercial 'name',
7595                        COUNT(q.commercial) totalCommercial
7596                    FROM tbl_quotations q
7597                    WHERE
7598                        q.for_add = 0
7599                        AND q.{$field} IS NOT NULL
7600                        {$whereQ}
7601                    GROUP BY q.commercial
7602                    HAVING COUNT(q.commercial) > 0
7603                    ORDER BY totalCommercial DESC";
7604
7605            $resultCommercials = DB::select($query);
7606
7607            $now = TblQuotations::whereIn('company_id', $this->companyIds)->orderBy($field, 'DESC')->pluck($field)->first();
7608            $weekNumber = date('W', strtotime($now));
7609            $thisWeek = date('Y-m-d', strtotime($now . " - " . (date('N', strtotime($now)) - 1) . " days"));
7610
7611            $query = "SELECT
7612                        q.commercial 'name',
7613                        COUNT(q.commercial) totalCommercial
7614                    FROM tbl_quotations q
7615                    WHERE
7616                        q.for_add = 0
7617                        AND q.{$field} IS NOT NULL
7618                        AND YEARWEEK(q.{$field}, 1) = YEARWEEK(NOW(), 1)
7619                        {$whereQ}
7620                    GROUP BY q.commercial
7621                    HAVING COUNT(q.commercial) > 0
7622                    ORDER BY totalCommercial DESC";
7623
7624            $resultCommercialsOrder = DB::select($query);
7625
7626            $namesToRemove = array();
7627
7628            foreach ($resultCommercialsOrder as $item) {
7629                $namesToRemove[$item->name] = true;
7630            }
7631
7632            $resultArray = [];
7633            foreach ($resultCommercials as $item) {
7634                if (!isset($namesToRemove[$item->name])) {
7635                    $resultArray[] = $item;
7636                }
7637            }
7638
7639            $resultCommercials = array_merge($resultCommercialsOrder, $resultArray);
7640
7641            $cols = "";
7642
7643            $colsGroupConcatIds = "";
7644
7645            foreach ($resultCommercials as $item) {
7646                $cols .= ",COALESCE(
7647                    SUM(
7648                        CASE WHEN q.commercial = '{$item->name}' AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) {$acc} THEN {$col} ELSE 0 END
7649                    ), 0
7650                ) '{$item->name}'";
7651
7652                $colsGroupConcatIds .= ",GROUP_CONCAT(CASE WHEN q.commercial = '{$item->name}' AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.id END) 'groupConcatIds-{$item->name}'";
7653            }
7654
7655            $cols .= ",COALESCE(
7656                SUM(
7657                    CASE WHEN q.commercial IS NOT NULL AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) {$acc} THEN {$col} ELSE 0 END
7658                ), 0
7659            ) total";
7660
7661            if(@$data['data_to_display'] == 3){
7662
7663                $cols = "";
7664
7665                foreach ($resultCommercials as $item) {
7666                    $cols .= ",COALESCE(
7667                        (
7668                            SUM(CASE WHEN q.commercial = '{$item->name}' AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.amount END)
7669                        ) /
7670                        (
7671                            SUM(CASE WHEN q.commercial = '{$item->name}' AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END)
7672                        )
7673                    , 0) '{$item->name}'";
7674                }
7675
7676                $cols .= ",COALESCE(
7677                    (
7678                        SUM(CASE WHEN q.commercial IS NOT NULL AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) {$acc}  THEN q.amount END)
7679                    ) /
7680                    (
7681                        SUM(CASE WHEN q.commercial IS NOT NULL AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END)
7682                    )
7683                , 0) total";
7684            }
7685
7686            if(@$data['data_to_display'] == 4){
7687
7688                $cols = "";
7689
7690                foreach ($resultCommercials as $item) {
7691                    $cols .= ",COALESCE(
7692                        (
7693                            SUM(CASE WHEN q.commercial = '{$item->name}' AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) AND q.acceptance_date IS NOT NULL THEN 1 END)
7694                        ) /
7695                        (
7696                            SUM(CASE WHEN q.commercial = '{$item->name}' AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) AND q.created_at IS NOT NULL THEN 1 END)
7697                        ) * 100
7698                    , 0) '{$item->name}'";
7699                }
7700
7701                $cols .= ",COALESCE(
7702                    (
7703                        SUM(CASE WHEN q.commercial IS NOT NULL AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) AND q.acceptance_date IS NOT NULL THEN 1 END)
7704                    ) /
7705                    (
7706                        SUM(CASE WHEN q.commercial IS NOT NULL AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) AND q.created_at IS NOT NULL THEN 1 END)
7707                    ) * 100
7708                , 0) total";
7709            }
7710
7711            $query  = "SELECT
7712                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
7713                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
7714                            LPAD(WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'week',
7715                            DATE_FORMAT(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY), '%W, %M %e') 'namedate',
7716                            GROUP_CONCAT(
7717                                CASE WHEN q.{$field} IS NOT NULL
7718                                THEN q.id END
7719                            ) AS groupConcatIds
7720                            {$colsGroupConcatIds}
7721                            {$cols}
7722                        FROM
7723                            tbl_quotations q
7724                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
7725                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
7726                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
7727                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
7728                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
7729                        WHERE
7730                            q.{$field} IS NOT NULL
7731                            AND q.for_add != 1
7732                            AND q.budget_type_id != 7
7733                            AND q.budget_type_id IS NOT NULL
7734                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
7735                            {$where}
7736                            {$whereYear}
7737                        GROUP BY
7738                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
7739                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
7740                            WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) WITH ROLLUP
7741                        ORDER BY
7742                            YEAR DESC,
7743                            MONTH ASC,
7744                            WEEK ASC,
7745                            DATE_FORMAT(q.{$field}, '%e') ASC";
7746
7747            $value = Cache::get(base64_encode($query));
7748
7749            if(!$value){
7750                $result = DB::select($query);
7751
7752                Cache::put(base64_encode($query), $result, 600);
7753            }else{
7754                $result = $value;
7755            }
7756
7757            return response([
7758                'message' => 'OK',
7759                'data' => $result,
7760                'commercials' => $resultCommercials
7761            ]);
7762
7763        } catch (\Exception $e) {
7764            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7765        }
7766    }
7767
7768    function clear_open_data($companyId){
7769
7770        try {
7771
7772            $companyIds = array($companyId);
7773            if($companyId == 0){
7774                $companyIds = $this->companyIds;
7775            }
7776
7777            $user = TblUsers::where('id', $this->userId)->first();
7778
7779            if(count($companyIds) > 0){
7780
7781                foreach ($companyIds as $id) {
7782                    $startedAt = date('Y-m-d H:i:s');
7783                    $affectedRows = DB::delete("DELETE FROM tbl_quotations WHERE company_id = {$id} AND for_add = 1 AND DATE_FORMAT(created_at, '%Y-%m-%d') != DATE_FORMAT(NOW(), '%Y-%m-%d')");
7784
7785                    TblOrdersUpdateLogs::create(
7786                        array(
7787                            'company_id' => $id,
7788                            'to_process' => 'Orders',
7789                            'status' => 'success',
7790                            'for_add_deleted_affected_rows' => $affectedRows,
7791                            'processed_by' => $user->name,
7792                            'started_at' => $startedAt,
7793                            'ended_at' => date('Y-m-d H:i:s')
7794                        )
7795                    );
7796                }
7797            }
7798
7799            return response([
7800                'message' => 'OK',
7801            ]);
7802
7803        } catch (\Exception $e) {
7804            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7805        }
7806
7807    }
7808
7809    function list_quotation_analytics_order_size(Request $request){
7810
7811        try {
7812
7813            $data = $request->all();
7814            $companyId = addslashes($data['company_id']);
7815            $field = $data['field'];
7816
7817            $where = "";
7818            $dateLflArray = array();
7819            $whereYear = "";
7820            $companyIds = $this->companyIds;
7821
7822            if($field == 'acceptance_date'){
7823                if(@$data['data_to_display'] == 4){
7824                    $field = 'created_at';
7825                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7826                }
7827            }else{
7828                $field = 'created_at';
7829                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7830            }
7831
7832            if(isset($data['years']) && $data['years'] != null){
7833                $years = implode(',', $data['years']);
7834                if(count($data['years']) > 0){
7835                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
7836                }
7837            }
7838
7839            if($companyId != 0){
7840                $companyIds = array($companyId);
7841            }
7842
7843            foreach ($companyIds as $v) {
7844
7845                $lflWhere = " AND q.company_id = {$v} ";
7846
7847                $query = "SELECT
7848                            CONCAT(
7849                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
7850                                ' - ',
7851                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
7852                            ) AS date_like,
7853                            YEAR(q.{$field}) 'year',
7854                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
7855                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
7856                            {$v} 'company_id'
7857                        FROM
7858                            tbl_quotations q
7859                        WHERE
7860                            q.{$field} IS NOT NULL
7861                            AND q.for_add != 1
7862                            {$lflWhere}
7863                            {$whereYear}
7864                        GROUP BY YEAR(q.{$field})
7865                        ORDER BY YEAR(q.{$field}) DESC";
7866
7867                $dateLike = DB::select($query);
7868
7869                $dateLflArray[$v] = $dateLike;
7870            }
7871
7872            $isFy = true;
7873
7874            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
7875                $isFy = false;
7876                $ytdArray = array();
7877                $ytdAcceptanceArray = array();
7878                $lflCompanyIds = array();
7879                foreach ($dateLflArray as $k => $v) {
7880                    foreach ($dateLflArray[$k] as $item) {
7881                        $year = $item->year;
7882                        $now = date('m-d');
7883                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
7884                    }
7885
7886                    $ytdArray = implode(' OR ', $ytdArray);
7887                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
7888                    $ytdArray = array();
7889                }
7890
7891                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7892                $where .= " AND ({$lflCompanyIds}";
7893            }
7894
7895            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
7896                $isFy = false;
7897                $lflArray = array();
7898                $ytdAcceptanceArray = array();
7899                $lflCompanyIds = array();
7900                foreach ($dateLflArray as $k => $v) {
7901                    foreach ($dateLflArray[$k] as $item) {
7902                        $year = $item->year;
7903                        $min_date_like = $item->min_date_like;
7904                        $max_date_like = $item->max_date_like;
7905                        array_push($lflArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}')");
7906                    }
7907
7908                    $lflArray = implode(' OR ', $lflArray);
7909                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
7910                    $lflArray = array();
7911                }
7912
7913                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7914                $where .= " AND ({$lflCompanyIds}";
7915            }
7916
7917            if($isFy){
7918                if($companyId != 0){
7919                    $where .= " AND q.company_id = {$companyId} ";
7920                }else{
7921                    $where .= " AND q.company_id IN ({$this->companyId})";
7922                }
7923            }
7924
7925            if(isset($data['source']) && $data['source'] != null){
7926                $where .= " AND s.name = '{$data['source']}'";
7927            }
7928
7929            if(isset($data['source']) && $data['source'] != null){
7930                $where .= " AND s.name = '{$data['source']}'";
7931            }
7932
7933            if(isset($data['commercial']) && $data['commercial'] != null){
7934                $where .= " AND q.commercial = '{$data['commercial']}'";
7935            }
7936
7937            if(isset($data['created_by']) && $data['created_by'] != null){
7938                $where .= " AND q.created_by = '{$data['created_by']}'";
7939            }
7940
7941            if(isset($data['budget_type']) && $data['budget_type'] != null){
7942                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
7943            }
7944
7945            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
7946                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
7947            }
7948
7949            if(isset($data['budget_status']) && $data['budget_status'] != null){
7950                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
7951            }
7952
7953            if(isset($data['client_type']) && $data['client_type'] != null){
7954                $where .= " AND ct.customer_type_id = {$data['client_type']}";
7955            }
7956
7957            if(isset($data['segment_id']) && $data['segment_id'] != null){
7958                $where .= " AND q.segment_id = {$data['segment_id']}";
7959            }
7960
7961            $col = "q.one";
7962
7963            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
7964                if($data['data_to_display'] == 1){
7965                    $col = "q.one";
7966                }
7967
7968                if($data['data_to_display'] == 2){
7969                    $col = "q.amount";
7970                }
7971            }
7972
7973            if((isset($data['start_date']) && $data['start_date'] != null) && isset($data['end_date']) && $data['end_date'] != null){
7974                $where .= " AND q.{$field} BETWEEN '{$data['start_date']}' AND '{$data['end_date']}";
7975            }elseif((isset($data['start_date']) && $data['start_date'] == null || $data['start_date'] == "") && isset($data['end_date']) && $data['end_date'] != null){
7976                $where .= " AND q.{$field} = '{$data['end_date']}";
7977            }
7978
7979            $whereQ = $where;
7980
7981            $sortBy = array(
7982                0 => 'q.amount < 100',
7983                1 => 'q.amount BETWEEN 100 AND 500',
7984                2 => 'q.amount BETWEEN 500 AND 2000',
7985                3 => 'q.amount BETWEEN 2000 AND 10000',
7986                4 => 'q.amount BETWEEN 10000 AND 30000',
7987                5 => 'q.amount BETWEEN 30000 AND 100000',
7988                6 => 'q.amount BETWEEN 100000 AND 999999999999'
7989            );
7990
7991            $query = "SELECT
7992                        q.commercial 'name',
7993                        COUNT(q.commercial) totalCommercial
7994                    FROM tbl_quotations q
7995                    LEFT JOIN tbl_sources s ON s.source_id = q.source_id
7996                    LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
7997                    LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
7998                    LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
7999                    WHERE
8000                        q.for_add = 0
8001                        AND q.{$field} IS NOT NULL
8002                        AND q.for_add != 1
8003                        AND q.budget_type_id != 7
8004                        AND q.budget_type_id IS NOT NULL
8005                        {$whereQ}
8006                        {$whereYear}
8007                    GROUP BY q.commercial
8008                    HAVING COUNT(q.commercial) > 0
8009                    ORDER BY totalCommercial DESC";
8010
8011            $resultCommercials = DB::select($query);
8012
8013            if(isset($data['sort_by'])){
8014                if($data['sort_by'] != 7){
8015                    $s = $sortBy[$data['sort_by']];
8016                    $whereQ .= " AND {$s} ";
8017                }
8018            }
8019
8020            $num = "COUNT(1)";
8021
8022            if(@$data['data_to_display'] == 2){
8023                $num = "SUM(q.amount)";
8024            }
8025
8026            if(@$data['data_to_display'] == 3){
8027                $num = "SUM(q.amount) / COUNT(1)";
8028            }
8029
8030            if(@$data['data_to_display'] == 4){
8031                $num = "(SUM(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) / COUNT(q.created_at) * 100)";
8032            }
8033
8034            $query = "SELECT
8035                    q.commercial 'name',
8036                    COUNT(q.commercial) totalCommercial,
8037                    {$num} num
8038                FROM tbl_quotations q
8039                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8040                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8041                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8042                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8043                WHERE
8044                    q.for_add = 0
8045                    AND q.{$field} IS NOT NULL
8046                    AND q.for_add != 1
8047                    AND q.budget_type_id != 7
8048                    AND q.budget_type_id IS NOT NULL
8049                    {$whereQ}
8050                    {$whereYear}
8051                GROUP BY q.commercial
8052                HAVING COUNT(q.commercial) > 0
8053                ORDER BY num DESC";
8054
8055            $resultCommercialsOrder = DB::select($query);
8056
8057            foreach ($resultCommercialsOrder as $item) {
8058                $namesToRemove[$item->name] = true;
8059            }
8060
8061            $resultArray = [];
8062            foreach ($resultCommercials as $item) {
8063                if (!isset($namesToRemove[$item->name])) {
8064                    $resultArray[] = $item;
8065                }
8066            }
8067
8068            $resultCommercials = array_merge($resultCommercialsOrder, $resultArray);
8069
8070            $cols = "";
8071
8072            $colsGroupConcatIds = "";
8073
8074            foreach ($resultCommercials as $item) {
8075                $cols .= ",COALESCE(
8076                    SUM(
8077                        CASE WHEN q.commercial = '{$item->name}' THEN {$col} ELSE 0 END
8078                    ), 0
8079                ) '{$item->name}'";
8080
8081                $colsGroupConcatIds .= ",GROUP_CONCAT(CASE WHEN q.commercial = '{$item->name}' THEN q.id END) 'groupConcatIds-{$item->name}'";
8082            }
8083
8084            $cols .= ",COALESCE(
8085                SUM(
8086                    CASE WHEN q.commercial IS NOT NULL THEN {$col} ELSE 0 END
8087                ), 0
8088            ) total";
8089
8090            $range = "CASE
8091                        WHEN amount < 100 THEN '< 100€'
8092                        WHEN amount BETWEEN 100 AND 500 THEN '100€ - 500€'
8093                        WHEN amount BETWEEN 500 AND 2000 THEN '500€ - 2k€'
8094                        WHEN amount BETWEEN 2000 AND 10000 THEN '2k€ - 10k€'
8095                        WHEN amount BETWEEN 10000 AND 30000 THEN '10k€ - 30k€'
8096                        WHEN amount BETWEEN 30000 AND 100000 THEN '30k€ - 100k€'
8097                        WHEN amount BETWEEN 100000 AND 999999999999 THEN '> 100k€'
8098                    END AS amount_range";
8099
8100            if(@$data['data_to_display'] == 3){
8101
8102                $range = "CASE
8103                            WHEN SUM(amount) / COUNT(1) < 100 THEN '< 100€'
8104                            WHEN SUM(amount) / COUNT(1) BETWEEN 100 AND 500 THEN '100€ - 500€'
8105                            WHEN SUM(amount) / COUNT(1) BETWEEN 500 AND 2000 THEN '500€ - 2k€'
8106                            WHEN SUM(amount) / COUNT(1) BETWEEN 2000 AND 10000 THEN '2k€ - 10k€'
8107                            WHEN SUM(amount) / COUNT(1) BETWEEN 10000 AND 30000 THEN '10k€ - 30k€'
8108                            WHEN SUM(amount) / COUNT(1) BETWEEN 30000 AND 100000 THEN '30k€ - 100k€'
8109                            WHEN SUM(amount) / COUNT(1) BETWEEN 100000 AND 999999999999 THEN '> 100k€'
8110                        END AS amount_range";
8111
8112                $cols = "";
8113
8114                foreach ($resultCommercials as $item) {
8115                    $cols .= ",COALESCE(
8116                        (
8117                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.amount END)
8118                        ) /
8119                        (
8120                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.one END)
8121                        )
8122                    , 0) '{$item->name}'";
8123                }
8124
8125                $cols .= ",COALESCE(
8126                    (
8127                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.amount END)
8128                    ) /
8129                    (
8130                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.one END)
8131                    )
8132                , 0) total";
8133            }
8134
8135            if(@$data['data_to_display'] == 4){
8136
8137                $cols = "";
8138
8139                foreach ($resultCommercials as $item) {
8140                    $cols .= ",COALESCE(
8141                        (
8142                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.acceptanceDate END)
8143                        ) /
8144                        (
8145                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.createdAt END)
8146                        ) * 100
8147                    , 0) '{$item->name}'";
8148                }
8149
8150                $cols .= ",COALESCE(
8151                    (
8152                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.acceptanceDate END)
8153                    ) /
8154                    (
8155                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.createdAt END)
8156                    ) * 100
8157                , 0) total";
8158            }
8159
8160            $query  = "WITH amount_ranges AS (
8161                            SELECT '< 100€' AS amount_range
8162                            UNION ALL SELECT '100€ - 500€'
8163                            UNION ALL SELECT '500€ - 2k€'
8164                            UNION ALL SELECT '2k€ - 10k€'
8165                            UNION ALL SELECT '10k€ - 30k€'
8166                            UNION ALL SELECT '30k€ - 100k€'
8167                            UNION ALL SELECT '> 100k€'
8168                        )
8169
8170                        SELECT
8171                            ar.amount_range,
8172                             GROUP_CONCAT(
8173                                q.id
8174                            ) AS groupConcatIds
8175                            {$colsGroupConcatIds}
8176                            {$cols}
8177                        FROM
8178                            amount_ranges ar
8179                        LEFT JOIN (
8180                            SELECT
8181                                commercial,
8182                                GROUP_CONCAT(
8183                                    CASE WHEN q.{$field} IS NOT NULL THEN id END
8184                                ) id,
8185                                amount AS amount,
8186                                COUNT(CASE WHEN q.created_at IS NOT NULL THEN 1 END) createdAt,
8187                                COUNT(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 END) acceptanceDate,
8188                                COUNT(1) AS one,
8189                                {$range}
8190                            FROM
8191                                tbl_quotations q
8192                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8193                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8194                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8195                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8196                            WHERE
8197                                q.{$field} IS NOT NULL
8198                                AND q.for_add = 0
8199                                AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL)
8200                                AND q.for_add != 1
8201                                AND q.budget_type_id != 7
8202                                AND q.budget_type_id IS NOT NULL
8203                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
8204                                {$where}
8205                                {$whereYear}
8206                            GROUP BY
8207                                commercial,
8208                                id
8209                        ) AS q ON ar.amount_range = q.amount_range
8210                        GROUP BY
8211                            ar.amount_range WITH ROLLUP
8212                        ORDER BY
8213                            CASE
8214                                WHEN ar.amount_range = '< 100€' THEN 1
8215                                WHEN ar.amount_range = '100€ - 500€' THEN 2
8216                                WHEN ar.amount_range = '500€ - 2k€' THEN 3
8217                                WHEN ar.amount_range = '2k€ - 10k€' THEN 4
8218                                WHEN ar.amount_range = '10k€ - 30k€' THEN 5
8219                                WHEN ar.amount_range = '30k€ - 100k€' THEN 6
8220                                ELSE 7
8221                            END";
8222
8223            $value = Cache::get(base64_encode($query));
8224
8225            if(!$value){
8226                $result = DB::select($query);
8227
8228                Cache::put(base64_encode($query), $result, 600);
8229            }else{
8230                $result = $value;
8231            }
8232
8233            return response([
8234                'message' => 'OK',
8235                'data' => $result,
8236                'commercials' => $resultCommercials
8237            ]);
8238
8239        } catch (\Exception $e) {
8240            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8241        }
8242
8243    }
8244
8245    function send_email_template_preview($emailTemplateId){
8246
8247        try {
8248
8249            $emailTemplateId = addslashes($emailTemplateId);
8250
8251            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
8252
8253            $user   = TblUsers::where('id', $this->userId)->first();
8254            $error  = false;
8255
8256            $toEmail = $user->email;
8257
8258            $availableParameters = [
8259                'quote_id',
8260                'company_id',
8261                'client',
8262                'client_type',
8263                'phone_number',
8264                'email',
8265                'issue_date',
8266                'request_date',
8267                'duration',
8268                'invoice_number',
8269                'type',
8270                'acceptance_date',
8271                'status',
8272                'source',
8273                'amount',
8274                'reason_for_not_following_up',
8275                'last_follow_up_date',
8276                'last_follow_up_comment',
8277                'reason_for_rejection_id',
8278                'reason_for_rejection',
8279                'commercial',
8280                'created_at',
8281                'created_by',
8282                'updated_at',
8283                'updated_by'
8284            ];
8285
8286            $dateParameters = [
8287                'issue_date',
8288                'request_date',
8289                'acceptance_date',
8290                'last_follow_up_date',
8291                'created_at',
8292                'updated_at',
8293            ];
8294
8295            if($this->locale == 'es'){
8296                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
8297            }
8298
8299            if($this->locale == 'es'){
8300                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
8301            }
8302
8303            $body = $emailTemplate->html;
8304            $subject = $emailTemplate->subject;
8305
8306            preg_match_all('/{{(.*?)}}/', $body, $matches);
8307
8308            $parameters = $matches[1];
8309
8310            $result = TblQuotations::where('for_add', 0)->whereIn('company_id', $this->companyIds)->first();
8311
8312            foreach ($parameters as $parameter) {
8313
8314                if(in_array($parameter, $dateParameters)){
8315                    if($result->{$parameter}){
8316                        $result->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result->{$parameter})));
8317                    }
8318                }
8319
8320                if(in_array($parameter, $availableParameters)){
8321                    $body = str_replace('{{' . $parameter . '}}', $result->{$parameter}, $body);
8322                }
8323            }
8324
8325            preg_match_all('/{{(.*?)}}/', $subject, $matches);
8326
8327            $parameters = $matches[1];
8328
8329            foreach ($parameters as $parameter) {
8330
8331                if(in_array($parameter, $dateParameters)){
8332                    if($result->{$parameter}){
8333                        $result->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result->{$parameter})));
8334                    }
8335                }
8336
8337                if(in_array($parameter, $availableParameters)){
8338                    $subject = str_replace('{{' . $parameter . '}}', $result->{$parameter}, $subject);
8339                }
8340            }
8341
8342
8343            $email = new \SendGrid\Mail\Mail();
8344
8345            $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
8346
8347            foreach ($templateFiles as $item) {
8348                $f = storage_path('app/public/uploads/' . $item->filename);
8349                $imgpath = file_get_contents($f);
8350                $mimeType = mime_content_type($f);
8351
8352                $email->addAttachment(
8353                    $imgpath,
8354                    $mimeType,
8355                    str_replace(' ', '', $item->original_name),
8356                    "inline",
8357                    str_replace(' ', '', $item->original_name),
8358                );
8359
8360                $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
8361            }
8362
8363            $html = '<!DOCTYPE html>';
8364            $html .= '<html>';
8365            $html .= '<head>';
8366            $html .= '<meta charset="UTF-8">';
8367            $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
8368            $html .= '</head>';
8369            $html .= '<body>';
8370            $html .= $body;
8371            $html .= '</body>';
8372            $html .= '</html>';
8373
8374            if($toEmail != null){
8375
8376                $companyEmail = null;
8377
8378                if($emailTemplate->from_id != null){
8379                    $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
8380                }else{
8381                    $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result->company_id)->first();
8382                }
8383
8384                if(!$companyEmail){
8385                    return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
8386                }
8387
8388                $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
8389                $email->setSubject($subject);
8390                $email->addTo($toEmail);
8391                $email->addContent("text/html", $html);
8392
8393                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
8394
8395                $response = $sendgrid->send($email);
8396                if ($response->statusCode() == 202) {
8397                    return response(['message' => 'OK']);
8398                }
8399            }
8400
8401            return response(['message' => 'KO']);
8402
8403        } catch (\Exception $e) {
8404            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8405        }
8406
8407    }
8408
8409    function list_quotation_analytics_by_types_of_budgets_company_per_week(Request $request){
8410
8411        try {
8412
8413            $data = $request->all();
8414            $companyId = addslashes($data['company_id']);
8415            $field = $data['field'];
8416
8417            $where = "";
8418            $whereYear = "";
8419            $dateLflArray = array();
8420            $companyIds = $this->companyIds;
8421
8422            $acc = "";
8423            if($field == 'acceptance_date'){
8424                $acc = " AND q.acceptance_date IS NOT NULL ";
8425                // $field = 'created_at';
8426
8427                if(@$data['data_to_display'] == 4){
8428                    $field = 'created_at';
8429                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8430                }
8431            }else{
8432                $field = 'created_at';
8433                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8434            }
8435
8436            if($companyId != 0){
8437                $companyIds = array($companyId);
8438            }
8439
8440            if(isset($data['years']) && $data['years'] != null){
8441                $years = implode(',', $data['years']);
8442                if(count($data['years']) > 0){
8443                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
8444                }
8445            }
8446
8447            foreach ($companyIds as $v) {
8448
8449                $lflWhere = " AND q.company_id = {$v} ";
8450
8451                $query = "SELECT
8452                            CONCAT(
8453                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
8454                                ' - ',
8455                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
8456                            ) AS date_like,
8457                            YEAR(q.{$field}) 'year',
8458                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
8459                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
8460                            {$v} 'company_id'
8461                        FROM
8462                            tbl_quotations q
8463                        WHERE
8464                            q.{$field} IS NOT NULL
8465                            AND q.for_add != 1
8466                            {$lflWhere}
8467                            {$whereYear}
8468                        GROUP BY YEAR(q.{$field})
8469                        ORDER BY YEAR(q.{$field}) DESC";
8470
8471                $dateLike = DB::select($query);
8472
8473                $dateLflArray[$v] = $dateLike;
8474            }
8475
8476            $isFy = true;
8477
8478            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
8479                $isFy = false;
8480                $ytdArray = array();
8481                $ytdAcceptanceArray = array();
8482                $lflCompanyIds = array();
8483                foreach ($dateLflArray as $k => $v) {
8484                    foreach ($dateLflArray[$k] as $item) {
8485                        $year = $item->year;
8486                        $now = date('m-d');
8487                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
8488                    }
8489
8490                    $ytdArray = implode(' OR ', $ytdArray);
8491                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
8492                    $ytdArray = array();
8493                }
8494
8495                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8496                $where .= " AND ({$lflCompanyIds}";
8497            }
8498
8499            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
8500                $isFy = false;
8501                $lflArray = array();
8502                $ytdAcceptanceArray = array();
8503                $lflCompanyIds = array();
8504                foreach ($dateLflArray as $k => $v) {
8505                    foreach ($dateLflArray[$k] as $item) {
8506                        $year = $item->year;
8507                        $min_date_like = $item->min_date_like;
8508                        $max_date_like = $item->max_date_like;
8509                        array_push($lflArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}')");
8510                    }
8511
8512                    $lflArray = implode(' OR ', $lflArray);
8513                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
8514                    $lflArray = array();
8515                }
8516
8517                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8518                $where .= " AND ({$lflCompanyIds}";
8519            }
8520
8521            if($isFy){
8522                if($companyId != 0){
8523                    $where .= " AND q.company_id = {$companyId} ";
8524                }else{
8525                    $where .= " AND q.company_id IN ({$this->companyId})";
8526                }
8527            }
8528
8529            if(isset($data['source']) && $data['source'] != null){
8530                $where .= " AND s.name = '{$data['source']}'";
8531            }
8532
8533            if(isset($data['month']) && $data['month'] != null){
8534                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
8535            }
8536
8537            if(isset($data['week']) && $data['week'] != null){
8538                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
8539            }
8540
8541            if(isset($data['commercial']) && $data['commercial'] != null){
8542                $where .= " AND q.commercial = '{$data['commercial']}'";
8543            }
8544
8545            if(isset($data['created_by']) && $data['created_by'] != null){
8546                $where .= " AND q.created_by = '{$data['created_by']}'";
8547            }
8548
8549            if(isset($data['budget_type']) && $data['budget_type'] != null){
8550                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
8551            }
8552
8553            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
8554                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
8555            }
8556
8557            if(isset($data['budget_status']) && $data['budget_status'] != null){
8558                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
8559            }
8560
8561            if(isset($data['client_type']) && $data['client_type'] != null){
8562                $where .= " AND ct.customer_type_id = {$data['client_type']}";
8563            }
8564
8565            if(isset($data['segment_id']) && $data['segment_id'] != null){
8566                $where .= " AND q.segment_id = {$data['segment_id']}";
8567            }
8568
8569            $col = "1";
8570
8571            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
8572                if($data['data_to_display'] == 1){
8573                    $col = "1";
8574                }
8575
8576                if($data['data_to_display'] == 2){
8577                    $col = "q.amount";
8578                }
8579            }
8580
8581            $budgetTypes = TblBudgetTypes::orderByRaw("ISNULL(priority), priority ASC")->get();
8582            $cols = "";
8583            foreach ($budgetTypes as $item) {
8584                if($item->name == '' || $item->name == null){
8585                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} ELSE 0 END), 0) AS 'Otros'";
8586                }else{
8587                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN {$col} ELSE 0 END), 0) AS '{$item->name}'";
8588                }
8589            }
8590
8591            $budgetTypeGroups = TblBudgetTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
8592
8593            $colsGroups = ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} END), 0) AS Otros";
8594
8595            foreach ($budgetTypeGroups as $item) {
8596                $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8597                $colsGroups .= ",GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.id END) AS 'groupConcatIds{$budgetTypeGroupName}'";
8598                $colsGroups .= ",COALESCE(SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN {$col} END), 0) AS '{$budgetTypeGroupName}'";
8599            }
8600
8601            $colsGroups .= ",COALESCE(SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN {$col} END), 0) AS total";
8602
8603            $col = $colsGroups . $cols;
8604
8605            if(@$data['data_to_display'] == 3){
8606
8607                $cols = "";
8608                foreach ($budgetTypes as $item) {
8609                    if($item->name == '' || $item->name == null){
8610                        $cols .= ",COALESCE(
8611                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount ELSE 0 END) /
8612                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 ELSE 0 END) * 100
8613                                    , 0) AS 'Otros'";
8614                    }else{
8615                        $cols .= ", COALESCE(
8616                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN q.amount ELSE 0 END) /
8617                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN 1 ELSE 0 END)
8618                                    , 0) AS '{$item->name}'";
8619                    }
8620                }
8621
8622                $colsGroups = ",COALESCE(
8623                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount END)) /
8624                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 END))
8625                            , 0) Otros";
8626
8627                foreach ($budgetTypeGroups as $item) {
8628                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8629                    $colsGroups .= ",GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.id END) AS 'groupConcatIds{$budgetTypeGroupName}'";
8630                    $colsGroups .= ",COALESCE(
8631                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.amount END)) /
8632                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN 1 END))
8633                                    , 0) '{$budgetTypeGroupName}'";
8634                }
8635
8636                $colsGroups .= ",COALESCE(
8637                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.amount END)) /
8638                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END))
8639                                , 0) total";
8640
8641                $col = $colsGroups . $cols;
8642            }
8643
8644            if(@$data['data_to_display'] == 4){
8645
8646                $cols = "";
8647
8648                foreach ($budgetTypes as $item) {
8649
8650                    if($item->name == '' || $item->name == null){
8651                        $cols .= ",COALESCE(
8652                                        SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) /
8653                                        SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 ELSE 0 END) * 100
8654                                    , 0) AS 'Otros'";
8655                    }else{
8656                        $cols .= ", COALESCE(
8657                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.acceptance_date IS NOT NULL THEN 1 END) /
8658                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.created_at IS NOT NULL THEN 1 END) * 100
8659                                    , 0) AS '{$item->name}'";
8660                    }
8661                }
8662
8663                $colsGroups = ",COALESCE(
8664                                    (SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 END)) /
8665                                    (SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 END)) * 100
8666                                , 0) Otros";
8667
8668                foreach ($budgetTypeGroups as $item) {
8669                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8670                    $colsGroups .= ",GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.id END) AS 'groupConcatIds{$budgetTypeGroupName}'";
8671                    $colsGroups .= ",COALESCE(
8672                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) AND q.acceptance_date IS NOT NULL THEN 1 END)) /
8673                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) AND q.created_at IS NOT NULL THEN 1 END)) * 100
8674                                    , 0) '{$budgetTypeGroupName}'";
8675                }
8676
8677                $colsGroups .= ",COALESCE(
8678                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) AND q.acceptance_date IS NOT NULL THEN 1 END)) /
8679                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) AND q.created_at IS NOT NULL THEN 1 END)) * 100
8680                                    , 0) total";
8681
8682                $col = $colsGroups . $cols;
8683            }
8684
8685            $query  = "SELECT
8686                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
8687                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
8688                            q.company_id,
8689                            c.name 'companyName',
8690                            GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.id END) groupConcatIds
8691                            {$col}
8692                        FROM
8693                            tbl_quotations q
8694                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8695                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8696                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8697                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
8698                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8699                            LEFT JOIN tbl_companies c ON q.company_id = c.company_id
8700                        WHERE
8701                            q.{$field} IS NOT NULL
8702                            AND q.for_add != 1
8703                            AND q.budget_type_id != 7
8704                            AND q.budget_type_id IS NOT NULL
8705                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
8706                            AND q.acceptance_date != '0000-00-00 00:00:00'
8707                            {$where}
8708                            {$whereYear}
8709                        GROUP BY
8710                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
8711                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
8712                            q.company_id WITH ROLLUP
8713                        ORDER BY
8714                            YEAR DESC,
8715                            MONTH ASC,
8716                            q.company_id ASC,
8717                            DATE_FORMAT(q.{$field}, '%e') ASC";
8718
8719            $result = DB::select($query);
8720
8721            $query = "SELECT
8722                        btg.budget_type_group_id,
8723                        btg.name,
8724                        (
8725                            SELECT
8726                                GROUP_CONCAT(COALESCE(bt.name, '') ORDER BY ISNULL(bt.priority), bt.priority ASC SEPARATOR '|')
8727                            FROM
8728                                tbl_budget_types bt
8729                            WHERE
8730                                bt.budget_type_group_id = btg.budget_type_group_id
8731                        ) budget_types
8732                        FROM
8733                            tbl_budget_type_groups btg
8734                        ORDER BY
8735                            ISNULL(btg.priority),
8736                            btg.priority ASC";
8737
8738            $budgetTypeGroups = DB::select($query);
8739
8740            foreach ($budgetTypeGroups as $item) {
8741                $item->group_key_name = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8742                $item->budget_types = explode("|", $item->budget_types);
8743            }
8744
8745            return response([
8746                'message' => 'OK',
8747                'data' => $result,
8748                'budgetTypeGroups' => $budgetTypeGroups
8749            ]);
8750
8751        } catch (\Exception $e) {
8752            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8753        }
8754    }
8755
8756    function request_permission_commercial(Request $request){
8757
8758        try {
8759
8760            $data = $request->all();
8761
8762            $id = addslashes($data['id']);
8763            $requestedBy = $data['requested_by'];
8764            $body = "";
8765
8766            $result = TblQuotations::where('id', $id)->first();
8767
8768            $subject = __('language.request_permission_commercial.subject');
8769            $subject = str_replace('{{quote_id}}', $result->quote_id, $subject);
8770            $subject = str_replace('{{username}}', $requestedBy, $subject);
8771
8772            $email = new \SendGrid\Mail\Mail();
8773
8774            $imgpath = File::get('fireservicetitan.png');
8775
8776            $email->addAttachment(
8777                $imgpath,
8778                "image/png",
8779                "fireservicetitan.png",
8780                "inline",
8781                "fireservicetitan"
8782            );
8783
8784            $url = env('URL') . "orders/{$id}?company_id={$result->company_id}";
8785            $href = "<a href='{$url}'>{$result->quote_id}</a>";
8786
8787            $user = TblUsers::where('name', $requestedBy)->first();
8788
8789            $urlClick = env('URL') . "update?confirm_request={$id}&requested_by={$user->id}&quote_id={$result->quote_id}";
8790            $company = TblCompanies::where('company_id', $result->company_id)->first();
8791
8792            $body .= __('language.request_permission_commercial.body_hello');
8793            $body .= __('language.request_permission_commercial.body_message');
8794
8795            $amount = $this->currency($result->amount, 1);
8796
8797            $body = str_replace('{{commercial}}', $result->commercial, $body);
8798            $body = str_replace('{{company}}', $company->name, $body);
8799            $body = str_replace('{{client}}', $result->client, $body);
8800            $body = str_replace('{{amount}}', $amount, $body);
8801            $body = str_replace('{{quote_id}}', $href, $body);
8802            $body = str_replace('{{click}}', $urlClick, $body);
8803            $body = str_replace('{{username}}', $requestedBy, $body);
8804
8805            $body .= "<p>Fire Service Titan</p>";
8806            $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
8807
8808            $html = '<!DOCTYPE html>';
8809            $html .= '<html>';
8810            $html .= '<head>';
8811            $html .= '<meta charset="UTF-8">';
8812            $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
8813            $html .= '</head>';
8814            $html .= '<body>';
8815            $html .= $body;
8816            $html .= '</body>';
8817            $html .= '</html>';
8818
8819            $user = TblUsers::where('id', $this->userId)->first();
8820
8821            if(env('SENDGRID_STAGING')){
8822                $email->addTo($user->email);
8823            }else{
8824                $email->addTo("luis.collar@fire.es");
8825
8826                $user = TblUsers::where('name', $result->created_by)->first();
8827                if($user && $user->email != "luis.collar@fire.es"){
8828                    $email->addTo($user->email);
8829                }
8830
8831                if($result->created_by != $result->commercial){
8832                    $user = TblUsers::where('name', $result->commercial)->first();
8833                    if($user->email != "luis.collar@fire.es"){
8834                        $email->addTo($user->email);
8835                    }
8836                }
8837            }
8838
8839            $email->setFrom("titan@fire.es");
8840            $email->setSubject($subject);
8841
8842            $email->addContent("text/html", $html);
8843
8844            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
8845
8846            $response = $sendgrid->send($email);
8847            if ($response->statusCode() == 202) {
8848                return response(['message' => 'OK']);
8849            }
8850
8851            return response(['message' => 'KO']);
8852
8853        } catch (\Exception $e) {
8854            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8855        }
8856
8857    }
8858
8859    function confirm_update_commercial(Request $request){
8860
8861        try {
8862            sleep(3);
8863            $data = $request->all();
8864            $id = addslashes($data['id']);
8865            $userId = addslashes($data['requested_by']);
8866
8867            $user = TblUsers::where('id', $userId)->first();
8868
8869            if($user){
8870
8871                TblQuotations::where('id', $data['id'])->update(
8872                    array(
8873                        'commercial' => $user->name,
8874                        'updated_at' => date('Y-m-d H:i:s')
8875                    )
8876                );
8877
8878            }else{
8879                return response(['message' => 'KO', 'error' => 'invalid_user']);
8880            }
8881
8882            return response(['message' => 'OK']);
8883
8884        } catch (\Exception $e) {
8885            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8886        }
8887    }
8888
8889    function calculateEmailRequestSize(Mail $email){
8890
8891        $size = 0;
8892
8893        // Add size of 'from', 'to', 'subject', 'content'
8894        $from = $email->getFrom();
8895        $size += strlen(json_encode([
8896            'from' => $from->getEmail() . ' ' . $from->getName(),
8897            'subject' => $email->getSubject()
8898        ]));
8899
8900        // Add size of 'to' (recipients)
8901        $personalizations = $email->getPersonalization();
8902        foreach ($personalizations as $personalization) {
8903            foreach ($personalization->getTos() as $to) {
8904                $size += strlen($to->getEmail() . ' ' . $to->getName());
8905            }
8906        }
8907
8908        // Add size of content
8909        foreach ($email->getContents() as $content) {
8910            $size += strlen($content->getValue());
8911        }
8912
8913        // Add size of attachments (if any)
8914
8915        if($email->getAttachments() != null && $email->getAttachments() != ""){
8916            foreach ($email->getAttachments() as $attachment) {
8917                $size += strlen($attachment->getContent()); // Base64 encoded size
8918                $size += strlen($attachment->getFilename());
8919                $size += strlen($attachment->getType());
8920            }
8921        }
8922
8923        $sizeInMegabytes = $size / 1048576; // 1 MB = 1,048,576 bytes
8924
8925        return (int) ceil($sizeInMegabytes);
8926    }
8927
8928    public function list_quotation_analytics_commercial_productivity(Request $request){
8929
8930        // try {
8931
8932            $data = $request->all();
8933            $companyId = addslashes($data['company_id']);
8934
8935            $where = "";
8936            $whereYear = "";
8937            $whereVisit = "";
8938
8939            $dateLflArray = array();
8940            $companyIds = $this->companyIds;
8941
8942            if($companyId != 0){
8943                $companyIds = array($companyId);
8944            }
8945
8946            $field = "issue_date";
8947
8948            if(isset($data['years']) && $data['years'] != null){
8949                $years = implode(',', $data['years']);
8950                if(count($data['years']) > 0){
8951                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
8952                }
8953            }
8954
8955            foreach ($companyIds as $v) {
8956
8957                $lflWhere = " AND q.company_id = {$v} ";
8958
8959                $query = "SELECT
8960                            CONCAT(
8961                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
8962                                ' - ',
8963                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
8964                            ) AS date_like,
8965                            YEAR(q.{$field}) 'year',
8966                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
8967                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
8968                            {$v} 'company_id'
8969                        FROM
8970                            tbl_quotations q
8971                        WHERE
8972                            q.{$field} IS NOT NULL
8973                            AND q.for_add != 1
8974                            {$lflWhere}
8975                            {$whereYear}
8976                        GROUP BY YEAR(q.{$field})
8977                        ORDER BY YEAR(q.{$field}) DESC";
8978
8979                $dateLike = DB::select($query);
8980
8981                if(count($dateLike) > 0){
8982                    $dateLflArray[$v] = $dateLike;
8983                }
8984            }
8985
8986            $whereAcceptanceDate = "";
8987
8988            if(isset($data['source']) && $data['source'] != null){
8989                $where .= " AND s.name = '{$data['source']}'";
8990            }
8991
8992            if(isset($data['month']) && $data['month'] != null){
8993                $where .= " AND MONTH(q.created_at) = '{$data['month']}'";
8994            }
8995
8996            if(isset($data['week']) && $data['week'] != null){
8997                $where .= " AND WEEK(q.created_at) = '{$data['week']}'";
8998            }
8999
9000            if(isset($data['commercial']) && $data['commercial'] != null){
9001                $commercial = implode("','", $data['commercial']);
9002                if(count($data['commercial']) > 0){
9003                    $where .= " AND q.commercial IN ('{$commercial}') ";
9004                    $whereVisit .= " AND q.commercial IN ('{$commercial}') ";
9005                }
9006            }
9007
9008            if(isset($data['created_by']) && $data['created_by'] != null){
9009                $created_by = implode("','", $data['created_by']);
9010                if(count($data['created_by']) > 0){
9011                    $where .= " AND q.created_by IN ('{$created_by}')";
9012                }
9013            }
9014
9015            if(isset($data['budget_type']) && $data['budget_type'] != null){
9016                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
9017            }
9018
9019            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
9020                $budgetTypeGroupIds = implode(",", $data['budget_type_group']);
9021                if(count($data['budget_type_group']) > 0){
9022                    $where .= " AND bt.budget_type_group_id IN ({$budgetTypeGroupIds})";
9023                }
9024            }
9025
9026            if(isset($data['budget_status']) && $data['budget_status'] != null){
9027                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
9028            }
9029
9030            if(isset($data['client_type']) && $data['client_type'] != null){
9031                $where .= " AND ct.customer_type_id = {$data['client_type']}";
9032            }
9033
9034            if(isset($data['segment_id']) && $data['segment_id'] != null){
9035                $where .= " AND q.segment_id = {$data['segment_id']}";
9036            }
9037
9038            if(isset($data['role_id']) && $data['role_id'] != null){
9039                $roleId = implode(",", $data['role_id']);
9040                if(count($data['role_id']) > 0){
9041                    $where .= " AND r.role_id IN ({$roleId})";
9042                    $whereVisit .= " AND r.role_id IN ({$roleId}";
9043                }
9044            }
9045
9046            $groupByFilter = 2;
9047            if(isset($data['group_by']) && $data['group_by'] != null){
9048                $groupByFilter = $data['group_by'];
9049            }
9050
9051            $groupBy = "1, 2, 3, q.commercial, budget_type";
9052
9053            if($groupByFilter == 1){
9054                $groupBy = "1, q.commercial, 2, 3, budget_type";
9055            }
9056
9057            if($groupByFilter == 3){
9058                $groupBy = "1, budget_type, q.commercial, 2, 3";
9059            }
9060
9061            $aggregatedBy = 1;
9062            $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', LPAD(q.week, 2, 0) AS 'week', ";
9063            $aggregatedByCalc = " / 4";
9064            if(isset($data['aggregated_by']) && $data['aggregated_by'] != null){
9065                $aggregatedBy = $data['aggregated_by'];
9066                if($data['aggregated_by'] == 1){
9067
9068                    $groupBy = "1, 2, 3, q.commercial, budget_type";
9069
9070                    if($groupByFilter == 1){
9071                        $groupBy = "1, q.commercial, 2, 3, budget_type";
9072                    }
9073
9074                    if($groupByFilter == 3){
9075                        $groupBy = "1, budget_type, q.commercial, 2, 3";
9076                    }
9077
9078                    $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', LPAD(q.week, 2, 0) AS 'week', ";
9079                }elseif($data['aggregated_by'] == 2){
9080                    $groupBy = "1, 2, q.commercial, budget_type";
9081
9082                    if($groupByFilter == 1){
9083                        $groupBy = "1, q.commercial, 2, budget_type";
9084                    }
9085
9086                    if($groupByFilter == 3){
9087                        $groupBy = "1, budget_type, q.commercial, 2";
9088                    }
9089
9090                    $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', NULL AS 'week',";
9091                    $aggregatedByCalc = "";
9092                }elseif($data['aggregated_by'] == 3){
9093                    $groupBy = "1, q.commercial, budget_type";
9094
9095                    if($groupByFilter == 3){
9096                        $groupBy = "1, budget_type, q.commercial";
9097                    }
9098
9099                    $aggregatedCol = "NULL AS 'month', NULL AS 'week',";
9100                    $aggregatedByCalc = " * 12";
9101                }
9102            }
9103
9104            $whereAcceptanceDate = $where;
9105            $whereCreatedAt = $where;
9106
9107            $isFy = true;
9108
9109            if($companyId != 0){
9110                $where .= " AND q.company_id = {$companyId} ";
9111                $whereCreatedAt .= " AND q.company_id = {$companyId} ";
9112                $whereAcceptanceDate .= " AND q.company_id = {$companyId} ";
9113                $whereVisit .= " AND q.company_id = {$companyId} ";
9114            }else{
9115                $where .= " AND q.company_id IN ({$this->companyId}";
9116                $whereCreatedAt .= " AND q.company_id IN ({$this->companyId}";
9117                $whereAcceptanceDate .= " AND q.company_id IN ({$this->companyId}";
9118                $whereVisit .= " AND q.company_id IN ({$this->companyId}";
9119            }
9120
9121            if(isset($data['campaign']) && $data['campaign'] != null){
9122                $campaign = implode("','", $data['campaign']);
9123                if(count($data['campaign']) > 0){
9124                    $whereVisit .= " AND q.campaign IN ('{$campaign}')";
9125                }
9126            }
9127
9128            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
9129                $isFy = false;
9130                $now = date('m-d');
9131
9132                $where .= " AND q.{$field} BETWEEN DATE_FORMAT(q.{$field}, '%Y-01-01') AND DATE_FORMAT(q.{$field}, '%Y-{$now}') ";
9133                $whereCreatedAt .= " AND q.created_at BETWEEN DATE_FORMAT(q.created_at, '%Y-01-01') AND DATE_FORMAT(q.created_at, '%Y-{$now}') ";
9134                $whereAcceptanceDate .= " AND q.acceptance_date BETWEEN DATE_FORMAT(q.acceptance_date, '%Y-01-01') AND DATE_FORMAT(q.acceptance_date, '%Y-{$now}') ";
9135                $whereVisit .= " AND q.visit_date BETWEEN DATE_FORMAT(q.visit_date, '%Y-01-01') AND DATE_FORMAT(q.visit_date, '%Y-{$now}') ";
9136            }
9137
9138            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
9139                $isFy = false;
9140                $lflArray = array();
9141                $ytdAcceptanceArray = array();
9142                $lflCompanyIds = array();
9143                $lflCompanyIdsAcc = array();
9144                foreach ($dateLflArray as $k => $v) {
9145                    foreach ($dateLflArray[$k] as $item) {
9146                        $year = $item->year;
9147                        $min_date_like = $item->min_date_like;
9148                        $max_date_like = $item->max_date_like;
9149                        array_push($lflArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}')");
9150                        array_push($ytdAcceptanceArray, "DATE_FORMAT(q.acceptance_date, '%Y-%m-%d') BETWEEN LEAST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}') AND GREATEST('{$year}-{$min_date_like}', '{$year}-{$max_date_like}')");
9151                    }
9152
9153                    $lflArray = implode(' OR ', $lflArray);
9154                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
9155                    $lflArray = array();
9156
9157                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
9158                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
9159                    $ytdAcceptanceArray = array();
9160                }
9161
9162                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
9163                $where .= " AND ({$lflCompanyIds}";
9164
9165                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
9166                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
9167            }
9168
9169            $orderBy = "CASE WHEN q.commercial IS NULL OR q.budget_type IS NULL THEN q.priority END DESC, q.priority ASC,";
9170
9171            if(isset($data['order_by'])){
9172                $col = $data['order_by']['column'];
9173                $sort = $data['order_by']['sort'];
9174
9175                if(!empty($sort) || $sort != null){
9176                    $orderBy = "CASE WHEN q.commercial IS NULL OR q.budget_type IS NULL THEN {$col} END DESC, {$col} {$sort},";
9177                }
9178            }
9179
9180
9181            $visitTypes = TblVisitTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
9182
9183            $visitCols = "";
9184            $visitMainTableCols = "";
9185            $visitSubMainTableCols = "";
9186            $visitSubTableCols = "";
9187            $visitMainCols = "";
9188
9189            $visitCall = array("Visita", "Llamada");
9190
9191            foreach ($visitCall as $value) {
9192                foreach ($visitTypes as $item) {
9193                    $visitTypeNames = $value . $item->visit_type_group_id;
9194                    $visitCols .= ",COUNT(CASE WHEN q.visit_date IS NOT NULL AND v.visit_type_group_id = {$item->visit_type_group_id} AND q.visit_call = '{$value}' THEN 1 END) AS 'total{$visitTypeNames}'";
9195                    $visitCols .= ",GROUP_CONCAT(CASE WHEN q.visit_date IS NOT NULL AND v.visit_type_group_id = {$item->visit_type_group_id} AND q.visit_call = '{$value}' THEN q.id END) AS 'groupConcatIds{$visitTypeNames}'";
9196                    $visitMainTableCols .= ",COALESCE(SUM(q.total{$visitTypeNames}), 0) AS 'total{$visitTypeNames}'";
9197                    $visitMainTableCols .= ",GROUP_CONCAT(q.groupConcatIds{$visitTypeNames})  AS 'groupConcatIds{$visitTypeNames}'";
9198                    $visitSubMainTableCols .= ",q.total{$visitTypeNames}";
9199                    $visitSubMainTableCols .= ",q.groupConcatIds{$visitTypeNames}";
9200                    $visitSubTableCols .= ",0 AS total{$visitTypeNames}";
9201                    $visitSubTableCols .= ",NULL AS groupConcatIds{$visitTypeNames}";
9202                    $visitMainCols .= ",COALESCE(SUM(q.total{$visitTypeNames}), 0) total{$visitTypeNames}";
9203                    $visitMainCols .= ",GROUP_CONCAT(q.groupConcatIds{$visitTypeNames}) groupConcatIds{$visitTypeNames}";
9204                }
9205            }
9206
9207
9208            $businessGoalsDefault = TblBusinessGoals::where('is_default', 1)->where('budget_type_group_id', 999999999)->first();
9209
9210            $businessGoalsDefault->issue_objective = $businessGoalsDefault->issue_objective ?? 1;
9211            $businessGoalsDefault->acceptance_objective = $businessGoalsDefault->acceptance_objective ?? 1;
9212            $businessGoalsDefault->new_objective = $businessGoalsDefault->new_objective ?? 1;
9213            $businessGoalsDefault->is_amount = $businessGoalsDefault->is_amount ?? 1;
9214
9215            $gO = "";
9216
9217            if($groupByFilter != 3){
9218                $gO = "ORDER BY
9219                        1 DESC,
9220                        2 ASC,
9221                        3 ASC,
9222                        q.commercial ASC,
9223                        {$orderBy}
9224                        DATE_FORMAT(q.namedate, '%e') ASC";
9225            }else{
9226                $gO = "ORDER BY
9227                        1 DESC,
9228                        2 ASC,
9229                        3 ASC,
9230                        budget_type ASC,
9231                        q.commercial ASC";
9232            }
9233
9234            $query = "WITH business_goal_objective_users AS (
9235                        SELECT
9236                            bg.user_id,
9237                            bg.issue_objective,
9238                            bg.acceptance_objective,
9239                            bg.new_objective,
9240                            bg.is_amount
9241                        FROM tbl_business_goals bg
9242                        WHERE bg.budget_type_group_id = 999999999
9243                    ), business_goal_objective_roles AS (
9244                        SELECT
9245                            bg.role_id,
9246                            bg.issue_objective,
9247                            bg.acceptance_objective,
9248                            bg.new_objective,
9249                            bg.is_amount
9250                        FROM tbl_business_goals bg
9251                        WHERE bg.budget_type_group_id = 999999999
9252                    )
9253
9254                    SELECT
9255                        q.year,
9256                        {$aggregatedCol}
9257                        q.namedate created_at,
9258                        q.commercial,
9259                        q.budget_type,
9260                        COALESCE(SUM(q.issue_date), 0) totalIssue,
9261                        COALESCE(SUM(q.created_at), 0) totalCreatedAt,
9262                        GROUP_CONCAT(q.groupConcatIds) groupConcatIds,
9263                        SUM(q.totalIssueObjective) totalIssueObjective,
9264                        CASE
9265                            WHEN SUM(q.totalIssueObjective) BETWEEN 1 AND 70 THEN 'text-danger'
9266                            WHEN SUM(q.totalIssueObjective) BETWEEN 70 AND 90 THEN 'text-warning'
9267                        END textIssueColor,
9268                        SUM(q.revenueIssue) revenueIssue,
9269                        SUM(q.totalIssueObjectiveMonthly) totalIssueObjectiveMonthly,
9270                        SUM(q.totalIssueObjectiveYearly) totalIssueObjectiveYearly,
9271                        COALESCE(SUM(q.acceptance_date), 0) totalAcceptance,
9272                        GROUP_CONCAT(q.groupConcatCreatedAtIds) groupConcatCreatedAtIds,
9273                        SUM(q.totalIssueLessThan5) AS totalIssueLessThan5,
9274                        GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) AS groupConcatIdsIssueLessThan5,
9275                        GROUP_CONCAT(q.groupConcatAcceptanceIds) groupConcatAcceptanceIds,
9276                        SUM(q.totalAcceptanceObjective) totalAcceptanceObjective,
9277                        SUM(q.totalAcceptanceObjectiveMonthly) totalAcceptanceObjectiveMonthly,
9278                        SUM(q.totalAcceptanceObjectiveYearly) totalAcceptanceObjectiveYearly,
9279                        CASE
9280                            WHEN SUM(q.totalAcceptanceObjective) BETWEEN 1 AND 70 THEN 'text-danger'
9281                            WHEN SUM(q.totalAcceptanceObjective) BETWEEN 70 AND 90 THEN 'text-warning'
9282                        END textAcceptanceColor,
9283                        SUM(q.revenueAcceptance) revenueAcceptance,
9284                        COALESCE(SUM(q.totalRejected), 0) totalRejected,
9285                        GROUP_CONCAT(q.groupConcatRejectedIds) groupConcatRejectedIds,
9286                        SUM(q.revenueRejected) revenueRejected,
9287                        COALESCE(SUM(q.totalNew)) totalNew,
9288                        GROUP_CONCAT(q.groupConcatNewIds) groupConcatNewIds,
9289                        SUM(q.totalNewObjective) totalNewObjective,
9290                        SUM(q.totalNewObjectiveMonthly) totalNewObjectiveMonthly,
9291                        SUM(q.totalNewObjectiveYearly) totalNewObjectiveYearly,
9292                        CASE
9293                            WHEN SUM(q.totalNewObjective) BETWEEN 1 AND 70 THEN 'text-danger'
9294                            WHEN SUM(q.totalNewObjective) BETWEEN 70 AND 90 THEN 'text-warning'
9295                        END textNewColor,
9296                        SUM(q.revenueNew) revenueNew,
9297                        COALESCE(SUM(q.totalVisit), 0) totalVisit,
9298                        GROUP_CONCAT(q.groupConcatVisitIds) groupConcatVisitIds,
9299                        COALESCE(SUM(q.totalCall), 0) totalCall,
9300                        GROUP_CONCAT(q.groupConcatCallIds) groupConcatCallIds,
9301                        SUM(q.is_amountIssue) AS is_amountIssue,
9302                        SUM(q.is_amountNew) AS is_amountNew,
9303                        SUM(q.is_amountAcceptance) AS is_amountAcceptance,
9304                        SUM(q.issueObjective) AS issueObjective,
9305                        SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9306                        SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9307                        SUM(q.newObjective) AS newObjective,
9308                        SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9309                        SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9310                        SUM(q.acceptanceObjective) AS acceptanceObjective,
9311                        SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9312                        SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9313                        {$visitMainCols}
9314                    FROM
9315                    (
9316                        SELECT
9317                            q.year,
9318                            q.month,
9319                            q.week,
9320                            q.namedate,
9321                            SUM(q.issue_date) AS issue_date,
9322                            q.acceptance_date,
9323                            q.created_at,
9324                            q.commercial,
9325                            q.budget_type,
9326                            GROUP_CONCAT(q.groupConcatIds) AS groupConcatIds,
9327                            CASE
9328                                WHEN q.is_amountIssue > 0 THEN
9329                                    SUM(q.revenueIssue / q.issueObjective) * 100
9330                                ELSE
9331                                    SUM(q.issue_date / q.issueObjective) * 100
9332                                END
9333                            AS totalIssueObjective,
9334                            CASE
9335                                WHEN q.is_amountIssue > 0 THEN
9336                                    SUM(q.revenueIssue / q.issueObjectiveMonthly) * 100
9337                                ELSE
9338                                    SUM(q.issue_date / q.issueObjectiveMonthly) * 100
9339                                END
9340                            AS totalIssueObjectiveMonthly,
9341                            CASE
9342                                WHEN q.is_amountIssue > 0 THEN
9343                                    SUM(q.revenueIssue / q.issueObjectiveYearly) * 100
9344                                ELSE
9345                                    SUM(q.issue_date / q.issueObjectiveYearly) * 100
9346                                END
9347                            AS totalIssueObjectiveYearly,
9348                            SUM(q.revenueIssue) revenueIssue,
9349                            GROUP_CONCAT(q.groupConcatCreatedAtIds) AS groupConcatCreatedAtIds,
9350                            SUM(q.totalIssueLessThan5) totalIssueLessThan5,
9351                            GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) groupConcatIdsIssueLessThan5,
9352                            GROUP_CONCAT(q.groupConcatAcceptanceIds) AS groupConcatAcceptanceIds,
9353                            SUM(q.acceptanceObjective) totalAcceptanceObjective,
9354                            SUM(q.acceptanceObjectiveMonthly) totalAcceptanceObjectiveMonthly,
9355                            SUM(q.acceptanceObjectiveYearly) totalAcceptanceObjectiveYearly,
9356                            q.revenueAcceptance,
9357                            SUM(q.totalRejected) AS totalRejected,
9358                            GROUP_CONCAT(q.groupConcatRejectedIds) AS groupConcatRejectedIds,
9359                            SUM(q.revenueRejected) revenueRejected,
9360                            SUM(q.totalNew) AS totalNew,
9361                            GROUP_CONCAT(q.groupConcatNewIds) AS groupConcatNewIds,
9362                            CASE
9363                                WHEN q.is_amountNew > 0 THEN
9364                                    SUM(q.revenueNew / q.newObjective) * 100
9365                                ELSE
9366                                    SUM(q.totalNew / q.newObjective) * 100
9367                                END
9368                            AS totalNewObjective,
9369                             CASE
9370                                WHEN q.is_amountNew > 0 THEN
9371                                    SUM(q.revenueNew / q.newObjectiveMonthly) * 100
9372                                ELSE
9373                                    SUM(q.totalNew / q.newObjectiveMonthly) * 100
9374                                END
9375                            AS totalNewObjectiveMonthly,
9376                             CASE
9377                                WHEN q.is_amountNew > 0 THEN
9378                                    SUM(q.revenueNew / q.newObjectiveYearly) * 100
9379                                ELSE
9380                                    SUM(q.totalNew / q.newObjectiveYearly) * 100
9381                                END
9382                            AS totalNewObjectiveYearly,
9383                            SUM(q.revenueNew) revenueNew,
9384                            q.totalVisit,
9385                            q.groupConcatVisitIds,
9386                            q.totalCall,
9387                            q.groupConcatCallIds,
9388                            q.priority,
9389                            SUM(q.is_amountIssue) AS is_amountIssue,
9390                            SUM(q.is_amountNew) AS is_amountNew,
9391                            SUM(q.is_amountAcceptance) AS is_amountAcceptance,
9392                            SUM(q.issueObjective) AS issueObjective,
9393                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9394                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9395                            SUM(q.newObjective) AS newObjective,
9396                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9397                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9398                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9399                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9400                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9401                            {$visitSubMainTableCols}
9402                        FROM (
9403                            SELECT
9404                                YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'year',
9405                                MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'month',
9406                                WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'week',
9407                                DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') namedate,
9408                                COUNT(CASE WHEN q.issue_date IS NOT NULL THEN 1 END) issue_date,
9409                                0 acceptance_date,
9410                                0 created_at,
9411                                q.commercial,
9412                                btg.name budget_type,
9413                                GROUP_CONCAT(CASE WHEN q.issue_date IS NOT NULL THEN q.id END) AS groupConcatIds,
9414
9415                                SUM(CASE WHEN q.issue_date IS NOT NULL THEN q.amount END) AS revenueIssue,
9416                                NULL groupConcatCreatedAtIds,
9417                                0 totalIssueLessThan5,
9418                                NULL groupConcatIdsIssueLessThan5,
9419                                NULL groupConcatAcceptanceIds,
9420
9421                                0 revenueAcceptance,
9422                                COUNT(CASE WHEN bs.name = 'Rechazado' THEN 1 END) AS totalRejected,
9423                                GROUP_CONCAT(DISTINCT CASE WHEN bs.name = 'Rechazado' THEN q.id END) AS groupConcatRejectedIds,
9424                                COALESCE(SUM(CASE WHEN bs.name = 'Rechazado' THEN q.amount END), 0) AS revenueRejected,
9425                                COUNT(CASE WHEN ct.name = 'Nuevo' THEN 1 END) AS totalNew,
9426                                GROUP_CONCAT(DISTINCT CASE WHEN ct.name = 'Nuevo' THEN q.id END) AS groupConcatNewIds,
9427
9428                                COALESCE(SUM(CASE WHEN ct.name = 'Nuevo' THEN q.amount END), 0) revenueNew,
9429                                0 totalVisit,
9430                                NULL groupConcatVisitIds,
9431                                0 totalCall,
9432                                NULL groupConcatCallIds,
9433                                btg.priority,
9434                                CAST(
9435                                    CASE
9436                                        WHEN bg.issue_objective IS NOT NULL THEN bg.is_amount
9437                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.is_amount
9438                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.is_amount
9439                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.is_amount
9440                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.is_amount
9441                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9442                                    END
9443                                AS DOUBLE) AS is_amountIssue,
9444                                CAST(
9445                                    CASE
9446                                        WHEN bg.new_objective IS NOT NULL THEN bg.is_amount
9447                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.is_amount
9448                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.is_amount
9449                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.is_amount
9450                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.is_amount
9451                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9452                                    END
9453                                AS DOUBLE) AS is_amountNew,
9454                                0 is_amountAcceptance,
9455                                CAST(
9456                                    CASE
9457                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9458                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9459                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9460                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9461                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9462                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9463                                    END {$aggregatedByCalc}
9464                                AS DOUBLE) AS issueObjective,
9465                                CAST(
9466                                    CASE
9467                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9468                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9469                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9470                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9471                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9472                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9473                                    END
9474                                AS DOUBLE) AS issueObjectiveMonthly,
9475                                CAST(
9476                                    CASE
9477                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9478                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9479                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9480                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9481                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9482                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9483                                    END * 12
9484                                AS DOUBLE) AS issueObjectiveYearly,
9485                                CAST(
9486                                    CASE
9487                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9488                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9489                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9490                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9491                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9492                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9493                                    END {$aggregatedByCalc}
9494                                AS DOUBLE) AS newObjective,
9495                                CAST(
9496                                    CASE
9497                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9498                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9499                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9500                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9501                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9502                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9503                                    END
9504                                AS DOUBLE) AS newObjectiveMonthly,
9505                                CAST(
9506                                    CASE
9507                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9508                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9509                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9510                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9511                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9512                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9513                                    END * 12
9514                                AS DOUBLE) AS newObjectiveYearly,
9515                                0 acceptanceObjective,
9516                                0 acceptanceObjectiveMonthly,
9517                                0 acceptanceObjectiveYearly
9518                                {$visitSubTableCols}
9519                            FROM
9520                            tbl_quotations q
9521                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9522                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9523                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9524                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9525                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9526                                LEFT JOIN tbl_users u ON q.commercial = u.name
9527                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9528                                LEFT JOIN tbl_business_goals bg ON bg.budget_type_group_id = btg.budget_type_group_id AND bg.user_id = u.id
9529                                LEFT JOIN tbl_business_goals bg1 ON bg1.budget_type_group_id = btg.budget_type_group_id AND bg1.role_id = r.role_id
9530                                LEFT JOIN tbl_business_goals bgde ON bgde.budget_type_group_id = btg.budget_type_group_id AND bgde.is_default = 1
9531                                LEFT JOIN business_goal_objective_users bgou ON bgou.user_id = u.id
9532                                LEFT JOIN business_goal_objective_roles bgor ON bgor.role_id = r.role_id
9533                            WHERE
9534                                q.budget_type_id != 7
9535                                AND q.budget_type_id IS NOT NULL
9536                                AND q.for_add != 1
9537                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9538                                AND bt.include = 1
9539                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9540                                {$where}
9541                                {$whereYear}
9542                            GROUP BY
9543                                {$groupBy}
9544                        ) q
9545                        GROUP BY
9546                            {$groupBy} WITH ROLLUP
9547
9548                        UNION ALL
9549
9550                        SELECT
9551                            q.year,
9552                            q.month,
9553                            q.week,
9554                            q.namedate,
9555                            q.issue_date,
9556                            SUM(q.acceptance_date) AS acceptance_date,
9557                            q.created_at,
9558                            q.commercial,
9559                            q.budget_type,
9560                            q.groupConcatIds,
9561                            q.issueObjective totalIssueObjective,
9562                            q.issueObjectiveMonthly totalIssueObjectiveMonthly,
9563                            q.issueObjectiveYearly totalIssueObjectiveYearly,
9564                            q.revenueIssue,
9565                            q.groupConcatCreatedAtIds,
9566                            q.totalIssueLessThan5,
9567                            q.groupConcatIdsIssueLessThan5,
9568                            GROUP_CONCAT(q.groupConcatAcceptanceIds) AS groupConcatAcceptanceIds,
9569                            CASE
9570                                WHEN q.is_amountAcceptance > 0 THEN
9571                                    SUM(q.revenueAcceptance / q.acceptanceObjective) * 100
9572                                ELSE
9573                                    SUM(q.acceptance_date / q.acceptanceObjective) * 100
9574                                END
9575                            AS totalAcceptanceObjective,
9576                            CASE
9577                                WHEN q.is_amountAcceptance > 0 THEN
9578                                    SUM(q.revenueAcceptance / q.acceptanceObjectiveMonthly) * 100
9579                                ELSE
9580                                    SUM(q.acceptance_date / q.acceptanceObjectiveMonthly) * 100
9581                                END
9582                            AS totalAcceptanceObjectiveMonthly,
9583                            CASE
9584                                WHEN q.is_amountAcceptance > 0 THEN
9585                                    SUM(q.revenueAcceptance / q.acceptanceObjectiveYearly) * 100
9586                                ELSE
9587                                    SUM(q.acceptance_date / q.acceptanceObjectiveYearly) * 100
9588                                END
9589                            AS totalAcceptanceObjectiveYearly,
9590                            SUM(q.revenueAcceptance) revenueAcceptance,
9591                            q.totalRejected,
9592                            q.groupConcatRejectedIds,
9593                            q.revenueRejected,
9594                            q.totalNew,
9595                            q.groupConcatNewIds,
9596                            q.newObjective totalNewObjective,
9597                            q.newObjectiveMonthly totalNewObjectiveMonthly,
9598                            q.newObjectiveYearly totalNewObjectiveYearly,
9599                            q.revenueNew,
9600                            q.totalVisit,
9601                            q.groupConcatVisitIds,
9602                            q.totalCall,
9603                            q.groupConcatCallIds,
9604                            q.priority,
9605                            SUM(q.is_amountIssue) AS is_amountIssue,
9606                            q.is_amountNew,
9607                            q.is_amountAcceptance,
9608                            SUM(q.issueObjective) AS issueObjective,
9609                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9610                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9611                            SUM(q.newObjective) AS newObjective,
9612                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9613                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9614                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9615                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9616                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9617                            {$visitSubMainTableCols}
9618                        FROM (
9619                            SELECT
9620                                YEAR(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'year',
9621                                MONTH(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'month',
9622                                WEEK(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'week',
9623                                DATE_FORMAT(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY), '%W, %M %e') namedate,
9624                                0 issue_date,
9625                                COUNT(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 END) acceptance_date,
9626                                0 created_at,
9627                                q.commercial,
9628                                btg.name budget_type,
9629                                NULL groupConcatIds,
9630
9631                                0 revenueIssue,
9632                                NULL groupConcatCreatedAtIds,
9633                                0 totalIssueLessThan5,
9634                                NULL groupConcatIdsIssueLessThan5,
9635                                GROUP_CONCAT(CASE WHEN q.acceptance_date IS NOT NULL THEN q.id END) AS groupConcatAcceptanceIds,
9636
9637                                COALESCE(SUM(CASE WHEN q.acceptance_date IS NOT NULL THEN q.amount END), 0) AS revenueAcceptance,
9638                                0 totalRejected,
9639                                NULL groupConcatRejectedIds,
9640                                0 revenueRejected,
9641                                0 totalNew,
9642                                NULL groupConcatNewIds,
9643                                NULL totalNewObjective,
9644                                NULL totalNewObjectiveMonthly,
9645                                NULL totalNewObjectiveYearly,
9646                                0 revenueNew,
9647                                0 totalVisit,
9648                                NULL groupConcatVisitIds,
9649                                0 totalCall,
9650                                NULL groupConcatCallIds,
9651                                btg.priority,
9652                                0 is_amountIssue,
9653                                0 is_amountNew,
9654                                CAST(
9655                                    CASE
9656                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.is_amount
9657                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.is_amount
9658                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.is_amount
9659                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.is_amount
9660                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.is_amount
9661                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9662                                    END
9663                                AS DOUBLE) AS is_amountAcceptance,
9664                                0 issueObjective,
9665                                0 issueObjectiveMonthly,
9666                                0 issueObjectiveYearly,
9667                                0 newObjective,
9668                                0 newObjectiveMonthly,
9669                                0 newObjectiveYearly,
9670                                CAST(
9671                                    CASE
9672                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
9673                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
9674                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
9675                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
9676                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
9677                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
9678                                    END {$aggregatedByCalc}
9679                                AS DOUBLE) AS acceptanceObjective,
9680                                CAST(
9681                                    CASE
9682                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
9683                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
9684                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
9685                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
9686                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
9687                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
9688                                    END
9689                                AS DOUBLE) AS acceptanceObjectiveMonthly,
9690                                CAST(
9691                                    CASE
9692                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
9693                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
9694                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
9695                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
9696                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
9697                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
9698                                    END * 12
9699                                AS DOUBLE) AS acceptanceObjectiveYearly
9700                                {$visitSubTableCols}
9701                            FROM
9702                            tbl_quotations q
9703                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9704                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9705                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9706                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9707                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9708                                LEFT JOIN tbl_users u ON q.commercial = u.name
9709                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9710                                LEFT JOIN tbl_business_goals bg ON bg.budget_type_group_id = btg.budget_type_group_id AND bg.user_id = u.id
9711                                LEFT JOIN tbl_business_goals bg1 ON bg1.budget_type_group_id = btg.budget_type_group_id AND bg1.role_id = r.role_id
9712                                LEFT JOIN tbl_business_goals bgde ON bgde.budget_type_group_id = btg.budget_type_group_id AND bgde.is_default = 1
9713                                LEFT JOIN business_goal_objective_users bgou ON bgou.user_id = u.id
9714                                LEFT JOIN business_goal_objective_roles bgor ON bgor.role_id = r.role_id
9715                            WHERE
9716                                q.budget_type_id != 7
9717                                AND q.budget_type_id IS NOT NULL
9718                                AND q.for_add != 1
9719                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9720                                AND bt.include = 1
9721                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9722                                {$whereAcceptanceDate}
9723                                {$whereYear}
9724                            GROUP BY
9725                                {$groupBy}
9726                        ) q
9727                        GROUP BY
9728                            {$groupBy} WITH ROLLUP
9729
9730                        UNION ALL
9731
9732                        SELECT
9733                            q.year,
9734                            q.month,
9735                            q.week,
9736                            q.namedate,
9737                            q.issue_date,
9738                            q.acceptance_date,
9739                            SUM(q.created_at) AS created_at,
9740                            q.commercial,
9741                            q.budget_type,
9742                            q.groupConcatIds,
9743                            q.issueObjective totalIssueObjective,
9744                            q.issueObjectiveMonthly totalIssueObjectiveMonthly,
9745                            q.issueObjectiveYearly totalIssueObjectiveYearly,
9746                            q.revenueIssue,
9747                            GROUP_CONCAT(q.groupConcatCreatedAtIds) AS groupConcatCreatedAtIds,
9748                            SUM(q.totalIssueLessThan5) AS totalIssueLessThan5,
9749                            GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) AS groupConcatIdsIssueLessThan5,
9750                            NULL groupConcatAcceptanceIds,
9751                            0 totalAcceptanceObjective,
9752                            0 totalAcceptanceObjectiveMonthly,
9753                            0 totalAcceptanceObjectiveYearly,
9754                            SUM(q.revenueAcceptance) revenueAcceptance,
9755                            q.totalRejected,
9756                            q.groupConcatRejectedIds,
9757                            q.revenueRejected,
9758                            q.totalNew,
9759                            q.groupConcatNewIds,
9760                            q.newObjective totalNewObjective,
9761                            q.newObjectiveMonthly totalNewObjectiveMonthly,
9762                            q.newObjectiveYearly totalNewObjectiveYearly,
9763                            q.revenueNew,
9764                            q.totalVisit,
9765                            q.groupConcatVisitIds,
9766                            q.totalCall,
9767                            q.groupConcatCallIds,
9768                            q.priority,
9769                            SUM(q.is_amountIssue) AS is_amountIssue,
9770                            q.is_amountNew,
9771                            q.is_amountAcceptance,
9772                            SUM(q.issueObjective) AS issueObjective,
9773                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9774                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9775                            SUM(q.newObjective) AS newObjective,
9776                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9777                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9778                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9779                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9780                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9781                            {$visitSubMainTableCols}
9782                        FROM (
9783                            SELECT
9784                                YEAR(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'year',
9785                                MONTH(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'month',
9786                                WEEK(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'week',
9787                                DATE_FORMAT(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY), '%W, %M %e') namedate,
9788                                0 issue_date,
9789                                0 acceptance_date,
9790                                COUNT(CASE WHEN q.created_at IS NOT NULL THEN 1 END) created_at,
9791                                q.commercial,
9792                                btg.name budget_type,
9793                                NULL groupConcatIds,
9794
9795                                0 revenueIssue,
9796                                GROUP_CONCAT(CASE WHEN q.created_at IS NOT NULL THEN q.id END) AS groupConcatCreatedAtIds,
9797                                COUNT(CASE WHEN ABS(DATEDIFF(q.created_at, q.issue_date)) < 5 THEN 1 END) AS totalIssueLessThan5,
9798                                GROUP_CONCAT(CASE WHEN ABS(DATEDIFF(q.created_at, q.issue_date)) < 5 THEN q.id END) AS groupConcatIdsIssueLessThan5,
9799                                NULL groupConcatAcceptanceIds,
9800
9801                                0 AS revenueAcceptance,
9802                                0 totalRejected,
9803                                NULL groupConcatRejectedIds,
9804                                0 revenueRejected,
9805                                0 totalNew,
9806                                NULL groupConcatNewIds,
9807                                NULL totalNewObjective,
9808                                NULL totalNewObjectiveMonthly,
9809                                NULL totalNewObjectiveYearly,
9810                                0 revenueNew,
9811                                0 totalVisit,
9812                                NULL groupConcatVisitIds,
9813                                0 totalCall,
9814                                NULL groupConcatCallIds,
9815                                btg.priority,
9816                                0 is_amountIssue,
9817                                0 is_amountNew,
9818                                0 is_amountAcceptance,
9819                                0 issueObjective,
9820                                0 issueObjectiveMonthly,
9821                                0 issueObjectiveYearly,
9822                                0 newObjective,
9823                                0 newObjectiveMonthly,
9824                                0 newObjectiveYearly,
9825                                0 acceptanceObjective,
9826                                0 acceptanceObjectiveMonthly,
9827                                0 acceptanceObjectiveYearly
9828                                {$visitSubTableCols}
9829                            FROM
9830                            tbl_quotations q
9831                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9832                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9833                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9834                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9835                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9836                                LEFT JOIN tbl_users u ON q.commercial = u.name
9837                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9838                            WHERE
9839                                q.budget_type_id != 7
9840                                AND q.budget_type_id IS NOT NULL
9841                                AND q.for_add != 1
9842                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9843                                AND bt.include = 1
9844                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9845                                {$whereCreatedAt}
9846                                {$whereYear}
9847                            GROUP BY
9848                                {$groupBy}
9849                        ) q
9850                        GROUP BY
9851                            {$groupBy} WITH ROLLUP
9852
9853                        UNION ALL
9854
9855                        SELECT
9856                            YEAR(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) YEAR,
9857                            MONTH(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) MONTH,
9858                            WEEK(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) WEEK,
9859                            DATE_FORMAT(DATE_ADD(visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY), '%W, %M %e') namedate,
9860                            0 issue_date,
9861                            0 acceptance_date,
9862                            0 created_at,
9863                            commercial,
9864                            NULL budget_type,
9865                            NULL groupConcatIds,
9866                            NULL totalIssueObjective,
9867                            NULL totalIssueObjectiveMonthly,
9868                            NULL totalIssueObjectiveYearly,
9869                            0 revenueIssue,
9870                            NULL groupConcatCreatedAtIds,
9871                            0 totalIssueLessThan5,
9872                            NULL groupConcatIdsIssueLessThan5,
9873                            NULL groupConcatAcceptanceIds,
9874                            NULL totalAcceptanceObjective,NULL totalAcceptanceObjectiveMonthly,
9875                            NULL totalAcceptanceObjectiveYearly,
9876                            0 revenueAcceptance,
9877                            0 totalRejected,
9878                            NULL groupConcatRejectedIds,
9879                            0 revenueRejected,
9880                            0 totalNew,
9881                            NULL groupConcatNewIds,
9882                            NULL totalNewObjective,NULL totalNewObjectiveMonthly,
9883                            NULL totalNewObjectiveYearly,
9884                            0 revenueNew,
9885                            COUNT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Visita' THEN 1 END) totalVisit,
9886                            GROUP_CONCAT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Visita' THEN q.id END) AS groupConcatVisitIds,
9887                            COUNT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Llamada' THEN 1 END) totalCall,
9888                            GROUP_CONCAT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Llamada' THEN q.id END) AS groupConcatCallIds,
9889                            0 priority,
9890                            0 is_amountIssue,
9891                            0 is_amountNew,
9892                            0 is_amountAcceptance,
9893                            0 issueObjective,
9894                            0 issueObjectiveMonthly,
9895                            0 issueObjectiveYearly,
9896                            0 newObjective,
9897                            0 newObjectiveMontly,
9898                            0 newObjectiveYearly,
9899                            0 acceptanceObjective,
9900                            0 acceptanceObjectiveMonthly,
9901                            0 acceptanceObjectiveYearly
9902                            {$visitCols}
9903                        FROM
9904                            tbl_pipelines q
9905                        LEFT JOIN tbl_users u ON q.commercial = u.name
9906                        LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9907                        LEFT JOIN tbl_visit_types v ON q.visit_type_id = v.visit_type_id
9908                        WHERE q.visit_date IS NOT NULL
9909                            {$whereVisit}
9910                        GROUP BY
9911                            {$groupBy}
9912                             WITH ROLLUP
9913                    ) q
9914                    WHERE
9915                        q.year NOT IN (2021, 2022)
9916                    GROUP BY
9917                        {$groupBy}
9918                    {$gO}";
9919
9920            $value = Cache::get(base64_encode($query));
9921
9922            if(!$value){
9923                $result = DB::select($query);
9924
9925                $structureData = new StructureData();
9926                $result = $structureData->parse($result, $groupByFilter, $aggregatedBy);
9927
9928                Cache::put(base64_encode($query), $result, 600);
9929            }else{
9930                $result = $value;
9931            }
9932
9933            return response([
9934                'message' => 'OK',
9935                'data' => $result
9936            ]);
9937
9938        // } catch (\Exception $e) {
9939        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
9940        // }
9941    }
9942
9943    function list_quotations_deleted($companyId){
9944
9945        try {
9946
9947            $companyId = addslashes($companyId);
9948            $where = "";
9949
9950            if($companyId != 0){
9951                $where = " a.company_id = {$companyId} ";
9952            }else{
9953                $where = " a.company_id IN ({$this->companyId})";
9954            }
9955
9956            $query = "SELECT
9957                        a.id,
9958                        a.quote_id,
9959                        a.company_id,
9960                        b.name company_name,
9961                        a.created_by,
9962                        a.updated_by,
9963                        a.updated_at,
9964                        a.for_add,
9965                        c.name reason,
9966                        a.reason_for_deletion
9967                    FROM tbl_quotations_deleted a
9968                    LEFT JOIN tbl_companies b
9969                        ON a.company_id = b.company_id
9970                    LEFT JOIN tbl_reasons c
9971                        ON a.reason_id = c.reason_id
9972                    WHERE {$where}
9973                    ORDER BY a.updated_at DESC";
9974
9975            $result = DB::select($query);
9976
9977            return response([
9978                'message' => 'OK',
9979                'data' => $result
9980            ]);
9981        } catch (\Exception $e) {
9982            return response(['message' => 'KO', 'error' => $e->getMessage()]);
9983        }
9984    }
9985
9986    function delete_sengrid($id){
9987
9988        try {
9989
9990            $id = addslashes($id);
9991
9992            $order = TblQuotations::where('id', $id)->first();
9993
9994            if($order){
9995                if($order->x_message_id != null){
9996                    TblSendgridWebhook::where('quotation_id', $id)->where('x_message_id', $order->x_message_id)->delete();
9997
9998                    TblQuotations::where('id', $id)->update(
9999                        array(
10000                            'x_message_id' => null,
10001                            'x_status' => null
10002                        )
10003                    );
10004
10005                    Cache::flush();
10006                }
10007            }
10008
10009            return response([
10010                'message' => 'OK'
10011            ]);
10012
10013        } catch (\Exception $e) {
10014            return response(['message' => 'KO', 'error' => $e->getMessage()]);
10015        }
10016    }
10017
10018    function download_productivity_commercial(Request $request){
10019
10020        try {
10021
10022            ini_set('max_execution_time', 123456);
10023
10024            $data = $request->all();
10025
10026            $result = $this->list_quotation_analytics_commercial_productivity($request);
10027            $result = $result->original['data'];
10028
10029            $spreadsheet = new Spreadsheet();
10030            $worksheet   = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, "Inputs");
10031            $spreadsheet->addSheet($worksheet, 0);
10032            $col         = range('A', 'Z');
10033
10034            for($i = 0; $i < 26; $i++){
10035                $worksheet->getColumnDimension($col[$i])->setAutoSize(true);
10036                if($i != 1){
10037                    $worksheet->getStyle($col[$i])
10038                        ->getAlignment()
10039                        ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
10040                }
10041            }
10042
10043            $l = 1;
10044            $worksheet->setCellValue('A' . $l, "Años");
10045
10046            if($data['group_by'] == 1){
10047                $worksheet->setCellValue('B' . $l, "Comercials");
10048                $worksheet->setCellValue('C' . $l, "Meses");
10049                $worksheet->setCellValue('D' . $l, "Semanas");
10050            }else{
10051                $worksheet->setCellValue('B' . $l, "Meses");
10052                $worksheet->setCellValue('C' . $l, "Semanas");
10053                $worksheet->setCellValue('D' . $l, "Comercials");
10054            }
10055
10056            $worksheet->setCellValue('E' . $l, "Categorías de presupuesto");
10057            $worksheet->setCellValue('F' . $l, "Presupuestos emitidos (#)");
10058            $worksheet->setCellValue('G' . $l, "Presupuestos emitidos (€)");
10059            $worksheet->setCellValue('H' . $l, "Presupuestos emitidos (Objetivo)");
10060            $worksheet->setCellValue('I' . $l, "Presupuestos aceptados (#)");
10061            $worksheet->setCellValue('J' . $l, "Presupuestos aceptados (€)");
10062            $worksheet->setCellValue('K' . $l, "Presupuestos aceptados (Objetivo)");
10063            $worksheet->setCellValue('L' . $l, "Presupuestos rechazados (#)");
10064            $worksheet->setCellValue('M' . $l, "Presupuestos rechazados (€)");
10065            $worksheet->setCellValue('N' . $l, "Presupuestos emitidos a nuevos clientes (#)");
10066            $worksheet->setCellValue('O' . $l, "Presupuestos emitidos a nuevos clientes (€)");
10067            $worksheet->setCellValue('P' . $l, "Presupuestos emitidos a nuevos clientes (Objetivo)");
10068            $worksheet->setCellValue('Q' . $l, "Venta (Llamada #)");
10069            $worksheet->setCellValue('R' . $l, "Venta (Visita #)");
10070            $worksheet->setCellValue('S' . $l, "Servicio (Llamada #)");
10071            $worksheet->setCellValue('T' . $l, "Servicio (Visita #)");
10072
10073            $l++;
10074
10075            foreach ($result as $item) {
10076
10077                $worksheet->setCellValue('A' . $l, $item['year']);
10078                $worksheet->setCellValue('F' . $l, $item['totalIssue']);
10079                $worksheet->setCellValue('G' . $l, $item['revenueIssue']);
10080                $worksheet->setCellValue('H' . $l, "-");
10081
10082                $worksheet->setCellValue('I' . $l, $item['totalAcceptance']);
10083                $worksheet->setCellValue('J' . $l, $item['revenueAcceptance']);
10084                $worksheet->setCellValue('K' . $l, "-");
10085
10086                $worksheet->setCellValue('L' . $l, $item['totalRejected']);
10087                $worksheet->setCellValue('M' . $l, $item['revenueRejected']);
10088
10089                $worksheet->setCellValue('N' . $l, $item['totalNew']);
10090                $worksheet->setCellValue('O' . $l, $item['revenueNew']);
10091                $worksheet->setCellValue('P' . $l, "-");
10092
10093                $worksheet->setCellValue('Q' . $l, $item['totalLlamada1']);
10094                $worksheet->setCellValue('R' . $l, $item['totalVisita1']);
10095
10096                $worksheet->setCellValue('S' . $l, $item['totalLlamada2']);
10097                $worksheet->setCellValue('T' . $l, $item['totalVisita2']);
10098
10099                $l++;
10100
10101                if($data['group_by'] == 1){
10102
10103                    if(count($item['commercials']) > 0){
10104
10105                        foreach ($item['commercials'] as $c) {
10106                            $worksheet->setCellValue('A' . $l, $item['year']);
10107
10108                            $worksheet->setCellValue('B' . $l, $c['commercial']);
10109                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10110                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10111                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10112
10113                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10114                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10115                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10116
10117                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10118                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10119
10120                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10121                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10122                            $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10123
10124                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10125                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10126
10127                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10128                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10129                            $l++;
10130
10131                            if(isset($c['budget_types']) && count($c['budget_types']) > 0){
10132                                foreach ($c['budget_types'] as $b) {
10133                                    $worksheet->setCellValue('A' . $l, $item['year']);
10134                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10135
10136                                    $worksheet->setCellValue('E' . $l, $b['name']);
10137                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10138                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10139                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10140
10141                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10142                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10143                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10144
10145                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10146                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10147
10148                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10149                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10150                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10151
10152                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10153                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10154
10155                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10156                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10157                                    $l++;
10158                                }
10159                            }
10160
10161                            if(isset($c['months']) && count($c['months']) > 0){
10162                                foreach ($c['months'] as $m) {
10163                                    $worksheet->setCellValue('A' . $l, $item['year']);
10164                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10165
10166                                    $worksheet->setCellValue('C' . $l, $m['month']);
10167                                    $worksheet->setCellValue('F' . $l, $m['totalIssue']);
10168                                    $worksheet->setCellValue('G' . $l, $m['revenueIssue']);
10169                                    $worksheet->setCellValue('H' . $l, $m['totalIssueObjectiveMonthly']);
10170
10171                                    $worksheet->setCellValue('I' . $l, $m['totalAcceptance']);
10172                                    $worksheet->setCellValue('J' . $l, $m['revenueAcceptance']);
10173                                    $worksheet->setCellValue('K' . $l, $m['totalAcceptanceObjectiveMonthly']);
10174
10175                                    $worksheet->setCellValue('L' . $l, $m['totalRejected']);
10176                                    $worksheet->setCellValue('M' . $l, $m['revenueRejected']);
10177
10178                                    $worksheet->setCellValue('N' . $l, $m['totalNew']);
10179                                    $worksheet->setCellValue('O' . $l, $m['revenueNew']);
10180                                    $worksheet->setCellValue('P' . $l, $m['totalNewObjectiveMonthly']);
10181
10182                                    $worksheet->setCellValue('Q' . $l, $m['totalLlamada1']);
10183                                    $worksheet->setCellValue('R' . $l, $m['totalVisita1']);
10184
10185                                    $worksheet->setCellValue('S' . $l, $m['totalLlamada2']);
10186                                    $worksheet->setCellValue('T' . $l, $m['totalVisita2']);
10187                                    $l++;
10188
10189                                    if(isset($m['weeks']) && count(@$m['weeks']) > 0 && count(@$m['weeks']) != 1){
10190                                        foreach ($m['weeks'] as $w) {
10191                                            $worksheet->setCellValue('A' . $l, $item['year']);
10192                                            $worksheet->setCellValue('B' . $l, $c['commercial']);
10193                                            $worksheet->setCellValue('C' . $l, $m['month']);
10194
10195                                            $worksheet->setCellValue('D' . $l, $w['created_at']);
10196                                            $worksheet->setCellValue('F' . $l, $w['totalIssue']);
10197                                            $worksheet->setCellValue('G' . $l, $w['revenueIssue']);
10198                                            $worksheet->setCellValue('H' . $l, $w['totalIssueObjective']);
10199
10200                                            $worksheet->setCellValue('I' . $l, $w['totalAcceptance']);
10201                                            $worksheet->setCellValue('J' . $l, $w['revenueAcceptance']);
10202                                            $worksheet->setCellValue('K' . $l, $w['totalAcceptanceObjective']);
10203
10204                                            $worksheet->setCellValue('L' . $l, $w['totalRejected']);
10205                                            $worksheet->setCellValue('M' . $l, $w['revenueRejected']);
10206
10207                                            $worksheet->setCellValue('N' . $l, $w['totalNew']);
10208                                            $worksheet->setCellValue('O' . $l, $w['revenueNew']);
10209                                            $worksheet->setCellValue('P' . $l, $w['totalNewObjective']);
10210
10211                                            $worksheet->setCellValue('Q' . $l, $w['totalLlamada1']);
10212                                            $worksheet->setCellValue('R' . $l, $w['totalVisita1']);
10213
10214                                            $worksheet->setCellValue('S' . $l, $w['totalLlamada2']);
10215                                            $worksheet->setCellValue('T' . $l, $w['totalVisita2']);
10216                                            $l++;
10217
10218                                            if(count($w['budget_types']) > 0){
10219                                                foreach ($w['budget_types'] as $b) {
10220                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10221                                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10222                                                    $worksheet->setCellValue('C' . $l, $m['month']);
10223
10224                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10225                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10226                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10227                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10228
10229                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10230                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10231                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10232
10233                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10234                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10235
10236                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10237                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10238                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10239
10240                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10241                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10242
10243                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10244                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10245                                                    $l++;
10246                                                }
10247                                            }
10248                                        }
10249                                    }elseif(isset($m['weeks']) && count(@$m['weeks']) == 1){
10250                                        foreach ($m['weeks'] as $w) {
10251                                            if(count($w['budget_types']) > 0){
10252                                                foreach ($w['budget_types'] as $b) {
10253                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10254                                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10255                                                    $worksheet->setCellValue('C' . $l, $m['month']);
10256
10257                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10258                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10259                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10260                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10261
10262                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10263                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10264                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10265
10266                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10267                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10268
10269                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10270                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10271                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10272
10273                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10274                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10275
10276                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10277                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10278                                                    $l++;
10279                                                }
10280                                            }
10281                                        }
10282
10283                                    }
10284                                }
10285                            }
10286                        }
10287                    }
10288                }else{
10289
10290                    if(isset($item['months']) && count($item['months']) > 0){
10291                        foreach ($item['months'] as $m) {
10292                            $worksheet->setCellValue('A' . $l, $item['year']);
10293                            $worksheet->setCellValue('B' . $l, $m['month']);
10294                            $worksheet->setCellValue('F' . $l, $m['totalIssue']);
10295                            $worksheet->setCellValue('G' . $l, $m['revenueIssue']);
10296                            $worksheet->setCellValue('H' . $l, "-");
10297
10298                            $worksheet->setCellValue('I' . $l, $m['totalAcceptance']);
10299                            $worksheet->setCellValue('J' . $l, $m['revenueAcceptance']);
10300                            $worksheet->setCellValue('K' . $l, "-");
10301
10302                            $worksheet->setCellValue('L' . $l, $m['totalRejected']);
10303                            $worksheet->setCellValue('M' . $l, $m['revenueRejected']);
10304
10305                            $worksheet->setCellValue('N' . $l, $m['totalNew']);
10306                            $worksheet->setCellValue('O' . $l, $m['revenueNew']);
10307                            $worksheet->setCellValue('P' . $l, "-");
10308
10309                            $worksheet->setCellValue('Q' . $l, $m['totalLlamada1']);
10310                            $worksheet->setCellValue('R' . $l, $m['totalVisita1']);
10311
10312                            $worksheet->setCellValue('S' . $l, $m['totalLlamada2']);
10313                            $worksheet->setCellValue('T' . $l, $m['totalVisita2']);
10314                            $l++;
10315
10316                            if(isset($m['weeks']) && count(@$m['weeks']) > 0){
10317                                foreach ($m['weeks'] as $w) {
10318                                    $worksheet->setCellValue('A' . $l, $item['year']);
10319                                    $worksheet->setCellValue('B' . $l, $m['month']);
10320
10321                                    $worksheet->setCellValue('C' . $l, $w['created_at']);
10322                                    $worksheet->setCellValue('F' . $l, $w['totalIssue']);
10323                                    $worksheet->setCellValue('G' . $l, $w['revenueIssue']);
10324                                    $worksheet->setCellValue('H' . $l, "-");
10325
10326                                    $worksheet->setCellValue('I' . $l, $w['totalAcceptance']);
10327                                    $worksheet->setCellValue('J' . $l, $w['revenueAcceptance']);
10328                                    $worksheet->setCellValue('K' . $l, "-");
10329
10330                                    $worksheet->setCellValue('L' . $l, $w['totalRejected']);
10331                                    $worksheet->setCellValue('M' . $l, $w['revenueRejected']);
10332
10333                                    $worksheet->setCellValue('N' . $l, $w['totalNew']);
10334                                    $worksheet->setCellValue('O' . $l, $w['revenueNew']);
10335                                    $worksheet->setCellValue('P' . $l, "-");
10336
10337                                    $worksheet->setCellValue('Q' . $l, $w['totalLlamada1']);
10338                                    $worksheet->setCellValue('R' . $l, $w['totalVisita1']);
10339
10340                                    $worksheet->setCellValue('S' . $l, $w['totalLlamada2']);
10341                                    $worksheet->setCellValue('T' . $l, $w['totalVisita2']);
10342                                    $l++;
10343
10344                                    if(count($w['commercials']) > 0){
10345                                        foreach ($w['commercials'] as $c) {
10346                                            $worksheet->setCellValue('A' . $l, $item['year']);
10347                                            $worksheet->setCellValue('B' . $l, $m['month']);
10348
10349                                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10350                                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10351                                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10352                                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjective']);
10353
10354                                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10355                                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10356                                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjective']);
10357
10358                                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10359                                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10360
10361                                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10362                                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10363                                            $worksheet->setCellValue('P' . $l, $c['totalNewObjective']);
10364
10365                                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10366                                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10367
10368                                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10369                                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10370                                            $l++;
10371
10372                                            if(count($c['budget_types']) > 0){
10373                                                foreach ($c['budget_types'] as $b) {
10374                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10375                                                    $worksheet->setCellValue('B' . $l, $m['month']);
10376                                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10377
10378                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10379                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10380                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10381                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10382
10383                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10384                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10385                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10386
10387                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10388                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10389
10390                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10391                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10392                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10393
10394                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10395                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10396
10397                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10398                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10399                                                    $l++;
10400                                                }
10401                                            }
10402                                        }
10403                                    }
10404                                }
10405                            }
10406
10407                            if(count($m['commercials']) > 0){
10408                                foreach ($m['commercials'] as $c) {
10409                                    $worksheet->setCellValue('A' . $l, $item['year']);
10410                                    $worksheet->setCellValue('B' . $l, $m['month']);
10411
10412                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10413                                    $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10414                                    $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10415                                    $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10416
10417                                    $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10418                                    $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10419                                    $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10420
10421                                    $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10422                                    $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10423
10424                                    $worksheet->setCellValue('N' . $l, $c['totalNew']);
10425                                    $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10426                                    $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10427
10428                                    $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10429                                    $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10430
10431                                    $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10432                                    $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10433                                    $l++;
10434
10435                                    if(count($c['budget_types']) > 0){
10436                                        foreach ($c['budget_types'] as $b) {
10437                                            $worksheet->setCellValue('A' . $l, $item['year']);
10438                                            $worksheet->setCellValue('B' . $l, $m['month']);
10439                                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10440
10441                                            $worksheet->setCellValue('E' . $l, $b['name']);
10442                                            $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10443                                            $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10444                                            $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10445
10446                                            $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10447                                            $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10448                                            $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10449
10450                                            $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10451                                            $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10452
10453                                            $worksheet->setCellValue('N' . $l, $b['totalNew']);
10454                                            $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10455                                            $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10456
10457                                            $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10458                                            $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10459
10460                                            $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10461                                            $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10462                                            $l++;
10463                                        }
10464                                    }
10465                                }
10466                            }
10467                        }
10468                    }
10469
10470                    if(count($item['commercials']) > 0){
10471                        foreach ($item['commercials'] as $c) {
10472                            $worksheet->setCellValue('A' . $l, $item['year']);
10473
10474                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10475                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10476                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10477                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10478
10479                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10480                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10481                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10482
10483                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10484                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10485
10486                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10487                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10488                            $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10489
10490                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10491                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10492
10493                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10494                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10495                            $l++;
10496
10497                            if(count($c['budget_types']) > 0){
10498                                foreach ($c['budget_types'] as $b) {
10499                                    $worksheet->setCellValue('A' . $l, $item['year']);
10500                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10501
10502                                    $worksheet->setCellValue('E' . $l, $b['name']);
10503                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10504                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10505                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10506
10507                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10508                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10509                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10510
10511                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10512                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10513
10514                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10515                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10516                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10517
10518                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10519                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10520
10521                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10522                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10523                                    $l++;
10524                                }
10525                            }
10526                        }
10527                    }
10528                }
10529
10530                $l++;
10531            }
10532
10533            if($data['group_by'] == 1){
10534                if($data['aggregated_by'] == 3){
10535                    $worksheet->removeColumn('C');
10536                    $worksheet->removeColumn('C');
10537                }elseif($data['aggregated_by'] == 2){
10538                    $worksheet->removeColumn('D');
10539                }
10540            }else{
10541                if($data['aggregated_by'] == 3){
10542                    $worksheet->removeColumn('B');
10543                    $worksheet->removeColumn('B');
10544                }elseif($data['aggregated_by'] == 2){
10545                    $worksheet->removeColumn('C');
10546                }
10547            }
10548
10549
10550
10551            $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
10552            ob_start();
10553            $writer->save('php://output');
10554            $file = ob_get_contents();
10555            ob_end_clean();
10556
10557            return response($file);
10558
10559        } catch (\Exception $e) {
10560            return response(['message' => 'KO', 'error' => $e->getMessage()]);
10561        }
10562
10563    }
10564
10565    function update_commercial_numbers($companyId)
10566    {
10567        $phpBinary = '/usr/bin/php';
10568
10569        $artisanPath = escapeshellarg(base_path('artisan'));
10570
10571        $command = sprintf(
10572            '%s %s update:commercial-numbers %s > /dev/null 2>&1 &',
10573            $phpBinary,
10574            $artisanPath,
10575            $companyId
10576        );
10577
10578        exec($command, $output, $returnVar);
10579    }
10580
10581    function list_quotation_analytics_by_service_type(Request $request){
10582
10583        try {
10584
10585            $data = $request->all();
10586            $companyId = addslashes($data['company_id']);
10587            $where  = "";
10588
10589            if($companyId != 0){
10590                $where .= " AND c.company_id = {$companyId} ";
10591            }else{
10592                $where .= " AND c.company_id IN ({$this->companyId}";
10593            }
10594
10595            $col = "1";
10596
10597            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
10598                if($data['data_to_display'] == 1){
10599                    $col = "1";
10600                }
10601
10602                if($data['data_to_display'] == 2){
10603                    $col = "q.amount";
10604                }
10605            }
10606
10607            if(isset($data['approvals'])){
10608                $approvals = addslashes($data['approvals']);
10609
10610                if($approvals == 2){
10611                    $where .= " AND q.for_approval != 1 ";
10612                }
10613
10614                if($approvals == 3){
10615                    $where .= " AND q.for_approval > 0 ";
10616                }
10617
10618                if($approvals == 4){
10619                    $where .= " AND q.approved_by IS NOT NULL";
10620                }
10621
10622                if($approvals == 5){
10623                    $where .= " AND q.for_approval = 2 AND q.approved_by IS NULL";
10624                }
10625
10626                if($approvals == 6){
10627                    $where .= " AND q.approved_by IS NOT NULL AND q.approved_by_v2 IS NOT NULL";
10628                }
10629
10630                if($approvals == 7){
10631                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NOT NULL AND q.approved_by_v2 IS NULL";
10632                }
10633
10634                if($approvals == 8){
10635                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NULL AND q.approved_by_v2 IS NOT NULL";
10636                }
10637
10638                if($approvals == 9){
10639                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NULL AND q.approved_by_v2 IS NULL";
10640                }
10641            }
10642
10643            if(isset($data['role_id']) && $data['role_id'] != null){
10644                $roleIds = implode(",", $data['role_id']);
10645                if(count($data['role_id']) > 0){
10646                    $where .= " AND u.role_id IN ({$roleIds}, 999999999)";
10647                }
10648            }
10649
10650            if(isset($data['client_type']) && $data['client_type'] != null){
10651                $where .= " AND q.customer_type_id = {$data['client_type']}";
10652            }
10653
10654            $weekDay = "- WEEKDAY(q.date)";
10655
10656            if(isset($data['start_of_the_week']) && $data['start_of_the_week'] != null){
10657                switch ($data['start_of_the_week']) {
10658                    case 0:
10659                        $weekDay = "- WEEKDAY(q.date)";
10660                        break;
10661                    case 1:
10662                        $weekDay = "(1 - WEEKDAY(q.date))";
10663                        break;
10664                    case 2:
10665                        $weekDay = "(2 - WEEKDAY(q.date))";
10666                        break;
10667                    case 3:
10668                        $weekDay = "(3 - WEEKDAY(q.date))";
10669                        break;
10670                    case 4:
10671                        $weekDay = "(4 - WEEKDAY(q.date))";
10672                        break;
10673                    default:
10674                        $weekDay = "- WEEKDAY(q.date)";
10675                        break;
10676                }
10677            }
10678
10679            $whereDates = "";
10680
10681            if((isset($data['start_date']) && $data['start_date'] != null) && (isset($data['end_date']) && $data['end_date'] != null)){
10682                $whereDates = " AND q.date BETWEEN '{$data['start_date']}' AND '{$data['end_date']}";
10683            }
10684
10685            $query = "SELECT
10686                        q.region,
10687                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) 'year',
10688                        LPAD(MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'month',
10689                        LPAD(WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'week',
10690                        DATE_FORMAT(DATE_ADD(q.date, INTERVAL {$weekDay} DAY), '%W, %M %e') namedate,
10691
10692                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' THEN q.id END) AS groupConcatIdsTotalEnviado,
10693                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END), 0) AS totalIssueEnviado,
10694
10695                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoEnviado,
10696                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoEnviado,
10697                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalMantenimientoPercentageEnviado,
10698
10699                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosEnviado,
10700                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosEnviado,
10701                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalCorrectivosPercentageEnviado,
10702
10703                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasEnviado,
10704                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasEnviado,
10705                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalObrasPercentageEnviado,
10706
10707                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
10708                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
10709                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalOtrosPercentageEnviado,
10710
10711                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
10712                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
10713                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalOtrosPercentageEnviado,
10714
10715                        CASE
10716                            WHEN SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.amount ELSE 0 END) = 0 THEN 0
10717                            ELSE SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.s1 ELSE 0 END)
10718                                / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.amount ELSE 0 END)
10719                        END AS weightedAverageMarginForTheCompanyEnviado,
10720                        CASE
10721                            WHEN SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.amount ELSE 0 END) = 0 THEN 0
10722                            ELSE SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.s2 ELSE 0 END)
10723                                / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.amount ELSE 0 END)
10724                        END AS weightedAverageInvoiceEnviado,
10725
10726                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' THEN q.id END) AS groupConcatIdsTotalAceptado,
10727                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END), 0) AS totalIssueAceptado,
10728
10729                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoAceptado,
10730                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoAceptado,
10731                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) * 100, 0) totalMantenimientoPercentageAceptado,
10732
10733                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosAceptado,
10734                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosAceptado,
10735                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) * 100, 0) totalCorrectivosPercentageAceptado,
10736
10737                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasAceptado,
10738                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasAceptado,
10739                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) * 100, 0) totalObrasPercentageAceptado,
10740
10741                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosAceptado,
10742                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosAceptado,
10743                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) / SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) * 100, 0) totalOtrosPercentageAceptado,
10744
10745                        CASE
10746                            WHEN SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.amount ELSE 0 END) = 0 THEN 0
10747                            ELSE SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.s1 ELSE 0 END)
10748                                / SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.amount ELSE 0 END)
10749                        END AS weightedAverageMarginForTheCompanyAceptado,
10750                        CASE
10751                            WHEN SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.amount ELSE 0 END) = 0 THEN 0
10752                            ELSE SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.s2 ELSE 0 END)
10753                                / SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.amount ELSE 0 END)
10754                        END AS weightedAverageInvoiceAceptado,
10755
10756                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN 1 END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalIssuePercentage,
10757                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END) * 100, 0) totalMantenimientoPercentage,
10758                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END) * 100, 0) totalCorrectivosPercentage,
10759                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END) * 100, 0) totalObrasPercentage,
10760                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) * 100 , 0) totalOtrosPercentage,
10761
10762                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL THEN {$col} END) * 100, 0) totalIssuePercentageLead,
10763                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL AND q.budget_type_group_id = 3 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL AND q.budget_type_group_id = 3 THEN {$col} END) * 100, 0) totalMantenimientoPercentageLead,
10764                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL AND q.budget_type_group_id = 5 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL AND q.budget_type_group_id = 5 THEN {$col} END) * 100, 0) totalCorrectivosPercentageLead,
10765                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL AND q.budget_type_group_id = 4 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL AND q.budget_type_group_id = 4 THEN {$col} END) * 100, 0) totalObrasPercentageLead,
10766                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) * 100 , 0) totalOtrosPercentageLead
10767                    FROM
10768                    (
10769                        SELECT
10770                            c.region,
10771                            q.issue_date AS DATE,
10772                            'issue' AS date_type,
10773                            q.acceptance_date,
10774                            q.issue_date,
10775                            q.id,
10776                            q.margin_for_the_company,
10777                            CASE
10778                                WHEN bt.budget_type_group_id = 4
10779                                AND q.budget_margin_enabled > 0
10780                                AND q.budget_margin_enabled IS NOT NULL
10781                                AND q.margin_for_the_company <> 0
10782                            THEN q.margin_for_the_company * q.amount
10783                            END s1,
10784                            q.invoice_margin,
10785                            CASE
10786                                WHEN bt.budget_type_group_id = 4
10787                                AND q.budget_margin_enabled > 0
10788                                AND q.budget_margin_enabled IS NOT NULL
10789                                AND q.invoice_margin <> 0
10790                            THEN q.invoice_margin * q.amount
10791                            END s2,
10792                            q.budget_type_id,
10793                            q.budget_status_id,
10794                            q.amount,
10795                            bt.budget_type_group_id,
10796                            q.budget_margin_enabled
10797                        FROM
10798                            tbl_quotations q
10799                        JOIN tbl_companies c
10800                            ON c.company_id = q.company_id
10801                        LEFT JOIN tbl_budget_types bt
10802                            ON q.budget_type_id = bt.budget_type_id
10803                        LEFT JOIN tbl_users u
10804                            ON u.name = q.created_by
10805                        LEFT JOIN tbl_roles r
10806                            ON r.role_id = u.role_id
10807                        WHERE
10808                            q.issue_date IS NOT NULL
10809                            AND q.for_add != 1
10810                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
10811                            AND (q.commercial IS NOT NULL AND q.commercial != '')
10812                            AND q.budget_type_id != 7
10813                            AND q.budget_type_id IS NOT NULL
10814                            {$where}
10815
10816                        UNION ALL
10817
10818                        SELECT
10819                            c.region,
10820                            q.acceptance_date AS DATE,
10821                            'acceptance' AS date_type,
10822                            q.acceptance_date,
10823                            q.issue_date,
10824                            q.id,
10825                            q.margin_for_the_company,
10826                            CASE
10827                                WHEN bt.budget_type_group_id = 4
10828                                AND q.budget_margin_enabled > 0
10829                                AND q.budget_margin_enabled IS NOT NULL
10830                                AND q.margin_for_the_company > 0
10831                            THEN q.margin_for_the_company * q.amount
10832                            END s1,
10833                            q.invoice_margin,
10834                            CASE
10835                                WHEN bt.budget_type_group_id = 4
10836                                AND q.budget_margin_enabled <> 0
10837                                AND q.budget_margin_enabled IS NOT NULL
10838                                AND q.invoice_margin <> 0
10839                            THEN q.invoice_margin * q.amount
10840                            END s2,
10841                            q.budget_type_id,
10842                            q.budget_status_id,
10843                            q.amount,
10844                            bt.budget_type_group_id,
10845                            q.budget_margin_enabled
10846                        FROM
10847                            tbl_quotations q
10848                        JOIN tbl_companies c
10849                            ON c.company_id = q.company_id
10850                        LEFT JOIN tbl_budget_types bt
10851                            ON q.budget_type_id = bt.budget_type_id
10852                        LEFT JOIN tbl_users u
10853                            ON u.name = q.created_by
10854                        LEFT JOIN tbl_roles r
10855                            ON r.role_id = u.role_id
10856                        WHERE
10857                            q.acceptance_date IS NOT NULL
10858                            AND q.for_add != 1
10859                            AND q.budget_type_id IS NOT NULL
10860                            AND q.budget_type_id != 7
10861                            AND q.acceptance_date != '0000-00-00 00:00:00'
10862                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
10863                            {$where}
10864                    ) AS q
10865                    WHERE q.date != '0000-00-00 00:00:00' {$whereDates}
10866                    GROUP BY
10867                        q.region,
10868                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
10869                        MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
10870                        WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) WITH ROLLUP
10871                    ORDER BY
10872                        q.region IS NULL,
10873                        q.region,
10874                        CASE WHEN q.region IS NOT NULL
10875                            AND YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
10876                            AND MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
10877                            AND WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
10878                        THEN 0
10879                        ELSE 1 END,
10880                    YEAR DESC,
10881                    MONTH ASC,
10882                    WEEK ASC";
10883
10884            $value = Cache::get(base64_encode($query));
10885
10886            if(!$value){
10887                $result = DB::select($query);
10888
10889                Cache::put(base64_encode($query), $result, 600);
10890            }else{
10891                $result = $value;
10892            }
10893
10894            $query = "SELECT
10895                        q.region,
10896                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) 'year',
10897                        LPAD(MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'month',
10898                        LPAD(WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'week',
10899                        DATE_FORMAT(DATE_ADD(q.date, INTERVAL {$weekDay} DAY), '%W, %M %e') namedate,
10900
10901                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' THEN q.id END) AS groupConcatIdsTotalEnviado,
10902                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END), 0) AS totalIssueEnviado,
10903
10904                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoEnviado,
10905                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoEnviado,
10906                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalMantenimientoPercentageEnviado,
10907
10908                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosEnviado,
10909                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosEnviado,
10910                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalCorrectivosPercentageEnviado,
10911
10912                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasEnviado,
10913                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasEnviado,
10914                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalObrasPercentageEnviado,
10915
10916                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
10917                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
10918                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalOtrosPercentageEnviado,
10919
10920                        CASE
10921                            WHEN SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.amount ELSE 0 END) = 0 THEN 0
10922                            ELSE SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.s1 ELSE 0 END)
10923                                / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.amount ELSE 0 END)
10924                        END AS weightedAverageMarginForTheCompanyEnviado,
10925                        CASE
10926                            WHEN SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.amount ELSE 0 END) = 0 THEN 0
10927                            ELSE SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.s2 ELSE 0 END)
10928                                / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.amount ELSE 0 END)
10929                        END AS weightedAverageInvoiceEnviado,
10930
10931                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' THEN q.id END) AS groupConcatIdsTotalAceptado,
10932                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END), 0) AS totalIssueAceptado,
10933
10934                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoAceptado,
10935                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoAceptado,
10936                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) * 100, 0) totalMantenimientoPercentageAceptado,
10937
10938                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosAceptado,
10939                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosAceptado,
10940                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) * 100, 0) totalCorrectivosPercentageAceptado,
10941
10942                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasAceptado,
10943                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasAceptado,
10944                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) * 100, 0) totalObrasPercentageAceptado,
10945
10946                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosAceptado,
10947                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosAceptado,
10948                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) / SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) * 100, 0) totalOtrosPercentageAceptado,
10949
10950                        CASE
10951                            WHEN SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.amount ELSE 0 END) = 0 THEN 0
10952                            ELSE SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.s1 ELSE 0 END)
10953                                / SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.margin_for_the_company <> 0 THEN q.amount ELSE 0 END)
10954                        END AS weightedAverageMarginForTheCompanyAceptado,
10955                        CASE
10956                            WHEN SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.amount ELSE 0 END) = 0 THEN 0
10957                            ELSE SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.s2 ELSE 0 END)
10958                                / SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 AND q.budget_margin_enabled > 0 AND q.invoice_margin <> 0 THEN q.amount ELSE 0 END)
10959                        END AS weightedAverageInvoiceAceptado,
10960
10961                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalIssuePercentage,
10962                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END) * 100, 0) totalMantenimientoPercentage,
10963                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END) * 100, 0) totalCorrectivosPercentage,
10964                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END) * 100, 0) totalObrasPercentage,
10965                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) * 100 , 0) totalOtrosPercentage,
10966
10967                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL THEN {$col} END) * 100, 0) totalIssuePercentageLead,
10968                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL AND q.budget_type_group_id = 3 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL AND q.budget_type_group_id = 3 THEN {$col} END) * 100, 0) totalMantenimientoPercentageLead,
10969                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL AND q.budget_type_group_id = 5 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL AND q.budget_type_group_id = 5 THEN {$col} END) * 100, 0) totalCorrectivosPercentageLead,
10970                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL AND q.budget_type_group_id = 4 THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL AND q.budget_type_group_id = 4 THEN {$col} END) * 100, 0) totalObrasPercentageLead,
10971                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.issue_date IS NOT NULL AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' AND q.acceptance_date IS NOT NULL AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END) * 100 , 0) totalOtrosPercentageLead
10972                    FROM
10973                    (
10974                        SELECT
10975                            'Total Grupo FIRE' region,
10976                            q.issue_date AS DATE,
10977                            'issue' AS date_type,
10978                            q.acceptance_date,
10979                            q.issue_date,
10980                            q.id,
10981                            q.margin_for_the_company,
10982                            CASE
10983                                WHEN bt.budget_type_group_id = 4
10984                                AND q.budget_margin_enabled > 0
10985                                AND q.budget_margin_enabled IS NOT NULL
10986                                AND q.margin_for_the_company <> 0
10987                            THEN q.margin_for_the_company * q.amount
10988                            END s1,
10989                            q.invoice_margin,
10990                            CASE
10991                                WHEN bt.budget_type_group_id = 4
10992                                AND q.budget_margin_enabled > 0
10993                                AND q.budget_margin_enabled IS NOT NULL
10994                                AND q.invoice_margin <> 0
10995                            THEN q.invoice_margin * q.amount
10996                            END s2,
10997                            q.budget_type_id,
10998                            q.budget_status_id,
10999                            q.amount,
11000                            bt.budget_type_group_id,
11001                            q.budget_margin_enabled
11002                        FROM
11003                            tbl_quotations q
11004                        JOIN tbl_companies c
11005                            ON c.company_id = q.company_id
11006                        LEFT JOIN tbl_budget_types bt
11007                            ON q.budget_type_id = bt.budget_type_id
11008                        LEFT JOIN tbl_users u
11009                            ON u.name = q.created_by
11010                        LEFT JOIN tbl_roles r
11011                            ON r.role_id = u.role_id
11012                        WHERE
11013                            q.issue_date IS NOT NULL
11014                            AND q.for_add != 1
11015                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
11016                            AND (q.commercial IS NOT NULL AND q.commercial != '')
11017                            AND q.budget_type_id != 7
11018                            AND q.budget_type_id IS NOT NULL
11019                            {$where}
11020
11021                        UNION ALL
11022
11023                        SELECT
11024                            'Total Grupo FIRE' region,
11025                            q.acceptance_date AS DATE,
11026                            'acceptance' AS date_type,
11027                            q.acceptance_date,
11028                            q.issue_date,
11029                            q.id,
11030                            q.margin_for_the_company,
11031                            CASE
11032                                WHEN bt.budget_type_group_id = 4
11033                                AND q.budget_margin_enabled > 0
11034                                AND q.budget_margin_enabled IS NOT NULL
11035                                AND q.margin_for_the_company <> 0
11036                            THEN q.margin_for_the_company * q.amount
11037                            END s1,
11038                            q.invoice_margin,
11039                            CASE
11040                                WHEN bt.budget_type_group_id = 4
11041                                AND q.budget_margin_enabled > 0
11042                                AND q.budget_margin_enabled IS NOT NULL
11043                                AND q.invoice_margin <> 0
11044                            THEN q.invoice_margin * q.amount
11045                            END s2,
11046                            q.budget_type_id,
11047                            q.budget_status_id,
11048                            q.amount,
11049                            bt.budget_type_group_id,
11050                            q.budget_margin_enabled
11051                        FROM
11052                            tbl_quotations q
11053                        JOIN tbl_companies c
11054                            ON c.company_id = q.company_id
11055                        LEFT JOIN tbl_budget_types bt
11056                            ON q.budget_type_id = bt.budget_type_id
11057                        LEFT JOIN tbl_users u
11058                            ON u.name = q.created_by
11059                        LEFT JOIN tbl_roles r
11060                            ON r.role_id = u.role_id
11061                        WHERE
11062                            q.acceptance_date IS NOT NULL
11063
11064                            AND q.for_add != 1
11065                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
11066                            AND (q.commercial IS NOT NULL AND q.commercial != '')
11067                            AND q.budget_type_id != 7
11068                            AND q.budget_type_id IS NOT NULL
11069                            {$where}
11070                    ) AS q
11071                    WHERE q.date != '0000-00-00 00:00:00' {$whereDates}
11072                    GROUP BY
11073                        q.region,
11074                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11075                        MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11076                        WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) WITH ROLLUP
11077                    ORDER BY
11078                        q.region IS NULL,
11079                        q.region,
11080                        CASE WHEN q.region IS NOT NULL
11081                            AND YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11082                            AND MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11083                            AND WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11084                        THEN 0
11085                        ELSE 1 END,
11086                    YEAR DESC,
11087                    MONTH ASC,
11088                    WEEK ASC";
11089
11090            $totalGroupValue = Cache::get(base64_encode($query));
11091
11092            if(!$totalGroupValue){
11093                $totalGroup = DB::select($query);
11094
11095                Cache::put(base64_encode($query), $totalGroup, 600);
11096            }else{
11097                $totalGroup = $totalGroupValue;
11098            }
11099
11100            array_pop($result);
11101            $merged = array_merge($result, $totalGroup);
11102
11103            return response([
11104                'message' => 'OK',
11105                'data' => $merged
11106            ]);
11107
11108        } catch (\Exception $e) {
11109            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11110        }
11111
11112    }
11113
11114    public function getIdsFromInternalQuoteIds($ids){
11115        $idsArray = array_filter(explode(',', $ids), 'is_numeric');
11116        return TblQuotations::whereIn("internal_quote_id", $idsArray)
11117            ->pluck("id")
11118            ->toArray();
11119    }
11120
11121    public function checkQuotationExistByInternalQuoteId(Request $request)
11122    {
11123        try{
11124            $idsString = $request->all()["ids"];
11125            $ids = explode(',',$idsString);
11126            $region = urldecode(@getallheaders()["Region"]);
11127            $company = TblCompanies::where("region", $region)->first();
11128
11129            if(!$company){
11130                Throw new \Exception("Region no encontrada");
11131            }
11132
11133            $companyId = $company->company_id;
11134
11135            $idsChecked = [];
11136
11137            foreach ($ids as $id){
11138                $quote = TblQuotations::where("internal_quote_id", $id)->where("company_id", $companyId)->first();
11139                if(
11140                    ($companyId === 18 || $companyId === 22)
11141                    && !$quote
11142                ){
11143                    $quote = TblQuotations::where("internal_quote_id", $id)->whereIn("company_id", [18,22])->first();
11144                }
11145                $idsChecked[$id] = $quote ? $quote->id : null;
11146            }
11147
11148            return response([
11149                'message' => 'OK',
11150                'data' => $idsChecked
11151            ]);
11152
11153        }catch (\Exception $e) {
11154            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11155        }
11156
11157    }
11158
11159    public function addUpdateLog($id, $userId, $field, $oldData, $newData){
11160        $oldRegister = null;
11161        $newRegister = null;
11162
11163        if($field == "company_id"){
11164            $oldRegister = TblCompanies::where("company_id", $oldData)->first();
11165            $newRegister = TblCompanies::where("company_id", $newData)->first();
11166        }
11167
11168        if($field == "customer_type_id"){
11169            $oldRegister = TblCustomerTypes::where("customer_type_id", $oldData)->first();
11170            $newRegister = TblCustomerTypes::where("customer_type_id", $newData)->first();
11171        }
11172
11173        if($field == "segment_id"){
11174            $oldRegister = TblSegments::where("segment_id", $oldData)->first();
11175            $newRegister = TblSegments::where("segment_id", $newData)->first();
11176        }
11177
11178        if($field == "budget_type_id"){
11179            $oldRegister = TblBudgetTypes::where("budget_type_id", $oldData)->first();
11180            $newRegister = TblBudgetTypes::where("budget_type_id", $newData)->first();
11181        }
11182
11183        if($field == "budget_status_id"){
11184            $oldRegister = TblBudgetStatus::where("budget_status_id", $oldData)->first();
11185            $newRegister = TblBudgetStatus::where("budget_status_id", $newData)->first();
11186        }
11187
11188        if($field == "source_id"){
11189            $oldRegister = TblSources::where("source_id", $oldData)->first();
11190            $newRegister = TblSources::where("source_id", $newData)->first();
11191        }
11192
11193        $oldData = $oldRegister ? $oldRegister->name : 'N/A';
11194        $newData = $newRegister ? $newRegister->name : 'N/A';
11195
11196        if(is_numeric($userId)){
11197            $userName = TblUsers::where("id", $userId)->first()->name;
11198        } else {
11199            $userName = $userId;
11200        }
11201
11202        if($oldData !== $newData){
11203            TblQuotationsLog::create(
11204                array(
11205                    'quotation_id' => $id,
11206                    'user' => $userName,
11207                    'field' => $field,
11208                    'old_value' => $oldData,
11209                    'new_value' => $newData
11210                )
11211            );
11212        }
11213    }
11214}