Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 5421
0.00% covered (danger)
0.00%
0 / 81
CRAP
0.00% covered (danger)
0.00%
0 / 1
Quotations
0.00% covered (danger)
0.00%
0 / 5421
0.00% covered (danger)
0.00%
0 / 81
1686102
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
6
 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
0.00% covered (danger)
0.00%
0 / 366
0.00% covered (danger)
0.00%
0 / 1
14280
 compareArrays
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
42
 convertValue
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
56
 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
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
72
 list_quotations
0.00% covered (danger)
0.00%
0 / 371
0.00% covered (danger)
0.00%
0 / 1
14520
 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 / 116
0.00% covered (danger)
0.00%
0 / 1
1560
 list_quotation_analytics_send_budgets
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 1
342
 list_quotation_analytics_track_budgets
0.00% covered (danger)
0.00%
0 / 116
0.00% covered (danger)
0.00%
0 / 1
1260
 list_quotation_analytics_types_budgets
0.00% covered (danger)
0.00%
0 / 118
0.00% covered (danger)
0.00%
0 / 1
992
 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
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
132
 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 / 30
0.00% covered (danger)
0.00%
0 / 1
20
 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 / 189
0.00% covered (danger)
0.00%
0 / 1
3540
 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 / 182
0.00% covered (danger)
0.00%
0 / 1
2862
 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 / 191
0.00% covered (danger)
0.00%
0 / 1
4290
 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 / 186
0.00% covered (danger)
0.00%
0 / 1
3540
 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 / 229
0.00% covered (danger)
0.00%
0 / 1
4290
 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
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 list_quotation_analytics_by_service_type
0.00% covered (danger)
0.00%
0 / 163
0.00% covered (danger)
0.00%
0 / 1
1190
 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
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
132
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                $where .= " AND q.company_id IN ({$this->companyId}";
3009            }
3010
3011            if(isset($data['source']) && $data['source'] != null){
3012                $where .= " AND s.name = '{$data['source']}'";
3013            }
3014
3015            if(isset($data['month']) && $data['month'] != null){
3016                $where .= " AND MONTH(q.issue_date) = '{$data['month']}'";
3017            }
3018
3019            if(isset($data['week']) && $data['week'] != null){
3020                $where .= " AND WEEK(q.issue_date) = '{$data['week']}'";
3021            }
3022
3023            if(isset($data['commercial']) && $data['commercial'] != null){
3024                $where .= " AND q.commercial = '{$data['commercial']}'";
3025            }
3026
3027            if(isset($data['created_by']) && $data['created_by'] != null){
3028                $where .= " AND q.created_by = '{$data['created_by']}'";
3029            }
3030
3031            if(isset($data['budget_type']) && $data['budget_type'] != null){
3032                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
3033            }
3034
3035            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3036                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3037            }
3038
3039            if(isset($data['budget_status']) && $data['budget_status'] != null){
3040                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3041            }
3042
3043            if(isset($data['client_type']) && $data['client_type'] != null){
3044                $where .= " AND ct.customer_type_id = {$data['client_type']}";
3045            }
3046
3047            if(isset($data['segment_id']) && $data['segment_id'] != null){
3048                $where .= " AND q.segment_id = {$data['segment_id']}";
3049            }
3050
3051            $query = "SELECT
3052                        YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) AS 'year',
3053                        LPAD(MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'month',
3054                        LPAD(WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'week',
3055                        DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') issue_date,
3056                        COUNT(
3057                            CASE WHEN q.issue_date IS NOT NULL
3058                            THEN 1 END
3059                        ) AS totalIssue,
3060                        GROUP_CONCAT(
3061                            CASE WHEN q.issue_date IS NOT NULL
3062                            THEN q.id END
3063                        ) AS groupConcatIds,
3064                        SUM(
3065                            CASE WHEN q.issue_date IS NOT NULL THEN q.amount END
3066                        ) AS revenueIssue,
3067                        COUNT(
3068                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN 1 END
3069                        ) AS totalAcceptance,
3070                        SUM(
3071                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN q.amount END
3072                        ) AS revenueAcceptance,
3073                        SUM(
3074                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN q.amount END
3075                        ) / SUM(
3076                            CASE WHEN q.issue_date IS NOT NULL THEN q.amount END
3077                        ) * 100 AS revenueAcceptanceIssuedPercentage,
3078                        COUNT(
3079                            CASE WHEN bs.name = 'Rechazado' THEN 1 END
3080                        ) AS totalRejected,
3081                        SUM(
3082                            CASE WHEN bs.name = 'Rechazado' THEN q.amount END
3083                        ) AS revenueRejected,
3084                        COUNT(
3085                            CASE WHEN bs.name = 'Rechazado - automaticamente' THEN 1 END
3086                        ) AS totalRejectedAutomatic,
3087                        SUM(
3088                            CASE WHEN bs.name = 'Rechazado - automaticamente' THEN q.amount END
3089                        ) AS revenueRejectedAutomatic
3090                    FROM
3091                        tbl_quotations q
3092                        LEFT JOIN tbl_sources s ON s.source_id = q.source_id
3093                        LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3094                        LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3095                        LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
3096                    WHERE
3097                        q.issue_date IS NOT NULL
3098                        AND q.budget_type_id != 7
3099                        AND q.budget_type_id IS NOT NULL
3100                        AND q.for_add != 1
3101                        AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3102                        {$where}
3103                        {$whereYear}
3104                        AND YEAR(q.issue_date) NOT IN (2021, 2022)
3105                    GROUP BY
3106                        YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3107                        MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3108                        WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) WITH ROLLUP
3109                    ORDER BY
3110                        YEAR DESC,
3111                        MONTH ASC,
3112                        WEEK ASC,
3113                        DATE_FORMAT(q.issue_date, '%e') ASC";
3114
3115            $value = Cache::get(base64_encode($query));
3116
3117            if(!$value){
3118                $result = DB::select($query);
3119
3120                Cache::put(base64_encode($query), $result, 600);
3121            }else{
3122                $result = $value;
3123            }
3124
3125            return response([
3126                'message' => 'OK',
3127                'data' => $result
3128            ]);
3129
3130        } catch (\Exception $e) {
3131            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3132        }
3133    }
3134
3135    public function list_quotation_analytics_send_budgets(Request $request){
3136
3137        try {
3138
3139            $data = $request->all();
3140            $companyId = addslashes($data['company_id']);
3141
3142            $whereYear = "";
3143
3144            $where = " AND q.company_id IN ({$this->companyId}";
3145
3146            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3147                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3148            }
3149
3150            if(isset($data['budget_status']) && $data['budget_status'] != null){
3151                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3152            }
3153
3154            if(isset($data['years']) && $data['years'] != null){
3155                $years = implode(',', $data['years']);
3156                if(count($data['years']) > 0){
3157                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3158                }
3159            }
3160
3161            $query = "SELECT
3162                            YEAR(q.issue_date) AS 'year',
3163                            MONTH(q.issue_date) AS 'month',
3164                            SUM(
3165                                CASE WHEN MONTH(request_date) = MONTH(issue_date) THEN 1 ELSE 0 END
3166                            ) totalRequest,
3167                            COUNT(
3168                                CASE WHEN q.issue_date IS NOT NULL THEN 1 END
3169                            ) AS totalIssue,
3170                            GROUP_CONCAT(
3171                                CASE WHEN q.issue_date IS NOT NULL
3172                                THEN q.id END
3173                            ) AS groupConcatIds,
3174                            SUM(
3175                                CASE WHEN MONTH(request_date) = MONTH(issue_date) THEN 1 ELSE 0 END
3176                            ) /
3177                            COUNT(
3178                                CASE WHEN q.issue_date IS NOT NULL THEN 1 END
3179                            ) * 100 issuePercentage,
3180                            AVG(
3181                                COALESCE(q.duration, 0)
3182                            ) AS averageDurationIssue,
3183                            COALESCE(
3184                                AVG(
3185                                    CASE WHEN bt.name = 'Mantenimiento' THEN COALESCE(q.duration, 0) ELSE NULL END
3186                                ), 0
3187                            ) AS averageDurationMaintenance,
3188                            COALESCE(
3189                                AVG(
3190                                    CASE WHEN bt.name = 'Nuevos' THEN COALESCE(q.duration, 0) ELSE NULL END
3191                                ), 0
3192                            ) AS averageDurationNew,
3193                            COALESCE(
3194                                AVG(
3195                                    CASE WHEN bt.name = 'Correctivos' THEN COALESCE(q.duration, 0) ELSE NULL END
3196                                ), 0
3197                            ) AS averageDurationCorretive,
3198                            COALESCE(
3199                                AVG(
3200                                    CASE WHEN bt.name = 'Anomalías' THEN COALESCE(q.duration, 0) ELSE NULL END
3201                                ), 0
3202                            ) AS averageDurationAnomalies,
3203                            COALESCE(
3204                                AVG(
3205                                    CASE WHEN bt.name = 'Precios Unitarios' THEN COALESCE(q.duration, 0) ELSE NULL END
3206                                ), 0
3207                            ) AS averageDurationUnitPrice,
3208                            COALESCE(
3209                                AVG(
3210                                    CASE WHEN bt.name = 'Instalaciones' THEN COALESCE(q.duration, 0) ELSE NULL END
3211                                ), 0
3212                            ) AS averageDurationFacilities,
3213                            COALESCE(
3214                                AVG(
3215                                    CASE WHEN bt.name = 'Alquiler' THEN COALESCE(q.duration, 0) ELSE NULL END
3216                                ), 0
3217                            ) AS averageDurationRent,
3218                            COALESCE(
3219                                AVG(
3220                                    CASE WHEN bt.name = 'OCA visita' THEN COALESCE(q.duration, 0) ELSE NULL END
3221                                ), 0
3222                            ) AS averageDurationOCA,
3223                            COALESCE(
3224                                AVG(
3225                                    CASE WHEN bt.name = 'Retirada y gestion de residuos' THEN COALESCE(q.duration, 0) ELSE NULL END
3226                                ), 0
3227                            ) AS averageDurationWRM,
3228                            COALESCE(
3229                                AVG(
3230                                    CASE WHEN bt.name = 'Formación' THEN COALESCE(q.duration, 0) ELSE NULL END
3231                                ), 0
3232                            ) AS averageDurationTraining,
3233                            COALESCE(
3234                                AVG(
3235                                    CASE WHEN bt.name = 'Anomalías de facilities' THEN COALESCE(q.duration, 0) ELSE NULL END
3236                                ), 0
3237                            ) AS averageDurationFacilityAnomalies
3238                        FROM
3239                            tbl_quotations q
3240                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3241                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_id = btg.budget_type_id
3242                        WHERE
3243                            q.issue_date IS NOT NULL
3244                            AND q.budget_type_id != 7
3245                            AND q.budget_type_id IS NOT NULL
3246                            AND q.for_add != 1
3247                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3248                            {$where}
3249                            {$whereYear}
3250                        GROUP BY
3251                            YEAR(q.issue_date),
3252                            MONTH(q.issue_date) WITH ROLLUP
3253                        ORDER BY
3254                            YEAR(q.issue_date) DESC,
3255                            MONTH(q.issue_date) ASC";
3256
3257            $sendBudgets = array();
3258            $sendBudgetsTotals = array();
3259
3260            $value = Cache::get(base64_encode($query));
3261
3262            if(!$value){
3263                $result = DB::select($query);
3264
3265                Cache::put(base64_encode($query), $result, 600);
3266            }else{
3267                $result = $value;
3268            }
3269
3270            if(count($result) > 0){
3271                for ($i = 0; $i < count($result); $i++) {
3272
3273                    if($result[$i]->year == null && $result[$i]->month == null){
3274                        $result[$i]->month = "totalGeneral";
3275                        $sendBudgetsTotals["totalGeneral"] = $result[$i];
3276                        continue;
3277                    }elseif($result[$i]->month == null && $result[$i]->year != null){
3278                        if(count($data['years']) > 0 || $whereYear == ""){
3279                            $result[$i]->month = "totalSub";
3280                        }else{
3281                            continue;
3282                        }
3283                    }else{
3284                        $result[$i]->month = sprintf("%02d", $result[$i]->month);
3285                    }
3286
3287                    $sendBudgets[$result[$i]->year][$result[$i]->month] = $result[$i];
3288                }
3289            }
3290
3291            return response([
3292                'message' => 'OK',
3293                'data' => $sendBudgets,
3294                'totals' => $sendBudgetsTotals
3295            ]);
3296
3297        } catch (\Exception $e) {
3298            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3299        }
3300    }
3301
3302    public function list_quotation_analytics_track_budgets(Request $request){
3303
3304        try {
3305
3306            $data = $request->all();
3307            $companyId = addslashes($data['company_id']);
3308
3309            $where = "";
3310            $whereYear = "";
3311            $isBetween = false;
3312
3313            $dateLflArray = array();
3314            $companyIds = $this->companyIds;
3315
3316            if($companyId != 0){
3317                $companyIds = array($companyId);
3318            }
3319
3320            if(isset($data['years']) && $data['years'] != null){
3321                $years = implode(',', $data['years']);
3322                if(count($data['years']) > 0){
3323                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3324                }
3325            }
3326
3327            $field = "issue_date";
3328
3329            foreach ($companyIds as $v) {
3330
3331                $lflWhere = " AND q.company_id = {$v} ";
3332
3333                $query = "SELECT
3334                            CONCAT(
3335                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
3336                                ' - ',
3337                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
3338                            ) AS date_like,
3339                            YEAR(q.{$field}) 'year',
3340                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
3341                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
3342                            {$v} 'company_id'
3343                        FROM
3344                            tbl_quotations q
3345                        WHERE
3346                            q.{$field} IS NOT NULL
3347                            AND q.for_add != 1
3348                            {$lflWhere}
3349                            {$whereYear}
3350                        GROUP BY YEAR(q.{$field})
3351                        ORDER BY YEAR(q.{$field}) DESC";
3352
3353                $dateLike = DB::select($query);
3354
3355                $dateLflArray[$v] = $dateLike;
3356            }
3357
3358            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
3359
3360            $isFy = true;
3361
3362            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
3363                $isFy = false;
3364                $ytdArray = array();
3365                $ytdAcceptanceArray = array();
3366                $lflCompanyIds = array();
3367                $lflCompanyIdsAcc = array();
3368                foreach ($dateLflArray as $k => $v) {
3369                    foreach ($dateLflArray[$k] as $item) {
3370                        $year = $item->year;
3371                        $now = date('m-d');
3372                        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)");
3373                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
3374                    }
3375
3376                    $ytdArray = implode(' OR ', $ytdArray);
3377                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
3378                    $ytdArray = array();
3379
3380                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3381                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3382                    $ytdAcceptanceArray = array();
3383                }
3384
3385                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3386                $where .= " AND ({$lflCompanyIds}";
3387
3388                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3389                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3390            }
3391
3392            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
3393                $isFy = false;
3394                $lflArray = array();
3395                $ytdAcceptanceArray = array();
3396                $lflCompanyIds = array();
3397                $lflCompanyIdsAcc = array();
3398                foreach ($dateLflArray as $k => $v) {
3399                    foreach ($dateLflArray[$k] as $item) {
3400                        $year = $item->year;
3401                        $min_date_like = $item->min_date_like;
3402                        $max_date_like = $item->max_date_like;
3403                        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)");
3404                        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}')");
3405                    }
3406
3407                    $lflArray = implode(' OR ', $lflArray);
3408                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
3409                    $lflArray = array();
3410
3411                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3412                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3413                    $ytdAcceptanceArray = array();
3414                }
3415
3416                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3417                $where .= " AND ({$lflCompanyIds}";
3418
3419                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3420                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3421            }
3422
3423            if($isFy){                
3424                $where .= " AND q.company_id IN ({$this->companyId}";
3425            }
3426
3427            if(isset($data['source']) && $data['source'] != null){
3428                $where .= " AND s.name = '{$data['source']}'";
3429            }
3430
3431            if(isset($data['commercial']) && $data['commercial'] != null){
3432                $where .= " AND q.commercial = '{$data['commercial']}'";
3433            }
3434
3435            if(isset($data['created_by']) && $data['created_by'] != null){
3436                $where .= " AND q.created_by = '{$data['created_by']}'";
3437            }
3438
3439            if(isset($data['budget_type']) && $data['budget_type'] != null){
3440                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
3441            }
3442
3443            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3444                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3445            }
3446
3447            if(isset($data['budget_status']) && $data['budget_status'] != null){
3448                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3449            }
3450
3451            if(isset($data['client_type']) && $data['client_type'] != null){
3452                $where .= " AND ct.customer_type_id = {$data['client_type']}";
3453            }
3454
3455            if(isset($data['segment_id']) && $data['segment_id'] != null){
3456                $where .= " AND q.segment_id = {$data['segment_id']}";
3457            }
3458
3459            $query = "SELECT
3460                            YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) AS 'year',
3461                            LPAD(MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'month',
3462                            LPAD(WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'week',
3463                            DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') issue_date,
3464                            COUNT(
3465                                CASE WHEN q.issue_date IS NOT NULL
3466                                THEN 1 END
3467                            ) AS totalIssue,
3468                            GROUP_CONCAT(
3469                                CASE WHEN q.issue_date IS NOT NULL
3470                                THEN q.id END
3471                            ) AS groupConcatIds,
3472                            COUNT(
3473                                CASE WHEN {$whereAcceptanceDate}
3474                                AND bs.name = 'Aceptado' THEN 1 END) totalAccept,
3475                            COUNT(
3476                                CASE WHEN q.acceptance_date IS NOT NULL
3477                                AND {$whereAcceptanceDate}
3478                                AND bs.name = 'Aceptado'
3479                                AND DATEDIFF(q.acceptance_date, q.issue_date) <= 10 THEN 1 END
3480                            ) / COUNT(
3481                                CASE WHEN q.issue_date IS NOT NULL
3482                                THEN 1 END
3483                            ) * 100 AS percentageOfacceptanceLessThan10,
3484                            COUNT(
3485                                CASE WHEN q.acceptance_date IS NOT NULL
3486                                AND {$whereAcceptanceDate}
3487                                AND bs.name = 'Aceptado'
3488                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 10
3489                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 30 THEN 1 END
3490                            ) / COUNT(
3491                                CASE WHEN q.issue_date IS NOT NULL
3492                                THEN 1 END
3493                            ) * 100 AS percentageOfacceptanceLessThan30,
3494                            COUNT(
3495                                CASE WHEN q.acceptance_date IS NOT NULL
3496                                AND {$whereAcceptanceDate}
3497                                AND bs.name = 'Aceptado'
3498                                AND DATEDIFF(q.acceptance_date, q.issue_date) >= 30 THEN 1 END
3499                            ) / COUNT(
3500                                CASE WHEN q.issue_date IS NOT NULL
3501                                THEN 1 END
3502                            ) * 100 AS percentageOfacceptanceMoreThan30,
3503                            COUNT(CASE WHEN
3504                                {$whereAcceptanceDate} THEN 1 END
3505                            ) / COUNT(
3506                                CASE WHEN q.issue_date IS NOT NULL
3507                                THEN 1 END
3508                            ) * 100 acceptedPercentage,
3509                            COALESCE(
3510                                AVG(
3511                                    CASE WHEN q.issue_date IS NOT NULL
3512                                    AND q.acceptance_date IS NOT NULL
3513                                    AND {$whereAcceptanceDate}
3514                                    AND bs.name = 'Aceptado'
3515                                    THEN DATEDIFF(q.acceptance_date, q.issue_date) ELSE NULL END
3516                                ), 0
3517                            )
3518                            AS averageAcceptedDuration,
3519                            COALESCE(
3520                                AVG(
3521                                    CASE WHEN q.issue_date IS NOT NULL
3522                                    AND q.request_date IS NOT NULL
3523                                    THEN DATEDIFF(q.issue_date, q.request_date) ELSE NULL END
3524                                ), 0
3525                            )
3526                            AS averageRequestedDays
3527                        FROM
3528                            tbl_quotations q
3529                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3530                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3531                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
3532                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
3533                        WHERE
3534                            q.issue_date IS NOT NULL
3535                            AND q.budget_type_id != 7
3536                            AND q.budget_type_id IS NOT NULL
3537                            AND q.for_add != 1
3538                            {$where}
3539                            {$whereYear}
3540                        GROUP BY
3541                            YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3542                            MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3543                            WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) WITH ROLLUP
3544                        ORDER BY
3545                            YEAR DESC,
3546                            MONTH ASC,
3547                            WEEK ASC,
3548                            DATE_FORMAT(q.issue_date, '%e') ASC";
3549
3550            $value = Cache::get(base64_encode($query));
3551
3552            if(!$value){
3553                $result = DB::select($query);
3554
3555                Cache::put(base64_encode($query), $result, 600);
3556            }else{
3557                $result = $value;
3558            }
3559
3560            return response([
3561                'message' => 'OK',
3562                'data' => $result
3563            ]);
3564
3565        } catch (\Exception $e) {
3566            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3567        }
3568    }
3569
3570    public function list_quotation_analytics_types_budgets(Request $request){
3571
3572        try {
3573
3574            $data = $request->all();
3575            $companyId = addslashes($data['company_id']);
3576
3577            $where = "";
3578            $whereYear = "";
3579            $isBetween = false;
3580
3581            $dateLflArray = array();
3582            $companyIds = $this->companyIds;
3583
3584            if($companyId != 0){
3585                $companyIds = array($companyId);
3586            }
3587
3588            if(isset($data['years']) && $data['years'] != null){
3589                $years = implode(',', $data['years']);
3590                if(count($data['years']) > 0){
3591                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3592                }
3593            }
3594
3595            $field = "issue_date";
3596
3597            foreach ($companyIds as $v) {
3598
3599                $lflWhere = " AND q.company_id = {$v} ";
3600
3601                $query = "SELECT
3602                            CONCAT(
3603                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
3604                                ' - ',
3605                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
3606                            ) AS date_like,
3607                            YEAR(q.{$field}) 'year',
3608                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
3609                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
3610                            {$v} 'company_id'
3611                        FROM
3612                            tbl_quotations q
3613                        WHERE
3614                            q.{$field} IS NOT NULL
3615                            AND q.for_add != 1
3616                            {$lflWhere}
3617                            {$whereYear}
3618                        GROUP BY YEAR(q.{$field})
3619                        ORDER BY YEAR(q.{$field}) DESC";
3620
3621                $dateLike = DB::select($query);
3622
3623                $dateLflArray[$v] = $dateLike;
3624            }
3625
3626            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
3627
3628            $isFy = true;
3629
3630            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
3631                $isFy = false;
3632                $ytdArray = array();
3633                $ytdAcceptanceArray = array();
3634                $lflCompanyIds = array();
3635                $lflCompanyIdsAcc = array();
3636                foreach ($dateLflArray as $k => $v) {
3637                    foreach ($dateLflArray[$k] as $item) {
3638                        $year = $item->year;
3639                        $now = date('m-d');
3640                        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)");
3641                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
3642                    }
3643
3644                    $ytdArray = implode(' OR ', $ytdArray);
3645                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
3646                    $ytdArray = array();
3647
3648                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3649                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3650                    $ytdAcceptanceArray = array();
3651                }
3652
3653                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3654                $where .= " AND ({$lflCompanyIds}";
3655
3656                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3657                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3658            }
3659
3660            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
3661                $isFy = false;
3662                $lflArray = array();
3663                $ytdAcceptanceArray = array();
3664                $lflCompanyIds = array();
3665                $lflCompanyIdsAcc = array();
3666                foreach ($dateLflArray as $k => $v) {
3667                    foreach ($dateLflArray[$k] as $item) {
3668                        $year = $item->year;
3669                        $min_date_like = $item->min_date_like;
3670                        $max_date_like = $item->max_date_like;
3671                        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)");
3672                        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}')");
3673                    }
3674
3675                    $lflArray = implode(' OR ', $lflArray);
3676                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
3677                    $lflArray = array();
3678
3679                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3680                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3681                    $ytdAcceptanceArray = array();
3682                }
3683
3684                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3685                $where .= " AND ({$lflCompanyIds}";
3686
3687                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3688                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3689            }
3690
3691            if($isFy){                
3692                $where .= " AND q.company_id IN ({$this->companyId}";
3693            }
3694
3695            if(isset($data['budget_status']) && $data['budget_status'] != null){
3696                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3697            }
3698
3699            if(isset($data['segment_id']) && $data['segment_id'] != null){
3700                $where .= " AND q.segment_id = {$data['segment_id']}";
3701            }
3702
3703            $query = "SELECT
3704                            YEAR(q.issue_date) AS 'year',
3705                            bt.name,
3706                            COUNT(
3707                                CASE WHEN q.issue_date IS NOT NULL
3708                                THEN 1 END
3709                            ) AS totalIssue,
3710                            GROUP_CONCAT(
3711                                CASE WHEN q.issue_date IS NOT NULL
3712                                THEN q.id END
3713                            ) AS groupConcatIds,
3714                            COUNT(CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN 1 END) totalAccept,
3715                            COUNT(
3716                                CASE WHEN q.acceptance_date IS NOT NULL
3717                                AND {$whereAcceptanceDate}
3718                                AND bs.name = 'Aceptado'
3719                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 10 THEN 1 END
3720                            ) / COUNT(
3721                                CASE WHEN q.issue_date IS NOT NULL
3722                                THEN 1 END
3723                            ) * 100 AS percentageOfacceptanceLessThan10,
3724                            COUNT(
3725                                CASE WHEN q.acceptance_date IS NOT NULL
3726                                AND {$whereAcceptanceDate}
3727                                AND bs.name = 'Aceptado'
3728                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 10
3729                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 30 THEN 1 END
3730                            ) / COUNT(
3731                                CASE WHEN q.issue_date IS NOT NULL
3732                                THEN 1 END
3733                            ) * 100 AS percentageOfacceptanceLessThan30,
3734                            COUNT(
3735                                CASE WHEN q.acceptance_date IS NOT NULL
3736                                AND {$whereAcceptanceDate}
3737                                AND bs.name = 'Aceptado'
3738                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 30 THEN 1 END
3739                            ) / COUNT(
3740                                CASE WHEN q.issue_date IS NOT NULL
3741                                THEN 1 END
3742                            ) * 100 AS percentageOfacceptanceMoreThan30,
3743                            COUNT(CASE WHEN {$whereAcceptanceDate} THEN 1 END) / COUNT(
3744                                CASE WHEN q.issue_date IS NOT NULL
3745                                THEN 1 END
3746                            ) * 100 acceptedPercentage,
3747                            COALESCE(
3748                                AVG(
3749                                    CASE WHEN q.issue_date IS NOT NULL
3750                                    AND q.acceptance_date IS NOT NULL
3751                                    AND {$whereAcceptanceDate}
3752                                    AND bs.name = 'Aceptado'
3753                                    THEN DATEDIFF(q.acceptance_date, q.issue_date) ELSE NULL END
3754                                ), 0
3755                            )
3756                            AS averageAcceptedDuration,
3757                            COALESCE(
3758                                AVG(
3759                                    CASE WHEN q.issue_date IS NOT NULL
3760                                    AND q.request_date IS NOT NULL
3761                                    AND q.issue_date > q.request_date
3762                                    THEN DATEDIFF(q.issue_date, q.request_date) ELSE NULL END
3763                                ), 0
3764                            )
3765                            AS averageRequestedDays
3766                        FROM
3767                            tbl_quotations q
3768                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3769                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3770                        WHERE
3771                            q.issue_date IS NOT NULL
3772                            AND q.budget_type_id != 7
3773                            AND q.budget_type_id IS NOT NULL
3774                            AND q.for_add != 1
3775                            {$where}
3776                            {$whereYear}
3777                        GROUP BY
3778                            YEAR(q.issue_date),
3779                            bt.name WITH ROLLUP";
3780
3781            $value = Cache::get(base64_encode($query));
3782
3783            if(!$value){
3784                $result = DB::select($query);
3785
3786                Cache::put(base64_encode($query), $result, 600);
3787            }else{
3788                $result = $value;
3789            }
3790
3791            $typesBudgets = array();
3792            $typesBudgetsTotals = array();
3793
3794            if(count($result) > 0){
3795                for ($i = 0; $i < count($result); $i++) {
3796
3797                    if($result[$i]->year == null && $result[$i]->name == null){
3798                        $result[$i]->name = "totalGeneral";
3799                        $typesBudgetsTotals["totalGeneral"] = $result[$i];
3800                        continue;
3801                    }elseif($result[$i]->name == null && $result[$i]->year != null){
3802                        if(count($data['years']) > 0 || $whereYear == ""){
3803                            $result[$i]->name = "totalSub";
3804                        }else{
3805                            continue;
3806                        }
3807                    }
3808
3809                    $typesBudgets[$result[$i]->year][$result[$i]->name] = $result[$i];
3810                }
3811            }
3812
3813            return response([
3814                'message' => 'OK',
3815                'data' => $typesBudgets,
3816                'totals' => $typesBudgetsTotals
3817            ]);
3818
3819        } catch (\Exception $e) {
3820            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3821        }
3822    }
3823
3824    function download_quotations(Request $request){
3825        ini_set('max_execution_time', 123456);
3826        $data = $request->all();
3827        $companyId = addslashes($data['company_id']);
3828        $userId = addslashes($data['user_id']);
3829
3830        $where = "";
3831
3832        $query = "SELECT
3833                b.name
3834            FROM tbl_users a
3835            LEFT JOIN tbl_roles b
3836                ON a.role_id = b.role_id
3837            WHERE a.id = {$userId}";
3838
3839        $role = DB::select($query);
3840
3841        $r = new Request([
3842            'filterModel' => $data['filterModel'],
3843            'sortModel' => $data['sortModel'],
3844            'start' => 0,
3845            'end' => 999999999,
3846            'company_id' => $data['company_id'],
3847            'user_id' => $data['user_id'],
3848            'ids' => $data['ids'],
3849            'searchText' => $data['searchText'],
3850            'ids_not_in' => $data['ids_not_in']
3851        ]);
3852
3853        $result = $this->list_quotations($r);
3854
3855        $spreadsheet = new Spreadsheet();
3856        $worksheet   = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, "Inputs");
3857        $spreadsheet->addSheet($worksheet, 0);
3858        $col         = range('A', 'Z');
3859
3860        for($i = 0; $i < 26; $i++){
3861            $worksheet->getColumnDimension($col[$i])->setAutoSize(true);
3862            if($i != 1){
3863                $worksheet->getStyle($col[$i])
3864                    ->getAlignment()
3865                    ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
3866            }
3867        }
3868
3869        $worksheet->getColumnDimension("AB")->setAutoSize(true);
3870        $worksheet->getStyle("AB")
3871            ->getAlignment()
3872            ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
3873
3874        $l = 1;
3875        $worksheet->setCellValue('A' . $l, __('language.ID'));
3876        $worksheet->setCellValue('B' . $l, __('language.INTERNAL_ID'));
3877        $worksheet->setCellValue('C' . $l, __('language.CLIENT'));
3878        $worksheet->setCellValue('D' . $l, __('language.AMOUNT'));
3879        $worksheet->setCellValue('E' . $l, __('language.INVOICE_MARGIN'));
3880        $worksheet->setCellValue('F' . $l, __('language.MARGIN_FOR_THE_COMPANY'));
3881        $worksheet->setCellValue('G' . $l, __('language.TYPE'));
3882        $worksheet->setCellValue('H' . $l, __('language.STATUS'));
3883        $worksheet->setCellValue('I' . $l, __('language.CREATED_BY'));
3884        $worksheet->setCellValue('J' . $l, __('language.COMMERCIAL'));
3885        $worksheet->setCellValue('K' . $l, __('language.CREATED_AT'));
3886        $worksheet->setCellValue('L' . $l, __('language.ACCEPTANCE_DATE'));
3887        $worksheet->setCellValue('M' . $l, __('language.REQUEST_DATE'));
3888        $worksheet->setCellValue('N' . $l, __('language.ISSUE_DATE'));
3889        $worksheet->setCellValue('O' . $l, __('language.DURATION'));
3890        $worksheet->setCellValue('P' . $l, __('language.CLIENT_TYPE'));
3891        $worksheet->setCellValue('Q' . $l, __('language.SEGMENT'));
3892        $worksheet->setCellValue('R' . $l, __('language.LIKEHOOD'));
3893        $worksheet->setCellValue('S' . $l, __('language.SOURCE'));
3894        $worksheet->setCellValue('T' . $l, __('language.LAST_FOLLOW_UP_DATE'));
3895        $worksheet->setCellValue('U' . $l, __('language.REASON_FOR_NOT_FOLLOWING_UP'));
3896        $worksheet->setCellValue('V' . $l, __('language.REASON_FOR_REJECTION'));
3897        $worksheet->setCellValue('W' . $l, __('language.EMAIL'));
3898        $worksheet->setCellValue('X' . $l, __('language.EMAIL_STATUS'));
3899        $worksheet->setCellValue('Y' . $l, __('language.PHONE_NUMBER'));
3900        $worksheet->setCellValue('Z' . $l, __('language.ORDER_NUMBER'));
3901        $worksheet->setCellValue('AA' . $l, __('language.BOX_WORK_G3W'));
3902        $worksheet->setCellValue('AB' . $l, __('language.APPROVAL_REQUIRED'));
3903        $worksheet->setCellValue('AC' . $l, __('language.FILES_COUNT'));
3904        $worksheet->setCellValue('AD' . $l, __('language.ACCEPTED_BY'));
3905        $worksheet->setCellValue('AE' . $l, __('language.ACCEPTED_AT'));
3906        $worksheet->setCellValue('AF' . $l, "Origen");
3907        $worksheet->setCellValue('AG' . $l, "Origen Edit");
3908        $worksheet->setCellValue('AH' . $l, __('language.G3W_WARNING'));
3909        $worksheet->setCellValue('AI' . $l, __('language.COMPANY_NAME'));
3910
3911        $styleArray = [
3912            'font' => [
3913                'bold' => true,
3914            ]
3915        ];
3916
3917        $worksheet->getStyle('A1:AH1')
3918            ->getFill()
3919            ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
3920            ->getStartColor()
3921            ->setARGB('523779');
3922
3923        $worksheet->getStyle('A1:AH1')
3924            ->getFont()
3925            ->getColor()
3926            ->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
3927
3928        $worksheet->getStyle('A1:AH1')->applyFromArray($styleArray);
3929
3930        $l = 2;
3931        $result = $result->original['data'];
3932
3933        for ($i = 0; $i < count($result); $i++) {
3934
3935            if($result[$i]->request_date){
3936                $result[$i]->request_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->request_date);
3937            }
3938
3939            if($result[$i]->issue_date){
3940                $result[$i]->issue_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->issue_date);
3941            }
3942
3943            if($result[$i]->acceptance_date){
3944                $result[$i]->acceptance_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->acceptance_date);
3945            }
3946
3947            if($result[$i]->last_follow_up_date){
3948                $result[$i]->last_follow_up_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->last_follow_up_date);
3949            }
3950
3951            if($result[$i]->created_at){
3952                $result[$i]->created_at = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->created_at);
3953            }
3954
3955            if($result[$i]->accepted_at){
3956                $result[$i]->accepted_at = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->accepted_at);
3957            }
3958
3959            $worksheet->setCellValue('A' . $l, $result[$i]->quote_id);
3960            $worksheet->setCellValue('B' . $l, $result[$i]->internal_quote_id);
3961            $worksheet->setCellValue('C' . $l, $result[$i]->client);
3962            $worksheet->setCellValue('D' . $l, $result[$i]->amount);
3963            $worksheet->setCellValue('E' . $l, $result[$i]->invoice_margin);
3964            $worksheet->setCellValue('F' . $l, $result[$i]->margin_for_the_company);
3965            $worksheet->setCellValue('G' . $l, $result[$i]->type);
3966            $worksheet->setCellValue('H' . $l, $result[$i]->status);
3967            $worksheet->setCellValue('I' . $l, $result[$i]->created_by);
3968            $worksheet->setCellValue('J' . $l, $result[$i]->commercial);
3969            $worksheet->setCellValue('K' . $l, $result[$i]->created_at);
3970
3971            $worksheet->getStyle('K' . $l)
3972                ->getNumberFormat()
3973                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
3974
3975            $worksheet->setCellValue('L' . $l, $result[$i]->acceptance_date);
3976
3977            $worksheet->getStyle('L' . $l)
3978                ->getNumberFormat()
3979                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
3980
3981            $worksheet->setCellValue('M' . $l, $result[$i]->request_date);
3982
3983            $worksheet->getStyle('M' . $l)
3984                ->getNumberFormat()
3985                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
3986
3987            $worksheet->setCellValue('N' . $l, $result[$i]->issue_date);
3988
3989            $worksheet->getStyle('N' . $l)
3990                ->getNumberFormat()
3991                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
3992
3993            $worksheet->setCellValue('O' . $l, '=DATEDIF(J'.$l.',K'.$l.',"d")');
3994            $worksheet->setCellValue('P' . $l, $result[$i]->client_type);
3995            $worksheet->setCellValue('Q' . $l, $result[$i]->segment);
3996            $worksheet->setCellValue('R' . $l, $result[$i]->likehood);
3997            $worksheet->setCellValue('S' . $l, $result[$i]->source);
3998            $worksheet->setCellValue('T' . $l, $result[$i]->last_follow_up_date);
3999
4000            $worksheet->getStyle('T' . $l)
4001                ->getNumberFormat()
4002                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4003
4004            $worksheet->setCellValue('U' . $l, $result[$i]->reason_for_not_following_up);
4005            $worksheet->setCellValue('V' . $l, $result[$i]->reason_for_rejection);
4006            $worksheet->setCellValue('W' . $l, $result[$i]->email);
4007            $worksheet->setCellValue('X' . $l, $result[$i]->x_status);
4008            $worksheet->setCellValue('Y' . $l, $result[$i]->phone_number);
4009            $worksheet->setCellValue('Z' . $l, $result[$i]->order_number);
4010            $worksheet->setCellValue('AA' . $l, $result[$i]->box_work_g3w);
4011            $worksheet->setCellValue('AB' . $l, ($result[$i]->for_approval == 1 || $result[$i]->for_approval == 3) ? __('language.YES') : __('language.NO'));
4012            $worksheet->setCellValue('AC' . $l, $result[$i]->has_attachment == 1 ? __('language.YES') : __('language.NO'));
4013            $worksheet->setCellValue('AD' . $l, $result[$i]->accepted_by);
4014            $worksheet->setCellValue('AE' . $l, $result[$i]->accepted_at);
4015
4016            $worksheet->getStyle('AE' . $l)
4017                ->getNumberFormat()
4018                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4019
4020            $worksheet->setCellValue('AF' . $l, $result[$i]->sync_import == 1 ? 'G3W' : 'Manual');
4021            $worksheet->setCellValue('AG' . $l, $result[$i]->sync_import_edited == 1 ? 'G3W' : 'Manual');
4022            $worksheet->setCellValue('AH' . $l, $result[$i]->g3w_warning == 1 ? 'Sí' : 'No');
4023            $worksheet->setCellValue('AI' . $l, $result[$i]->company_name);
4024            $l++;
4025
4026        }
4027
4028        if($role[0]->name == 'Regular'){
4029            $worksheet->removeColumn('D');
4030            $worksheet->removeColumn('W');
4031            $worksheet->removeColumn('X');
4032        }
4033
4034        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
4035        ob_start();
4036        $writer->save('php://output');
4037        $file = ob_get_contents();
4038        ob_end_clean();
4039
4040        return response($file);
4041    }
4042
4043    function bulk_upload(Request $request){
4044
4045        try {
4046
4047            $data = $request->all();
4048            $file = $request->file('file');
4049            $exte = 'Xlsx';
4050            $companyId = $data['company_id'];
4051
4052            if($file->getMimeType() == 'application/vnd.ms-excel'){
4053                $exte = 'Xls';
4054            }
4055
4056            $destination_path = env('BULK_UPLOAD_FILE_DESTINATION', 'E:/bulk_upload/');
4057            $filename         = $file->getClientOriginalName();
4058
4059            if(file_exists($destination_path . $filename)){
4060                $filename = pathinfo($filename, PATHINFO_FILENAME) . '-' . uniqid() . '.' . pathinfo($filename, PATHINFO_EXTENSION);
4061            }
4062
4063            $file->move($destination_path, $filename);
4064
4065            TblBulkUpload::create(
4066                array(
4067                    'company_id' => $companyId,
4068                    'filename' => $filename,
4069                    'status' => 'Uploading...',
4070                    'is_running' => 1,
4071                    'uploaded_by' => $data['created_by']
4072                )
4073            );
4074
4075            $command = "php BulkUploadQuotations.php '{$data['created_by']}' '{$exte}' '{$destination_path}' '{$filename}{$companyId}";
4076            exec($command . ' > /dev/null &');
4077
4078            $query = "";
4079            $isRunning = 0;
4080
4081            if($companyId == 0){
4082                $query = "SELECT * FROM tbl_bulk_upload ORDER BY started_at DESC";
4083                $isRunning = TblBulkUpload::where('is_running', 1)->count();
4084            }else{
4085                $query = "SELECT * FROM tbl_bulk_upload WHERE company_id = {$companyId} ORDER BY started_at DESC";
4086                $isRunning = TblBulkUpload::where('is_running', 1)->where('company_id', $companyId)->count();
4087            }
4088
4089            $result = DB::select($query);
4090
4091            return response(['message' => 'OK', 'data' => $result, 'is_running' => $isRunning]);
4092
4093        } catch (\Exception $e) {
4094            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4095        }
4096    }
4097
4098    function list_bulk_upload($companyId){
4099
4100        try {
4101
4102            $companyId = addslashes($companyId);
4103            $query = "";
4104            $isRunning = 0;
4105
4106            if($companyId == 0){
4107                $query = "SELECT * FROM tbl_bulk_upload ORDER BY started_at DESC";
4108                $isRunning = TblBulkUpload::where('is_running', 1)->count();
4109            }else{
4110                $query = "SELECT * FROM tbl_bulk_upload WHERE company_id = {$companyId} ORDER BY started_at DESC";
4111                $isRunning = TblBulkUpload::where('is_running', 1)->where('company_id', $companyId)->count();
4112            }
4113
4114            $result = DB::select($query);
4115
4116            return response(['message' => 'OK', 'data' => $result, 'is_running' => $isRunning]);
4117
4118        } catch (\Exception $e) {
4119            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4120        }
4121
4122    }
4123
4124    function delete_number(Request $request, $id){
4125
4126        try {
4127
4128            $id = addslashes($id);
4129            $data = $request->all();
4130
4131            $r = TblQuotations::where('id', $id)->first();
4132            $updatedAt = date('Y-m-d H:i:s');
4133            $query = "INSERT INTO tbl_quotations_deleted (id, quote_id, company_id, for_add, created_by, updated_by, updated_at)
4134                        SELECT id, quote_id, company_id, 1, created_by, '{$data['updated_by']}', '{$updatedAt}' FROM tbl_quotations WHERE id = {$id}";
4135
4136            DB::select($query);
4137
4138            TblQuotations::where('id', $id)->delete();
4139
4140            $latestBudget = TblQuotations::where('company_id', $r->company_id)->orderByRaw('id DESC')->pluck('quote_id')->first();
4141
4142            $query = "UPDATE tbl_companies SET last_id = '{$latestBudget}' WHERE company_id = {$r->company_id}";
4143            DB::select($query);
4144
4145            return response(['message' => 'OK']);
4146
4147        } catch (\Exception $e) {
4148            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4149        }
4150
4151    }
4152
4153    function get_number(Request $request, $companyId, $n = null){
4154
4155        try {
4156
4157            $companyId = addslashes($companyId);
4158            $data = $request->all();
4159            $latestBudget = array();
4160            $number = 0;
4161            $beforeLastId = null;
4162
4163            $x = true;
4164
4165            if($companyId == 0){
4166                $latestBudget = TblQuotations::orderByRaw('CAST(quote_id AS DOUBLE) DESC')->pluck('quote_id')->first();
4167            }else{
4168                $latestBudget = TblCompanies::where('company_id', $companyId)->pluck('last_id')->first();
4169
4170                if($latestBudget == null){
4171                    $latestBudget = TblQuotations::where('company_id', $companyId)->orderByRaw('id DESC')->pluck('quote_id')->first();
4172                    $beforeLastId = $latestBudget;
4173                }
4174            }
4175
4176            $number = $latestBudget;
4177
4178            while ($x) {
4179
4180                if(is_numeric(substr($number, -1))) {
4181                    $number++;
4182                }else{
4183                    $number .= "1";
4184                }
4185
4186                $check = 0;
4187
4188                if($companyId == 0){
4189                    $check = TblQuotations::where('quote_id', (string) $number)->count();
4190                }else{
4191                    $check = TblQuotations::where('company_id', $companyId)->where('quote_id', (string) $number)->count();
4192                }
4193
4194                if($check == 0){
4195                    $x = false;
4196                }
4197            }
4198
4199            $result = null;
4200
4201            if($n == null){
4202                $result = TblQuotations::create(array('quote_id' => $number, 'company_id' => $companyId, 'for_add' => 1, 'created_by' => $data['created_by']));
4203            }
4204
4205            if($beforeLastId == null){
4206                $beforeLastId = $number;
4207            }
4208
4209            $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}";
4210            DB::select($query);
4211
4212            return response([
4213                'message' => 'OK',
4214                'number' => $number,
4215                'id' => ($result !=  null) ? $result->id : null
4216            ]);
4217
4218
4219        } catch (\Exception $e) {
4220            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4221        }
4222
4223    }
4224
4225    function get_years(Request $request){
4226
4227        try {
4228
4229            $data = $request->all();
4230            $companyId = addslashes($data['company_id']);
4231            $where = "";
4232
4233            if($companyId != 0){
4234                $where = " AND company_id = {$companyId} ";
4235            }else{
4236                $where = " AND company_id IN ({$this->companyId}";
4237            }
4238
4239            $query = "SELECT
4240                        CONCAT(
4241                            DATE_FORMAT((SELECT MIN(issue_date) FROM tbl_quotations WHERE issue_date IS NOT NULL {$where}), '%c/%e/'), YEAR(issue_date),
4242                            ' - ',
4243                            DATE_FORMAT((SELECT MAX(issue_date) FROM tbl_quotations WHERE issue_date IS NOT NULL {$where}), '%c/%e/'), YEAR(issue_date)
4244                        ) AS date_like,
4245                        YEAR(issue_date) 'year'
4246                        FROM tbl_quotations
4247                        WHERE issue_date IS NOT NULL {$where}
4248                        GROUP BY YEAR(issue_date)
4249                        ORDER BY YEAR(issue_date) DESC";
4250
4251            $issueDate = DB::select($query);
4252
4253            $query = "SELECT
4254                        CONCAT(
4255                            DATE_FORMAT((SELECT MIN(created_at) FROM tbl_quotations WHERE created_at IS NOT NULL {$where}), '%c/%e/'), YEAR(created_at),
4256                            ' - ',
4257                            DATE_FORMAT((SELECT MAX(created_at) FROM tbl_quotations WHERE created_at IS NOT NULL {$where}), '%c/%e/'), YEAR(created_at)
4258                        ) AS date_like,
4259                        YEAR(created_at) 'year'
4260                        FROM tbl_quotations
4261                        WHERE created_at IS NOT NULL {$where}
4262                        GROUP BY YEAR(created_at)
4263                        ORDER BY YEAR(created_at) DESC";
4264
4265            $createdAt = DB::select($query);
4266
4267            $query = "SELECT
4268                        CONCAT(
4269                            DATE_FORMAT((SELECT MIN(acceptance_date) FROM tbl_quotations WHERE acceptance_date IS NOT NULL {$where}), '%c/%e/'), YEAR(acceptance_date),
4270                            ' - ',
4271                            DATE_FORMAT((SELECT MAX(acceptance_date) FROM tbl_quotations WHERE acceptance_date IS NOT NULL {$where}), '%c/%e/'), YEAR(acceptance_date)
4272                        ) AS date_like,
4273                        YEAR(acceptance_date) 'year'
4274                        FROM tbl_quotations
4275                        WHERE acceptance_date IS NOT NULL {$where}
4276                        GROUP BY YEAR(acceptance_date)
4277                        ORDER BY YEAR(acceptance_date) DESC";
4278
4279            $acceptanceDate = DB::select($query);
4280
4281            return response([
4282                'message' => 'OK',
4283                'data' => $issueDate,
4284                'created_at' => $createdAt,
4285                'acceptance_date' => $acceptanceDate
4286            ]);
4287
4288
4289        } catch (\Exception $e) {
4290            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4291        }
4292
4293    }
4294
4295    function human_filesize($bytes, $decimals = 2) {
4296        $size = ['B', 'KB', 'MB'];
4297
4298        $factor = floor((strlen($bytes) - 1) / 3);
4299        return number_format($bytes / pow(1024, $factor), 2, ',', '.') . $size[$factor];
4300    }
4301
4302    function get_files($quoteId){
4303
4304        try {
4305
4306            $quoteId = addslashes($quoteId);
4307
4308            $quoteId = (int)$quoteId;
4309            $query = "
4310            SELECT
4311                file_id,
4312                quotation_id,
4313                quote_id,
4314                original_name,
4315                filename,
4316                uploaded_by,
4317                uploaded_at,
4318                is_internal,
4319                file_size,
4320                file_hash,
4321                mime_type
4322            FROM tbl_files
4323            WHERE quotation_id = ?
4324            AND is_internal IS NULL";
4325
4326            $result = DB::select($query, [$quoteId]);
4327
4328            foreach ($result as $file) {
4329                if($file->file_size > 0) {
4330                    $file->filesize = $this->human_filesize($file->file_size);
4331                } else {            
4332                    $path = "uploads/" . $file->filename;
4333
4334                    if (Storage::disk('s3')->exists($path)) {
4335                        $fileSizeBytes = Storage::disk('s3')->size($path);
4336                    } else {
4337                        $fileSizeBytes = 0;
4338                    }
4339
4340                    $file->filesize = $this->human_filesize($fileSizeBytes);
4341                }
4342
4343                $file->original_name = $file->original_name . " ({$file->filesize})";
4344            }
4345
4346            $query = "
4347            SELECT
4348                file_id,
4349                quotation_id,
4350                quote_id,
4351                original_name,
4352                filename,
4353                uploaded_by,
4354                uploaded_at,
4355                is_internal,
4356                file_size,
4357                file_hash,
4358                mime_type
4359            FROM tbl_files
4360            WHERE quotation_id = ?
4361            AND is_internal = 1";
4362
4363            $internal = DB::select($query, [$quoteId]);
4364
4365            foreach ($internal as $file) {
4366                if($file->file_size > 0) {
4367                    $file->filesize = $this->human_filesize($file->file_size);
4368                } else {
4369                    $path = "uploads/" . $file->filename;
4370
4371                    if (Storage::disk('s3')->exists($path)) {
4372                        $fileSizeBytes = Storage::disk('s3')->size($path);
4373                    } else {
4374                        $fileSizeBytes = 0;
4375                    }
4376
4377                    $file->filesize = $this->human_filesize($fileSizeBytes);
4378                }
4379
4380                $file->original_name = $file->original_name . " ({$file->filesize})";
4381            }
4382
4383            $job = TblOngoingJobs::where('quotation_id', $quoteId)->first();
4384            $order = TblQuotations::where('id', $quoteId)->first();
4385
4386            $emails = explode(",", str_replace(" ", "", $order->email));
4387
4388            $sendGrid = TblSendgridWebhook::where('quotation_id', $quoteId)->where('x_message_id', $order->x_message_id)->first();
4389
4390            $uniqueEvents = array();
4391            $currentEvents = array();
4392            $status = 2;
4393
4394            $xStatus = "processed";
4395
4396            if($sendGrid){
4397                $emailErrors = array('deferred', 'bounce', 'dropped', 'spamreport', 'invalid');
4398                $events = json_decode($sendGrid->json_body, true);
4399                $xMessageId = $sendGrid->x_message_id;
4400                $isDelivered = 0;
4401                $isProcessed = 0;
4402                $isError = 0;
4403
4404                foreach ($emails as $email) {
4405
4406                    $emailEvents = array_filter($events, fn($event) => strtolower($event['email']) === strtolower($email));
4407
4408                    $statuses = array_unique(array_column($emailEvents, 'event'));
4409                    $eventCount = count($statuses);
4410
4411                    if ($eventCount === 1 && in_array('processed', $statuses)) {
4412                        $xStatus = "processed";
4413                    }
4414
4415                    if ($eventCount == 2) {
4416                        if (in_array('processed', $statuses) && in_array('delivered', $statuses)) {
4417                            $xStatus = "delivered";
4418                        }
4419
4420                        foreach ($emailErrors as $e) {
4421                            if (in_array('processed', $statuses) && in_array($e, $statuses)) {
4422                                $xStatus = $e;
4423                            }
4424                        }
4425
4426                    }elseif($eventCount > 2){
4427                        if (in_array('processed', $statuses) && in_array('delivered', $statuses)) {
4428                            $xStatus = "delivered";
4429                        }
4430
4431                        if($xStatus != "delivered"){
4432                            foreach ($emailErrors as $e) {
4433                                if (in_array('processed', $statuses) && in_array($e, $statuses)) {
4434                                    $xStatus = $e;
4435                                }
4436                            }
4437                        }
4438                    }
4439
4440
4441                    if($xStatus == "processed"){
4442                        $isProcessed++;
4443                    }elseif($xStatus == "delivered"){
4444                        $isDelivered++;
4445                    }else{
4446                        $isError++;
4447                    }
4448
4449                    foreach ($emailEvents as $event) {
4450                        $key = strtolower($event['email']) . '|' . $event['event'];
4451                        if (!isset($uniqueEvents[$key])) {
4452                            $uniqueEvents[$key] = $event;
4453                        }
4454                    }
4455                }
4456
4457                if($uniqueEvents){
4458                    foreach (array_values($uniqueEvents) as $d) {
4459                        $d['created_at'] = date('Y-m-d H:i:s', $d['timestamp']);
4460
4461                        if(isset($d['response'])){
4462                            $d['error'] = $d['response'];
4463                        }
4464
4465                        if(isset($d['reason'])){
4466                            $d['error'] = $d['reason'];
4467                        }
4468
4469                        array_push($currentEvents, $d);
4470                    }
4471                }
4472
4473
4474
4475                if(count($emails) == $isDelivered){
4476                    $status = 1;
4477                    $xStatus = "Completed";
4478                }elseif($isProcessed > 0){
4479                    $status = 2;
4480                    $xStatus = "Processing";
4481                }elseif($isError > 0){
4482                    $status = 3;
4483
4484                    if($xStatus == "bounce"){
4485                        $xStatus = "Error - Bounce";
4486                    }else{
4487                        $xStatus = "Error";
4488                    }
4489                }
4490            }
4491
4492            $z = 0;
4493
4494            if($order->x_status != $xStatus){
4495                TblQuotations::where('id', $order->id)->update(
4496                    array(
4497                        'x_status' => $xStatus
4498                    )
4499                );
4500                $z = 1;
4501                Cache::flush();
4502            }
4503
4504            if(empty($currentEvents)){
4505                $status = 0;
4506            }
4507
4508            $followUpLogs = TblFollowUpLogs::where('quotation_id', $quoteId)->orderBy('created_at', 'desc')->get();
4509
4510            $projectTypes = TblProjectTypes::where('company_id', $order->company_id)->get();
4511
4512            $sendgridFollowUpLogs = array();
4513
4514            if($order->y_message_id){
4515                $sendgridFollowUpLogs = TblSendgridWebhook::where('x_message_id', $order->y_message_id)->first();
4516
4517                if($sendgridFollowUpLogs){
4518                    $sendgridFollowUpLogs = json_decode($sendgridFollowUpLogs->json_body, true);
4519                    foreach ($sendgridFollowUpLogs as &$item) {
4520                        $item['created_at'] = date("Y-m-d H:i:s", $item['timestamp']);
4521                    }
4522                }
4523            }
4524
4525            return response([
4526                'message' => 'OK',
4527                'data' => $result,
4528                'followUpLogs' => $followUpLogs,
4529                'sendgridFollowUpLogs' => $sendgridFollowUpLogs,
4530                'internal' => $internal,
4531                'projectTypes' => $projectTypes,
4532                'currentEvents' => array(
4533                    'status' => $status,
4534                    'email' => $currentEvents,
4535                    $uniqueEvents,
4536                    $xStatus
4537                ),
4538                'job' => $job,
4539                'isUpdated' => $z
4540            ]);
4541
4542        } catch (\Exception $e) {
4543            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4544        }
4545
4546    }
4547
4548    public function download_file($fileId) {
4549        try {
4550            $fileId = addslashes($fileId);
4551            $file = TblFiles::where('file_id', $fileId)->first();
4552
4553            if (!$file) {
4554                return response()->json([
4555                    'message' => 'KO',
4556                    'error' => 'Archivo no encontrado'
4557                ], 404);
4558            }
4559
4560            if (!is_null($file->file_hash) && !empty($file->file)) {
4561                $fileContent = $file->file;
4562                $mimeType = $file->mime_type ?? 'application/octet-stream';
4563                $filename = $file->original_name ?? $file->filename ?? 'download';
4564
4565                return response($fileContent)
4566                    ->header('Content-Type', $mimeType)
4567                    ->header('Content-Disposition', 'attachment; filename="' . $filename . '"')
4568                    ->header('Content-Length', strlen($fileContent))
4569                    ->header('Cache-Control', 'no-cache, no-store, must-revalidate');
4570
4571            }
4572            else {
4573                $filePath = Storage::disk('s3')->get("uploads/" . $file->filename);
4574                // $filePath = storage_path('app/public/uploads/' . $file->filename);                
4575
4576                if (!Storage::disk('s3')->exists("uploads/" . $file->filename)) {
4577                    return response()->json([
4578                        'message' => 'KO',
4579                        'error' => 'Archivo físico no encontrado: ' . $file->filename
4580                    ], 404);
4581                }
4582
4583                $fileSize = filesize($filePath);
4584                $mimeType = mime_content_type($filePath) ?: 'application/octet-stream';
4585                $filename = $file->original_name ?? $file->filename;
4586
4587                $fileContent = file_get_contents($filePath);
4588
4589                return response($fileContent)
4590                    ->header('Content-Type', $mimeType)
4591                    ->header('Content-Disposition', 'attachment; filename="' . $filename . '"')
4592                    ->header('Content-Length', $fileSize)
4593                    ->header('Cache-Control', 'no-cache, no-store, must-revalidate');
4594            }
4595
4596        } catch (\Exception $e) {
4597            \Log::error('Error downloading file: ' . $e->getMessage());
4598            return response()->json([
4599                'message' => 'KO',
4600                'error' => 'Error interno del servidor: ' . $e->getMessage()
4601            ], 500);
4602        }
4603    }
4604
4605    function delete_file($fileId){
4606
4607        try {
4608
4609            $fileId = addslashes($fileId);
4610            $file = TblFiles::where('file_id', $fileId)->first();
4611            $result = TblFiles::where('file_id', $fileId)->first();
4612
4613            if($result){
4614                TblFiles::where('file_id', $fileId)->delete();
4615                $path = storage_path('app/public/uploads/' . $result->filename);
4616                Storage::disk('public')->delete('uploads/' . $result->filename);
4617
4618                if(!env('SENDGRID_STAGING')){
4619                    Storage::disk('s3')->delete('uploads/' . $result->filename);
4620                }
4621            }
4622
4623            $fileCount = TblFiles::where('quotation_id', $file->quotation_id)->count();
4624            $data = array();
4625            if($fileCount > 0){
4626                $data['has_attachment'] = 1;
4627            }else{
4628                $data['has_attachment'] = 0;
4629            }
4630
4631            TblQuotations::where('quote_id', $file->quote_id)->update($data);
4632
4633            return response(['message' => 'OK']);
4634
4635        } catch (\Exception $e) {
4636            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4637        }
4638    }
4639
4640    function send_email_to_client(Request $request){
4641
4642        try {
4643
4644            $data = $request->all();
4645
4646            // $id = addslashes($data['id']);
4647            $userId = addslashes($data['user_id']);
4648            $companyId = addslashes($data['company_id']);
4649
4650            $isResend = null;
4651
4652            if(isset($data['is_resend'])){
4653                $isResend = 1;
4654                unset($data['is_resend']);
4655            }
4656
4657            // $result = TblQuotations::where('id', $id)->first();
4658
4659            $where = "";
4660            $emailTemplateId = addslashes($data['email_template_id']);
4661            unset($data['email_template_id']);
4662
4663            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
4664            $limit = 0;
4665
4666            if($companyId == 0){
4667                $limit = 20;
4668            }else{
4669                $emailCompany = TblCompanies::where('company_id', $companyId)->first();
4670
4671                if($emailCompany->limit_send != null){
4672                    $limit = $emailCompany->limit_send;
4673                }
4674            }
4675
4676            if(isset($data['ids']) && count($data['ids']) > 0){
4677                $quoteIds = implode(",", $data['ids']);
4678                $where = " a.id IN ({$quoteIds}) AND ";
4679            }
4680
4681            if(isset($data['ids_not_in']) && count($data['ids_not_in']) > 0){
4682                $quoteIds = implode(",", $data['ids_not_in']);
4683                $where = " a.id NOT IN ({$quoteIds}) AND ";
4684            }
4685
4686            $r = new Request([
4687                'filterModel' => $data['filterModel'],
4688                'sortModel' => $data['sortModel'],
4689                'start' => 0,
4690                'end' => 999999999,
4691                'company_id' => $data['company_id'],
4692                'user_id' => $data['user_id'],
4693                'ids' => $data['ids'],
4694                'searchText' => $data['searchText'],
4695                'ids_not_in' => $data['ids_not_in']
4696            ]);
4697
4698            $listQuotations = $this->list_quotations($r);
4699            $d = $listQuotations->original['data'];
4700            $result = array();
4701
4702            for ($i = 0; $i < count($d); $i++) {
4703                if($d[$i]->email != null
4704                    && ($d[$i]->budget_status_id == 11 || $isResend == 1)
4705                ){
4706                    array_push($result, $d[$i]);
4707                }
4708            }
4709
4710            if(count($result) == 0){
4711                return response(['message' => 'OK', $d]);
4712            }
4713
4714            $user   = TblUsers::where('id', $userId)->first();
4715            $error  = false;
4716
4717            $availableParameters = [
4718                'quote_id',
4719                'company_id',
4720                'client',
4721                'client_type',
4722                'phone_number',
4723                'email',
4724                'issue_date',
4725                'request_date',
4726                'duration',
4727                'invoice_number',
4728                'type',
4729                'acceptance_date',
4730                'status',
4731                'source',
4732                'amount',
4733                'reason_for_not_following_up',
4734                'last_follow_up_date',
4735                'last_follow_up_comment',
4736                'reason_for_rejection_id',
4737                'reason_for_rejection',
4738                'commercial',
4739                'created_at',
4740                'created_by',
4741                'updated_at',
4742                'updated_by'
4743            ];
4744
4745            $dateParameters = [
4746                'issue_date',
4747                'request_date',
4748                'acceptance_date',
4749                'last_follow_up_date',
4750                'created_at',
4751                'updated_at',
4752            ];
4753
4754            if($this->locale == 'es'){
4755                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
4756            }
4757
4758            if($this->locale == 'es'){
4759                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
4760            }
4761
4762            for ($i = 0; $i < count($result); $i++) {
4763
4764                $body = $emailTemplate->html;
4765                if(isset($data['html'])){
4766                    $body = $data['html'];
4767                }
4768                $subject = $emailTemplate->subject;
4769                $commercialUser = $result[$i]->commercial;
4770
4771                if($result[$i]->email != null){
4772
4773                    if(env('SENDGRID_STAGING')){
4774                        $toEmail = $user->email;
4775                    }else{
4776                        $toEmail = $result[$i]->email;
4777                    }
4778
4779                    preg_match_all('/{{(.*?)}}/', $body, $matches);
4780
4781                    $parameters = $matches[1];
4782
4783                    foreach ($parameters as $parameter) {
4784
4785                        if(in_array($parameter, $dateParameters)){
4786                            if($result[$i]->{$parameter}){
4787                                $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
4788                            }
4789                        }
4790
4791                        if(in_array($parameter, $availableParameters)){
4792                            $body = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $body);
4793                        }
4794                    }
4795
4796                    preg_match_all('/{{(.*?)}}/', $subject, $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                            $subject = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $subject);
4810                        }
4811                    }
4812
4813                    $email = new \SendGrid\Mail\Mail();
4814
4815                    // $imgpath = \File::get('fireservicetitan.png');
4816                    // $base64 = "data:image/png;base64,".base64_encode($imgpath);
4817                    // $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
4818
4819                    // $email->addAttachment(
4820                    //     $imgpath,
4821                    //     "image/png",
4822                    //     "fireservicetitan.png",
4823                    //     "inline",
4824                    //     "fireservicetitan"
4825                    // );
4826
4827                    $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
4828
4829                    foreach ($templateFiles as $item) {
4830                        $f = storage_path('app/public/uploads/' . $item->filename);
4831
4832                        if (file_exists($f)) {
4833                            $imgpath = file_get_contents($f);
4834                            $base64 = "data:image/png;base64," . base64_encode($imgpath);
4835                            $mimeType = mime_content_type($f);
4836
4837                            $email->addAttachment(
4838                                $imgpath,
4839                                $mimeType,
4840                                str_replace(' ', '', $item->original_name),
4841                                "inline",
4842                                str_replace(' ', '', $item->original_name),
4843                            );
4844
4845                            $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
4846                        } else {
4847                            Log::channel('email_failed_log')->error("File not found: " . $f);
4848                        }
4849                    }
4850
4851                    $html = '<!DOCTYPE html>';
4852                    $html .= '<html>';
4853                    $html .= '<head>';
4854                    $html .= '<meta charset="UTF-8">';
4855                    $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
4856                    $html .= '</head>';
4857                    $html .= '<body>';
4858                    $html .= $body;
4859                    $html .= '</body>';
4860                    $html .= '</html>';
4861
4862                    if($toEmail != null){
4863
4864                        $toEmail = explode(",", $toEmail);
4865                        $toEmail = array_map('trim', $toEmail);
4866
4867                        $companyEmail = null;
4868
4869                        $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}'";
4870                        $commercialEmail = DB::select($queryUsers);
4871
4872                        if(count($commercialEmail) > 0){
4873                            $companyEmail = $commercialEmail[0];
4874                        }else{
4875                            if($emailTemplate->from_id != null){
4876                                $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
4877                            }else{
4878                                $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result[$i]->company_id)->first();
4879                            }
4880                        }
4881
4882                        if(!$companyEmail){
4883                            return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
4884                        }
4885
4886                        $ccBcc = TblCcBcc::where('company_id', $result[$i]->company_id)->get();
4887
4888                        $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
4889                        $email->setSubject($subject);
4890
4891                        foreach ($toEmail as $clientEmail) {
4892                            $isValid = $this->isEmailValid($clientEmail);
4893                            if($isValid){
4894                                $email->addTo($clientEmail);
4895                            }
4896                        }
4897
4898                        if(env('SENDGRID_STAGING')){
4899
4900                        }else{
4901                            if(!in_array($user->email, $toEmail)){
4902                                $email->addCc($user->email);
4903                            }
4904
4905                            if(count($ccBcc) > 0){
4906                                foreach ($ccBcc as $data) {
4907                                    if(!in_array($data->email, $toEmail) && $user->email != $data->email){
4908                                        $email->addBcc($data->email);
4909                                    }
4910                                }
4911                            }
4912                        }
4913
4914                        $email->addContent("text/html", $html);
4915
4916                        $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
4917
4918                        $files = TblFiles::where('quotation_id', $result[$i]->id)->where('is_internal', null)->get();
4919                        $requestSize = $this->calculateEmailRequestSize($email);
4920
4921                        foreach ($files as $key => $value) {
4922                            $fileContent = null;
4923                            $fileSize = 0;
4924                            $fileName = null;
4925
4926                            if (Storage::disk('s3')->exists("uploads/" . $files[$key]->filename)) {                                
4927                                $fileContent = Storage::disk('s3')->get("uploads/" . $files[$key]->filename);                                
4928                                $fileSize = (int) ceil(strlen($fileContent) / 1048576);                                
4929                                $fileName = $files[$key]->original_name;                                                            
4930                            }
4931                            else if ($files[$key]->file) {
4932                                $fileContent = $files[$key]->file;
4933
4934                                if (is_string($fileContent) && base64_decode($fileContent, true)) {
4935                                    $fileContent = base64_decode($fileContent);
4936                                }
4937
4938                                $fileSize = strlen($fileContent) / 1048576;
4939                                $fileSize = (int) ceil($fileSize);
4940                                $fileName = $files[$key]->original_name ?: $files[$key]->file_name ?: 'file';
4941                            }
4942
4943                            if ($fileContent && $fileSize > 0) {
4944                                if ($requestSize + $fileSize < 25) {
4945                                    $attachment = new \SendGrid\Mail\Attachment();
4946                                    $attachment->setFilename($fileName);
4947                                    $attachment->setDisposition("attachment");
4948
4949                                    $attachment->setContent(base64_encode($fileContent));
4950
4951                                    $email->addAttachment($attachment);
4952                                    $requestSize = $this->calculateEmailRequestSize($email);
4953                                }
4954                            }
4955                        }
4956
4957                        $response = $sendgrid->send($email);
4958                        if ($response->statusCode() == 202) {
4959                            $messageId = null;
4960
4961                            foreach ($response->headers() as $header) {
4962                                if (strpos(strtolower($header), 'x-message-id:') === 0) {
4963                                    $messageId = trim(substr($header, strpos($header, ':') + 1));
4964                                    break;
4965                                }
4966                            }
4967
4968                            $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;
4969                            $result[$i]->last_follow_up_comment = $result[$i]->last_follow_up_comment . "\n" . $comment;
4970
4971                            TblQuotations::where('id', $result[$i]->id)->update(
4972                                array(
4973                                    'last_follow_up_comment' => $result[$i]->last_follow_up_comment,
4974                                    'budget_status_id' => 2,
4975                                    'x_message_id' => $messageId,
4976                                    'x_status' => 'Processing',
4977                                    'updated_by' => $user->name,
4978                                    'updated_at' => date('Y-m-d H:i:s')
4979                                )
4980                            );
4981
4982                            $jsonBody = array();
4983
4984                            foreach ($toEmail as $clientEmail) {
4985                                $isValid = $this->isEmailValid($clientEmail);
4986                                $eventStatus = "processed";
4987                                $eventResponse = "";
4988                                if(!$isValid){
4989                                    $eventStatus = "invalid";
4990                                    $eventResponse = "Invalid email address";
4991                                }
4992
4993                                array_push(
4994                                    $jsonBody,
4995                                    array(
4996                                        'email' =>  $clientEmail,
4997                                        'event' => $eventStatus,
4998                                        'sg_message_id' => $messageId,
4999                                        'smtp-id' => $messageId,
5000                                        'timestamp' => strtotime(date('Y-m-d H:i:s')),
5001                                        'response' => $eventResponse
5002                                    )
5003                                );
5004                            }
5005
5006                            TblSendgridWebhook::create(
5007                                array(
5008                                    'quotation_id' => $result[$i]->id,
5009                                    'type' => 'sendToClient',
5010                                    'json_body' => json_encode($jsonBody),
5011                                    'x_message_id' => $messageId
5012                                )
5013                            );
5014
5015                            Log::channel('email_log')->info("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - EMAIL MANUALLY SENT');
5016                        } else {
5017                            $error = true;
5018                            Log::channel('email_failed_log')->error("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - ' . $response->body());
5019                        }
5020                    }
5021                }
5022            }
5023
5024            $this->update_commercial_numbers($companyId);
5025
5026            Cache::flush();
5027            return response(['message' => 'OK', $result]);
5028
5029        } catch (\Exception $e) {
5030            Log::channel('email_failed_log')->error($e->getMessage());
5031            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5032        }
5033
5034    }
5035
5036    function send_email_follow_ups(Request $request, $automaticSendLimit = null){
5037
5038        try {
5039
5040            $data = $request->all();
5041
5042            $startedAt = date('Y-m-d H:i:s');
5043            $toEmail = "";
5044            $userId = addslashes($data['user_id']);
5045            $companyId = addslashes($data['company_id']);
5046            $emailTemplateId = addslashes($data['email_template_id']);
5047            unset($data['email_template_id']);
5048
5049            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
5050            $limit = 0;
5051
5052            $blockedDomains = array();
5053            $workingDays = 10;
5054            $limitReminderEmails = 3;
5055
5056            if($companyId == 0){
5057                $limit = 20;
5058            }else{
5059                $emailCompany = TblCompanies::where('company_id', $companyId)->first();
5060                $workingDays = $emailCompany->last_follow_up_date ?? 10;
5061                $limitReminderEmails = $emailCompany->limit_reminder_emails ?? 3;
5062
5063                if($emailCompany->limit_send != null){
5064                    $limit = $emailCompany->limit_send;
5065                }
5066            }
5067
5068            $r = new Request([
5069                'filterModel' => $data['filterModel'],
5070                'sortModel' => $data['sortModel'],
5071                'start' => 0,
5072                'end' => 999999999,
5073                'company_id' => $data['company_id'],
5074                'user_id' => $data['user_id'],
5075                'ids' => $data['ids'],
5076                'searchText' => $data['searchText'],
5077                'ids_not_in' => $data['ids_not_in'],
5078                'last_follow_up_date' => 1
5079            ]);
5080
5081            $listQuotations = $this->list_quotations($r);
5082            $d = $listQuotations->original['data'];
5083            $result = array();
5084
5085            if($automaticSendLimit != null){
5086                $limit = $automaticSendLimit;
5087            }
5088
5089            $l = 0;
5090            for ($i = 0; $i < count($d); $i++) {
5091                if($d[$i]->email != null
5092                    && $d[$i]->budget_status_id == 2
5093                    && $d[$i]->reason_for_not_following_up_id == null
5094                    && $d[$i]->total_sent < $limitReminderEmails
5095                    && $d[$i]->last_follow_up_date != null
5096                    && $d[$i]->last_follow_up_date < date('Y-m-d H:i:s')
5097                    && $d[$i]->last_follow_up_date > 0
5098                ){
5099                    if($l == $limit){
5100                        break;
5101                    }
5102                    array_push($result, $d[$i]);
5103                    $l++;
5104                }
5105            }
5106
5107            if(count($result) == 0){
5108                return response(['message' => 'OK']);
5109            }
5110
5111            $user   = TblUsers::where('id', $userId)->first();
5112            $error  = false;
5113
5114            $sentBy = $user->name;
5115
5116            $availableParameters = [
5117                'quote_id',
5118                'company_id',
5119                'client',
5120                'client_type',
5121                'phone_number',
5122                'email',
5123                'issue_date',
5124                'request_date',
5125                'duration',
5126                'invoice_number',
5127                'type',
5128                'acceptance_date',
5129                'status',
5130                'source',
5131                'amount',
5132                'reason_for_not_following_up',
5133                'last_follow_up_date',
5134                'last_follow_up_comment',
5135                'reason_for_rejection_id',
5136                'reason_for_rejection',
5137                'commercial',
5138                'created_at',
5139                'created_by',
5140                'updated_at',
5141                'updated_by'
5142            ];
5143
5144            $dateParameters = [
5145                'issue_date',
5146                'request_date',
5147                'acceptance_date',
5148                'last_follow_up_date',
5149                'created_at',
5150                'updated_at',
5151            ];
5152
5153
5154
5155            if($this->locale == 'es'){
5156                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
5157            }
5158
5159            $totalSent = 0;
5160            $totalSentIds = array();
5161            $totalFailedIds = array();
5162            $totalErrorIds = array();
5163            $currentQuotationId = null;
5164
5165            for ($i = 0; $i < count($result); $i++) {$budgetTypeId = $result[$i]->budget_type_id;
5166                $currentQuotationId = $result[$i]->quote_id;
5167                $body = $emailTemplate->html;
5168                if(isset($data['html'])){
5169                    $body = $data['html'];
5170                }
5171                $subject = $emailTemplate->subject;
5172                $commercialUser = $result[$i]->commercial;
5173
5174                $blockedDomains = TblBlockedDomains::where('company_id', $result[$i]->company_id)->pluck('domain')->toArray();
5175
5176                if(env('SENDGRID_STAGING')){
5177                    $toEmail = $user->email;
5178                }else{
5179                    $toEmail = $result[$i]->email;
5180                }
5181
5182                preg_match_all('/{{(.*?)}}/', $body, $matches);
5183
5184                $parameters = $matches[1];
5185
5186                foreach ($parameters as $parameter) {
5187
5188                    if(in_array($parameter, $dateParameters)){
5189                        if($result[$i]->{$parameter}){
5190                            $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
5191                        }
5192                    }
5193
5194                    if(in_array($parameter, $availableParameters)){
5195                        $body = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $body);
5196                    }
5197                }
5198
5199                preg_match_all('/{{(.*?)}}/', $subject, $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                        $subject = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $subject);
5213                    }
5214                }
5215
5216                $email = new \SendGrid\Mail\Mail();
5217
5218                $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
5219
5220                foreach ($templateFiles as $item) {
5221                    $f = storage_path('app/public/uploads/' . $item->filename);
5222
5223                    if (file_exists($f)) {
5224                        $imgpath = file_get_contents($f);
5225                        $base64 = "data:image/png;base64," . base64_encode($imgpath);
5226                        $mimeType = mime_content_type($f);
5227
5228                        $email->addAttachment(
5229                            $imgpath,
5230                            $mimeType,
5231                            str_replace(' ', '', $item->original_name),
5232                            "inline",
5233                            str_replace(' ', '', $item->original_name),
5234                        );
5235
5236                        $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
5237                    } else {
5238                        Log::channel('email_failed_log')->error("File not found: " . $f);
5239                    }
5240                }
5241
5242                $html = '<!DOCTYPE html>';
5243                $html .= '<html>';
5244                $html .= '<head>';
5245                $html .= '<meta charset="UTF-8">';
5246                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
5247                $html .= '</head>';
5248                $html .= '<body>';
5249                $html .= $body;
5250                $html .= '</body>';
5251                $html .= '</html>';
5252
5253                if($automaticSendLimit != null){
5254                    $sentBy = "System";
5255                }
5256
5257                if($toEmail != null){
5258
5259                    $toEmail = explode(",", $toEmail);
5260                    $toEmail = array_map('trim', $toEmail);
5261
5262                    $companyEmail = null;
5263
5264                    $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}'";
5265                    $commercialEmail = DB::select($queryUsers);
5266
5267                    if(count($commercialEmail) > 0){
5268                        $companyEmail = $commercialEmail[0];
5269                    }else{
5270                        if($emailTemplate->from_id != null){
5271                            $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
5272                        }else{
5273                            $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result[$i]->company_id)->first();
5274                        }
5275                    }
5276
5277                    if(!$companyEmail){
5278                        return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
5279                    }
5280
5281                    $ccBcc = TblCcBcc::where('company_id', $result[$i]->company_id)->get();
5282
5283                    $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
5284                    $email->setSubject($subject);
5285
5286                    $s = 0;
5287                    $addTo = array();
5288                    foreach ($toEmail as $clientEmail) {
5289                        $isValid = $this->isEmailValid($clientEmail);
5290                        if($isValid){
5291                            $domain = substr($clientEmail, strpos($clientEmail, '@') + 1);
5292
5293                            if(!in_array($domain, $blockedDomains)){
5294                                $email->addTo($clientEmail);
5295                                array_push($addTo, $clientEmail);
5296                                $s++;
5297                            }
5298                        }else{
5299                            TblFollowUpLogs::create(
5300                                array(
5301                                    'quotation_id' => $result[$i]->id,
5302                                    'email' => $clientEmail,
5303                                    'sent_by' => $sentBy,
5304                                    'status' => 'Invalid email'
5305                                )
5306                            );
5307                        }
5308                    }
5309
5310                    if($s == 0){
5311                        array_push($totalFailedIds, $result[$i]->id);
5312                        Log::channel('email_failed_log')->error($s. 'ID:' . $result[$i]->id . ' - ' . json_encode($toEmail));
5313                        continue;
5314                    }
5315
5316                    if(env('SENDGRID_STAGING')){
5317
5318                    }else{
5319                        if(count($ccBcc) > 0){
5320                            foreach ($ccBcc as $data) {
5321                                if(!in_array($data->email, $toEmail)){
5322                                    $email->addBcc($data->email);
5323                                }
5324                            }
5325                        }
5326                    }
5327
5328                    $email->addContent("text/html", $html);
5329
5330                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5331
5332                    $files = TblFiles::where('quotation_id', $result[$i]->id)->where('is_internal', null)->get();
5333                    $requestSize = $this->calculateEmailRequestSize($email);
5334
5335                    foreach ($files as $key => $value) {
5336                        if ($files[$key]->filename && Storage::disk('s3')->exists("uploads/" . $files[$key]->filename)) {
5337                                                        
5338                            $fileContent = Storage::disk('s3')->get("uploads/" . $files[$key]->filename);
5339                            $fileSize = strlen($fileContent) / 1048576;
5340                            $fileSize = (int) ceil($fileSize);
5341
5342                            $originalName = $files[$key]->original_name ?: basename($files[$key]->filename);
5343                        }
5344                        else if ($files[$key]->file) {
5345                            $fileContent = $files[$key]->file;
5346
5347                            if (is_string($fileContent) && base64_decode($fileContent, true)) {
5348                                $fileContent = base64_decode($fileContent);
5349                            }
5350
5351                            $fileSize = strlen($fileContent) / 1048576;
5352                            $fileSize = (int) ceil($fileSize);
5353
5354                            $originalName = $files[$key]->original_name ?: ($files[$key]->file_name ?: 'file');
5355                        }
5356                        else {
5357                            continue;
5358                        }
5359
5360                        if($fileSize > 0){
5361                            if($requestSize + $fileSize < 25){
5362                                $attachment = new \SendGrid\Mail\Attachment();
5363                                $attachment->setFilename($originalName);
5364                                $attachment->setDisposition("attachment");
5365
5366                                $attachment->setContent(base64_encode($fileContent));
5367
5368                                if ($files[$key]->mime_type) {
5369                                    $attachment->setType($files[$key]->mime_type);
5370                                }
5371
5372                                $email->addAttachment($attachment);
5373                                $requestSize = $this->calculateEmailRequestSize($email);
5374                            } else {
5375                                Log::warning("File omitted due to size limit: " . $originalName);
5376                            }
5377                        }
5378                    }
5379
5380                    $response = $sendgrid->send($email);
5381                    if ($response->statusCode() == 202) {
5382
5383                        $messageId = null;
5384
5385                        foreach ($response->headers() as $header) {
5386                            if (strpos(strtolower($header), 'x-message-id:') === 0) {
5387                                $messageId = trim(substr($header, strpos($header, ':') + 1));
5388                                break;
5389                            }
5390                        }
5391
5392                        $lastFollowUp = TblLastFollowUpDate::where('company_id', $companyId)->where('budget_type_id', $budgetTypeId)->first();
5393                        $workingDaysN = $workingDays;
5394                        if($lastFollowUp != null){
5395                            if($lastFollowUp->last_follow_up_date){
5396                                $workingDaysN = $lastFollowUp->last_follow_up_date;
5397                            }
5398                        }
5399
5400                        $comment = "Email automático enviado el " . date('Y-m-d H:i:s') . " por usuario " . $sentBy;
5401                        $result[$i]->last_follow_up_comment = $result[$i]->last_follow_up_comment . "\n" . $comment;
5402                        $date = strtotime("{$workingDaysN} weekdays");
5403                        $result[$i]->last_follow_up_date = date('Y-m-d H:i:s', $date);
5404                        $totalSentQ = $result[$i]->total_sent + 1;
5405
5406                        array_push($totalSentIds, $result[$i]->id);
5407
5408                        foreach ($addTo as $addToEmail) {
5409                            TblFollowUpLogs::create(
5410                                array(
5411                                    'quotation_id' => $result[$i]->id,
5412                                    'email' => $addToEmail,
5413                                    'sent_by' => $sentBy,
5414                                    'status' => 'OK'
5415                                )
5416                            );
5417                        }
5418
5419                        if($totalSentQ >= $limitReminderEmails){
5420                            $result[$i]->reason_for_not_following_up_id = 3;
5421                            $result[$i]->last_follow_up_date = null;
5422                        }
5423
5424                        TblQuotations::where('id', $result[$i]->id)->update(
5425                            array(
5426                                'last_follow_up_comment' => $result[$i]->last_follow_up_comment,
5427                                'last_follow_up_date' => $result[$i]->last_follow_up_date,
5428                                'total_sent' => $result[$i]->total_sent + 1,
5429                                'y_message_id' => $messageId,
5430                                'y_status' => 'Processing',
5431                                'reason_for_not_following_up_id' => $result[$i]->reason_for_not_following_up_id,
5432                                'updated_by' => $sentBy,
5433                                'updated_at' => date('Y-m-d H:i:s')
5434                            )
5435                        );
5436
5437                        $jsonBody = array();
5438
5439                        foreach ($toEmail as $clientEmail) {
5440                            $isValid = $this->isEmailValid($clientEmail);
5441                            $eventStatus = "processed";
5442                            $eventResponse = "";
5443                            if(!$isValid){
5444                                $eventStatus = "invalid";
5445                                $eventResponse = "Invalid email address";
5446                            }
5447
5448                            array_push(
5449                                $jsonBody,
5450                                array(
5451                                    'email' =>  $clientEmail,
5452                                    'event' => $eventStatus,
5453                                    'sg_message_id' => $messageId,
5454                                    'smtp-id' => $messageId,
5455                                    'timestamp' => strtotime(date('Y-m-d H:i:s')),
5456                                    'response' => $eventResponse
5457                                )
5458                            );
5459                        }
5460
5461                        TblSendgridWebhook::create(
5462                            array(
5463                                'quotation_id' => $result[$i]->id,
5464                                'type' => 'followUps',
5465                                'json_body' => json_encode($jsonBody),
5466                                'x_message_id' => $messageId
5467                            )
5468                        );
5469
5470                        Log::channel('email_log')->info("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - EMAIL SENT');
5471                        $totalSent++;
5472                        $workingDays = 10;
5473                    } else {
5474                        $error = true;
5475                        array_push($totalErrorIds, $result[$i]->id);
5476                        Log::channel('email_failed_log')->error("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - ' . $response->body());
5477
5478                        foreach ($addTo as $addToEmail) {
5479                            TblFollowUpLogs::create(
5480                                array(
5481                                    'quotation_id' => $result[$i]->id,
5482                                    'email' => $addToEmail,
5483                                    'sent_by' => $sentBy,
5484                                    'status' => $response->body()
5485                                )
5486                            );
5487                        }
5488                    }
5489
5490                    $body = "";
5491                    $subject = "";
5492                }
5493            }
5494            Cache::flush();
5495
5496            Log::channel('send_email_follow_ups')->info(
5497                json_encode(
5498                    array(
5499                        "success" => $totalSentIds,
5500                        "failed" => $totalFailedIds,
5501                        "error" => $totalErrorIds
5502                    )
5503                )
5504            );
5505
5506            $this->update_commercial_numbers($companyId);
5507
5508            if($error){
5509                return response(['message' => 'KO']);
5510            }else{
5511
5512                if($automaticSendLimit != null){
5513                    TblOrdersUpdateLogs::create(
5514                        array(
5515                            'company_id' => $companyId,
5516                            'to_process' => 'Orders',
5517                            'status' => 'success',
5518                            'follow_ups_affected_rows' => $totalSent,
5519                            'processed_by' => $sentBy,
5520                            'started_at' => $startedAt,
5521                            'ended_at' => date('Y-m-d H:i:s')
5522                        )
5523                    );
5524                }
5525
5526                return response(['message' => 'OK', 'data' => $totalSent . ' ' . __('language.total_follow_up_sent')]);
5527            }
5528
5529        } catch (\Throwable $e) {
5530            Log::channel('email_failed_log')->error($e->getMessage());
5531            return response(['message' => 'KO', 'error' => $e->getMessage(), 'quotation_id' => $currentQuotationId]);
5532        }
5533    }
5534
5535    function create_sender_identity(Request $request){
5536
5537        try {
5538
5539            $data = $request->all();
5540            $sData = $data;
5541            $companyId = $data['company_id'];
5542            $createdBy = $data['created_by'];
5543            unset($data['company_id']);
5544            unset($data['created_by']);
5545
5546            $sender = TblCompanyEmails::where('from_email', $data['from_email'])->where('verified', 1)->count();
5547
5548            if($sender > 0){
5549                TblCompanyEmails::create($sData);
5550                return response(['message' => 'OK', 'data' => $data, 'is_verified' => 'yes']);
5551            }
5552
5553            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5554            $data['reply_to'] = $data['from_email'];
5555            $data['reply_to_name'] = $data['from_name'];
5556            $requestBody = $data;
5557            $error  = false;
5558
5559            $response = $sendgrid->client->verified_senders()->post($requestBody);
5560
5561            if ($response->statusCode() == 201) {
5562                $x = json_decode($response->body());
5563
5564                $data['company_id'] = $companyId;
5565                $data['created_by'] = $createdBy;
5566                $data['response_id'] = $x->id;
5567                TblCompanyEmails::create($data);
5568                Log::channel('email_log')->info('EMAIL: ' . $data['from_email'] . ' - VERIFICATION SENT');
5569            } else {
5570                $error = true;
5571                Log::channel('email_log')->error('REQUEST BODY: - ' . $response->body());
5572            }
5573
5574            $response = json_decode($response->body());
5575
5576            if($error){
5577                if($response->errors[0]->message == "already exists" && $response->errors[0]->field == "from_email"){
5578                    TblCompanyEmails::create($sData);
5579                    return response(['message' => 'OK', 'data' => $data, 'is_verified' => 'yes']);
5580                }
5581
5582                $errMessage = $response->errors[0]->field . ': ' . $response->errors[0]->message;
5583                return response(['message' => 'KO', 'error' => $errMessage]);
5584            }else{
5585                return response(['message' => 'OK', 'data' => $response, 'is_verified' => 'no']);
5586            }
5587
5588        } catch (\Exception $e) {
5589            Log::channel('email_log')->error('EMAIL:' . $data['from_email'] . ' - ' . $e->getMessage());
5590            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5591        }
5592    }
5593
5594    function get_sender_identity($companyId){
5595
5596        try {
5597
5598            $companyId = addslashes($companyId);
5599
5600            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5601
5602            $response = $sendgrid->client->verified_senders()->get();
5603
5604            if ($response->statusCode() == 200) {
5605                $x = json_decode($response->body())->results;
5606
5607                foreach ($x as $item) {
5608                    TblCompanyEmails::where('from_email', $item->from_email)->update(array(
5609                        'verified' => $item->verified,
5610                        'reply_to' => $item->reply_to,
5611                        'response_id' => $item->id
5612                    ));
5613                }
5614            }
5615
5616            $companyEmails = TblCompanyEmails::where('company_id', $companyId)->get();
5617
5618            return response(['message' => 'OK', 'data' => $companyEmails]);
5619
5620        } catch (\Exception $e) {
5621            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5622        }
5623    }
5624
5625    function get_all_sender_identity($companyId){
5626
5627        try {
5628
5629            $companyId = addslashes($companyId);
5630
5631            $query = "SELECT
5632                        id,
5633                        response_id,
5634                        nickname,
5635                        CONCAT(nickname, ' - ', from_email) from_email,
5636                        from_name,
5637                        reply_to,
5638                        reply_to_name,
5639                        address,
5640                        address2,
5641                        state,
5642                        city,
5643                        country,
5644                        zip,
5645                        verified,
5646                        locked,
5647                        is_active,
5648                        created_by,
5649                        created_at,
5650                        updated_by,
5651                        updated_at
5652                    FROM
5653                        tbl_company_emails
5654                    WHERE
5655                        company_id != {$companyId}
5656                        AND from_email NOT IN (
5657                        SELECT
5658                            from_email
5659                        FROM
5660                            tbl_company_emails
5661                        WHERE
5662                            company_id = {$companyId}
5663                        )
5664                    ";
5665
5666            $companyEmails = DB::select($query);
5667
5668            return response(['message' => 'OK', 'data' => $companyEmails]);
5669
5670        } catch (\Exception $e) {
5671            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5672        }
5673    }
5674
5675    function delete_sender_identity(Request $request){
5676
5677        try {
5678
5679            $data = $request->all();
5680            $responseId = addslashes($data['response_id']);
5681            $id = addslashes($data['id']);
5682
5683            $sender = TblCompanyEmails::where('response_id', $responseId)->count();
5684
5685            if($sender > 1){
5686                TblCompanyEmails::where('id', $id)->delete();
5687            }else{
5688                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5689
5690                $response = $sendgrid->client->verified_senders()->_($responseId)->delete();
5691
5692                if ($response->statusCode() == 204) {
5693                    TblCompanyEmails::where('response_id', $responseId)->delete();
5694                }
5695            }
5696
5697
5698            return response(['message' => 'OK']);
5699
5700        } catch (\Exception $e) {
5701            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5702        }
5703    }
5704
5705    function create_template(Request $request){
5706
5707        try {
5708
5709            $data = $request->all();
5710
5711            $files = $request->file('files');
5712            unset($data['files']);
5713
5714            if($files){
5715                $totalFileCount = count($files);
5716                if($totalFileCount > 2){
5717                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
5718                }
5719            }
5720
5721            $result = TblEmailConfiguration::create($data);
5722            $id = $result->id;
5723
5724            $directory = 'public/uploads';
5725            $origFilename = 'fireservicetitan.png';
5726            $file = 'public/uploads/fireservicetitan.png';
5727
5728            $sourcePath = public_path($origFilename);
5729            $destinationPath = 'public/uploads/' . $origFilename;
5730
5731            $filename = $id . '-EI' . time() . '-' . $origFilename;
5732
5733            Storage::putFileAs($directory, new \Illuminate\Http\File($sourcePath), $filename);
5734            Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5735
5736            TblEmailFiles::create(
5737                array(
5738                    'email_template_id' => $id,
5739                    'original_name' => $origFilename,
5740                    'filename' => $filename,
5741                    'uploaded_by' => $data['created_by']
5742                )
5743            );
5744
5745            if($files){
5746
5747                $uploadedFiles = [];
5748                $i = 0;
5749
5750                $combinedFilesSize = 0;
5751
5752                foreach ($files as $file) {
5753                    $i++;
5754
5755                    $origFilename = str_replace(" ", "", $file->getClientOriginalName());
5756
5757                    $filename = $id . '-EI' . time() . '-' . $origFilename;
5758
5759                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
5760
5761                    if($combinedFilesSize > 25000000){
5762                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
5763                    }
5764
5765                    Storage::putFileAs($directory, $file, $filename);
5766                    Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5767
5768                    if(in_array($origFilename, $uploadedFiles)){
5769                        $origFilename = $origFilename . $i;
5770                    }
5771
5772                    TblEmailFiles::create(
5773                        array(
5774                            'email_template_id' => $id,
5775                            'original_name' => $origFilename,
5776                            'filename' => $filename,
5777                            'uploaded_by' => $data['created_by']
5778                        )
5779                    );
5780
5781                    $uploadedFiles[] = $file->getClientOriginalName();
5782                }
5783            }
5784
5785            return response(['message' => 'OK']);
5786
5787        } catch (\Exception $e) {
5788            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5789        }
5790    }
5791
5792    function get_email_files($emailTemplateId){
5793
5794        try {
5795
5796            $emailTemplateId = addslashes($emailTemplateId);
5797
5798            $result = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
5799
5800            foreach ($result as $key => $value) {
5801                $path = storage_path('app/public/uploads/' . $result[$key]->filename);
5802
5803                if (File::exists($path)) {
5804                    $fileSizeBytes = File::size($path);
5805                    $result[$key]->filesize = $this->human_filesize($fileSizeBytes);
5806                    $result[$key]->original_name = $result[$key]->original_name . " ({$result[$key]->filesize})";
5807                    $result[$key]->img = "data:image/png;base64,".base64_encode(file_get_contents($path));
5808                }
5809            }
5810
5811            return response(['message' => 'OK', 'data' => $result]);
5812
5813        } catch (\Exception $e) {
5814            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5815        }
5816    }
5817
5818    function download_email_template_file($fileId){
5819
5820        try {
5821
5822            $fileId = addslashes($fileId);
5823
5824            $result = TblEmailFiles::where('file_id', $fileId)->first();
5825
5826            if($result){
5827                $path = storage_path('app/public/uploads/' . $result->filename);
5828
5829                if (!Storage::disk('public')->exists('uploads/' . $result->filename)) {
5830                    return response(['message' => 'KO']);
5831                }
5832
5833                return response()->download($path);
5834            }
5835
5836            return response(['message' => 'KO']);
5837
5838        } catch (\Exception $e) {
5839            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5840        }
5841
5842    }
5843
5844    function delete_email_template_file($fileId){
5845
5846        try {
5847
5848            $fileId = addslashes($fileId);
5849            $file = TblEmailFiles::where('file_id', $fileId)->first();
5850            $result = TblEmailFiles::where('file_id', $fileId)->first();
5851
5852            if($result){
5853                TblEmailFiles::where('file_id', $fileId)->delete();
5854                $path = storage_path('app/public/uploads/' . $result->filename);
5855                Storage::disk('public')->delete('uploads/' . $result->filename);
5856            }
5857
5858            return response(['message' => 'OK']);
5859
5860        } catch (\Exception $e) {
5861            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5862        }
5863    }
5864
5865    function update_email_template_order(Request $request, $id){
5866
5867        try {
5868
5869            $id = addslashes($id);
5870            $data = $request->all();
5871
5872            foreach ($data as $item) {
5873                TblEmailFiles::where('file_id', $item['file_id'])->update(array('order' => $item['order']));
5874            }
5875
5876        } catch (\Exception $e) {
5877            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5878        }
5879
5880    }
5881
5882
5883    function update_email_template(Request $request, $id){
5884
5885        try {
5886
5887            $data = $request->all();
5888
5889            $id = addslashes($id);
5890
5891            $files = $request->file('files');
5892            unset($data['files']);
5893
5894            $fileCount = TblEmailFiles::where('email_template_id', $id)->count();
5895
5896            if($files){
5897                $totalFileCount = $fileCount + count($files);
5898                if($totalFileCount > 3){
5899                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
5900                }
5901            }
5902
5903            if(isset($data['cron_default'])){
5904                TblEmailConfiguration::where('company_id', $data['company_id'])->where('cron_default', 1)->update(array('cron_default' => 0));
5905            }
5906
5907            $data['updated_at'] = date('Y-m-d H:i:s');
5908            TblEmailConfiguration::where('id', $id)->update($data);
5909
5910            if($files){
5911
5912                $directory = 'public/uploads';
5913                $uploadedFiles = [];
5914                $i = 0;
5915
5916                $combinedFilesSize = 0;
5917                foreach ($files as $file) {
5918                    $i++;
5919                    $origFilename = str_replace(" ", "", $file->getClientOriginalName());
5920                    $filename = $id . '-EI' . time() . '-' . $origFilename;
5921
5922                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
5923
5924                    if($combinedFilesSize > 25000000){
5925                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
5926                    }
5927
5928                    Storage::putFileAs($directory, $file, $filename);
5929                    Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5930
5931                    if(in_array($origFilename, $uploadedFiles)){
5932                        $origFilename = $origFilename . $i;
5933                    }
5934
5935                    TblEmailFiles::create(
5936                        array(
5937                            'email_template_id' => $id,
5938                            'original_name' => $origFilename,
5939                            'filename' => $filename,
5940                            'uploaded_by' => $data['updated_by']
5941                        )
5942                    );
5943
5944                    $uploadedFiles[] = $file->getClientOriginalName();
5945                }
5946            }
5947
5948            return response(['message' => 'OK']);
5949
5950        } catch (\Exception $e) {
5951            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5952        }
5953
5954    }
5955
5956    function delete_template($id){
5957
5958        try {
5959
5960            $id = addslashes($id);
5961
5962            TblEmailConfiguration::where('id', $id)->delete();
5963
5964            return response(['message' => 'OK']);
5965
5966        } catch (\Exception $e) {
5967            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5968        }
5969
5970    }
5971
5972    function get_email_template($companyId){
5973
5974        try {
5975
5976            $companyId = addslashes($companyId);
5977            
5978            $where = " a.company_id IN ({$this->companyId}";
5979
5980            $query = "SELECT
5981                        a.id,
5982                        a.from_id,
5983                        CASE
5984                            WHEN a.type = 'followUps' THEN 'Follow-ups'
5985                            WHEN a.type = 'sendToClient' THEN 'Send to client'
5986                        END types,
5987                        (SELECT from_email FROM tbl_company_emails WHERE id = a.from_id) from_email,
5988                        CASE WHEN {$companyId} = 0 THEN CONCAT(b.name, ' - ', a.name) ELSE a.name END `name`,
5989                        a.subject,
5990                        a.html,
5991                        a.is_active,
5992                        a.type,
5993                        a.created_by,
5994                        a.created_at,
5995                        a.updated_by,
5996                        a.updated_at,
5997                        a.cron_default
5998                    FROM tbl_email_configuration a
5999                    LEFT JOIN tbl_companies b
6000                        ON b.company_id = a.company_id
6001                    WHERE {$where}
6002                    ORDER BY a.id DESC";
6003
6004            $result = DB::select($query);
6005
6006            return response(['message' => 'OK', 'data' => $result]);
6007
6008        } catch (\Exception $e) {
6009            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6010        }
6011
6012    }
6013
6014    function update_sender_identity(Request $request, $responseId){
6015
6016        try {
6017
6018            $data = $request->all();
6019            $companyId = $data['company_id'];
6020            $updatedBy = $data['updated_by'];
6021            $active = $data['is_active'];
6022            $id = addslashes($data['id']);
6023            unset($data['id']);
6024            unset($data['company_id']);
6025            unset($data['updated_by']);
6026            unset($data['is_active']);
6027
6028            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
6029            $data['reply_to'] = $data['from_email'];
6030            $data['reply_to_name'] = $data['from_name'];
6031            $requestBody = $data;
6032            $error  = false;
6033
6034            $response = $sendgrid->client->verified_senders()->_($responseId)->patch($requestBody);
6035
6036            if ($response->statusCode() == 200) {
6037                $x = json_decode($response->body());
6038
6039                $data['updated_by'] = $updatedBy;
6040                $data['updated_at'] = date('Y-m-d H:i:s');
6041                $data['is_active'] = $active;
6042
6043                TblCompanyEmails::where('company_id', $companyId)->update(array('is_active' => 0));
6044                TblCompanyEmails::where('id', $id)->update($data);
6045
6046                Log::channel('email_log')->info('EMAIL: ' . $data['from_email'] . ' - UPDATED');
6047            } else {
6048                $error = true;
6049                Log::channel('email_log')->error('REQUEST BODY: - ' . $response->body());
6050            }
6051
6052            $response = json_decode($response->body());
6053
6054            if($error){
6055                $errMessage = @$response->errors[0]->field . ': ' . @$response->errors[0]->message;
6056                return response(['message' => 'KO', 'error' => $errMessage]);
6057            }else{
6058                return response(['message' => 'OK', 'data' => $response]);
6059            }
6060
6061        } catch (\Exception $e) {
6062            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6063        }
6064
6065    }
6066
6067    function resend_verification($id){
6068
6069        try {
6070
6071            $id = addslashes($id);
6072
6073            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
6074
6075            $response = $sendgrid->client->verified_senders()->resend()->_($id)->post();
6076
6077            if ($response->statusCode() == 204) {
6078                return response(['message' => 'OK']);
6079            }else{
6080                $response = json_decode($response->body());
6081                $errMessage = $response->errors[0]->error_id . ': ' . $response->errors[0]->message;
6082                return response(['message' => 'KO', 'error' => $errMessage]);
6083            }
6084
6085        } catch (\Exception $e) {
6086            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6087        }
6088    }
6089
6090    function list_quotation_analytics_by_performance(Request $request){
6091
6092        try {
6093
6094            $data = $request->all();
6095            $companyId = addslashes($data['company_id']);
6096            $where .= " AND company_id IN ({$this->companyId}) AND for_add = 0 ";            
6097
6098            if(isset($data['budget_status']) && $data['budget_status'] != null){
6099                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
6100            }
6101
6102            $latestYear = TblQuotations::max(DB::raw('YEAR(issue_date)'));
6103            $md = date('m-d');
6104
6105            $query = "SELECT
6106                        q.years,
6107                        q.totalIssue,
6108                        (q.total_acceptance_percentage - q.totalAcceptancePercentage) / q.totalAcceptancePercentage * 100 totalAcceptancePercentage,
6109                        q.totalAccept
6110                    FROM
6111                        (
6112                        SELECT
6113                            YEAR(a.issue_date) years,
6114                            (b.total_issued - COUNT(a.issue_date)) / COUNT(a.issue_date) * 100 totalIssue,
6115                            COUNT(
6116                                CASE WHEN a.acceptance_date IS NOT NULL
6117                                AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6118                                AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6119                                AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6120                                AND a.budget_status_id = 3 THEN 1 END
6121                            ) / COUNT(a.issue_date) * 100 totalAcceptancePercentage,
6122                            b.total_acceptance_percentage,
6123                            (b.total_acceptance -
6124                                COUNT(
6125                                    CASE WHEN a.acceptance_date IS NOT NULL
6126                                    AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6127                                    AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6128                                    AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6129                                    AND a.budget_status_id = 3 THEN 1 END)
6130                                    ) / COUNT(
6131                                            CASE WHEN a.acceptance_date IS NOT NULL
6132                                            AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6133                                            AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6134                                            AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6135                                            AND a.budget_status_id = 3 THEN 1 END
6136                            ) * 100 totalAccept
6137                        FROM
6138                            tbl_quotations a
6139                            JOIN (
6140                            SELECT
6141                                YEAR(issue_date) current_year,
6142                                COUNT(issue_date) total_issued,
6143                                COUNT(
6144                                    CASE WHEN acceptance_date IS NOT NULL
6145                                    AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6146                                    AND CONCAT(YEAR(acceptance_date), '-{$md}')
6147                                    AND YEAR(acceptance_date) = YEAR(issue_date)
6148                                    AND budget_status_id = 3 THEN 1 END
6149                                ) total_acceptance,
6150                                COUNT(
6151                                    CASE WHEN acceptance_date IS NOT NULL
6152                                    AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6153                                    AND CONCAT(YEAR(acceptance_date), '-{$md}')
6154                                    AND YEAR(acceptance_date) = YEAR(issue_date)
6155                                    AND budget_status_id = 3 THEN 1 END
6156                                ) / COUNT(issue_date) * 100 total_acceptance_percentage
6157                            FROM
6158                                tbl_quotations
6159                            WHERE
6160                                issue_date IS NOT NULL
6161                                AND YEAR(issue_date) = {$latestYear}
6162                                AND DATE_FORMAT(issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(issue_date), '-01-01')
6163                                AND CONCAT(YEAR(issue_date), '-{$md}')
6164                                {$where}
6165                            GROUP by
6166                                1
6167                            ) b
6168                        WHERE
6169                            a.issue_date IS NOT NULL
6170                            AND a.budget_type_id != 7
6171                            AND a.budget_type_id IS NOT NULL
6172                            AND {$latestYear} > YEAR(a.issue_date)
6173                            AND DATE_FORMAT(a.issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.issue_date), '-01-01')
6174                            AND CONCAT(YEAR(a.issue_date), '-{$md}')
6175                        GROUP BY
6176                            1
6177                        ORDER BY
6178                            YEAR(issue_date) DESC
6179                        ) q
6180                    ";
6181
6182            $resultYtd = DB::select($query);
6183
6184            $query = "SELECT
6185                        YEAR(issue_date) years,
6186                        COUNT(issue_date) totalIssue,
6187                        COUNT(
6188                            CASE WHEN acceptance_date IS NOT NULL
6189                            AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6190                            AND CONCAT(YEAR(acceptance_date), '-{$md}')
6191                            AND YEAR(acceptance_date) = YEAR(issue_date)
6192                            AND budget_status_id = 3 THEN 1 END
6193                        ) totalAccept,
6194                        COUNT(
6195                            CASE WHEN acceptance_date IS NOT NULL
6196                            AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6197                            AND CONCAT(YEAR(acceptance_date), '-{$md}')
6198                            AND YEAR(acceptance_date) = YEAR(issue_date)
6199                            AND budget_status_id = 3 THEN 1 END
6200                        ) / COUNT(issue_date) * 100 totalAcceptancePercentage
6201                    FROM
6202                        tbl_quotations
6203                    WHERE
6204                        issue_date IS NOT NULL
6205                        AND budget_type_id != 7
6206                        AND budget_type_id IS NOT NULL
6207                        AND DATE_FORMAT(issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(issue_date), '-01-01')
6208                        AND CONCAT(YEAR(issue_date), '-{$md}')
6209                        {$where}
6210                    GROUP BY
6211                        1
6212                    ORDER BY
6213                        YEAR(issue_date) DESC
6214                    ";
6215
6216            $resultYears = DB::select($query);
6217
6218            return response(['message' => 'OK', 'ytdData' => $resultYtd, 'yearsData' => $resultYears]);
6219
6220        } catch (\Exception $e) {
6221            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6222        }
6223    }
6224
6225    function list_orders_update_logs($companyId){
6226
6227        try {
6228
6229            $where = "";
6230
6231            if($companyId != 0){
6232                $where .= " a.company_id = {$companyId}";
6233            }else{
6234                $where .= " a.company_id IN ({$this->companyId})";
6235            }
6236
6237            $query = "SELECT
6238                        a.id,
6239                        b.name company,
6240                        a.to_process,
6241                        a.rejected_affected_rows,
6242                        a.for_add_deleted_affected_rows,
6243                        a.month_change_affected_rows,
6244                        a.follow_ups_affected_rows,
6245                        a.sync_succesfull,
6246                        a.sync_error,
6247                        a.sync_error_message,
6248                        a.sync_success_ids,
6249                        a.cleared_email_errors,
6250                        a.remaining_email_errors,
6251                        CASE
6252                            WHEN a.rejected_affected_rows IS NOT NULL THEN a.rejected_affected_rows
6253                            WHEN a.for_add_deleted_affected_rows IS NOT NULL THEN a.for_add_deleted_affected_rows
6254                            WHEN a.month_change_affected_rows IS NOT NULL THEN a.month_change_affected_rows
6255                            WHEN a.follow_ups_affected_rows IS NOT NULL THEN a.follow_ups_affected_rows
6256                        END totals,
6257                        a.status,
6258                        a.processed_by,
6259                        a.started_at,
6260                        a.ended_at,
6261                        a.rejected_automatically_ids
6262                    FROM `tbl_orders_update_logs` a
6263                    LEFT JOIN tbl_companies b
6264                        ON a.company_id = b.company_id
6265                    WHERE {$where}
6266                    ORDER BY started_at DESC";
6267
6268            $result = DB::select($query);
6269
6270            return response(['message' => 'OK', 'data' => $result]);
6271
6272        } catch (\Exception $e) {
6273            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6274        }
6275
6276    }
6277
6278    function list_g3w_orders_update_logs($companyId){
6279
6280        try {
6281            $result = TblG3WOrdersUpdateLogs::where("company_id", $companyId)->get();
6282
6283            return response(['message' => 'OK', 'data' => $result]);
6284
6285        } catch (\Exception $e) {
6286            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6287        }
6288
6289    }
6290
6291    function update_budget_status_rejected_manual(Request $request){
6292
6293        try {
6294
6295            $data = $request->all();
6296
6297            $update = $this->update_budget_status_rejected($data['company_id'], $data['processed_by']);
6298
6299            if($update){
6300                return response(['message' => 'OK']);
6301            }else{
6302                return response(['message' => 'KO']);
6303            }
6304
6305        } catch (\Exception $e) {
6306            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6307        }
6308    }
6309
6310    function update_budget_status_rejected($companyId = null, $processedBy = "System"){
6311
6312        try {
6313
6314            $startedAt = date('Y-m-d H:i:s');
6315            $companyId = addslashes($companyId);
6316            $where = "";
6317
6318            $budgetTypes = TblBudgetTypes::get();
6319
6320            if(count($budgetTypes) > 0){
6321
6322                $companies = array();
6323
6324                if($companyId != 0){
6325                    $companies = TblCompanies::where('company_id', $companyId)->get();
6326                    $where = "AND company_id = {$companyId}";
6327                }else{
6328                    $companies = TblCompanies::get();
6329                }
6330
6331                for ($i = 0; $i < count($budgetTypes); $i++) {
6332
6333                    $days = $budgetTypes[$i]->duration;
6334                    $id = $budgetTypes[$i]->budget_type_id;
6335
6336                    if($days == null || $days == 0){
6337                        continue;
6338                    }
6339
6340                    for ($c = 0; $c < count($companies); $c++) {
6341                        $companyId = $companies[$c]->company_id;
6342
6343                        $query = "SELECT
6344                                    GROUP_CONCAT(id) ids
6345                                FROM
6346                                    tbl_quotations
6347                                WHERE
6348                                    budget_type_id = {$id}
6349                                AND budget_status_id IN (1, 2, 11)
6350                                AND DATEDIFF(NOW(), issue_date) >= {$days}
6351                                AND for_add = 0
6352                                {$where}";
6353
6354                        $result = DB::select($query);
6355
6356                        if(count($result) > 0){
6357
6358                            $ids = $result[0]->ids;
6359
6360                            if($ids != null || $ids != ""){
6361                                $query = "UPDATE
6362                                            tbl_quotations
6363                                        SET
6364                                            budget_status_id = 7
6365                                        WHERE
6366                                            id IN ({$ids})";
6367
6368                                DB::select($query);
6369
6370                                TblOrdersUpdateLogs::create(
6371                                    array(
6372                                        'company_id' => $companyId,
6373                                        'to_process' => 'Orders',
6374                                        'status' => 'success',
6375                                        'rejected_automatically_ids' => $ids,
6376                                        'processed_by' => $processedBy,
6377                                        'started_at' => $startedAt,
6378                                        'ended_at' => date('Y-m-d H:i:s')
6379                                    )
6380                                );
6381                            }
6382                        }
6383                    }
6384                }
6385            }
6386
6387            Cache::flush();
6388
6389            return response(['message' => 'OK']);
6390
6391        } catch (\Exception $e) {
6392
6393            TblOrdersUpdateLogs::create(
6394                array(
6395                    'company_id' => $companyId,
6396                    'to_process' => 'Orders',
6397                    'status' => $e->getMessage(),
6398                    'processed_by' => $processedBy,
6399                    'started_at' => $startedAt,
6400                    'ended_at' => date('Y-m-d H:i:s')
6401                )
6402            );
6403
6404            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6405        }
6406
6407    }
6408
6409    function bulk_update_quotation(Request $request){
6410
6411        // try {
6412
6413            $data = $request->all();
6414
6415            $r = new Request([
6416                'filterModel' => $data['filterModel'],
6417                'sortModel' => $data['sortModel'],
6418                'start' => 0,
6419                'end' => 999999999,
6420                'company_id' => $data['company_id'],
6421                'user_id' => $data['user_id'],
6422                'ids' => $data['ids'],
6423                'searchText' => $data['searchText'],
6424                'ids_not_in' => $data['ids_not_in']
6425            ]);
6426
6427            $listQuotations = $this->list_quotations($r);
6428            $d = $listQuotations->original['data'];
6429
6430            if(count($d) > 0){
6431                if(isset($data['last_follow_up_date']) && $data['last_follow_up_date'] == 1){
6432                    unset($data['last_follow_up_date']);
6433                }
6434                // unset($data['last_follow_up_date']);
6435                unset($data['filterModel']);
6436                unset($data['sortModel']);
6437                unset($data['start']);
6438                unset($data['end']);
6439                unset($data['company_id']);
6440                unset($data['user_id']);
6441                unset($data['ids']);
6442                unset($data['searchText']);
6443                unset($data['ids_not_in']);
6444
6445                $result = array();
6446                for ($i = 0; $i < count($d); $i++) {
6447                    array_push($result, $d[$i]->id);
6448                }
6449
6450                TblQuotations::whereIn('id', $result)->update($data);
6451
6452                Cache::flush();
6453            }
6454
6455            return response(['message' => 'OK', $data]);
6456
6457        // } catch (\Exception $e) {
6458        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
6459        // }
6460
6461    }
6462
6463    function move_budget_and_job(Request $request){
6464
6465        try {
6466
6467            $data = $request->all();
6468            $id = addslashes($data['id']);
6469            $companyId = addslashes($data['company_id']);
6470
6471            unset($data['id']);
6472            unset($data['company_id']);
6473
6474            $budget = TblQuotations::where('id', $id)->first();
6475
6476            $quotationId = $budget->id;
6477            $companyIdJob = $budget->company_id;
6478
6479            $query = "SELECT
6480                        COUNT(1) total
6481                    FROM tbl_company_users a
6482                    LEFT JOIN tbl_users b
6483                        ON a.user_id = b.id
6484                    WHERE a.company_id = {$companyId}
6485                    AND b.name = '{$budget->commercial}'
6486                    ORDER BY b.name ASC";
6487
6488            $result = DB::select($query);
6489
6490            $commercial = $budget->commercial;
6491
6492            if($result[0]->total == 0){
6493                $commercial = $data['created_by'];
6494            }
6495
6496            $r = new Request([
6497                'created_by' => $commercial,
6498            ]);
6499
6500            $result = $this->get_number($r, $companyId, 1);
6501            $newNumber = $result->original['number'];
6502
6503            TblQuotations::where('id', $id)->update(
6504                array(
6505                    'quote_id' => $newNumber,
6506                    'company_id' => $companyId,
6507                    'from_company_id' => $budget->company_id,
6508                    'commercial' => $commercial,
6509                )
6510            );
6511
6512            $job = TblOngoingJobs::where('quotation_id', $quotationId)->first();
6513
6514            $jobId = null;
6515
6516            if($job){
6517                $jobId = $job->id;
6518
6519                $query = "SELECT
6520                            COUNT(1) total
6521                        FROM tbl_company_users a
6522                        LEFT JOIN tbl_users b
6523                            ON a.user_id = b.id
6524                        WHERE a.company_id = {$companyId}
6525                        AND b.name = '{$job->responsible_for_work}'
6526                        ORDER BY b.name ASC";
6527
6528                $result = DB::select($query);
6529
6530                $responsibleForWork = $job->responsible_for_work;
6531
6532                if($result[0]->total == 0){
6533                    $responsibleForWork = $data['created_by'];
6534                }
6535
6536                TblOngoingJobs::where('quotation_id', $id)->update(
6537                    array(
6538                        'quote_id' => $newNumber,
6539                        'company_id' => $companyId,
6540                        'responsible_for_work' => $responsibleForWork,
6541                    )
6542                );
6543            }
6544
6545            Cache::flush();
6546
6547            return response([
6548                'message' => 'OK',
6549                'quotation_id' => $quotationId,
6550                'job_id' => $jobId
6551            ]);
6552
6553        } catch (\Exception $e) {
6554            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6555        }
6556    }
6557
6558    function list_quotation_analytics_by_types_of_budgets_created_per_week(Request $request){
6559
6560        try {
6561
6562            $data = $request->all();
6563            $companyId = addslashes($data['company_id']);
6564            $field = $data['field'];
6565
6566            $where = "";
6567            $whereYear = "";
6568            $dateLflArray = array();
6569            $companyIds = $this->companyIds;
6570
6571            if($companyId != 0){
6572                $companyIds = array($companyId);
6573            }
6574
6575            $acc = "";
6576            if($field == 'acceptance_date'){
6577                $acc = " AND q.acceptance_date IS NOT NULL ";
6578                // $field = 'created_at';
6579
6580                if(@$data['data_to_display'] == 4){
6581                    $field = 'created_at';
6582                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
6583                }
6584            }else{
6585                $field = 'created_at';
6586                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
6587            }
6588
6589            if(isset($data['years']) && $data['years'] != null){
6590                $years = implode(',', $data['years']);
6591                if(count($data['years']) > 0){
6592                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
6593                }
6594            }
6595
6596            foreach ($companyIds as $v) {
6597
6598                $lflWhere = " AND q.company_id = {$v} ";
6599
6600                $query = "SELECT
6601                            CONCAT(
6602                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
6603                                ' - ',
6604                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
6605                            ) AS date_like,
6606                            YEAR(q.{$field}) 'year',
6607                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
6608                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
6609                            {$v} 'company_id'
6610                        FROM
6611                            tbl_quotations q
6612                        WHERE
6613                            q.{$field} IS NOT NULL
6614                            AND q.for_add != 1
6615                            {$lflWhere}
6616                            {$whereYear}
6617                        GROUP BY YEAR(q.{$field})
6618                        ORDER BY YEAR(q.{$field}) DESC";
6619
6620                $dateLike = DB::select($query);
6621
6622                $dateLflArray[$v] = $dateLike;
6623            }
6624
6625            $isFy = true;
6626
6627            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
6628                $isFy = false;
6629                $ytdArray = array();
6630                $ytdAcceptanceArray = array();
6631                $lflCompanyIds = array();
6632                foreach ($dateLflArray as $k => $v) {
6633                    foreach ($dateLflArray[$k] as $item) {
6634                        $year = $item->year;
6635                        $now = date('m-d');
6636                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
6637                    }
6638
6639                    $ytdArray = implode(' OR ', $ytdArray);
6640                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
6641                    $ytdArray = array();
6642                }
6643
6644                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
6645                $where .= " AND ({$lflCompanyIds}";
6646            }
6647
6648            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
6649                $isFy = false;
6650                $lflArray = array();
6651                $ytdAcceptanceArray = array();
6652                $lflCompanyIds = array();
6653                foreach ($dateLflArray as $k => $v) {
6654                    foreach ($dateLflArray[$k] as $item) {
6655                        $year = $item->year;
6656                        $min_date_like = $item->min_date_like;
6657                        $max_date_like = $item->max_date_like;
6658                        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}')");
6659                    }
6660
6661                    $lflArray = implode(' OR ', $lflArray);
6662                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
6663                    $lflArray = array();
6664                }
6665
6666                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
6667                $where .= " AND ({$lflCompanyIds}";
6668            }
6669
6670            if($isFy){                
6671                $where .= " AND q.company_id IN ({$this->companyId}";
6672            }
6673
6674            if(isset($data['source']) && $data['source'] != null){
6675                $where .= " AND s.name = '{$data['source']}'";
6676            }
6677
6678            if(isset($data['month']) && $data['month'] != null){
6679                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
6680            }
6681
6682            if(isset($data['week']) && $data['week'] != null){
6683                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
6684            }
6685
6686            if(isset($data['commercial']) && $data['commercial'] != null){
6687                $where .= " AND q.commercial = '{$data['commercial']}'";
6688            }
6689
6690            if(isset($data['created_by']) && $data['created_by'] != null){
6691                $where .= " AND q.created_by = '{$data['created_by']}'";
6692            }
6693
6694            if(isset($data['budget_type']) && $data['budget_type'] != null){
6695                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
6696            }
6697
6698            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
6699                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
6700            }
6701
6702            if(isset($data['budget_status']) && $data['budget_status'] != null){
6703                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
6704            }
6705
6706            if(isset($data['client_type']) && $data['client_type'] != null){
6707                $where .= " AND ct.customer_type_id = {$data['client_type']}";
6708            }
6709
6710
6711            if(isset($data['segment_id']) && $data['segment_id'] != null){
6712                $where .= " AND q.segment_id = {$data['segment_id']}";
6713            }
6714
6715            $col = "1";
6716
6717            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
6718                if($data['data_to_display'] == 1){
6719                    $col = "1";
6720                }
6721
6722                if($data['data_to_display'] == 2){
6723                    $col = "q.amount";
6724                }
6725            }
6726
6727            $budgetTypes = TblBudgetTypes::orderByRaw("ISNULL(priority), priority ASC")->get();
6728            $cols = "";
6729            foreach ($budgetTypes as $item) {
6730                if($item->name == '' || $item->name == null){
6731                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} ELSE 0 END), 0) AS 'Otros'";
6732                }else{
6733                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN {$col} ELSE 0 END), 0) AS '{$item->name}'";
6734                }
6735            }
6736
6737            $budgetTypeGroups = TblBudgetTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
6738
6739            $colsGroups = ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} END), 0) AS Otros";
6740
6741            foreach ($budgetTypeGroups as $item) {
6742                $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6743                $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}'";
6744                $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}'";
6745            }
6746
6747            $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";
6748
6749            $col = $colsGroups . $cols;
6750
6751            if(@$data['data_to_display'] == 3){
6752
6753                $cols = "";
6754                foreach ($budgetTypes as $item) {
6755                    if($item->name == '' || $item->name == null){
6756                        $cols .= ",COALESCE(
6757                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount ELSE 0 END) /
6758                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 ELSE 0 END) * 100 , 0
6759                                    ) AS 'Otros'";
6760                    }else{
6761                        $cols .= ",COALESCE(
6762                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN q.amount ELSE 0 END) /
6763                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN 1 ELSE 0 END), 0
6764                                    ) AS '{$item->name}'";
6765                    }
6766                }
6767
6768                $colsGroups = ",COALESCE(
6769                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount END)) /
6770                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 END))
6771                            , 0) Otros";
6772
6773                foreach ($budgetTypeGroups as $item) {
6774                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6775                    $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}'";
6776                    $colsGroups .= ",COALESCE(
6777                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.amount END)) /
6778                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN 1 END))
6779                                    , 0) '{$budgetTypeGroupName}'";
6780                }
6781
6782                $colsGroups .= ",COALESCE(
6783                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.amount END)) /
6784                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END))
6785                                , 0) total";
6786
6787                $col = $colsGroups . $cols;
6788            }
6789
6790            if(@$data['data_to_display'] == 4){
6791
6792                $cols = "";
6793
6794                foreach ($budgetTypes as $item) {
6795
6796                    if($item->name == '' || $item->name == null){
6797                        $cols .= ",COALESCE(
6798                                        SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) /
6799                                        SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 ELSE 0 END) * 100 , 0
6800                                ) AS 'Otros'";
6801                    }else{
6802                        $cols .= ", COALESCE(
6803                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.acceptance_date IS NOT NULL THEN 1 END) /
6804                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.created_at IS NOT NULL THEN 1 END) * 100, 0
6805                                ) AS '{$item->name}'";
6806                    }
6807                }
6808
6809                $colsGroups = ",COALESCE(
6810                                    (SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 END)) /
6811                                    (SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 END)) * 100
6812                                    , 0) Otros";
6813
6814                foreach ($budgetTypeGroups as $item) {
6815                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6816                    $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}'";
6817                    $colsGroups .= ",COALESCE(
6818                                        (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)) /
6819                                        (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
6820                                    , 0) '{$budgetTypeGroupName}'";
6821                }
6822
6823                $colsGroups .= ",COALESCE(
6824                                    (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)) /
6825                                    (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
6826                                    , 0) total";
6827
6828                $col = $colsGroups . $cols;
6829            }
6830
6831            $query  = "SELECT
6832                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
6833                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
6834                            LPAD(WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'week',
6835                            DATE_FORMAT(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY), '%W, %M %e') 'namedate',
6836                            GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.id END) groupConcatIds
6837                            {$col}
6838                        FROM
6839                            tbl_quotations q
6840                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
6841                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
6842                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
6843                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
6844                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
6845                        WHERE
6846                            q.{$field} IS NOT NULL
6847                            AND q.for_add != 1
6848                            AND q.budget_type_id IS NOT NULL
6849                            AND q.budget_type_id != 7
6850                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
6851                            AND q.acceptance_date != '0000-00-00 00:00:00'
6852                            {$where}
6853                            {$whereYear}
6854                        GROUP BY
6855                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
6856                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
6857                            WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) WITH ROLLUP
6858                        ORDER BY
6859                            YEAR DESC,
6860                            MONTH ASC,
6861                            WEEK ASC,
6862                            DATE_FORMAT(q.{$field}, '%e') ASC";
6863            // return $query;
6864            $result = DB::select($query);
6865
6866            $query = "SELECT
6867                        btg.budget_type_group_id,
6868                        btg.name,
6869                        (
6870                            SELECT
6871                                GROUP_CONCAT(COALESCE(bt.name, '') ORDER BY ISNULL(bt.priority), bt.priority ASC SEPARATOR '|')
6872                            FROM
6873                                tbl_budget_types bt
6874                            WHERE
6875                                bt.budget_type_group_id = btg.budget_type_group_id
6876                        ) budget_types
6877                        FROM
6878                            tbl_budget_type_groups btg
6879                        ORDER BY
6880                            ISNULL(btg.priority),
6881                            btg.priority ASC";
6882
6883            $budgetTypeGroups = DB::select($query);
6884
6885            foreach ($budgetTypeGroups as $item) {
6886                $item->group_key_name = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6887                $item->budget_types = explode("|", $item->budget_types);
6888            }
6889
6890            return response([
6891                'message' => 'OK',
6892                'data' => $result,
6893                'budgetTypeGroups' => $budgetTypeGroups
6894            ]);
6895
6896        } catch (\Exception $e) {
6897            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6898        }
6899    }
6900
6901    public function preview_file($id){
6902        
6903        try {
6904
6905            $file = TblFiles::where("file_id", $id)->first();
6906            
6907            if (!$file) {
6908                return response()->json([
6909                    'message' => 'KO',
6910                    'error' => __('language.file_not_found')
6911                ], 404);
6912            }                                
6913                        
6914            if (!Storage::disk('s3')->exists("uploads/" . $file->filename)) {                
6915                return response()->json(['message' => 'File not found'], 404);
6916            }
6917            
6918            $url = Storage::disk('s3')->temporaryUrl(
6919                "uploads/" . $file->filename,
6920                now()->addMinutes(5)
6921            );
6922
6923            return response()->json([
6924                'filename' => $file->filename,
6925                'url' => $url,
6926                'uploaded_by' => $file->uploaded_by,
6927                'uploaded_at' => $file->uploaded_at
6928            ]);
6929
6930        } catch (\Exception $e) {
6931            return response()->json([
6932                'message' => 'KO',
6933                'error' => $e->getMessage()
6934            ], 500);
6935        }
6936    }
6937
6938    function get_past_added_quotation(Request $request){
6939
6940        try {
6941
6942            $data = $request->all();
6943            $keyword = addslashes($data['keyword']);
6944            $result = array();
6945
6946            if(isset($keyword) && !empty($keyword)){
6947                $array = explode(' ', $keyword);
6948
6949                $where = "";
6950
6951                $availableParameters = array('client', 'email');
6952
6953                $searchTextArray = explode(" ", $keyword);
6954
6955                $searchArray = array();
6956                $matchScoreArray = array();
6957                foreach ($availableParameters as $field) {
6958                    foreach ($searchTextArray as $word) {
6959                        array_push($searchArray, "({$field} LIKE '%{$word}%')");
6960                        array_push($matchScoreArray, "CASE WHEN {$field} LIKE '%{$word}%' THEN 1 ELSE 0 END");
6961                    }
6962                }
6963
6964                $searchArray = implode(" OR ", $searchArray);
6965                $matchScoreArray = implode(" + ", $matchScoreArray);
6966                $matchScoreCol = "({$matchScoreArray})";
6967                $where .= " AND ({$searchArray}";
6968
6969                $query = "SELECT
6970                            id,
6971                            client,
6972                            segment_id,
6973                            CONCAT(`client`, ' - ', email) `client_email`,
6974                            email,
6975                            phone_number,
6976                            customer_type_id,
6977                            {$matchScoreCol} match_score
6978                        FROM tbl_quotations
6979                        WHERE for_add = 0
6980                        AND email IS NOT NULL AND phone_number IS NOT NULL
6981                        {$where}
6982                        GROUP BY client, email
6983                        ORDER BY match_score DESC, client ASC
6984                        ";
6985
6986                $result = DB::select($query);
6987            }
6988
6989            return response(['message' => 'OK', 'data' => $result]);
6990
6991        } catch (\Exception $e) {
6992            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6993        }
6994    }
6995
6996    function send_acceptance_notification($quotationId, $companyId, $userId, $updatedBy){
6997
6998        $budget = TblQuotations::where('id', $quotationId)->first();
6999
7000        if($budget != null){
7001            $to = TblToAcceptanceNotifications::where('company_id', $companyId)->get();
7002            $cc = TblCcAcceptanceNotifications::where('company_id', $companyId)->get();
7003
7004            if(count($to) > 0 && count($cc) > 0){
7005
7006                $company = TblCompanies::where('company_id', $companyId)->first();
7007
7008                $quoteId = $budget->quote_id;
7009                $amount = $this->currency($budget->amount, 1);
7010
7011                $url = env('URL') . "orders/{$quotationId}?company_id={$companyId}";
7012                $href = "<a href='{$url}'>{$quoteId}</a>";
7013
7014                $imgpath = File::get('fireservicetitan.png');
7015                $base64 = "data:image/png;base64,".base64_encode($imgpath);
7016
7017                $body = __('language.send_acceptance_notification.body_hello');
7018                $body .= __('language.send_acceptance_notification.body_message');
7019
7020                $body = str_replace('{{client}}', $budget->client, $body);
7021                $body = str_replace('{{username}}', $updatedBy, $body);
7022                $body = str_replace('{{company}}', $company->name, $body);
7023                $body = str_replace('{{amount}}', $amount, $body);
7024                $body = str_replace('{{quote_id}}', $href, $body);
7025
7026                $body .= "<p>Fire Service Titan</p>";
7027                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
7028
7029                $html = '<!DOCTYPE html>';
7030                $html .= '<html>';
7031                $html .= '<head>';
7032                $html .= '<meta charset="UTF-8">';
7033                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
7034                $html .= '</head>';
7035                $html .= '<body>';
7036                $html .= $body;
7037                $html .= '</body>';
7038                $html .= '</html>';
7039
7040
7041                $subject = __('language.send_acceptance_notification.subject');
7042                $subject = str_replace('{{quote_id}}', $quoteId, $subject);
7043
7044                $email = new \SendGrid\Mail\Mail();
7045
7046                $user = TblUsers::where('id', $userId)->first();
7047
7048                if(env('SENDGRID_STAGING')){
7049                    $email->addTo($user->email);
7050                }else{
7051
7052                    $emails = array();
7053
7054                    foreach ($to as $item) {
7055                        if(!in_array($item->email, $emails)){
7056                            array_push($emails, $item->email);
7057                            $email->addTo($item->email);
7058                        }
7059                    }
7060
7061                    foreach ($cc as $item) {
7062                        if(!in_array($item->email, $emails)){
7063                            array_push($emails, $item->email);
7064                            $email->addCc($item->email);
7065                        }
7066                    }
7067
7068                    $email->addCc($user->email);
7069                    array_push($emails, $user->email);
7070
7071                    $ccUser = TblUsers::where('name', $budget->commercial)->first();
7072
7073                    if($ccUser){
7074                        if(!in_array($ccUser->email, $emails)){
7075                            $email->addCc($ccUser->email);
7076                        }
7077                    }
7078                }
7079
7080                $email->setFrom('fire@fire.es', 'Fire Service Titan');
7081                $email->setSubject($subject);
7082                $email->addContent("text/html", $html);
7083
7084                $email->addAttachment(
7085                    $imgpath,
7086                    "image/png",
7087                    "fireservicetitan.png",
7088                    "inline",
7089                    "fireservicetitan"
7090                );
7091
7092                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
7093
7094                $response = $sendgrid->send($email);
7095                if ($response->statusCode() == 202) {
7096
7097                    $comment = "Email de aprobación automática enviada al equipo de opearciones el " . date('Y-m-d H:i:s');
7098                    $budget->last_follow_up_comment = $budget->last_follow_up_comment . "\n" . $comment;
7099
7100                    TblQuotations::where('id', $quotationId)->update(
7101                        array(
7102                            'last_follow_up_comment' => $budget->last_follow_up_comment
7103                        )
7104                    );
7105
7106                    Log::channel('email_log')->info('ID:' . $quoteId . ' - ACCEPTANCE EMAIL NOTIFICATION SENT');
7107                } else {
7108                    $error = true;
7109                    Log::channel('email_log')->error('ID:' . $quoteId . ' - ' . $response->body());
7110                }
7111
7112            }
7113        }
7114    }
7115
7116    function get_total_quotations_by_budget_status(Request $request){
7117
7118        try {
7119
7120            $data = $request->all();            
7121
7122            $companyId = addslashes($data['company_id']);
7123            
7124            $where = " AND a.company_id IN ({$this->companyId}";
7125            
7126            $user = null;
7127
7128            if(isset($data['commercial'])){
7129                if($data['commercial'] != 'All'){
7130                    $user = TblUsers::where('name', $data['commercial'])->first();
7131                }
7132            }else{
7133                $user = TblUsers::where('id', $this->userId)->first();
7134            }
7135
7136            $totalPendingFollowUps = 0;
7137            $totalRequestAndVisit = 0;
7138            $totalError = 0;
7139            $totalG3WError = 0;
7140
7141            $d = false;
7142
7143            if($user != null){
7144                $where .= " AND a.commercial = '{$user->name}";
7145                $d = true;
7146            }
7147
7148            if($data['commercial'] == 'All'){
7149                $d = true;
7150            }
7151
7152            if($d){
7153                $query = "SELECT
7154                            COUNT(DISTINCT a.id) total
7155                        FROM
7156                            tbl_quotations a
7157                            LEFT JOIN (
7158                                SELECT
7159                                a.id,
7160                                SUBSTRING_INDEX(
7161                                    SUBSTRING_INDEX(a.email, ',', n.digit + 1),
7162                                    ',',
7163                                    -1
7164                                ) AS email_domain
7165                                FROM
7166                                tbl_quotations a
7167                                INNER JOIN (
7168                                    SELECT
7169                                    0 AS digit
7170                                    UNION ALL
7171                                    SELECT
7172                                    1
7173                                    UNION ALL
7174                                    SELECT
7175                                    2
7176                                    UNION ALL
7177                                    SELECT
7178                                    3
7179                                    UNION ALL
7180                                    SELECT
7181                                    4
7182                                    UNION ALL
7183                                    SELECT
7184                                    5
7185                                    UNION ALL
7186                                    SELECT
7187                                    6
7188                                    UNION ALL
7189                                    SELECT
7190                                    7
7191                                    UNION ALL
7192                                    SELECT
7193                                    8
7194                                    UNION ALL
7195                                    SELECT
7196                                    9
7197                                ) n ON LENGTH(
7198                                    REPLACE(a.email, ',', '')
7199                                ) <= LENGTH(a.email)- n.digit
7200                                GROUP BY a.id
7201                            ) temp ON a.id = temp.id
7202                            LEFT JOIN tbl_companies b
7203                                ON a.company_id = b.company_id
7204                        WHERE
7205                            a.last_follow_up_date < NOW()
7206                            AND a.budget_status_id IN (2)
7207                            AND a.email IS NOT NULL
7208                            AND a.email <> ''
7209                            AND NOT EXISTS (
7210                                SELECT
7211                                1
7212                                FROM
7213                                tbl_blocked_domains bd
7214                                WHERE
7215                                temp.email_domain LIKE CONCAT('%', bd.domain, '%')
7216                                AND bd.company_id = a.company_id
7217                            )
7218                            AND a.last_follow_up_date IS NOT NULL
7219                            AND a.reason_for_not_following_up_id IS NULL
7220                            AND a.last_follow_up_date > 0
7221                            AND a.total_sent < b.limit_reminder_emails
7222                            AND a.for_add = 0 {$where}";
7223
7224                    $result = DB::select($query);
7225
7226                    $totalPendingFollowUps = $result[0]->total;
7227
7228                    $query = "SELECT
7229                                COUNT(1) total
7230                            FROM
7231                                tbl_quotations a
7232                            WHERE
7233                                a.budget_status_id IN (6, 8, 12)
7234                                {$where}
7235                            ";
7236
7237                    $result = DB::select($query);
7238
7239                    $totalRequestAndVisit = $result[0]->total;
7240
7241                    $query = "SELECT
7242                                COUNT(1) total
7243                            FROM
7244                                tbl_quotations a
7245                            WHERE
7246                                a.x_status LIKE '%Error%'
7247                                {$where}
7248                            ";
7249
7250                    $result = DB::select($query);
7251
7252                    $totalError = $result[0]->total;
7253
7254                    $query = "SELECT
7255                                COUNT(1) total
7256                                FROM
7257                                    tbl_quotations a
7258                                WHERE
7259                                    a.g3w_warning = 1
7260                                    AND a.sync_import = 1
7261                                    {$where}
7262                                ";
7263
7264                    $result = DB::select($query);
7265
7266                    $totalG3WError = $result[0]->total;
7267            }
7268
7269            return response([
7270                'message' => 'OK',
7271                'userId' => ($user) ? $user->id : null,
7272                'totalPendingFollowUps' => $totalPendingFollowUps,
7273                'totalRequestAndVisit' => $totalRequestAndVisit,
7274                'totalError' => $totalError,
7275                'totalG3WError' => $totalG3WError
7276            ]);
7277
7278
7279        } catch (\Exception $e) {
7280            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7281        }
7282
7283    }
7284
7285    function sendgrid_webhook_receiver(Request $request){
7286
7287        try {
7288
7289            $data = $request->all();
7290
7291            $jsonBody = array();
7292            $order = array();
7293            $orderEmails = array();
7294
7295            Log::channel('email_log')->info('WEBHOOK: ' . json_encode($data));
7296
7297            $quoteId = null;
7298
7299            foreach ($data as $item) {
7300                $matches = explode(".", $item['sg_message_id']);
7301                $messageId = $matches[0];
7302
7303                Log::channel('email_log')->info('MESSAGE-ID: ' . $messageId);
7304
7305                $result = TblSendgridWebhook::where('x_message_id', $messageId)->first();
7306                $quoteId = $result->quotation_id;
7307                Log::channel('email_log')->info('SENDGRID-BODY: ' . json_encode($result));
7308
7309                if(empty($order)){
7310                    $order = TblQuotations::where('x_message_id', $messageId)->first();
7311                    $quoteId = $order->id;
7312                    // if(env('SENDGRID_STAGING')){
7313                    //     $user = TblUsers::where('name', $order->updated_by)->first();
7314
7315                    //     $orderEmails = array($user->email);
7316                    // }else{
7317                        $orderEmails = explode(",", $order->email);
7318                    // }
7319                }
7320
7321                // if(in_array($item['email'], $orderEmails)){
7322                    if($result->json_body == null){
7323                        array_push($jsonBody, $item);
7324                    }else{
7325                        $jsonBody = json_decode($result->json_body);
7326                        array_push($jsonBody, $item);
7327                    }
7328                // }
7329
7330                Log::channel('email_log')->info('JSON-BODY: ' . json_encode($jsonBody));
7331
7332                TblSendgridWebhook::where('x_message_id', $messageId)->update(
7333                    array(
7334                        'json_body' => json_encode($jsonBody),
7335                        'updated_at' => date('Y-m-d H:i:s')
7336                    )
7337                );
7338
7339                if($quoteId != null){
7340                    $this->get_files($quoteId);
7341                }
7342
7343                Cache::flush();
7344            }
7345
7346        } catch (\Exception $e) {
7347            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7348        }
7349
7350    }
7351
7352    function isEmailValid($email) {
7353        // Regular expression pattern for email validation
7354        $pattern = '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/';
7355
7356        // Check if the email matches the pattern
7357        if (preg_match($pattern, $email)) {
7358            return true; // Valid email
7359        } else {
7360            return false; // Invalid email
7361        }
7362    }
7363
7364    function list_email_status($companyId){
7365
7366        try {
7367
7368            $companyId = addslashes($companyId);
7369
7370            $where = " company_id IN ({$this->companyId})";
7371
7372            $query = "SELECT DISTINCT x_status FROM tbl_quotations WHERE {$where} AND x_status IS NOT NULL";
7373            $result = DB::select($query);
7374
7375            return response([
7376                'message' => 'OK',
7377                'data' => $result,
7378            ]);
7379
7380
7381        } catch (\Exception $e) {
7382            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7383        }
7384
7385    }
7386
7387    function list_quotation_analytics_commercial(Request $request){
7388
7389        try {
7390
7391            $data = $request->all();
7392            $companyId = addslashes($data['company_id']);
7393            $field = $data['field'];
7394
7395            $where = "";
7396            $whereYear = "";
7397            $dateLflArray = array();
7398            $companyIds = $this->companyIds;
7399            $whereQ = "";
7400
7401            $acc = "";
7402            if($field == 'acceptance_date'){
7403                $acc = " AND q.acceptance_date IS NOT NULL ";
7404                // $field = 'created_at';
7405
7406                if(@$data['data_to_display'] == 4){
7407                    $field = 'created_at';
7408                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7409                    $whereQ .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7410                }
7411            }else{
7412                $field = 'created_at';
7413                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7414                $whereQ .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7415            }
7416
7417            if(isset($data['years']) && $data['years'] != null){
7418                $years = implode(',', $data['years']);
7419                if(count($data['years']) > 0){
7420                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
7421                }
7422            }
7423
7424            if($companyId != 0){
7425                $companyIds = array($companyId);
7426            }
7427
7428            foreach ($companyIds as $v) {
7429
7430                $lflWhere = " AND q.company_id = {$v} ";
7431
7432                $query = "SELECT
7433                            CONCAT(
7434                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
7435                                ' - ',
7436                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
7437                            ) AS date_like,
7438                            YEAR(q.{$field}) 'year',
7439                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
7440                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
7441                            {$v} 'company_id'
7442                        FROM
7443                            tbl_quotations q
7444                        WHERE
7445                            q.{$field} IS NOT NULL
7446                            AND q.for_add != 1
7447                            {$lflWhere}
7448                            {$whereYear}
7449                        GROUP BY YEAR(q.{$field})
7450                        ORDER BY YEAR(q.{$field}) DESC";
7451
7452                $dateLike = DB::select($query);
7453
7454                $dateLflArray[$v] = $dateLike;
7455            }
7456
7457            $isFy = true;
7458
7459            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
7460                $isFy = false;
7461                $ytdArray = array();
7462                $ytdAcceptanceArray = array();
7463                $lflCompanyIds = array();
7464                foreach ($dateLflArray as $k => $v) {
7465                    foreach ($dateLflArray[$k] as $item) {
7466                        $year = $item->year;
7467                        $now = date('m-d');
7468                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
7469                    }
7470
7471                    $ytdArray = implode(' OR ', $ytdArray);
7472                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
7473                    $ytdArray = array();
7474                }
7475
7476                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7477                $where .= " AND ({$lflCompanyIds}";
7478                $whereQ .= " AND ({$lflCompanyIds}";
7479            }
7480
7481            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
7482                $isFy = false;
7483                $lflArray = array();
7484                $ytdAcceptanceArray = array();
7485                $lflCompanyIds = array();
7486                foreach ($dateLflArray as $k => $v) {
7487                    foreach ($dateLflArray[$k] as $item) {
7488                        $year = $item->year;
7489                        $min_date_like = $item->min_date_like;
7490                        $max_date_like = $item->max_date_like;
7491                        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}')");
7492                    }
7493
7494                    $lflArray = implode(' OR ', $lflArray);
7495                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
7496                    $lflArray = array();
7497                }
7498
7499                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7500                $where .= " AND ({$lflCompanyIds}";
7501                $whereQ .= " AND ({$lflCompanyIds}";
7502            }
7503
7504            if($isFy){
7505                $where .= " AND q.company_id IN ({$this->companyId})";
7506                $whereQ .= " AND q.company_id IN ({$this->companyId})";
7507            }            
7508
7509            if(isset($data['source']) && $data['source'] != null){
7510                $where .= " AND s.name = '{$data['source']}'";
7511            }
7512
7513            if(isset($data['month']) && $data['month'] != null){
7514                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
7515            }
7516
7517            if(isset($data['week']) && $data['week'] != null){
7518                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
7519            }
7520
7521            if(isset($data['commercial']) && $data['commercial'] != null){
7522                $where .= " AND q.commercial = '{$data['commercial']}'";
7523            }
7524
7525            if(isset($data['created_by']) && $data['created_by'] != null){
7526                $where .= " AND q.created_by = '{$data['created_by']}'";
7527            }
7528
7529            if(isset($data['budget_type']) && $data['budget_type'] != null){
7530                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
7531            }
7532
7533            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
7534                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
7535            }
7536
7537            if(isset($data['budget_status']) && $data['budget_status'] != null){
7538                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
7539            }
7540
7541            if(isset($data['client_type']) && $data['client_type'] != null){
7542                $where .= " AND ct.customer_type_id = {$data['client_type']}";
7543            }
7544
7545            if(isset($data['segment_id']) && $data['segment_id'] != null){
7546                $where .= " AND q.segment_id = {$data['segment_id']}";
7547            }
7548
7549            $col = "1";
7550
7551            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
7552                if($data['data_to_display'] == 1){
7553                    $col = "1";
7554                }
7555
7556                if($data['data_to_display'] == 2){
7557                    $col = "q.amount";
7558                }
7559            }
7560
7561            $query = "SELECT
7562                        q.commercial 'name',
7563                        COUNT(q.commercial) totalCommercial
7564                    FROM tbl_quotations q
7565                    WHERE
7566                        q.for_add = 0
7567                        AND q.{$field} IS NOT NULL
7568                        {$whereQ}
7569                    GROUP BY q.commercial
7570                    HAVING COUNT(q.commercial) > 0
7571                    ORDER BY totalCommercial DESC";
7572
7573            $resultCommercials = DB::select($query);
7574
7575            $now = TblQuotations::whereIn('company_id', $this->companyIds)->orderBy($field, 'DESC')->pluck($field)->first();
7576            $weekNumber = date('W', strtotime($now));
7577            $thisWeek = date('Y-m-d', strtotime($now . " - " . (date('N', strtotime($now)) - 1) . " days"));
7578
7579            $query = "SELECT
7580                        q.commercial 'name',
7581                        COUNT(q.commercial) totalCommercial
7582                    FROM tbl_quotations q
7583                    WHERE
7584                        q.for_add = 0
7585                        AND q.{$field} IS NOT NULL
7586                        AND YEARWEEK(q.{$field}, 1) = YEARWEEK(NOW(), 1)
7587                        {$whereQ}
7588                    GROUP BY q.commercial
7589                    HAVING COUNT(q.commercial) > 0
7590                    ORDER BY totalCommercial DESC";
7591
7592            $resultCommercialsOrder = DB::select($query);
7593
7594            $namesToRemove = array();
7595
7596            foreach ($resultCommercialsOrder as $item) {
7597                $namesToRemove[$item->name] = true;
7598            }
7599
7600            $resultArray = [];
7601            foreach ($resultCommercials as $item) {
7602                if (!isset($namesToRemove[$item->name])) {
7603                    $resultArray[] = $item;
7604                }
7605            }
7606
7607            $resultCommercials = array_merge($resultCommercialsOrder, $resultArray);
7608
7609            $cols = "";
7610
7611            $colsGroupConcatIds = "";
7612
7613            foreach ($resultCommercials as $item) {
7614                $cols .= ",COALESCE(
7615                    SUM(
7616                        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
7617                    ), 0
7618                ) '{$item->name}'";
7619
7620                $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}'";
7621            }
7622
7623            $cols .= ",COALESCE(
7624                SUM(
7625                    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
7626                ), 0
7627            ) total";
7628
7629            if(@$data['data_to_display'] == 3){
7630
7631                $cols = "";
7632
7633                foreach ($resultCommercials as $item) {
7634                    $cols .= ",COALESCE(
7635                        (
7636                            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)
7637                        ) /
7638                        (
7639                            SUM(CASE WHEN q.commercial = '{$item->name}' AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END)
7640                        )
7641                    , 0) '{$item->name}'";
7642                }
7643
7644                $cols .= ",COALESCE(
7645                    (
7646                        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)
7647                    ) /
7648                    (
7649                        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)
7650                    )
7651                , 0) total";
7652            }
7653
7654            if(@$data['data_to_display'] == 4){
7655
7656                $cols = "";
7657
7658                foreach ($resultCommercials as $item) {
7659                    $cols .= ",COALESCE(
7660                        (
7661                            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)
7662                        ) /
7663                        (
7664                            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)
7665                        ) * 100
7666                    , 0) '{$item->name}'";
7667                }
7668
7669                $cols .= ",COALESCE(
7670                    (
7671                        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)
7672                    ) /
7673                    (
7674                        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)
7675                    ) * 100
7676                , 0) total";
7677            }
7678
7679            $query  = "SELECT
7680                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
7681                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
7682                            LPAD(WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'week',
7683                            DATE_FORMAT(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY), '%W, %M %e') 'namedate',
7684                            GROUP_CONCAT(
7685                                CASE WHEN q.{$field} IS NOT NULL
7686                                THEN q.id END
7687                            ) AS groupConcatIds
7688                            {$colsGroupConcatIds}
7689                            {$cols}
7690                        FROM
7691                            tbl_quotations q
7692                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
7693                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
7694                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
7695                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
7696                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
7697                        WHERE
7698                            q.{$field} IS NOT NULL
7699                            AND q.for_add != 1
7700                            AND q.budget_type_id != 7
7701                            AND q.budget_type_id IS NOT NULL
7702                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
7703                            {$where}
7704                            {$whereYear}
7705                        GROUP BY
7706                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
7707                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
7708                            WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) WITH ROLLUP
7709                        ORDER BY
7710                            YEAR DESC,
7711                            MONTH ASC,
7712                            WEEK ASC,
7713                            DATE_FORMAT(q.{$field}, '%e') ASC";
7714
7715            $value = Cache::get(base64_encode($query));
7716
7717            if(!$value){
7718                $result = DB::select($query);
7719
7720                Cache::put(base64_encode($query), $result, 600);
7721            }else{
7722                $result = $value;
7723            }
7724
7725            return response([
7726                'message' => 'OK',
7727                'data' => $result,
7728                'commercials' => $resultCommercials
7729            ]);
7730
7731        } catch (\Exception $e) {
7732            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7733        }
7734    }
7735
7736    function clear_open_data($companyId){
7737
7738        try {
7739
7740            $companyIds = array($companyId);
7741            if($companyId == 0){
7742                $companyIds = $this->companyIds;
7743            }
7744
7745            $user = TblUsers::where('id', $this->userId)->first();
7746
7747            if(count($companyIds) > 0){
7748
7749                foreach ($companyIds as $id) {
7750                    $startedAt = date('Y-m-d H:i:s');
7751                    $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')");
7752
7753                    TblOrdersUpdateLogs::create(
7754                        array(
7755                            'company_id' => $id,
7756                            'to_process' => 'Orders',
7757                            'status' => 'success',
7758                            'for_add_deleted_affected_rows' => $affectedRows,
7759                            'processed_by' => $user->name,
7760                            'started_at' => $startedAt,
7761                            'ended_at' => date('Y-m-d H:i:s')
7762                        )
7763                    );
7764                }
7765            }
7766
7767            return response([
7768                'message' => 'OK',
7769            ]);
7770
7771        } catch (\Exception $e) {
7772            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7773        }
7774
7775    }
7776
7777    function list_quotation_analytics_order_size(Request $request){
7778
7779        try {
7780
7781            $data = $request->all();
7782            $companyId = addslashes($data['company_id']);
7783            $field = $data['field'];
7784
7785            $where = "";
7786            $dateLflArray = array();
7787            $whereYear = "";
7788            $companyIds = $this->companyIds;
7789
7790            if($field == 'acceptance_date'){
7791                if(@$data['data_to_display'] == 4){
7792                    $field = 'created_at';
7793                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7794                }
7795            }else{
7796                $field = 'created_at';
7797                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7798            }
7799
7800            if(isset($data['years']) && $data['years'] != null){
7801                $years = implode(',', $data['years']);
7802                if(count($data['years']) > 0){
7803                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
7804                }
7805            }
7806
7807            if($companyId != 0){
7808                $companyIds = array($companyId);
7809            }
7810
7811            foreach ($companyIds as $v) {
7812
7813                $lflWhere = " AND q.company_id = {$v} ";
7814
7815                $query = "SELECT
7816                            CONCAT(
7817                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
7818                                ' - ',
7819                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
7820                            ) AS date_like,
7821                            YEAR(q.{$field}) 'year',
7822                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
7823                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
7824                            {$v} 'company_id'
7825                        FROM
7826                            tbl_quotations q
7827                        WHERE
7828                            q.{$field} IS NOT NULL
7829                            AND q.for_add != 1
7830                            {$lflWhere}
7831                            {$whereYear}
7832                        GROUP BY YEAR(q.{$field})
7833                        ORDER BY YEAR(q.{$field}) DESC";
7834
7835                $dateLike = DB::select($query);
7836
7837                $dateLflArray[$v] = $dateLike;
7838            }
7839
7840            $isFy = true;
7841
7842            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
7843                $isFy = false;
7844                $ytdArray = array();
7845                $ytdAcceptanceArray = array();
7846                $lflCompanyIds = array();
7847                foreach ($dateLflArray as $k => $v) {
7848                    foreach ($dateLflArray[$k] as $item) {
7849                        $year = $item->year;
7850                        $now = date('m-d');
7851                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
7852                    }
7853
7854                    $ytdArray = implode(' OR ', $ytdArray);
7855                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
7856                    $ytdArray = array();
7857                }
7858
7859                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7860                $where .= " AND ({$lflCompanyIds}";
7861            }
7862
7863            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
7864                $isFy = false;
7865                $lflArray = array();
7866                $ytdAcceptanceArray = array();
7867                $lflCompanyIds = array();
7868                foreach ($dateLflArray as $k => $v) {
7869                    foreach ($dateLflArray[$k] as $item) {
7870                        $year = $item->year;
7871                        $min_date_like = $item->min_date_like;
7872                        $max_date_like = $item->max_date_like;
7873                        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}')");
7874                    }
7875
7876                    $lflArray = implode(' OR ', $lflArray);
7877                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
7878                    $lflArray = array();
7879                }
7880
7881                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7882                $where .= " AND ({$lflCompanyIds}";
7883            }
7884
7885            if($isFy){                
7886                $where .= " AND q.company_id IN ({$this->companyId}";
7887            }
7888
7889            if(isset($data['source']) && $data['source'] != null){
7890                $where .= " AND s.name = '{$data['source']}'";
7891            }
7892
7893            if(isset($data['source']) && $data['source'] != null){
7894                $where .= " AND s.name = '{$data['source']}'";
7895            }
7896
7897            if(isset($data['commercial']) && $data['commercial'] != null){
7898                $where .= " AND q.commercial = '{$data['commercial']}'";
7899            }
7900
7901            if(isset($data['created_by']) && $data['created_by'] != null){
7902                $where .= " AND q.created_by = '{$data['created_by']}'";
7903            }
7904
7905            if(isset($data['budget_type']) && $data['budget_type'] != null){
7906                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
7907            }
7908
7909            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
7910                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
7911            }
7912
7913            if(isset($data['budget_status']) && $data['budget_status'] != null){
7914                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
7915            }
7916
7917            if(isset($data['client_type']) && $data['client_type'] != null){
7918                $where .= " AND ct.customer_type_id = {$data['client_type']}";
7919            }
7920
7921            if(isset($data['segment_id']) && $data['segment_id'] != null){
7922                $where .= " AND q.segment_id = {$data['segment_id']}";
7923            }
7924
7925            $col = "q.one";
7926
7927            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
7928                if($data['data_to_display'] == 1){
7929                    $col = "q.one";
7930                }
7931
7932                if($data['data_to_display'] == 2){
7933                    $col = "q.amount";
7934                }
7935            }
7936
7937            if((isset($data['start_date']) && $data['start_date'] != null) && isset($data['end_date']) && $data['end_date'] != null){
7938                $where .= " AND q.{$field} BETWEEN '{$data['start_date']}' AND '{$data['end_date']}";
7939            }elseif((isset($data['start_date']) && $data['start_date'] == null || $data['start_date'] == "") && isset($data['end_date']) && $data['end_date'] != null){
7940                $where .= " AND q.{$field} = '{$data['end_date']}";
7941            }
7942
7943            $whereQ = $where;
7944
7945            $sortBy = array(
7946                0 => 'q.amount < 100',
7947                1 => 'q.amount BETWEEN 100 AND 500',
7948                2 => 'q.amount BETWEEN 500 AND 2000',
7949                3 => 'q.amount BETWEEN 2000 AND 10000',
7950                4 => 'q.amount BETWEEN 10000 AND 30000',
7951                5 => 'q.amount BETWEEN 30000 AND 100000',
7952                6 => 'q.amount BETWEEN 100000 AND 999999999999'
7953            );
7954
7955            $query = "SELECT
7956                        q.commercial 'name',
7957                        COUNT(q.commercial) totalCommercial
7958                    FROM tbl_quotations q
7959                    LEFT JOIN tbl_sources s ON s.source_id = q.source_id
7960                    LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
7961                    LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
7962                    LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
7963                    WHERE
7964                        q.for_add = 0
7965                        AND q.{$field} IS NOT NULL
7966                        AND q.for_add != 1
7967                        AND q.budget_type_id != 7
7968                        AND q.budget_type_id IS NOT NULL
7969                        {$whereQ}
7970                        {$whereYear}
7971                    GROUP BY q.commercial
7972                    HAVING COUNT(q.commercial) > 0
7973                    ORDER BY totalCommercial DESC";
7974
7975            $resultCommercials = DB::select($query);
7976
7977            if(isset($data['sort_by'])){
7978                if($data['sort_by'] != 7){
7979                    $s = $sortBy[$data['sort_by']];
7980                    $whereQ .= " AND {$s} ";
7981                }
7982            }
7983
7984            $num = "COUNT(1)";
7985
7986            if(@$data['data_to_display'] == 2){
7987                $num = "SUM(q.amount)";
7988            }
7989
7990            if(@$data['data_to_display'] == 3){
7991                $num = "SUM(q.amount) / COUNT(1)";
7992            }
7993
7994            if(@$data['data_to_display'] == 4){
7995                $num = "(SUM(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) / COUNT(q.created_at) * 100)";
7996            }
7997
7998            $query = "SELECT
7999                    q.commercial 'name',
8000                    COUNT(q.commercial) totalCommercial,
8001                    {$num} num
8002                FROM tbl_quotations q
8003                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8004                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8005                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8006                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8007                WHERE
8008                    q.for_add = 0
8009                    AND q.{$field} IS NOT NULL
8010                    AND q.for_add != 1
8011                    AND q.budget_type_id != 7
8012                    AND q.budget_type_id IS NOT NULL
8013                    {$whereQ}
8014                    {$whereYear}
8015                GROUP BY q.commercial
8016                HAVING COUNT(q.commercial) > 0
8017                ORDER BY num DESC";
8018
8019            $resultCommercialsOrder = DB::select($query);
8020
8021            foreach ($resultCommercialsOrder as $item) {
8022                $namesToRemove[$item->name] = true;
8023            }
8024
8025            $resultArray = [];
8026            foreach ($resultCommercials as $item) {
8027                if (!isset($namesToRemove[$item->name])) {
8028                    $resultArray[] = $item;
8029                }
8030            }
8031
8032            $resultCommercials = array_merge($resultCommercialsOrder, $resultArray);
8033
8034            $cols = "";
8035
8036            $colsGroupConcatIds = "";
8037
8038            foreach ($resultCommercials as $item) {
8039                $cols .= ",COALESCE(
8040                    SUM(
8041                        CASE WHEN q.commercial = '{$item->name}' THEN {$col} ELSE 0 END
8042                    ), 0
8043                ) '{$item->name}'";
8044
8045                $colsGroupConcatIds .= ",GROUP_CONCAT(CASE WHEN q.commercial = '{$item->name}' THEN q.id END) 'groupConcatIds-{$item->name}'";
8046            }
8047
8048            $cols .= ",COALESCE(
8049                SUM(
8050                    CASE WHEN q.commercial IS NOT NULL THEN {$col} ELSE 0 END
8051                ), 0
8052            ) total";
8053
8054            $range = "CASE
8055                        WHEN amount < 100 THEN '< 100€'
8056                        WHEN amount BETWEEN 100 AND 500 THEN '100€ - 500€'
8057                        WHEN amount BETWEEN 500 AND 2000 THEN '500€ - 2k€'
8058                        WHEN amount BETWEEN 2000 AND 10000 THEN '2k€ - 10k€'
8059                        WHEN amount BETWEEN 10000 AND 30000 THEN '10k€ - 30k€'
8060                        WHEN amount BETWEEN 30000 AND 100000 THEN '30k€ - 100k€'
8061                        WHEN amount BETWEEN 100000 AND 999999999999 THEN '> 100k€'
8062                    END AS amount_range";
8063
8064            if(@$data['data_to_display'] == 3){
8065
8066                $range = "CASE
8067                            WHEN SUM(amount) / COUNT(1) < 100 THEN '< 100€'
8068                            WHEN SUM(amount) / COUNT(1) BETWEEN 100 AND 500 THEN '100€ - 500€'
8069                            WHEN SUM(amount) / COUNT(1) BETWEEN 500 AND 2000 THEN '500€ - 2k€'
8070                            WHEN SUM(amount) / COUNT(1) BETWEEN 2000 AND 10000 THEN '2k€ - 10k€'
8071                            WHEN SUM(amount) / COUNT(1) BETWEEN 10000 AND 30000 THEN '10k€ - 30k€'
8072                            WHEN SUM(amount) / COUNT(1) BETWEEN 30000 AND 100000 THEN '30k€ - 100k€'
8073                            WHEN SUM(amount) / COUNT(1) BETWEEN 100000 AND 999999999999 THEN '> 100k€'
8074                        END AS amount_range";
8075
8076                $cols = "";
8077
8078                foreach ($resultCommercials as $item) {
8079                    $cols .= ",COALESCE(
8080                        (
8081                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.amount END)
8082                        ) /
8083                        (
8084                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.one END)
8085                        )
8086                    , 0) '{$item->name}'";
8087                }
8088
8089                $cols .= ",COALESCE(
8090                    (
8091                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.amount END)
8092                    ) /
8093                    (
8094                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.one END)
8095                    )
8096                , 0) total";
8097            }
8098
8099            if(@$data['data_to_display'] == 4){
8100
8101                $cols = "";
8102
8103                foreach ($resultCommercials as $item) {
8104                    $cols .= ",COALESCE(
8105                        (
8106                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.acceptanceDate END)
8107                        ) /
8108                        (
8109                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.createdAt END)
8110                        ) * 100
8111                    , 0) '{$item->name}'";
8112                }
8113
8114                $cols .= ",COALESCE(
8115                    (
8116                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.acceptanceDate END)
8117                    ) /
8118                    (
8119                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.createdAt END)
8120                    ) * 100
8121                , 0) total";
8122            }
8123
8124            $query  = "WITH amount_ranges AS (
8125                            SELECT '< 100€' AS amount_range
8126                            UNION ALL SELECT '100€ - 500€'
8127                            UNION ALL SELECT '500€ - 2k€'
8128                            UNION ALL SELECT '2k€ - 10k€'
8129                            UNION ALL SELECT '10k€ - 30k€'
8130                            UNION ALL SELECT '30k€ - 100k€'
8131                            UNION ALL SELECT '> 100k€'
8132                        )
8133
8134                        SELECT
8135                            ar.amount_range,
8136                             GROUP_CONCAT(
8137                                q.id
8138                            ) AS groupConcatIds
8139                            {$colsGroupConcatIds}
8140                            {$cols}
8141                        FROM
8142                            amount_ranges ar
8143                        LEFT JOIN (
8144                            SELECT
8145                                commercial,
8146                                GROUP_CONCAT(
8147                                    CASE WHEN q.{$field} IS NOT NULL THEN id END
8148                                ) id,
8149                                amount AS amount,
8150                                COUNT(CASE WHEN q.created_at IS NOT NULL THEN 1 END) createdAt,
8151                                COUNT(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 END) acceptanceDate,
8152                                COUNT(1) AS one,
8153                                {$range}
8154                            FROM
8155                                tbl_quotations q
8156                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8157                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8158                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8159                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8160                            WHERE
8161                                q.{$field} IS NOT NULL
8162                                AND q.for_add = 0
8163                                AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL)
8164                                AND q.for_add != 1
8165                                AND q.budget_type_id != 7
8166                                AND q.budget_type_id IS NOT NULL
8167                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
8168                                {$where}
8169                                {$whereYear}
8170                            GROUP BY
8171                                commercial,
8172                                id
8173                        ) AS q ON ar.amount_range = q.amount_range
8174                        GROUP BY
8175                            ar.amount_range WITH ROLLUP
8176                        ORDER BY
8177                            CASE
8178                                WHEN ar.amount_range = '< 100€' THEN 1
8179                                WHEN ar.amount_range = '100€ - 500€' THEN 2
8180                                WHEN ar.amount_range = '500€ - 2k€' THEN 3
8181                                WHEN ar.amount_range = '2k€ - 10k€' THEN 4
8182                                WHEN ar.amount_range = '10k€ - 30k€' THEN 5
8183                                WHEN ar.amount_range = '30k€ - 100k€' THEN 6
8184                                ELSE 7
8185                            END";
8186
8187            $value = Cache::get(base64_encode($query));
8188
8189            if(!$value){
8190                $result = DB::select($query);
8191
8192                Cache::put(base64_encode($query), $result, 600);
8193            }else{
8194                $result = $value;
8195            }
8196
8197            return response([
8198                'message' => 'OK',
8199                'data' => $result,
8200                'commercials' => $resultCommercials
8201            ]);
8202
8203        } catch (\Exception $e) {
8204            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8205        }
8206
8207    }
8208
8209    function send_email_template_preview($emailTemplateId){
8210
8211        try {
8212
8213            $emailTemplateId = addslashes($emailTemplateId);
8214
8215            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
8216
8217            $user   = TblUsers::where('id', $this->userId)->first();
8218            $error  = false;
8219
8220            $toEmail = $user->email;
8221
8222            $availableParameters = [
8223                'quote_id',
8224                'company_id',
8225                'client',
8226                'client_type',
8227                'phone_number',
8228                'email',
8229                'issue_date',
8230                'request_date',
8231                'duration',
8232                'invoice_number',
8233                'type',
8234                'acceptance_date',
8235                'status',
8236                'source',
8237                'amount',
8238                'reason_for_not_following_up',
8239                'last_follow_up_date',
8240                'last_follow_up_comment',
8241                'reason_for_rejection_id',
8242                'reason_for_rejection',
8243                'commercial',
8244                'created_at',
8245                'created_by',
8246                'updated_at',
8247                'updated_by'
8248            ];
8249
8250            $dateParameters = [
8251                'issue_date',
8252                'request_date',
8253                'acceptance_date',
8254                'last_follow_up_date',
8255                'created_at',
8256                'updated_at',
8257            ];
8258
8259            if($this->locale == 'es'){
8260                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
8261            }
8262
8263            if($this->locale == 'es'){
8264                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
8265            }
8266
8267            $body = $emailTemplate->html;
8268            $subject = $emailTemplate->subject;
8269
8270            preg_match_all('/{{(.*?)}}/', $body, $matches);
8271
8272            $parameters = $matches[1];
8273
8274            $result = TblQuotations::where('for_add', 0)->whereIn('company_id', $this->companyIds)->first();
8275
8276            foreach ($parameters as $parameter) {
8277
8278                if(in_array($parameter, $dateParameters)){
8279                    if($result->{$parameter}){
8280                        $result->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result->{$parameter})));
8281                    }
8282                }
8283
8284                if(in_array($parameter, $availableParameters)){
8285                    $body = str_replace('{{' . $parameter . '}}', $result->{$parameter}, $body);
8286                }
8287            }
8288
8289            preg_match_all('/{{(.*?)}}/', $subject, $matches);
8290
8291            $parameters = $matches[1];
8292
8293            foreach ($parameters as $parameter) {
8294
8295                if(in_array($parameter, $dateParameters)){
8296                    if($result->{$parameter}){
8297                        $result->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result->{$parameter})));
8298                    }
8299                }
8300
8301                if(in_array($parameter, $availableParameters)){
8302                    $subject = str_replace('{{' . $parameter . '}}', $result->{$parameter}, $subject);
8303                }
8304            }
8305
8306
8307            $email = new \SendGrid\Mail\Mail();
8308
8309            $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
8310
8311            foreach ($templateFiles as $item) {
8312                $f = storage_path('app/public/uploads/' . $item->filename);
8313                $imgpath = file_get_contents($f);
8314                $mimeType = mime_content_type($f);
8315
8316                $email->addAttachment(
8317                    $imgpath,
8318                    $mimeType,
8319                    str_replace(' ', '', $item->original_name),
8320                    "inline",
8321                    str_replace(' ', '', $item->original_name),
8322                );
8323
8324                $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
8325            }
8326
8327            $html = '<!DOCTYPE html>';
8328            $html .= '<html>';
8329            $html .= '<head>';
8330            $html .= '<meta charset="UTF-8">';
8331            $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
8332            $html .= '</head>';
8333            $html .= '<body>';
8334            $html .= $body;
8335            $html .= '</body>';
8336            $html .= '</html>';
8337
8338            if($toEmail != null){
8339
8340                $companyEmail = null;
8341
8342                if($emailTemplate->from_id != null){
8343                    $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
8344                }else{
8345                    $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result->company_id)->first();
8346                }
8347
8348                if(!$companyEmail){
8349                    return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
8350                }
8351
8352                $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
8353                $email->setSubject($subject);
8354                $email->addTo($toEmail);
8355                $email->addContent("text/html", $html);
8356
8357                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
8358
8359                $response = $sendgrid->send($email);
8360                if ($response->statusCode() == 202) {
8361                    return response(['message' => 'OK']);
8362                }
8363            }
8364
8365            return response(['message' => 'KO']);
8366
8367        } catch (\Exception $e) {
8368            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8369        }
8370
8371    }
8372
8373    function list_quotation_analytics_by_types_of_budgets_company_per_week(Request $request){
8374
8375        try {
8376
8377            $data = $request->all();
8378            $companyId = addslashes($data['company_id']);
8379            $field = $data['field'];
8380
8381            $where = "";
8382            $whereYear = "";
8383            $dateLflArray = array();
8384            $companyIds = $this->companyIds;
8385
8386            $acc = "";
8387            if($field == 'acceptance_date'){
8388                $acc = " AND q.acceptance_date IS NOT NULL ";
8389                // $field = 'created_at';
8390
8391                if(@$data['data_to_display'] == 4){
8392                    $field = 'created_at';
8393                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8394                }
8395            }else{
8396                $field = 'created_at';
8397                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8398            }
8399
8400            if($companyId != 0){
8401                $companyIds = array($companyId);
8402            }
8403
8404            if(isset($data['years']) && $data['years'] != null){
8405                $years = implode(',', $data['years']);
8406                if(count($data['years']) > 0){
8407                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
8408                }
8409            }
8410
8411            foreach ($companyIds as $v) {
8412
8413                $lflWhere = " AND q.company_id = {$v} ";
8414
8415                $query = "SELECT
8416                            CONCAT(
8417                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
8418                                ' - ',
8419                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
8420                            ) AS date_like,
8421                            YEAR(q.{$field}) 'year',
8422                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
8423                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
8424                            {$v} 'company_id'
8425                        FROM
8426                            tbl_quotations q
8427                        WHERE
8428                            q.{$field} IS NOT NULL
8429                            AND q.for_add != 1
8430                            {$lflWhere}
8431                            {$whereYear}
8432                        GROUP BY YEAR(q.{$field})
8433                        ORDER BY YEAR(q.{$field}) DESC";
8434
8435                $dateLike = DB::select($query);
8436
8437                $dateLflArray[$v] = $dateLike;
8438            }
8439
8440            $isFy = true;
8441
8442            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
8443                $isFy = false;
8444                $ytdArray = array();
8445                $ytdAcceptanceArray = array();
8446                $lflCompanyIds = array();
8447                foreach ($dateLflArray as $k => $v) {
8448                    foreach ($dateLflArray[$k] as $item) {
8449                        $year = $item->year;
8450                        $now = date('m-d');
8451                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
8452                    }
8453
8454                    $ytdArray = implode(' OR ', $ytdArray);
8455                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
8456                    $ytdArray = array();
8457                }
8458
8459                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8460                $where .= " AND ({$lflCompanyIds}";
8461            }
8462
8463            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
8464                $isFy = false;
8465                $lflArray = array();
8466                $ytdAcceptanceArray = array();
8467                $lflCompanyIds = array();
8468                foreach ($dateLflArray as $k => $v) {
8469                    foreach ($dateLflArray[$k] as $item) {
8470                        $year = $item->year;
8471                        $min_date_like = $item->min_date_like;
8472                        $max_date_like = $item->max_date_like;
8473                        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}')");
8474                    }
8475
8476                    $lflArray = implode(' OR ', $lflArray);
8477                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
8478                    $lflArray = array();
8479                }
8480
8481                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8482                $where .= " AND ({$lflCompanyIds}";
8483            }
8484
8485            if($isFy){
8486                $where .= " AND q.company_id IN ({$this->companyId})";
8487            }
8488
8489            if(isset($data['source']) && $data['source'] != null){
8490                $where .= " AND s.name = '{$data['source']}'";
8491            }
8492
8493            if(isset($data['month']) && $data['month'] != null){
8494                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
8495            }
8496
8497            if(isset($data['week']) && $data['week'] != null){
8498                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
8499            }
8500
8501            if(isset($data['commercial']) && $data['commercial'] != null){
8502                $where .= " AND q.commercial = '{$data['commercial']}'";
8503            }
8504
8505            if(isset($data['created_by']) && $data['created_by'] != null){
8506                $where .= " AND q.created_by = '{$data['created_by']}'";
8507            }
8508
8509            if(isset($data['budget_type']) && $data['budget_type'] != null){
8510                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
8511            }
8512
8513            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
8514                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
8515            }
8516
8517            if(isset($data['budget_status']) && $data['budget_status'] != null){
8518                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
8519            }
8520
8521            if(isset($data['client_type']) && $data['client_type'] != null){
8522                $where .= " AND ct.customer_type_id = {$data['client_type']}";
8523            }
8524
8525            if(isset($data['segment_id']) && $data['segment_id'] != null){
8526                $where .= " AND q.segment_id = {$data['segment_id']}";
8527            }
8528
8529            $col = "1";
8530
8531            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
8532                if($data['data_to_display'] == 1){
8533                    $col = "1";
8534                }
8535
8536                if($data['data_to_display'] == 2){
8537                    $col = "q.amount";
8538                }
8539            }
8540
8541            $budgetTypes = TblBudgetTypes::orderByRaw("ISNULL(priority), priority ASC")->get();
8542            $cols = "";
8543            foreach ($budgetTypes as $item) {
8544                if($item->name == '' || $item->name == null){
8545                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} ELSE 0 END), 0) AS 'Otros'";
8546                }else{
8547                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN {$col} ELSE 0 END), 0) AS '{$item->name}'";
8548                }
8549            }
8550
8551            $budgetTypeGroups = TblBudgetTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
8552
8553            $colsGroups = ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} END), 0) AS Otros";
8554
8555            foreach ($budgetTypeGroups as $item) {
8556                $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8557                $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}'";
8558                $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}'";
8559            }
8560
8561            $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";
8562
8563            $col = $colsGroups . $cols;
8564
8565            if(@$data['data_to_display'] == 3){
8566
8567                $cols = "";
8568                foreach ($budgetTypes as $item) {
8569                    if($item->name == '' || $item->name == null){
8570                        $cols .= ",COALESCE(
8571                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount ELSE 0 END) /
8572                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 ELSE 0 END) * 100
8573                                    , 0) AS 'Otros'";
8574                    }else{
8575                        $cols .= ", COALESCE(
8576                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN q.amount ELSE 0 END) /
8577                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN 1 ELSE 0 END)
8578                                    , 0) AS '{$item->name}'";
8579                    }
8580                }
8581
8582                $colsGroups = ",COALESCE(
8583                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount END)) /
8584                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 END))
8585                            , 0) Otros";
8586
8587                foreach ($budgetTypeGroups as $item) {
8588                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8589                    $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}'";
8590                    $colsGroups .= ",COALESCE(
8591                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.amount END)) /
8592                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN 1 END))
8593                                    , 0) '{$budgetTypeGroupName}'";
8594                }
8595
8596                $colsGroups .= ",COALESCE(
8597                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.amount END)) /
8598                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END))
8599                                , 0) total";
8600
8601                $col = $colsGroups . $cols;
8602            }
8603
8604            if(@$data['data_to_display'] == 4){
8605
8606                $cols = "";
8607
8608                foreach ($budgetTypes as $item) {
8609
8610                    if($item->name == '' || $item->name == null){
8611                        $cols .= ",COALESCE(
8612                                        SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) /
8613                                        SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 ELSE 0 END) * 100
8614                                    , 0) AS 'Otros'";
8615                    }else{
8616                        $cols .= ", COALESCE(
8617                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.acceptance_date IS NOT NULL THEN 1 END) /
8618                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.created_at IS NOT NULL THEN 1 END) * 100
8619                                    , 0) AS '{$item->name}'";
8620                    }
8621                }
8622
8623                $colsGroups = ",COALESCE(
8624                                    (SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 END)) /
8625                                    (SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 END)) * 100
8626                                , 0) Otros";
8627
8628                foreach ($budgetTypeGroups as $item) {
8629                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8630                    $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}'";
8631                    $colsGroups .= ",COALESCE(
8632                                        (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)) /
8633                                        (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
8634                                    , 0) '{$budgetTypeGroupName}'";
8635                }
8636
8637                $colsGroups .= ",COALESCE(
8638                                    (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)) /
8639                                    (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
8640                                    , 0) total";
8641
8642                $col = $colsGroups . $cols;
8643            }
8644
8645            $query  = "SELECT
8646                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
8647                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
8648                            q.company_id,
8649                            c.name 'companyName',
8650                            GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.id END) groupConcatIds
8651                            {$col}
8652                        FROM
8653                            tbl_quotations q
8654                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8655                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8656                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8657                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
8658                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8659                            LEFT JOIN tbl_companies c ON q.company_id = c.company_id
8660                        WHERE
8661                            q.{$field} IS NOT NULL
8662                            AND q.for_add != 1
8663                            AND q.budget_type_id != 7
8664                            AND q.budget_type_id IS NOT NULL
8665                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
8666                            AND q.acceptance_date != '0000-00-00 00:00:00'
8667                            {$where}
8668                            {$whereYear}
8669                        GROUP BY
8670                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
8671                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
8672                            q.company_id WITH ROLLUP
8673                        ORDER BY
8674                            YEAR DESC,
8675                            MONTH ASC,
8676                            q.company_id ASC,
8677                            DATE_FORMAT(q.{$field}, '%e') ASC";
8678
8679            $result = DB::select($query);
8680
8681            $query = "SELECT
8682                        btg.budget_type_group_id,
8683                        btg.name,
8684                        (
8685                            SELECT
8686                                GROUP_CONCAT(COALESCE(bt.name, '') ORDER BY ISNULL(bt.priority), bt.priority ASC SEPARATOR '|')
8687                            FROM
8688                                tbl_budget_types bt
8689                            WHERE
8690                                bt.budget_type_group_id = btg.budget_type_group_id
8691                        ) budget_types
8692                        FROM
8693                            tbl_budget_type_groups btg
8694                        ORDER BY
8695                            ISNULL(btg.priority),
8696                            btg.priority ASC";
8697
8698            $budgetTypeGroups = DB::select($query);
8699
8700            foreach ($budgetTypeGroups as $item) {
8701                $item->group_key_name = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8702                $item->budget_types = explode("|", $item->budget_types);
8703            }
8704
8705            return response([
8706                'message' => 'OK',
8707                'data' => $result,
8708                'budgetTypeGroups' => $budgetTypeGroups
8709            ]);
8710
8711        } catch (\Exception $e) {
8712            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8713        }
8714    }
8715
8716    function request_permission_commercial(Request $request){
8717
8718        try {
8719
8720            $data = $request->all();
8721
8722            $id = addslashes($data['id']);
8723            $requestedBy = $data['requested_by'];
8724            $body = "";
8725
8726            $result = TblQuotations::where('id', $id)->first();
8727
8728            $subject = __('language.request_permission_commercial.subject');
8729            $subject = str_replace('{{quote_id}}', $result->quote_id, $subject);
8730            $subject = str_replace('{{username}}', $requestedBy, $subject);
8731
8732            $email = new \SendGrid\Mail\Mail();
8733
8734            $imgpath = File::get('fireservicetitan.png');
8735
8736            $email->addAttachment(
8737                $imgpath,
8738                "image/png",
8739                "fireservicetitan.png",
8740                "inline",
8741                "fireservicetitan"
8742            );
8743
8744            $url = env('URL') . "orders/{$id}?company_id={$result->company_id}";
8745            $href = "<a href='{$url}'>{$result->quote_id}</a>";
8746
8747            $user = TblUsers::where('name', $requestedBy)->first();
8748
8749            $urlClick = env('URL') . "update?confirm_request={$id}&requested_by={$user->id}&quote_id={$result->quote_id}";
8750            $company = TblCompanies::where('company_id', $result->company_id)->first();
8751
8752            $body .= __('language.request_permission_commercial.body_hello');
8753            $body .= __('language.request_permission_commercial.body_message');
8754
8755            $amount = $this->currency($result->amount, 1);
8756
8757            $body = str_replace('{{commercial}}', $result->commercial, $body);
8758            $body = str_replace('{{company}}', $company->name, $body);
8759            $body = str_replace('{{client}}', $result->client, $body);
8760            $body = str_replace('{{amount}}', $amount, $body);
8761            $body = str_replace('{{quote_id}}', $href, $body);
8762            $body = str_replace('{{click}}', $urlClick, $body);
8763            $body = str_replace('{{username}}', $requestedBy, $body);
8764
8765            $body .= "<p>Fire Service Titan</p>";
8766            $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
8767
8768            $html = '<!DOCTYPE html>';
8769            $html .= '<html>';
8770            $html .= '<head>';
8771            $html .= '<meta charset="UTF-8">';
8772            $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
8773            $html .= '</head>';
8774            $html .= '<body>';
8775            $html .= $body;
8776            $html .= '</body>';
8777            $html .= '</html>';
8778
8779            $user = TblUsers::where('id', $this->userId)->first();
8780
8781            if(env('SENDGRID_STAGING')){
8782                $email->addTo($user->email);
8783            }else{
8784                $email->addTo("luis.collar@fire.es");
8785
8786                $user = TblUsers::where('name', $result->created_by)->first();
8787                if($user && $user->email != "luis.collar@fire.es"){
8788                    $email->addTo($user->email);
8789                }
8790
8791                if($result->created_by != $result->commercial){
8792                    $user = TblUsers::where('name', $result->commercial)->first();
8793                    if($user->email != "luis.collar@fire.es"){
8794                        $email->addTo($user->email);
8795                    }
8796                }
8797            }
8798
8799            $email->setFrom("titan@fire.es");
8800            $email->setSubject($subject);
8801
8802            $email->addContent("text/html", $html);
8803
8804            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
8805
8806            $response = $sendgrid->send($email);
8807            if ($response->statusCode() == 202) {
8808                return response(['message' => 'OK']);
8809            }
8810
8811            return response(['message' => 'KO']);
8812
8813        } catch (\Exception $e) {
8814            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8815        }
8816
8817    }
8818
8819    function confirm_update_commercial(Request $request){
8820
8821        try {
8822            sleep(3);
8823            $data = $request->all();
8824            $id = addslashes($data['id']);
8825            $userId = addslashes($data['requested_by']);
8826
8827            $user = TblUsers::where('id', $userId)->first();
8828
8829            if($user){
8830
8831                TblQuotations::where('id', $data['id'])->update(
8832                    array(
8833                        'commercial' => $user->name,
8834                        'updated_at' => date('Y-m-d H:i:s')
8835                    )
8836                );
8837
8838            }else{
8839                return response(['message' => 'KO', 'error' => 'invalid_user']);
8840            }
8841
8842            return response(['message' => 'OK']);
8843
8844        } catch (\Exception $e) {
8845            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8846        }
8847    }
8848
8849    function calculateEmailRequestSize(Mail $email){
8850
8851        $size = 0;
8852
8853        // Add size of 'from', 'to', 'subject', 'content'
8854        $from = $email->getFrom();
8855        $size += strlen(json_encode([
8856            'from' => $from->getEmail() . ' ' . $from->getName(),
8857            'subject' => $email->getSubject()
8858        ]));
8859
8860        // Add size of 'to' (recipients)
8861        $personalizations = $email->getPersonalization();
8862        foreach ($personalizations as $personalization) {
8863            foreach ($personalization->getTos() as $to) {
8864                $size += strlen($to->getEmail() . ' ' . $to->getName());
8865            }
8866        }
8867
8868        // Add size of content
8869        foreach ($email->getContents() as $content) {
8870            $size += strlen($content->getValue());
8871        }
8872
8873        // Add size of attachments (if any)
8874
8875        if($email->getAttachments() != null && $email->getAttachments() != ""){
8876            foreach ($email->getAttachments() as $attachment) {
8877                $size += strlen($attachment->getContent()); // Base64 encoded size
8878                $size += strlen($attachment->getFilename());
8879                $size += strlen($attachment->getType());
8880            }
8881        }
8882
8883        $sizeInMegabytes = $size / 1048576; // 1 MB = 1,048,576 bytes
8884
8885        return (int) ceil($sizeInMegabytes);
8886    }
8887
8888    public function list_quotation_analytics_commercial_productivity(Request $request){
8889
8890        // try {
8891
8892            $data = $request->all();
8893            $companyId = addslashes($data['company_id']);
8894
8895            $where = "";
8896            $whereYear = "";
8897            $whereVisit = "";
8898
8899            $dateLflArray = array();
8900            $companyIds = $this->companyIds;
8901
8902            if($companyId != 0){
8903                $companyIds = array($companyId);
8904            }
8905
8906            $field = "issue_date";
8907
8908            if(isset($data['years']) && $data['years'] != null){
8909                $years = implode(',', $data['years']);
8910                if(count($data['years']) > 0){
8911                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
8912                }
8913            }
8914
8915            foreach ($companyIds as $v) {
8916
8917                $lflWhere = " AND q.company_id = {$v} ";
8918
8919                $query = "SELECT
8920                            CONCAT(
8921                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
8922                                ' - ',
8923                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
8924                            ) AS date_like,
8925                            YEAR(q.{$field}) 'year',
8926                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
8927                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
8928                            {$v} 'company_id'
8929                        FROM
8930                            tbl_quotations q
8931                        WHERE
8932                            q.{$field} IS NOT NULL
8933                            AND q.for_add != 1
8934                            {$lflWhere}
8935                            {$whereYear}
8936                        GROUP BY YEAR(q.{$field})
8937                        ORDER BY YEAR(q.{$field}) DESC";
8938
8939                $dateLike = DB::select($query);
8940
8941                if(count($dateLike) > 0){
8942                    $dateLflArray[$v] = $dateLike;
8943                }
8944            }
8945
8946            $whereAcceptanceDate = "";
8947
8948            if(isset($data['source']) && $data['source'] != null){
8949                $where .= " AND s.name = '{$data['source']}'";
8950            }
8951
8952            if(isset($data['month']) && $data['month'] != null){
8953                $where .= " AND MONTH(q.created_at) = '{$data['month']}'";
8954            }
8955
8956            if(isset($data['week']) && $data['week'] != null){
8957                $where .= " AND WEEK(q.created_at) = '{$data['week']}'";
8958            }
8959
8960            if(isset($data['commercial']) && $data['commercial'] != null){
8961                $commercial = implode("','", $data['commercial']);
8962                if(count($data['commercial']) > 0){
8963                    $where .= " AND q.commercial IN ('{$commercial}') ";
8964                    $whereVisit .= " AND q.commercial IN ('{$commercial}') ";
8965                }
8966            }
8967
8968            if(isset($data['created_by']) && $data['created_by'] != null){
8969                $created_by = implode("','", $data['created_by']);
8970                if(count($data['created_by']) > 0){
8971                    $where .= " AND q.created_by IN ('{$created_by}')";
8972                }
8973            }
8974
8975            if(isset($data['budget_type']) && $data['budget_type'] != null){
8976                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
8977            }
8978
8979            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
8980                $budgetTypeGroupIds = implode(",", $data['budget_type_group']);
8981                if(count($data['budget_type_group']) > 0){
8982                    $where .= " AND bt.budget_type_group_id IN ({$budgetTypeGroupIds})";
8983                }
8984            }
8985
8986            if(isset($data['budget_status']) && $data['budget_status'] != null){
8987                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
8988            }
8989
8990            if(isset($data['client_type']) && $data['client_type'] != null){
8991                $where .= " AND ct.customer_type_id = {$data['client_type']}";
8992            }
8993
8994            if(isset($data['segment_id']) && $data['segment_id'] != null){
8995                $where .= " AND q.segment_id = {$data['segment_id']}";
8996            }
8997
8998            if(isset($data['role_id']) && $data['role_id'] != null){
8999                $roleId = implode(",", $data['role_id']);
9000                if(count($data['role_id']) > 0){
9001                    $where .= " AND r.role_id IN ({$roleId})";
9002                    $whereVisit .= " AND r.role_id IN ({$roleId}";
9003                }
9004            }
9005
9006            $groupByFilter = 2;
9007            if(isset($data['group_by']) && $data['group_by'] != null){
9008                $groupByFilter = $data['group_by'];
9009            }
9010
9011            $groupBy = "1, 2, 3, q.commercial, budget_type";
9012
9013            if($groupByFilter == 1){
9014                $groupBy = "1, q.commercial, 2, 3, budget_type";
9015            }
9016
9017            if($groupByFilter == 3){
9018                $groupBy = "1, budget_type, q.commercial, 2, 3";
9019            }
9020
9021            $aggregatedBy = 1;
9022            $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', LPAD(q.week, 2, 0) AS 'week', ";
9023            $aggregatedByCalc = " / 4";
9024            if(isset($data['aggregated_by']) && $data['aggregated_by'] != null){
9025                $aggregatedBy = $data['aggregated_by'];
9026                if($data['aggregated_by'] == 1){
9027
9028                    $groupBy = "1, 2, 3, q.commercial, budget_type";
9029
9030                    if($groupByFilter == 1){
9031                        $groupBy = "1, q.commercial, 2, 3, budget_type";
9032                    }
9033
9034                    if($groupByFilter == 3){
9035                        $groupBy = "1, budget_type, q.commercial, 2, 3";
9036                    }
9037
9038                    $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', LPAD(q.week, 2, 0) AS 'week', ";
9039                }elseif($data['aggregated_by'] == 2){
9040                    $groupBy = "1, 2, q.commercial, budget_type";
9041
9042                    if($groupByFilter == 1){
9043                        $groupBy = "1, q.commercial, 2, budget_type";
9044                    }
9045
9046                    if($groupByFilter == 3){
9047                        $groupBy = "1, budget_type, q.commercial, 2";
9048                    }
9049
9050                    $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', NULL AS 'week',";
9051                    $aggregatedByCalc = "";
9052                }elseif($data['aggregated_by'] == 3){
9053                    $groupBy = "1, q.commercial, budget_type";
9054
9055                    if($groupByFilter == 3){
9056                        $groupBy = "1, budget_type, q.commercial";
9057                    }
9058
9059                    $aggregatedCol = "NULL AS 'month', NULL AS 'week',";
9060                    $aggregatedByCalc = " * 12";
9061                }
9062            }
9063
9064            $whereAcceptanceDate = $where;
9065            $whereCreatedAt = $where;
9066
9067            $isFy = true;
9068
9069            $where .= " AND q.company_id IN ({$this->companyId}";
9070            $whereCreatedAt .= " AND q.company_id IN ({$this->companyId}";
9071            $whereAcceptanceDate .= " AND q.company_id IN ({$this->companyId}";
9072            $whereVisit .= " AND q.company_id IN ({$this->companyId}";            
9073
9074            if(isset($data['campaign']) && $data['campaign'] != null){
9075                $campaign = implode("','", $data['campaign']);
9076                if(count($data['campaign']) > 0){
9077                    $whereVisit .= " AND q.campaign IN ('{$campaign}')";
9078                }
9079            }
9080
9081            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
9082                $isFy = false;
9083                $now = date('m-d');
9084
9085                $where .= " AND q.{$field} BETWEEN DATE_FORMAT(q.{$field}, '%Y-01-01') AND DATE_FORMAT(q.{$field}, '%Y-{$now}') ";
9086                $whereCreatedAt .= " AND q.created_at BETWEEN DATE_FORMAT(q.created_at, '%Y-01-01') AND DATE_FORMAT(q.created_at, '%Y-{$now}') ";
9087                $whereAcceptanceDate .= " AND q.acceptance_date BETWEEN DATE_FORMAT(q.acceptance_date, '%Y-01-01') AND DATE_FORMAT(q.acceptance_date, '%Y-{$now}') ";
9088                $whereVisit .= " AND q.visit_date BETWEEN DATE_FORMAT(q.visit_date, '%Y-01-01') AND DATE_FORMAT(q.visit_date, '%Y-{$now}') ";
9089            }
9090
9091            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
9092                $isFy = false;
9093                $lflArray = array();
9094                $ytdAcceptanceArray = array();
9095                $lflCompanyIds = array();
9096                $lflCompanyIdsAcc = array();
9097                foreach ($dateLflArray as $k => $v) {
9098                    foreach ($dateLflArray[$k] as $item) {
9099                        $year = $item->year;
9100                        $min_date_like = $item->min_date_like;
9101                        $max_date_like = $item->max_date_like;
9102                        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}')");
9103                        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}')");
9104                    }
9105
9106                    $lflArray = implode(' OR ', $lflArray);
9107                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
9108                    $lflArray = array();
9109
9110                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
9111                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
9112                    $ytdAcceptanceArray = array();
9113                }
9114
9115                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
9116                $where .= " AND ({$lflCompanyIds}";
9117
9118                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
9119                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
9120            }
9121
9122            $orderBy = "CASE WHEN q.commercial IS NULL OR q.budget_type IS NULL THEN q.priority END DESC, q.priority ASC,";
9123
9124            if(isset($data['order_by'])){
9125                $col = $data['order_by']['column'];
9126                $sort = $data['order_by']['sort'];
9127
9128                if(!empty($sort) || $sort != null){
9129                    $orderBy = "CASE WHEN q.commercial IS NULL OR q.budget_type IS NULL THEN {$col} END DESC, {$col} {$sort},";
9130                }
9131            }
9132
9133
9134            $visitTypes = TblVisitTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
9135
9136            $visitCols = "";
9137            $visitMainTableCols = "";
9138            $visitSubMainTableCols = "";
9139            $visitSubTableCols = "";
9140            $visitMainCols = "";
9141
9142            $visitCall = array("Visita", "Llamada");
9143
9144            foreach ($visitCall as $value) {
9145                foreach ($visitTypes as $item) {
9146                    $visitTypeNames = $value . $item->visit_type_group_id;
9147                    $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}'";
9148                    $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}'";
9149                    $visitMainTableCols .= ",COALESCE(SUM(q.total{$visitTypeNames}), 0) AS 'total{$visitTypeNames}'";
9150                    $visitMainTableCols .= ",GROUP_CONCAT(q.groupConcatIds{$visitTypeNames})  AS 'groupConcatIds{$visitTypeNames}'";
9151                    $visitSubMainTableCols .= ",q.total{$visitTypeNames}";
9152                    $visitSubMainTableCols .= ",q.groupConcatIds{$visitTypeNames}";
9153                    $visitSubTableCols .= ",0 AS total{$visitTypeNames}";
9154                    $visitSubTableCols .= ",NULL AS groupConcatIds{$visitTypeNames}";
9155                    $visitMainCols .= ",COALESCE(SUM(q.total{$visitTypeNames}), 0) total{$visitTypeNames}";
9156                    $visitMainCols .= ",GROUP_CONCAT(q.groupConcatIds{$visitTypeNames}) groupConcatIds{$visitTypeNames}";
9157                }
9158            }
9159
9160
9161            $businessGoalsDefault = TblBusinessGoals::where('is_default', 1)->where('budget_type_group_id', 999999999)->first();
9162
9163            $businessGoalsDefault->issue_objective = $businessGoalsDefault->issue_objective ?? 1;
9164            $businessGoalsDefault->acceptance_objective = $businessGoalsDefault->acceptance_objective ?? 1;
9165            $businessGoalsDefault->new_objective = $businessGoalsDefault->new_objective ?? 1;
9166            $businessGoalsDefault->is_amount = $businessGoalsDefault->is_amount ?? 1;
9167
9168            $gO = "";
9169
9170            if($groupByFilter != 3){
9171                $gO = "ORDER BY
9172                        1 DESC,
9173                        2 ASC,
9174                        3 ASC,
9175                        q.commercial ASC,
9176                        {$orderBy}
9177                        DATE_FORMAT(q.namedate, '%e') ASC";
9178            }else{
9179                $gO = "ORDER BY
9180                        1 DESC,
9181                        2 ASC,
9182                        3 ASC,
9183                        budget_type ASC,
9184                        q.commercial ASC";
9185            }
9186
9187            $query = "WITH business_goal_objective_users AS (
9188                        SELECT
9189                            bg.user_id,
9190                            bg.issue_objective,
9191                            bg.acceptance_objective,
9192                            bg.new_objective,
9193                            bg.is_amount
9194                        FROM tbl_business_goals bg
9195                        WHERE bg.budget_type_group_id = 999999999
9196                    ), business_goal_objective_roles AS (
9197                        SELECT
9198                            bg.role_id,
9199                            bg.issue_objective,
9200                            bg.acceptance_objective,
9201                            bg.new_objective,
9202                            bg.is_amount
9203                        FROM tbl_business_goals bg
9204                        WHERE bg.budget_type_group_id = 999999999
9205                    )
9206
9207                    SELECT
9208                        q.year,
9209                        {$aggregatedCol}
9210                        q.namedate created_at,
9211                        q.commercial,
9212                        q.budget_type,
9213                        COALESCE(SUM(q.issue_date), 0) totalIssue,
9214                        COALESCE(SUM(q.created_at), 0) totalCreatedAt,
9215                        GROUP_CONCAT(q.groupConcatIds) groupConcatIds,
9216                        SUM(q.totalIssueObjective) totalIssueObjective,
9217                        CASE
9218                            WHEN SUM(q.totalIssueObjective) BETWEEN 1 AND 70 THEN 'text-danger'
9219                            WHEN SUM(q.totalIssueObjective) BETWEEN 70 AND 90 THEN 'text-warning'
9220                        END textIssueColor,
9221                        SUM(q.revenueIssue) revenueIssue,
9222                        SUM(q.totalIssueObjectiveMonthly) totalIssueObjectiveMonthly,
9223                        SUM(q.totalIssueObjectiveYearly) totalIssueObjectiveYearly,
9224                        COALESCE(SUM(q.acceptance_date), 0) totalAcceptance,
9225                        GROUP_CONCAT(q.groupConcatCreatedAtIds) groupConcatCreatedAtIds,
9226                        SUM(q.totalIssueLessThan5) AS totalIssueLessThan5,
9227                        GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) AS groupConcatIdsIssueLessThan5,
9228                        GROUP_CONCAT(q.groupConcatAcceptanceIds) groupConcatAcceptanceIds,
9229                        SUM(q.totalAcceptanceObjective) totalAcceptanceObjective,
9230                        SUM(q.totalAcceptanceObjectiveMonthly) totalAcceptanceObjectiveMonthly,
9231                        SUM(q.totalAcceptanceObjectiveYearly) totalAcceptanceObjectiveYearly,
9232                        CASE
9233                            WHEN SUM(q.totalAcceptanceObjective) BETWEEN 1 AND 70 THEN 'text-danger'
9234                            WHEN SUM(q.totalAcceptanceObjective) BETWEEN 70 AND 90 THEN 'text-warning'
9235                        END textAcceptanceColor,
9236                        SUM(q.revenueAcceptance) revenueAcceptance,
9237                        COALESCE(SUM(q.totalRejected), 0) totalRejected,
9238                        GROUP_CONCAT(q.groupConcatRejectedIds) groupConcatRejectedIds,
9239                        SUM(q.revenueRejected) revenueRejected,
9240                        COALESCE(SUM(q.totalNew)) totalNew,
9241                        GROUP_CONCAT(q.groupConcatNewIds) groupConcatNewIds,
9242                        SUM(q.totalNewObjective) totalNewObjective,
9243                        SUM(q.totalNewObjectiveMonthly) totalNewObjectiveMonthly,
9244                        SUM(q.totalNewObjectiveYearly) totalNewObjectiveYearly,
9245                        CASE
9246                            WHEN SUM(q.totalNewObjective) BETWEEN 1 AND 70 THEN 'text-danger'
9247                            WHEN SUM(q.totalNewObjective) BETWEEN 70 AND 90 THEN 'text-warning'
9248                        END textNewColor,
9249                        SUM(q.revenueNew) revenueNew,
9250                        COALESCE(SUM(q.totalVisit), 0) totalVisit,
9251                        GROUP_CONCAT(q.groupConcatVisitIds) groupConcatVisitIds,
9252                        COALESCE(SUM(q.totalCall), 0) totalCall,
9253                        GROUP_CONCAT(q.groupConcatCallIds) groupConcatCallIds,
9254                        SUM(q.is_amountIssue) AS is_amountIssue,
9255                        SUM(q.is_amountNew) AS is_amountNew,
9256                        SUM(q.is_amountAcceptance) AS is_amountAcceptance,
9257                        SUM(q.issueObjective) AS issueObjective,
9258                        SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9259                        SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9260                        SUM(q.newObjective) AS newObjective,
9261                        SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9262                        SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9263                        SUM(q.acceptanceObjective) AS acceptanceObjective,
9264                        SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9265                        SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9266                        {$visitMainCols}
9267                    FROM
9268                    (
9269                        SELECT
9270                            q.year,
9271                            q.month,
9272                            q.week,
9273                            q.namedate,
9274                            SUM(q.issue_date) AS issue_date,
9275                            q.acceptance_date,
9276                            q.created_at,
9277                            q.commercial,
9278                            q.budget_type,
9279                            GROUP_CONCAT(q.groupConcatIds) AS groupConcatIds,
9280                            CASE
9281                                WHEN q.is_amountIssue > 0 THEN
9282                                    SUM(q.revenueIssue / q.issueObjective) * 100
9283                                ELSE
9284                                    SUM(q.issue_date / q.issueObjective) * 100
9285                                END
9286                            AS totalIssueObjective,
9287                            CASE
9288                                WHEN q.is_amountIssue > 0 THEN
9289                                    SUM(q.revenueIssue / q.issueObjectiveMonthly) * 100
9290                                ELSE
9291                                    SUM(q.issue_date / q.issueObjectiveMonthly) * 100
9292                                END
9293                            AS totalIssueObjectiveMonthly,
9294                            CASE
9295                                WHEN q.is_amountIssue > 0 THEN
9296                                    SUM(q.revenueIssue / q.issueObjectiveYearly) * 100
9297                                ELSE
9298                                    SUM(q.issue_date / q.issueObjectiveYearly) * 100
9299                                END
9300                            AS totalIssueObjectiveYearly,
9301                            SUM(q.revenueIssue) revenueIssue,
9302                            GROUP_CONCAT(q.groupConcatCreatedAtIds) AS groupConcatCreatedAtIds,
9303                            SUM(q.totalIssueLessThan5) totalIssueLessThan5,
9304                            GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) groupConcatIdsIssueLessThan5,
9305                            GROUP_CONCAT(q.groupConcatAcceptanceIds) AS groupConcatAcceptanceIds,
9306                            SUM(q.acceptanceObjective) totalAcceptanceObjective,
9307                            SUM(q.acceptanceObjectiveMonthly) totalAcceptanceObjectiveMonthly,
9308                            SUM(q.acceptanceObjectiveYearly) totalAcceptanceObjectiveYearly,
9309                            q.revenueAcceptance,
9310                            SUM(q.totalRejected) AS totalRejected,
9311                            GROUP_CONCAT(q.groupConcatRejectedIds) AS groupConcatRejectedIds,
9312                            SUM(q.revenueRejected) revenueRejected,
9313                            SUM(q.totalNew) AS totalNew,
9314                            GROUP_CONCAT(q.groupConcatNewIds) AS groupConcatNewIds,
9315                            CASE
9316                                WHEN q.is_amountNew > 0 THEN
9317                                    SUM(q.revenueNew / q.newObjective) * 100
9318                                ELSE
9319                                    SUM(q.totalNew / q.newObjective) * 100
9320                                END
9321                            AS totalNewObjective,
9322                             CASE
9323                                WHEN q.is_amountNew > 0 THEN
9324                                    SUM(q.revenueNew / q.newObjectiveMonthly) * 100
9325                                ELSE
9326                                    SUM(q.totalNew / q.newObjectiveMonthly) * 100
9327                                END
9328                            AS totalNewObjectiveMonthly,
9329                             CASE
9330                                WHEN q.is_amountNew > 0 THEN
9331                                    SUM(q.revenueNew / q.newObjectiveYearly) * 100
9332                                ELSE
9333                                    SUM(q.totalNew / q.newObjectiveYearly) * 100
9334                                END
9335                            AS totalNewObjectiveYearly,
9336                            SUM(q.revenueNew) revenueNew,
9337                            q.totalVisit,
9338                            q.groupConcatVisitIds,
9339                            q.totalCall,
9340                            q.groupConcatCallIds,
9341                            q.priority,
9342                            SUM(q.is_amountIssue) AS is_amountIssue,
9343                            SUM(q.is_amountNew) AS is_amountNew,
9344                            SUM(q.is_amountAcceptance) AS is_amountAcceptance,
9345                            SUM(q.issueObjective) AS issueObjective,
9346                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9347                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9348                            SUM(q.newObjective) AS newObjective,
9349                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9350                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9351                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9352                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9353                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9354                            {$visitSubMainTableCols}
9355                        FROM (
9356                            SELECT
9357                                YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'year',
9358                                MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'month',
9359                                WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'week',
9360                                DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') namedate,
9361                                COUNT(CASE WHEN q.issue_date IS NOT NULL THEN 1 END) issue_date,
9362                                0 acceptance_date,
9363                                0 created_at,
9364                                q.commercial,
9365                                btg.name budget_type,
9366                                GROUP_CONCAT(CASE WHEN q.issue_date IS NOT NULL THEN q.id END) AS groupConcatIds,
9367
9368                                SUM(CASE WHEN q.issue_date IS NOT NULL THEN q.amount END) AS revenueIssue,
9369                                NULL groupConcatCreatedAtIds,
9370                                0 totalIssueLessThan5,
9371                                NULL groupConcatIdsIssueLessThan5,
9372                                NULL groupConcatAcceptanceIds,
9373
9374                                0 revenueAcceptance,
9375                                COUNT(CASE WHEN bs.name = 'Rechazado' THEN 1 END) AS totalRejected,
9376                                GROUP_CONCAT(DISTINCT CASE WHEN bs.name = 'Rechazado' THEN q.id END) AS groupConcatRejectedIds,
9377                                COALESCE(SUM(CASE WHEN bs.name = 'Rechazado' THEN q.amount END), 0) AS revenueRejected,
9378                                COUNT(CASE WHEN ct.name = 'Nuevo' THEN 1 END) AS totalNew,
9379                                GROUP_CONCAT(DISTINCT CASE WHEN ct.name = 'Nuevo' THEN q.id END) AS groupConcatNewIds,
9380
9381                                COALESCE(SUM(CASE WHEN ct.name = 'Nuevo' THEN q.amount END), 0) revenueNew,
9382                                0 totalVisit,
9383                                NULL groupConcatVisitIds,
9384                                0 totalCall,
9385                                NULL groupConcatCallIds,
9386                                btg.priority,
9387                                CAST(
9388                                    CASE
9389                                        WHEN bg.issue_objective IS NOT NULL THEN bg.is_amount
9390                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.is_amount
9391                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.is_amount
9392                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.is_amount
9393                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.is_amount
9394                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9395                                    END
9396                                AS DOUBLE) AS is_amountIssue,
9397                                CAST(
9398                                    CASE
9399                                        WHEN bg.new_objective IS NOT NULL THEN bg.is_amount
9400                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.is_amount
9401                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.is_amount
9402                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.is_amount
9403                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.is_amount
9404                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9405                                    END
9406                                AS DOUBLE) AS is_amountNew,
9407                                0 is_amountAcceptance,
9408                                CAST(
9409                                    CASE
9410                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9411                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9412                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9413                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9414                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9415                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9416                                    END {$aggregatedByCalc}
9417                                AS DOUBLE) AS issueObjective,
9418                                CAST(
9419                                    CASE
9420                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9421                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9422                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9423                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9424                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9425                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9426                                    END
9427                                AS DOUBLE) AS issueObjectiveMonthly,
9428                                CAST(
9429                                    CASE
9430                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9431                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9432                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9433                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9434                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9435                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9436                                    END * 12
9437                                AS DOUBLE) AS issueObjectiveYearly,
9438                                CAST(
9439                                    CASE
9440                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9441                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9442                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9443                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9444                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9445                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9446                                    END {$aggregatedByCalc}
9447                                AS DOUBLE) AS newObjective,
9448                                CAST(
9449                                    CASE
9450                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9451                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9452                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9453                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9454                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9455                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9456                                    END
9457                                AS DOUBLE) AS newObjectiveMonthly,
9458                                CAST(
9459                                    CASE
9460                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9461                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9462                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9463                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9464                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9465                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9466                                    END * 12
9467                                AS DOUBLE) AS newObjectiveYearly,
9468                                0 acceptanceObjective,
9469                                0 acceptanceObjectiveMonthly,
9470                                0 acceptanceObjectiveYearly
9471                                {$visitSubTableCols}
9472                            FROM
9473                            tbl_quotations q
9474                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9475                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9476                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9477                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9478                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9479                                LEFT JOIN tbl_users u ON q.commercial = u.name
9480                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9481                                LEFT JOIN tbl_business_goals bg ON bg.budget_type_group_id = btg.budget_type_group_id AND bg.user_id = u.id
9482                                LEFT JOIN tbl_business_goals bg1 ON bg1.budget_type_group_id = btg.budget_type_group_id AND bg1.role_id = r.role_id
9483                                LEFT JOIN tbl_business_goals bgde ON bgde.budget_type_group_id = btg.budget_type_group_id AND bgde.is_default = 1
9484                                LEFT JOIN business_goal_objective_users bgou ON bgou.user_id = u.id
9485                                LEFT JOIN business_goal_objective_roles bgor ON bgor.role_id = r.role_id
9486                            WHERE
9487                                q.budget_type_id != 7
9488                                AND q.budget_type_id IS NOT NULL
9489                                AND q.for_add != 1
9490                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9491                                AND bt.include = 1
9492                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9493                                {$where}
9494                                {$whereYear}
9495                            GROUP BY
9496                                {$groupBy}
9497                        ) q
9498                        GROUP BY
9499                            {$groupBy} WITH ROLLUP
9500
9501                        UNION ALL
9502
9503                        SELECT
9504                            q.year,
9505                            q.month,
9506                            q.week,
9507                            q.namedate,
9508                            q.issue_date,
9509                            SUM(q.acceptance_date) AS acceptance_date,
9510                            q.created_at,
9511                            q.commercial,
9512                            q.budget_type,
9513                            q.groupConcatIds,
9514                            q.issueObjective totalIssueObjective,
9515                            q.issueObjectiveMonthly totalIssueObjectiveMonthly,
9516                            q.issueObjectiveYearly totalIssueObjectiveYearly,
9517                            q.revenueIssue,
9518                            q.groupConcatCreatedAtIds,
9519                            q.totalIssueLessThan5,
9520                            q.groupConcatIdsIssueLessThan5,
9521                            GROUP_CONCAT(q.groupConcatAcceptanceIds) AS groupConcatAcceptanceIds,
9522                            CASE
9523                                WHEN q.is_amountAcceptance > 0 THEN
9524                                    SUM(q.revenueAcceptance / q.acceptanceObjective) * 100
9525                                ELSE
9526                                    SUM(q.acceptance_date / q.acceptanceObjective) * 100
9527                                END
9528                            AS totalAcceptanceObjective,
9529                            CASE
9530                                WHEN q.is_amountAcceptance > 0 THEN
9531                                    SUM(q.revenueAcceptance / q.acceptanceObjectiveMonthly) * 100
9532                                ELSE
9533                                    SUM(q.acceptance_date / q.acceptanceObjectiveMonthly) * 100
9534                                END
9535                            AS totalAcceptanceObjectiveMonthly,
9536                            CASE
9537                                WHEN q.is_amountAcceptance > 0 THEN
9538                                    SUM(q.revenueAcceptance / q.acceptanceObjectiveYearly) * 100
9539                                ELSE
9540                                    SUM(q.acceptance_date / q.acceptanceObjectiveYearly) * 100
9541                                END
9542                            AS totalAcceptanceObjectiveYearly,
9543                            SUM(q.revenueAcceptance) revenueAcceptance,
9544                            q.totalRejected,
9545                            q.groupConcatRejectedIds,
9546                            q.revenueRejected,
9547                            q.totalNew,
9548                            q.groupConcatNewIds,
9549                            q.newObjective totalNewObjective,
9550                            q.newObjectiveMonthly totalNewObjectiveMonthly,
9551                            q.newObjectiveYearly totalNewObjectiveYearly,
9552                            q.revenueNew,
9553                            q.totalVisit,
9554                            q.groupConcatVisitIds,
9555                            q.totalCall,
9556                            q.groupConcatCallIds,
9557                            q.priority,
9558                            SUM(q.is_amountIssue) AS is_amountIssue,
9559                            q.is_amountNew,
9560                            q.is_amountAcceptance,
9561                            SUM(q.issueObjective) AS issueObjective,
9562                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9563                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9564                            SUM(q.newObjective) AS newObjective,
9565                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9566                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9567                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9568                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9569                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9570                            {$visitSubMainTableCols}
9571                        FROM (
9572                            SELECT
9573                                YEAR(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'year',
9574                                MONTH(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'month',
9575                                WEEK(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'week',
9576                                DATE_FORMAT(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY), '%W, %M %e') namedate,
9577                                0 issue_date,
9578                                COUNT(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 END) acceptance_date,
9579                                0 created_at,
9580                                q.commercial,
9581                                btg.name budget_type,
9582                                NULL groupConcatIds,
9583
9584                                0 revenueIssue,
9585                                NULL groupConcatCreatedAtIds,
9586                                0 totalIssueLessThan5,
9587                                NULL groupConcatIdsIssueLessThan5,
9588                                GROUP_CONCAT(CASE WHEN q.acceptance_date IS NOT NULL THEN q.id END) AS groupConcatAcceptanceIds,
9589
9590                                COALESCE(SUM(CASE WHEN q.acceptance_date IS NOT NULL THEN q.amount END), 0) AS revenueAcceptance,
9591                                0 totalRejected,
9592                                NULL groupConcatRejectedIds,
9593                                0 revenueRejected,
9594                                0 totalNew,
9595                                NULL groupConcatNewIds,
9596                                NULL totalNewObjective,
9597                                NULL totalNewObjectiveMonthly,
9598                                NULL totalNewObjectiveYearly,
9599                                0 revenueNew,
9600                                0 totalVisit,
9601                                NULL groupConcatVisitIds,
9602                                0 totalCall,
9603                                NULL groupConcatCallIds,
9604                                btg.priority,
9605                                0 is_amountIssue,
9606                                0 is_amountNew,
9607                                CAST(
9608                                    CASE
9609                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.is_amount
9610                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.is_amount
9611                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.is_amount
9612                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.is_amount
9613                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.is_amount
9614                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9615                                    END
9616                                AS DOUBLE) AS is_amountAcceptance,
9617                                0 issueObjective,
9618                                0 issueObjectiveMonthly,
9619                                0 issueObjectiveYearly,
9620                                0 newObjective,
9621                                0 newObjectiveMonthly,
9622                                0 newObjectiveYearly,
9623                                CAST(
9624                                    CASE
9625                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
9626                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
9627                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
9628                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
9629                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
9630                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
9631                                    END {$aggregatedByCalc}
9632                                AS DOUBLE) AS acceptanceObjective,
9633                                CAST(
9634                                    CASE
9635                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
9636                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
9637                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
9638                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
9639                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
9640                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
9641                                    END
9642                                AS DOUBLE) AS acceptanceObjectiveMonthly,
9643                                CAST(
9644                                    CASE
9645                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
9646                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
9647                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
9648                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
9649                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
9650                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
9651                                    END * 12
9652                                AS DOUBLE) AS acceptanceObjectiveYearly
9653                                {$visitSubTableCols}
9654                            FROM
9655                            tbl_quotations q
9656                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9657                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9658                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9659                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9660                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9661                                LEFT JOIN tbl_users u ON q.commercial = u.name
9662                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9663                                LEFT JOIN tbl_business_goals bg ON bg.budget_type_group_id = btg.budget_type_group_id AND bg.user_id = u.id
9664                                LEFT JOIN tbl_business_goals bg1 ON bg1.budget_type_group_id = btg.budget_type_group_id AND bg1.role_id = r.role_id
9665                                LEFT JOIN tbl_business_goals bgde ON bgde.budget_type_group_id = btg.budget_type_group_id AND bgde.is_default = 1
9666                                LEFT JOIN business_goal_objective_users bgou ON bgou.user_id = u.id
9667                                LEFT JOIN business_goal_objective_roles bgor ON bgor.role_id = r.role_id
9668                            WHERE
9669                                q.budget_type_id != 7
9670                                AND q.budget_type_id IS NOT NULL
9671                                AND q.for_add != 1
9672                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9673                                AND bt.include = 1
9674                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9675                                {$whereAcceptanceDate}
9676                                {$whereYear}
9677                            GROUP BY
9678                                {$groupBy}
9679                        ) q
9680                        GROUP BY
9681                            {$groupBy} WITH ROLLUP
9682
9683                        UNION ALL
9684
9685                        SELECT
9686                            q.year,
9687                            q.month,
9688                            q.week,
9689                            q.namedate,
9690                            q.issue_date,
9691                            q.acceptance_date,
9692                            SUM(q.created_at) AS created_at,
9693                            q.commercial,
9694                            q.budget_type,
9695                            q.groupConcatIds,
9696                            q.issueObjective totalIssueObjective,
9697                            q.issueObjectiveMonthly totalIssueObjectiveMonthly,
9698                            q.issueObjectiveYearly totalIssueObjectiveYearly,
9699                            q.revenueIssue,
9700                            GROUP_CONCAT(q.groupConcatCreatedAtIds) AS groupConcatCreatedAtIds,
9701                            SUM(q.totalIssueLessThan5) AS totalIssueLessThan5,
9702                            GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) AS groupConcatIdsIssueLessThan5,
9703                            NULL groupConcatAcceptanceIds,
9704                            0 totalAcceptanceObjective,
9705                            0 totalAcceptanceObjectiveMonthly,
9706                            0 totalAcceptanceObjectiveYearly,
9707                            SUM(q.revenueAcceptance) revenueAcceptance,
9708                            q.totalRejected,
9709                            q.groupConcatRejectedIds,
9710                            q.revenueRejected,
9711                            q.totalNew,
9712                            q.groupConcatNewIds,
9713                            q.newObjective totalNewObjective,
9714                            q.newObjectiveMonthly totalNewObjectiveMonthly,
9715                            q.newObjectiveYearly totalNewObjectiveYearly,
9716                            q.revenueNew,
9717                            q.totalVisit,
9718                            q.groupConcatVisitIds,
9719                            q.totalCall,
9720                            q.groupConcatCallIds,
9721                            q.priority,
9722                            SUM(q.is_amountIssue) AS is_amountIssue,
9723                            q.is_amountNew,
9724                            q.is_amountAcceptance,
9725                            SUM(q.issueObjective) AS issueObjective,
9726                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9727                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9728                            SUM(q.newObjective) AS newObjective,
9729                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9730                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9731                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9732                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9733                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9734                            {$visitSubMainTableCols}
9735                        FROM (
9736                            SELECT
9737                                YEAR(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'year',
9738                                MONTH(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'month',
9739                                WEEK(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'week',
9740                                DATE_FORMAT(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY), '%W, %M %e') namedate,
9741                                0 issue_date,
9742                                0 acceptance_date,
9743                                COUNT(CASE WHEN q.created_at IS NOT NULL THEN 1 END) created_at,
9744                                q.commercial,
9745                                btg.name budget_type,
9746                                NULL groupConcatIds,
9747
9748                                0 revenueIssue,
9749                                GROUP_CONCAT(CASE WHEN q.created_at IS NOT NULL THEN q.id END) AS groupConcatCreatedAtIds,
9750                                COUNT(CASE WHEN ABS(DATEDIFF(q.created_at, q.issue_date)) < 5 THEN 1 END) AS totalIssueLessThan5,
9751                                GROUP_CONCAT(CASE WHEN ABS(DATEDIFF(q.created_at, q.issue_date)) < 5 THEN q.id END) AS groupConcatIdsIssueLessThan5,
9752                                NULL groupConcatAcceptanceIds,
9753
9754                                0 AS revenueAcceptance,
9755                                0 totalRejected,
9756                                NULL groupConcatRejectedIds,
9757                                0 revenueRejected,
9758                                0 totalNew,
9759                                NULL groupConcatNewIds,
9760                                NULL totalNewObjective,
9761                                NULL totalNewObjectiveMonthly,
9762                                NULL totalNewObjectiveYearly,
9763                                0 revenueNew,
9764                                0 totalVisit,
9765                                NULL groupConcatVisitIds,
9766                                0 totalCall,
9767                                NULL groupConcatCallIds,
9768                                btg.priority,
9769                                0 is_amountIssue,
9770                                0 is_amountNew,
9771                                0 is_amountAcceptance,
9772                                0 issueObjective,
9773                                0 issueObjectiveMonthly,
9774                                0 issueObjectiveYearly,
9775                                0 newObjective,
9776                                0 newObjectiveMonthly,
9777                                0 newObjectiveYearly,
9778                                0 acceptanceObjective,
9779                                0 acceptanceObjectiveMonthly,
9780                                0 acceptanceObjectiveYearly
9781                                {$visitSubTableCols}
9782                            FROM
9783                            tbl_quotations q
9784                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9785                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9786                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9787                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9788                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9789                                LEFT JOIN tbl_users u ON q.commercial = u.name
9790                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9791                            WHERE
9792                                q.budget_type_id != 7
9793                                AND q.budget_type_id IS NOT NULL
9794                                AND q.for_add != 1
9795                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9796                                AND bt.include = 1
9797                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9798                                {$whereCreatedAt}
9799                                {$whereYear}
9800                            GROUP BY
9801                                {$groupBy}
9802                        ) q
9803                        GROUP BY
9804                            {$groupBy} WITH ROLLUP
9805
9806                        UNION ALL
9807
9808                        SELECT
9809                            YEAR(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) YEAR,
9810                            MONTH(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) MONTH,
9811                            WEEK(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) WEEK,
9812                            DATE_FORMAT(DATE_ADD(visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY), '%W, %M %e') namedate,
9813                            0 issue_date,
9814                            0 acceptance_date,
9815                            0 created_at,
9816                            commercial,
9817                            NULL budget_type,
9818                            NULL groupConcatIds,
9819                            NULL totalIssueObjective,
9820                            NULL totalIssueObjectiveMonthly,
9821                            NULL totalIssueObjectiveYearly,
9822                            0 revenueIssue,
9823                            NULL groupConcatCreatedAtIds,
9824                            0 totalIssueLessThan5,
9825                            NULL groupConcatIdsIssueLessThan5,
9826                            NULL groupConcatAcceptanceIds,
9827                            NULL totalAcceptanceObjective,NULL totalAcceptanceObjectiveMonthly,
9828                            NULL totalAcceptanceObjectiveYearly,
9829                            0 revenueAcceptance,
9830                            0 totalRejected,
9831                            NULL groupConcatRejectedIds,
9832                            0 revenueRejected,
9833                            0 totalNew,
9834                            NULL groupConcatNewIds,
9835                            NULL totalNewObjective,NULL totalNewObjectiveMonthly,
9836                            NULL totalNewObjectiveYearly,
9837                            0 revenueNew,
9838                            COUNT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Visita' THEN 1 END) totalVisit,
9839                            GROUP_CONCAT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Visita' THEN q.id END) AS groupConcatVisitIds,
9840                            COUNT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Llamada' THEN 1 END) totalCall,
9841                            GROUP_CONCAT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Llamada' THEN q.id END) AS groupConcatCallIds,
9842                            0 priority,
9843                            0 is_amountIssue,
9844                            0 is_amountNew,
9845                            0 is_amountAcceptance,
9846                            0 issueObjective,
9847                            0 issueObjectiveMonthly,
9848                            0 issueObjectiveYearly,
9849                            0 newObjective,
9850                            0 newObjectiveMontly,
9851                            0 newObjectiveYearly,
9852                            0 acceptanceObjective,
9853                            0 acceptanceObjectiveMonthly,
9854                            0 acceptanceObjectiveYearly
9855                            {$visitCols}
9856                        FROM
9857                            tbl_pipelines q
9858                        LEFT JOIN tbl_users u ON q.commercial = u.name
9859                        LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9860                        LEFT JOIN tbl_visit_types v ON q.visit_type_id = v.visit_type_id
9861                        WHERE q.visit_date IS NOT NULL
9862                            {$whereVisit}
9863                        GROUP BY
9864                            {$groupBy}
9865                             WITH ROLLUP
9866                    ) q
9867                    WHERE
9868                        q.year NOT IN (2021, 2022)
9869                    GROUP BY
9870                        {$groupBy}
9871                    {$gO}";            
9872
9873            $value = Cache::get(base64_encode($query));
9874
9875            if(!$value){
9876                $result = DB::select($query);
9877
9878                $structureData = new StructureData();
9879                $result = $structureData->parse($result, $groupByFilter, $aggregatedBy);
9880
9881                Cache::put(base64_encode($query), $result, 600);
9882            }else{
9883                $result = $value;
9884            }
9885
9886            return response([
9887                'message' => 'OK',
9888                'data' => $result
9889            ]);
9890
9891        // } catch (\Exception $e) {
9892        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
9893        // }
9894    }
9895
9896    function list_quotations_deleted($companyId){
9897
9898        try {
9899
9900            $companyId = addslashes($companyId);
9901            $where = "";
9902
9903            if($companyId != 0){
9904                $where = " a.company_id = {$companyId} ";
9905            }else{
9906                $where = " a.company_id IN ({$this->companyId})";
9907            }
9908
9909            $query = "SELECT
9910                        a.id,
9911                        a.quote_id,
9912                        a.company_id,
9913                        b.name company_name,
9914                        a.created_by,
9915                        a.updated_by,
9916                        a.updated_at,
9917                        a.for_add,
9918                        c.name reason,
9919                        a.reason_for_deletion
9920                    FROM tbl_quotations_deleted a
9921                    LEFT JOIN tbl_companies b
9922                        ON a.company_id = b.company_id
9923                    LEFT JOIN tbl_reasons c
9924                        ON a.reason_id = c.reason_id
9925                    WHERE {$where}
9926                    ORDER BY a.updated_at DESC";
9927
9928            $result = DB::select($query);
9929
9930            return response([
9931                'message' => 'OK',
9932                'data' => $result
9933            ]);
9934        } catch (\Exception $e) {
9935            return response(['message' => 'KO', 'error' => $e->getMessage()]);
9936        }
9937    }
9938
9939    function delete_sengrid($id){
9940
9941        try {
9942
9943            $id = addslashes($id);
9944
9945            $order = TblQuotations::where('id', $id)->first();
9946
9947            if($order){
9948                if($order->x_message_id != null){
9949                    TblSendgridWebhook::where('quotation_id', $id)->where('x_message_id', $order->x_message_id)->delete();
9950
9951                    TblQuotations::where('id', $id)->update(
9952                        array(
9953                            'x_message_id' => null,
9954                            'x_status' => null
9955                        )
9956                    );
9957
9958                    Cache::flush();
9959                }
9960            }
9961
9962            return response([
9963                'message' => 'OK'
9964            ]);
9965
9966        } catch (\Exception $e) {
9967            return response(['message' => 'KO', 'error' => $e->getMessage()]);
9968        }
9969    }
9970
9971    function download_productivity_commercial(Request $request){
9972
9973        try {
9974
9975            ini_set('max_execution_time', 123456);
9976
9977            $data = $request->all();
9978
9979            $result = $this->list_quotation_analytics_commercial_productivity($request);
9980            $result = $result->original['data'];
9981
9982            $spreadsheet = new Spreadsheet();
9983            $worksheet   = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, "Inputs");
9984            $spreadsheet->addSheet($worksheet, 0);
9985            $col         = range('A', 'Z');
9986
9987            for($i = 0; $i < 26; $i++){
9988                $worksheet->getColumnDimension($col[$i])->setAutoSize(true);
9989                if($i != 1){
9990                    $worksheet->getStyle($col[$i])
9991                        ->getAlignment()
9992                        ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
9993                }
9994            }
9995
9996            $l = 1;
9997            $worksheet->setCellValue('A' . $l, "Años");
9998
9999            if($data['group_by'] == 1){
10000                $worksheet->setCellValue('B' . $l, "Comercials");
10001                $worksheet->setCellValue('C' . $l, "Meses");
10002                $worksheet->setCellValue('D' . $l, "Semanas");
10003            }else{
10004                $worksheet->setCellValue('B' . $l, "Meses");
10005                $worksheet->setCellValue('C' . $l, "Semanas");
10006                $worksheet->setCellValue('D' . $l, "Comercials");
10007            }
10008
10009            $worksheet->setCellValue('E' . $l, "Categorías de presupuesto");
10010            $worksheet->setCellValue('F' . $l, "Presupuestos emitidos (#)");
10011            $worksheet->setCellValue('G' . $l, "Presupuestos emitidos (€)");
10012            $worksheet->setCellValue('H' . $l, "Presupuestos emitidos (Objetivo)");
10013            $worksheet->setCellValue('I' . $l, "Presupuestos aceptados (#)");
10014            $worksheet->setCellValue('J' . $l, "Presupuestos aceptados (€)");
10015            $worksheet->setCellValue('K' . $l, "Presupuestos aceptados (Objetivo)");
10016            $worksheet->setCellValue('L' . $l, "Presupuestos rechazados (#)");
10017            $worksheet->setCellValue('M' . $l, "Presupuestos rechazados (€)");
10018            $worksheet->setCellValue('N' . $l, "Presupuestos emitidos a nuevos clientes (#)");
10019            $worksheet->setCellValue('O' . $l, "Presupuestos emitidos a nuevos clientes (€)");
10020            $worksheet->setCellValue('P' . $l, "Presupuestos emitidos a nuevos clientes (Objetivo)");
10021            $worksheet->setCellValue('Q' . $l, "Venta (Llamada #)");
10022            $worksheet->setCellValue('R' . $l, "Venta (Visita #)");
10023            $worksheet->setCellValue('S' . $l, "Servicio (Llamada #)");
10024            $worksheet->setCellValue('T' . $l, "Servicio (Visita #)");
10025
10026            $l++;
10027
10028            foreach ($result as $item) {
10029
10030                $worksheet->setCellValue('A' . $l, $item['year']);
10031                $worksheet->setCellValue('F' . $l, $item['totalIssue']);
10032                $worksheet->setCellValue('G' . $l, $item['revenueIssue']);
10033                $worksheet->setCellValue('H' . $l, "-");
10034
10035                $worksheet->setCellValue('I' . $l, $item['totalAcceptance']);
10036                $worksheet->setCellValue('J' . $l, $item['revenueAcceptance']);
10037                $worksheet->setCellValue('K' . $l, "-");
10038
10039                $worksheet->setCellValue('L' . $l, $item['totalRejected']);
10040                $worksheet->setCellValue('M' . $l, $item['revenueRejected']);
10041
10042                $worksheet->setCellValue('N' . $l, $item['totalNew']);
10043                $worksheet->setCellValue('O' . $l, $item['revenueNew']);
10044                $worksheet->setCellValue('P' . $l, "-");
10045
10046                $worksheet->setCellValue('Q' . $l, $item['totalLlamada1']);
10047                $worksheet->setCellValue('R' . $l, $item['totalVisita1']);
10048
10049                $worksheet->setCellValue('S' . $l, $item['totalLlamada2']);
10050                $worksheet->setCellValue('T' . $l, $item['totalVisita2']);
10051
10052                $l++;
10053
10054                if($data['group_by'] == 1){
10055
10056                    if(count($item['commercials']) > 0){
10057
10058                        foreach ($item['commercials'] as $c) {
10059                            $worksheet->setCellValue('A' . $l, $item['year']);
10060
10061                            $worksheet->setCellValue('B' . $l, $c['commercial']);
10062                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10063                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10064                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10065
10066                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10067                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10068                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10069
10070                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10071                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10072
10073                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10074                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10075                            $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10076
10077                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10078                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10079
10080                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10081                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10082                            $l++;
10083
10084                            if(isset($c['budget_types']) && count($c['budget_types']) > 0){
10085                                foreach ($c['budget_types'] as $b) {
10086                                    $worksheet->setCellValue('A' . $l, $item['year']);
10087                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10088
10089                                    $worksheet->setCellValue('E' . $l, $b['name']);
10090                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10091                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10092                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10093
10094                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10095                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10096                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10097
10098                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10099                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10100
10101                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10102                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10103                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10104
10105                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10106                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10107
10108                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10109                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10110                                    $l++;
10111                                }
10112                            }
10113
10114                            if(isset($c['months']) && count($c['months']) > 0){
10115                                foreach ($c['months'] as $m) {
10116                                    $worksheet->setCellValue('A' . $l, $item['year']);
10117                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10118
10119                                    $worksheet->setCellValue('C' . $l, $m['month']);
10120                                    $worksheet->setCellValue('F' . $l, $m['totalIssue']);
10121                                    $worksheet->setCellValue('G' . $l, $m['revenueIssue']);
10122                                    $worksheet->setCellValue('H' . $l, $m['totalIssueObjectiveMonthly']);
10123
10124                                    $worksheet->setCellValue('I' . $l, $m['totalAcceptance']);
10125                                    $worksheet->setCellValue('J' . $l, $m['revenueAcceptance']);
10126                                    $worksheet->setCellValue('K' . $l, $m['totalAcceptanceObjectiveMonthly']);
10127
10128                                    $worksheet->setCellValue('L' . $l, $m['totalRejected']);
10129                                    $worksheet->setCellValue('M' . $l, $m['revenueRejected']);
10130
10131                                    $worksheet->setCellValue('N' . $l, $m['totalNew']);
10132                                    $worksheet->setCellValue('O' . $l, $m['revenueNew']);
10133                                    $worksheet->setCellValue('P' . $l, $m['totalNewObjectiveMonthly']);
10134
10135                                    $worksheet->setCellValue('Q' . $l, $m['totalLlamada1']);
10136                                    $worksheet->setCellValue('R' . $l, $m['totalVisita1']);
10137
10138                                    $worksheet->setCellValue('S' . $l, $m['totalLlamada2']);
10139                                    $worksheet->setCellValue('T' . $l, $m['totalVisita2']);
10140                                    $l++;
10141
10142                                    if(isset($m['weeks']) && count(@$m['weeks']) > 0 && count(@$m['weeks']) != 1){
10143                                        foreach ($m['weeks'] as $w) {
10144                                            $worksheet->setCellValue('A' . $l, $item['year']);
10145                                            $worksheet->setCellValue('B' . $l, $c['commercial']);
10146                                            $worksheet->setCellValue('C' . $l, $m['month']);
10147
10148                                            $worksheet->setCellValue('D' . $l, $w['created_at']);
10149                                            $worksheet->setCellValue('F' . $l, $w['totalIssue']);
10150                                            $worksheet->setCellValue('G' . $l, $w['revenueIssue']);
10151                                            $worksheet->setCellValue('H' . $l, $w['totalIssueObjective']);
10152
10153                                            $worksheet->setCellValue('I' . $l, $w['totalAcceptance']);
10154                                            $worksheet->setCellValue('J' . $l, $w['revenueAcceptance']);
10155                                            $worksheet->setCellValue('K' . $l, $w['totalAcceptanceObjective']);
10156
10157                                            $worksheet->setCellValue('L' . $l, $w['totalRejected']);
10158                                            $worksheet->setCellValue('M' . $l, $w['revenueRejected']);
10159
10160                                            $worksheet->setCellValue('N' . $l, $w['totalNew']);
10161                                            $worksheet->setCellValue('O' . $l, $w['revenueNew']);
10162                                            $worksheet->setCellValue('P' . $l, $w['totalNewObjective']);
10163
10164                                            $worksheet->setCellValue('Q' . $l, $w['totalLlamada1']);
10165                                            $worksheet->setCellValue('R' . $l, $w['totalVisita1']);
10166
10167                                            $worksheet->setCellValue('S' . $l, $w['totalLlamada2']);
10168                                            $worksheet->setCellValue('T' . $l, $w['totalVisita2']);
10169                                            $l++;
10170
10171                                            if(count($w['budget_types']) > 0){
10172                                                foreach ($w['budget_types'] as $b) {
10173                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10174                                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10175                                                    $worksheet->setCellValue('C' . $l, $m['month']);
10176
10177                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10178                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10179                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10180                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10181
10182                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10183                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10184                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10185
10186                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10187                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10188
10189                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10190                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10191                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10192
10193                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10194                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10195
10196                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10197                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10198                                                    $l++;
10199                                                }
10200                                            }
10201                                        }
10202                                    }elseif(isset($m['weeks']) && count(@$m['weeks']) == 1){
10203                                        foreach ($m['weeks'] as $w) {
10204                                            if(count($w['budget_types']) > 0){
10205                                                foreach ($w['budget_types'] as $b) {
10206                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10207                                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10208                                                    $worksheet->setCellValue('C' . $l, $m['month']);
10209
10210                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10211                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10212                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10213                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10214
10215                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10216                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10217                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10218
10219                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10220                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10221
10222                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10223                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10224                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10225
10226                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10227                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10228
10229                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10230                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10231                                                    $l++;
10232                                                }
10233                                            }
10234                                        }
10235
10236                                    }
10237                                }
10238                            }
10239                        }
10240                    }
10241                }else{
10242
10243                    if(isset($item['months']) && count($item['months']) > 0){
10244                        foreach ($item['months'] as $m) {
10245                            $worksheet->setCellValue('A' . $l, $item['year']);
10246                            $worksheet->setCellValue('B' . $l, $m['month']);
10247                            $worksheet->setCellValue('F' . $l, $m['totalIssue']);
10248                            $worksheet->setCellValue('G' . $l, $m['revenueIssue']);
10249                            $worksheet->setCellValue('H' . $l, "-");
10250
10251                            $worksheet->setCellValue('I' . $l, $m['totalAcceptance']);
10252                            $worksheet->setCellValue('J' . $l, $m['revenueAcceptance']);
10253                            $worksheet->setCellValue('K' . $l, "-");
10254
10255                            $worksheet->setCellValue('L' . $l, $m['totalRejected']);
10256                            $worksheet->setCellValue('M' . $l, $m['revenueRejected']);
10257
10258                            $worksheet->setCellValue('N' . $l, $m['totalNew']);
10259                            $worksheet->setCellValue('O' . $l, $m['revenueNew']);
10260                            $worksheet->setCellValue('P' . $l, "-");
10261
10262                            $worksheet->setCellValue('Q' . $l, $m['totalLlamada1']);
10263                            $worksheet->setCellValue('R' . $l, $m['totalVisita1']);
10264
10265                            $worksheet->setCellValue('S' . $l, $m['totalLlamada2']);
10266                            $worksheet->setCellValue('T' . $l, $m['totalVisita2']);
10267                            $l++;
10268
10269                            if(isset($m['weeks']) && count(@$m['weeks']) > 0){
10270                                foreach ($m['weeks'] as $w) {
10271                                    $worksheet->setCellValue('A' . $l, $item['year']);
10272                                    $worksheet->setCellValue('B' . $l, $m['month']);
10273
10274                                    $worksheet->setCellValue('C' . $l, $w['created_at']);
10275                                    $worksheet->setCellValue('F' . $l, $w['totalIssue']);
10276                                    $worksheet->setCellValue('G' . $l, $w['revenueIssue']);
10277                                    $worksheet->setCellValue('H' . $l, "-");
10278
10279                                    $worksheet->setCellValue('I' . $l, $w['totalAcceptance']);
10280                                    $worksheet->setCellValue('J' . $l, $w['revenueAcceptance']);
10281                                    $worksheet->setCellValue('K' . $l, "-");
10282
10283                                    $worksheet->setCellValue('L' . $l, $w['totalRejected']);
10284                                    $worksheet->setCellValue('M' . $l, $w['revenueRejected']);
10285
10286                                    $worksheet->setCellValue('N' . $l, $w['totalNew']);
10287                                    $worksheet->setCellValue('O' . $l, $w['revenueNew']);
10288                                    $worksheet->setCellValue('P' . $l, "-");
10289
10290                                    $worksheet->setCellValue('Q' . $l, $w['totalLlamada1']);
10291                                    $worksheet->setCellValue('R' . $l, $w['totalVisita1']);
10292
10293                                    $worksheet->setCellValue('S' . $l, $w['totalLlamada2']);
10294                                    $worksheet->setCellValue('T' . $l, $w['totalVisita2']);
10295                                    $l++;
10296
10297                                    if(count($w['commercials']) > 0){
10298                                        foreach ($w['commercials'] as $c) {
10299                                            $worksheet->setCellValue('A' . $l, $item['year']);
10300                                            $worksheet->setCellValue('B' . $l, $m['month']);
10301
10302                                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10303                                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10304                                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10305                                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjective']);
10306
10307                                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10308                                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10309                                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjective']);
10310
10311                                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10312                                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10313
10314                                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10315                                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10316                                            $worksheet->setCellValue('P' . $l, $c['totalNewObjective']);
10317
10318                                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10319                                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10320
10321                                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10322                                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10323                                            $l++;
10324
10325                                            if(count($c['budget_types']) > 0){
10326                                                foreach ($c['budget_types'] as $b) {
10327                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10328                                                    $worksheet->setCellValue('B' . $l, $m['month']);
10329                                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10330
10331                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10332                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10333                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10334                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10335
10336                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10337                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10338                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10339
10340                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10341                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10342
10343                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10344                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10345                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10346
10347                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10348                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10349
10350                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10351                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10352                                                    $l++;
10353                                                }
10354                                            }
10355                                        }
10356                                    }
10357                                }
10358                            }
10359
10360                            if(count($m['commercials']) > 0){
10361                                foreach ($m['commercials'] as $c) {
10362                                    $worksheet->setCellValue('A' . $l, $item['year']);
10363                                    $worksheet->setCellValue('B' . $l, $m['month']);
10364
10365                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10366                                    $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10367                                    $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10368                                    $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10369
10370                                    $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10371                                    $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10372                                    $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10373
10374                                    $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10375                                    $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10376
10377                                    $worksheet->setCellValue('N' . $l, $c['totalNew']);
10378                                    $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10379                                    $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10380
10381                                    $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10382                                    $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10383
10384                                    $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10385                                    $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10386                                    $l++;
10387
10388                                    if(count($c['budget_types']) > 0){
10389                                        foreach ($c['budget_types'] as $b) {
10390                                            $worksheet->setCellValue('A' . $l, $item['year']);
10391                                            $worksheet->setCellValue('B' . $l, $m['month']);
10392                                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10393
10394                                            $worksheet->setCellValue('E' . $l, $b['name']);
10395                                            $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10396                                            $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10397                                            $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10398
10399                                            $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10400                                            $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10401                                            $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10402
10403                                            $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10404                                            $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10405
10406                                            $worksheet->setCellValue('N' . $l, $b['totalNew']);
10407                                            $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10408                                            $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10409
10410                                            $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10411                                            $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10412
10413                                            $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10414                                            $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10415                                            $l++;
10416                                        }
10417                                    }
10418                                }
10419                            }
10420                        }
10421                    }
10422
10423                    if(count($item['commercials']) > 0){
10424                        foreach ($item['commercials'] as $c) {
10425                            $worksheet->setCellValue('A' . $l, $item['year']);
10426
10427                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10428                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10429                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10430                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10431
10432                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10433                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10434                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10435
10436                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10437                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10438
10439                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10440                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10441                            $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10442
10443                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10444                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10445
10446                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10447                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10448                            $l++;
10449
10450                            if(count($c['budget_types']) > 0){
10451                                foreach ($c['budget_types'] as $b) {
10452                                    $worksheet->setCellValue('A' . $l, $item['year']);
10453                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10454
10455                                    $worksheet->setCellValue('E' . $l, $b['name']);
10456                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10457                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10458                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10459
10460                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10461                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10462                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10463
10464                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10465                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10466
10467                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10468                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10469                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10470
10471                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10472                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10473
10474                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10475                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10476                                    $l++;
10477                                }
10478                            }
10479                        }
10480                    }
10481                }
10482
10483                $l++;
10484            }
10485
10486            if($data['group_by'] == 1){
10487                if($data['aggregated_by'] == 3){
10488                    $worksheet->removeColumn('C');
10489                    $worksheet->removeColumn('C');
10490                }elseif($data['aggregated_by'] == 2){
10491                    $worksheet->removeColumn('D');
10492                }
10493            }else{
10494                if($data['aggregated_by'] == 3){
10495                    $worksheet->removeColumn('B');
10496                    $worksheet->removeColumn('B');
10497                }elseif($data['aggregated_by'] == 2){
10498                    $worksheet->removeColumn('C');
10499                }
10500            }
10501
10502
10503
10504            $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
10505            ob_start();
10506            $writer->save('php://output');
10507            $file = ob_get_contents();
10508            ob_end_clean();
10509
10510            return response($file);
10511
10512        } catch (\Exception $e) {
10513            return response(['message' => 'KO', 'error' => $e->getMessage()]);
10514        }
10515
10516    }
10517
10518    function update_commercial_numbers($companyId)
10519    {
10520        $phpBinary = '/usr/bin/php';
10521
10522        $artisanPath = escapeshellarg(base_path('artisan'));
10523
10524        $command = sprintf(
10525            '%s %s update:commercial-numbers %s > /dev/null 2>&1 &',
10526            $phpBinary,
10527            $artisanPath,
10528            $companyId
10529        );
10530
10531        exec($command, $output, $returnVar);
10532    }
10533
10534    function list_quotation_analytics_by_service_type(Request $request){
10535
10536        try {
10537
10538            $data = $request->all();
10539            $companyId = addslashes($data['company_id']);
10540            $where  = "";
10541
10542            $where .= " AND c.company_id IN ({$this->companyId}";
10543
10544            $col = "1";
10545
10546            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
10547                if($data['data_to_display'] == 1){
10548                    $col = "1";
10549                }
10550
10551                if($data['data_to_display'] == 2){
10552                    $col = "q.amount";
10553                }
10554            }
10555
10556            if(isset($data['approvals'])){
10557                $approvals = addslashes($data['approvals']);
10558
10559                if($approvals == 2){
10560                    $where .= " AND q.for_approval != 1 ";
10561                }
10562
10563                if($approvals == 3){
10564                    $where .= " AND q.for_approval > 0 ";
10565                }
10566
10567                if($approvals == 4){
10568                    $where .= " AND q.approved_by IS NOT NULL";
10569                }
10570
10571                if($approvals == 5){
10572                    $where .= " AND q.for_approval = 2 AND q.approved_by IS NULL";
10573                }
10574
10575                if($approvals == 6){
10576                    $where .= " AND q.approved_by IS NOT NULL AND q.approved_by_v2 IS NOT NULL";
10577                }
10578
10579                if($approvals == 7){
10580                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NOT NULL AND q.approved_by_v2 IS NULL";
10581                }
10582
10583                if($approvals == 8){
10584                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NULL AND q.approved_by_v2 IS NOT NULL";
10585                }
10586
10587                if($approvals == 9){
10588                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NULL AND q.approved_by_v2 IS NULL";
10589                }
10590            }
10591
10592            if(isset($data['role_id']) && $data['role_id'] != null){
10593                $roleIds = implode(",", $data['role_id']);
10594                if(count($data['role_id']) > 0){
10595                    $where .= " AND u.role_id IN ({$roleIds}, 999999999)";
10596                }
10597            }
10598
10599            if(isset($data['client_type']) && $data['client_type'] != null){
10600                $where .= " AND q.customer_type_id = {$data['client_type']}";
10601            }
10602
10603            $weekDay = "- WEEKDAY(q.date)";
10604
10605            if(isset($data['start_of_the_week']) && $data['start_of_the_week'] != null){
10606                switch ($data['start_of_the_week']) {
10607                    case 0:
10608                        $weekDay = "- WEEKDAY(q.date)";
10609                        break;
10610                    case 1:
10611                        $weekDay = "(1 - WEEKDAY(q.date))";
10612                        break;
10613                    case 2:
10614                        $weekDay = "(2 - WEEKDAY(q.date))";
10615                        break;
10616                    case 3:
10617                        $weekDay = "(3 - WEEKDAY(q.date))";
10618                        break;
10619                    case 4:
10620                        $weekDay = "(4 - WEEKDAY(q.date))";
10621                        break;
10622                    default:
10623                        $weekDay = "- WEEKDAY(q.date)";
10624                        break;
10625                }
10626            }
10627
10628            $whereDates = "";
10629
10630            if((isset($data['start_date']) && $data['start_date'] != null) && (isset($data['end_date']) && $data['end_date'] != null)){
10631                $whereDates = " AND q.date BETWEEN '{$data['start_date']}' AND '{$data['end_date']}";
10632            }
10633
10634            $query = "SELECT
10635                        q.region,
10636                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) 'year',
10637                        LPAD(MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'month',
10638                        LPAD(WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'week',
10639                        DATE_FORMAT(DATE_ADD(q.date, INTERVAL {$weekDay} DAY), '%W, %M %e') namedate,
10640
10641                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' THEN q.id END) AS groupConcatIdsTotalEnviado,
10642                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END), 0) AS totalIssueEnviado,
10643
10644                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoEnviado,
10645                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoEnviado,
10646                        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,
10647
10648                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosEnviado,
10649                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosEnviado,
10650                        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,
10651
10652                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasEnviado,
10653                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasEnviado,
10654                        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,
10655
10656                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
10657                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
10658                        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,
10659
10660                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
10661                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
10662                        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,
10663
10664                        CASE
10665                            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
10666                            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)
10667                                / 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)
10668                        END AS weightedAverageMarginForTheCompanyEnviado,
10669                        CASE
10670                            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
10671                            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)
10672                                / 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)
10673                        END AS weightedAverageInvoiceEnviado,
10674
10675                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' THEN q.id END) AS groupConcatIdsTotalAceptado,
10676                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END), 0) AS totalIssueAceptado,
10677
10678                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoAceptado,
10679                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoAceptado,
10680                        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,
10681
10682                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosAceptado,
10683                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosAceptado,
10684                        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,
10685
10686                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasAceptado,
10687                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasAceptado,
10688                        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,
10689
10690                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosAceptado,
10691                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosAceptado,
10692                        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,
10693
10694                        CASE
10695                            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
10696                            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)
10697                                / 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)
10698                        END AS weightedAverageMarginForTheCompanyAceptado,
10699                        CASE
10700                            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
10701                            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)
10702                                / 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)
10703                        END AS weightedAverageInvoiceAceptado,
10704
10705                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN 1 END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalIssuePercentage,
10706                        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,
10707                        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,
10708                        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,
10709                        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,
10710
10711                        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,
10712                        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,
10713                        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,
10714                        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,
10715                        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
10716                    FROM
10717                    (
10718                        SELECT
10719                            c.region,
10720                            q.issue_date AS DATE,
10721                            'issue' AS date_type,
10722                            q.acceptance_date,
10723                            q.issue_date,
10724                            q.id,
10725                            q.margin_for_the_company,
10726                            CASE
10727                                WHEN bt.budget_type_group_id = 4
10728                                AND q.budget_margin_enabled > 0
10729                                AND q.budget_margin_enabled IS NOT NULL
10730                                AND q.margin_for_the_company <> 0
10731                            THEN q.margin_for_the_company * q.amount
10732                            END s1,
10733                            q.invoice_margin,
10734                            CASE
10735                                WHEN bt.budget_type_group_id = 4
10736                                AND q.budget_margin_enabled > 0
10737                                AND q.budget_margin_enabled IS NOT NULL
10738                                AND q.invoice_margin <> 0
10739                            THEN q.invoice_margin * q.amount
10740                            END s2,
10741                            q.budget_type_id,
10742                            q.budget_status_id,
10743                            q.amount,
10744                            bt.budget_type_group_id,
10745                            q.budget_margin_enabled
10746                        FROM
10747                            tbl_quotations q
10748                        JOIN tbl_companies c
10749                            ON c.company_id = q.company_id
10750                        LEFT JOIN tbl_budget_types bt
10751                            ON q.budget_type_id = bt.budget_type_id
10752                        LEFT JOIN tbl_users u
10753                            ON u.name = q.created_by
10754                        LEFT JOIN tbl_roles r
10755                            ON r.role_id = u.role_id
10756                        WHERE
10757                            q.issue_date IS NOT NULL
10758                            AND q.for_add != 1
10759                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
10760                            AND (q.commercial IS NOT NULL AND q.commercial != '')
10761                            AND q.budget_type_id != 7
10762                            AND q.budget_type_id IS NOT NULL
10763                            {$where}
10764
10765                        UNION ALL
10766
10767                        SELECT
10768                            c.region,
10769                            q.acceptance_date AS DATE,
10770                            'acceptance' AS date_type,
10771                            q.acceptance_date,
10772                            q.issue_date,
10773                            q.id,
10774                            q.margin_for_the_company,
10775                            CASE
10776                                WHEN bt.budget_type_group_id = 4
10777                                AND q.budget_margin_enabled > 0
10778                                AND q.budget_margin_enabled IS NOT NULL
10779                                AND q.margin_for_the_company > 0
10780                            THEN q.margin_for_the_company * q.amount
10781                            END s1,
10782                            q.invoice_margin,
10783                            CASE
10784                                WHEN bt.budget_type_group_id = 4
10785                                AND q.budget_margin_enabled <> 0
10786                                AND q.budget_margin_enabled IS NOT NULL
10787                                AND q.invoice_margin <> 0
10788                            THEN q.invoice_margin * q.amount
10789                            END s2,
10790                            q.budget_type_id,
10791                            q.budget_status_id,
10792                            q.amount,
10793                            bt.budget_type_group_id,
10794                            q.budget_margin_enabled
10795                        FROM
10796                            tbl_quotations q
10797                        JOIN tbl_companies c
10798                            ON c.company_id = q.company_id
10799                        LEFT JOIN tbl_budget_types bt
10800                            ON q.budget_type_id = bt.budget_type_id
10801                        LEFT JOIN tbl_users u
10802                            ON u.name = q.created_by
10803                        LEFT JOIN tbl_roles r
10804                            ON r.role_id = u.role_id
10805                        WHERE
10806                            q.acceptance_date IS NOT NULL
10807                            AND q.for_add != 1
10808                            AND q.budget_type_id IS NOT NULL
10809                            AND q.budget_type_id != 7
10810                            AND q.acceptance_date != '0000-00-00 00:00:00'
10811                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
10812                            {$where}
10813                    ) AS q
10814                    WHERE q.date != '0000-00-00 00:00:00' {$whereDates}
10815                    GROUP BY
10816                        q.region,
10817                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
10818                        MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
10819                        WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) WITH ROLLUP
10820                    ORDER BY
10821                        q.region IS NULL,
10822                        q.region,
10823                        CASE WHEN q.region IS NOT NULL
10824                            AND YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
10825                            AND MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
10826                            AND WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
10827                        THEN 0
10828                        ELSE 1 END,
10829                    YEAR DESC,
10830                    MONTH ASC,
10831                    WEEK ASC";
10832
10833            $value = Cache::get(base64_encode($query));
10834
10835            if(!$value){
10836                $result = DB::select($query);
10837
10838                Cache::put(base64_encode($query), $result, 600);
10839            }else{
10840                $result = $value;
10841            }
10842
10843            $query = "SELECT
10844                        q.region,
10845                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) 'year',
10846                        LPAD(MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'month',
10847                        LPAD(WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'week',
10848                        DATE_FORMAT(DATE_ADD(q.date, INTERVAL {$weekDay} DAY), '%W, %M %e') namedate,
10849
10850                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' THEN q.id END) AS groupConcatIdsTotalEnviado,
10851                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END), 0) AS totalIssueEnviado,
10852
10853                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoEnviado,
10854                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoEnviado,
10855                        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,
10856
10857                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosEnviado,
10858                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosEnviado,
10859                        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,
10860
10861                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasEnviado,
10862                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasEnviado,
10863                        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,
10864
10865                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
10866                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
10867                        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,
10868
10869                        CASE
10870                            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
10871                            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)
10872                                / 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)
10873                        END AS weightedAverageMarginForTheCompanyEnviado,
10874                        CASE
10875                            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
10876                            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)
10877                                / 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)
10878                        END AS weightedAverageInvoiceEnviado,
10879
10880                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' THEN q.id END) AS groupConcatIdsTotalAceptado,
10881                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END), 0) AS totalIssueAceptado,
10882
10883                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoAceptado,
10884                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoAceptado,
10885                        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,
10886
10887                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosAceptado,
10888                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosAceptado,
10889                        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,
10890
10891                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasAceptado,
10892                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasAceptado,
10893                        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,
10894
10895                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosAceptado,
10896                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosAceptado,
10897                        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,
10898
10899                        CASE
10900                            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
10901                            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)
10902                                / 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)
10903                        END AS weightedAverageMarginForTheCompanyAceptado,
10904                        CASE
10905                            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
10906                            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)
10907                                / 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)
10908                        END AS weightedAverageInvoiceAceptado,
10909
10910                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalIssuePercentage,
10911                        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,
10912                        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,
10913                        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,
10914                        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,
10915
10916                        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,
10917                        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,
10918                        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,
10919                        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,
10920                        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
10921                    FROM
10922                    (
10923                        SELECT
10924                            'Total Grupo FIRE' region,
10925                            q.issue_date AS DATE,
10926                            'issue' AS date_type,
10927                            q.acceptance_date,
10928                            q.issue_date,
10929                            q.id,
10930                            q.margin_for_the_company,
10931                            CASE
10932                                WHEN bt.budget_type_group_id = 4
10933                                AND q.budget_margin_enabled > 0
10934                                AND q.budget_margin_enabled IS NOT NULL
10935                                AND q.margin_for_the_company <> 0
10936                            THEN q.margin_for_the_company * q.amount
10937                            END s1,
10938                            q.invoice_margin,
10939                            CASE
10940                                WHEN bt.budget_type_group_id = 4
10941                                AND q.budget_margin_enabled > 0
10942                                AND q.budget_margin_enabled IS NOT NULL
10943                                AND q.invoice_margin <> 0
10944                            THEN q.invoice_margin * q.amount
10945                            END s2,
10946                            q.budget_type_id,
10947                            q.budget_status_id,
10948                            q.amount,
10949                            bt.budget_type_group_id,
10950                            q.budget_margin_enabled
10951                        FROM
10952                            tbl_quotations q
10953                        JOIN tbl_companies c
10954                            ON c.company_id = q.company_id
10955                        LEFT JOIN tbl_budget_types bt
10956                            ON q.budget_type_id = bt.budget_type_id
10957                        LEFT JOIN tbl_users u
10958                            ON u.name = q.created_by
10959                        LEFT JOIN tbl_roles r
10960                            ON r.role_id = u.role_id
10961                        WHERE
10962                            q.issue_date IS NOT NULL
10963                            AND q.for_add != 1
10964                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
10965                            AND (q.commercial IS NOT NULL AND q.commercial != '')
10966                            AND q.budget_type_id != 7
10967                            AND q.budget_type_id IS NOT NULL
10968                            {$where}
10969
10970                        UNION ALL
10971
10972                        SELECT
10973                            'Total Grupo FIRE' region,
10974                            q.acceptance_date AS DATE,
10975                            'acceptance' AS date_type,
10976                            q.acceptance_date,
10977                            q.issue_date,
10978                            q.id,
10979                            q.margin_for_the_company,
10980                            CASE
10981                                WHEN bt.budget_type_group_id = 4
10982                                AND q.budget_margin_enabled > 0
10983                                AND q.budget_margin_enabled IS NOT NULL
10984                                AND q.margin_for_the_company <> 0
10985                            THEN q.margin_for_the_company * q.amount
10986                            END s1,
10987                            q.invoice_margin,
10988                            CASE
10989                                WHEN bt.budget_type_group_id = 4
10990                                AND q.budget_margin_enabled > 0
10991                                AND q.budget_margin_enabled IS NOT NULL
10992                                AND q.invoice_margin <> 0
10993                            THEN q.invoice_margin * q.amount
10994                            END s2,
10995                            q.budget_type_id,
10996                            q.budget_status_id,
10997                            q.amount,
10998                            bt.budget_type_group_id,
10999                            q.budget_margin_enabled
11000                        FROM
11001                            tbl_quotations q
11002                        JOIN tbl_companies c
11003                            ON c.company_id = q.company_id
11004                        LEFT JOIN tbl_budget_types bt
11005                            ON q.budget_type_id = bt.budget_type_id
11006                        LEFT JOIN tbl_users u
11007                            ON u.name = q.created_by
11008                        LEFT JOIN tbl_roles r
11009                            ON r.role_id = u.role_id
11010                        WHERE
11011                            q.acceptance_date IS NOT NULL
11012
11013                            AND q.for_add != 1
11014                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
11015                            AND (q.commercial IS NOT NULL AND q.commercial != '')
11016                            AND q.budget_type_id != 7
11017                            AND q.budget_type_id IS NOT NULL
11018                            {$where}
11019                    ) AS q
11020                    WHERE q.date != '0000-00-00 00:00:00' {$whereDates}
11021                    GROUP BY
11022                        q.region,
11023                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11024                        MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11025                        WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) WITH ROLLUP
11026                    ORDER BY
11027                        q.region IS NULL,
11028                        q.region,
11029                        CASE WHEN q.region IS NOT NULL
11030                            AND YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11031                            AND MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11032                            AND WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11033                        THEN 0
11034                        ELSE 1 END,
11035                    YEAR DESC,
11036                    MONTH ASC,
11037                    WEEK ASC";
11038
11039            $totalGroupValue = Cache::get(base64_encode($query));
11040
11041            if(!$totalGroupValue){
11042                $totalGroup = DB::select($query);
11043
11044                Cache::put(base64_encode($query), $totalGroup, 600);
11045            }else{
11046                $totalGroup = $totalGroupValue;
11047            }
11048
11049            array_pop($result);
11050            $merged = array_merge($result, $totalGroup);
11051
11052            return response([
11053                'message' => 'OK',
11054                'data' => $merged
11055            ]);
11056
11057        } catch (\Exception $e) {
11058            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11059        }
11060
11061    }
11062
11063    public function getIdsFromInternalQuoteIds($ids){
11064        $idsArray = array_filter(explode(',', $ids), 'is_numeric');
11065        return TblQuotations::whereIn("internal_quote_id", $idsArray)
11066            ->pluck("id")
11067            ->toArray();
11068    }
11069
11070    public function checkQuotationExistByInternalQuoteId(Request $request)
11071    {
11072        try{
11073            $idsString = $request->all()["ids"];
11074            $ids = explode(',',$idsString);
11075            $region = urldecode(@getallheaders()["Region"]);
11076            $company = TblCompanies::where("region", $region)->first();
11077
11078            if(!$company){
11079                Throw new \Exception("Region no encontrada");
11080            }
11081
11082            $companyId = $company->company_id;
11083
11084            $idsChecked = [];
11085
11086            foreach ($ids as $id){
11087                $quote = TblQuotations::where("internal_quote_id", $id)->where("company_id", $companyId)->first();
11088                if(
11089                    ($companyId === 18 || $companyId === 22)
11090                    && !$quote
11091                ){
11092                    $quote = TblQuotations::where("internal_quote_id", $id)->whereIn("company_id", [18,22])->first();
11093                }
11094                $idsChecked[$id] = $quote ? $quote->id : null;
11095            }
11096
11097            return response([
11098                'message' => 'OK',
11099                'data' => $idsChecked
11100            ]);
11101
11102        }catch (\Exception $e) {
11103            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11104        }
11105
11106    }
11107
11108    public function addUpdateLog($id, $userId, $field, $oldData, $newData){
11109        $oldRegister = null;
11110        $newRegister = null;
11111
11112        if($field == "company_id"){
11113            $oldRegister = TblCompanies::where("company_id", $oldData)->first();
11114            $newRegister = TblCompanies::where("company_id", $newData)->first();
11115        }
11116
11117        if($field == "customer_type_id"){
11118            $oldRegister = TblCustomerTypes::where("customer_type_id", $oldData)->first();
11119            $newRegister = TblCustomerTypes::where("customer_type_id", $newData)->first();
11120        }
11121
11122        if($field == "segment_id"){
11123            $oldRegister = TblSegments::where("segment_id", $oldData)->first();
11124            $newRegister = TblSegments::where("segment_id", $newData)->first();
11125        }
11126
11127        if($field == "budget_type_id"){
11128            $oldRegister = TblBudgetTypes::where("budget_type_id", $oldData)->first();
11129            $newRegister = TblBudgetTypes::where("budget_type_id", $newData)->first();
11130        }
11131
11132        if($field == "budget_status_id"){
11133            $oldRegister = TblBudgetStatus::where("budget_status_id", $oldData)->first();
11134            $newRegister = TblBudgetStatus::where("budget_status_id", $newData)->first();
11135        }
11136
11137        if($field == "source_id"){
11138            $oldRegister = TblSources::where("source_id", $oldData)->first();
11139            $newRegister = TblSources::where("source_id", $newData)->first();
11140        }
11141
11142        $oldData = $oldRegister ? $oldRegister->name : 'N/A';
11143        $newData = $newRegister ? $newRegister->name : 'N/A';
11144
11145        if(is_numeric($userId)){
11146            $userName = TblUsers::where("id", $userId)->first()->name;
11147        } else {
11148            $userName = $userId;
11149        }
11150
11151        if($oldData !== $newData){
11152            TblQuotationsLog::create(
11153                array(
11154                    'quotation_id' => $id,
11155                    'user' => $userName,
11156                    'field' => $field,
11157                    'old_value' => $oldData,
11158                    'new_value' => $newData
11159                )
11160            );
11161        }
11162    }
11163}