Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
6.05% covered (danger)
6.05%
330 / 5457
2.47% covered (danger)
2.47%
2 / 81
CRAP
0.00% covered (danger)
0.00%
0 / 1
Quotations
6.05% covered (danger)
6.05%
330 / 5457
2.47% covered (danger)
2.47%
2 / 81
1435415.53
0.00% covered (danger)
0.00%
0 / 1
 __construct
57.14% covered (warning)
57.14%
8 / 14
0.00% covered (danger)
0.00%
0 / 1
5.26
 create_quotation
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 1
56
 currency
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 send_approval_notification
0.00% covered (danger)
0.00%
0 / 120
0.00% covered (danger)
0.00%
0 / 1
552
 send_approval_margin_notification
0.00% covered (danger)
0.00%
0 / 105
0.00% covered (danger)
0.00%
0 / 1
272
 approve_quotation
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
240
 send_approved_notification
0.00% covered (danger)
0.00%
0 / 97
0.00% covered (danger)
0.00%
0 / 1
110
 reject_quotation
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
240
 send_rejected_notification
0.00% covered (danger)
0.00%
0 / 97
0.00% covered (danger)
0.00%
0 / 1
110
 update_quotation
31.97% covered (danger)
31.97%
117 / 366
0.00% covered (danger)
0.00%
0 / 1
4578.12
 compareArrays
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
6
 convertValue
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
7.05
 callDeleteQuotation
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 get_quotation
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 get_quotation_log
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 send_notification
0.00% covered (danger)
0.00%
0 / 61
0.00% covered (danger)
0.00%
0 / 1
42
 delete_quotation
94.87% covered (success)
94.87%
37 / 39
0.00% covered (danger)
0.00%
0 / 1
8.01
 list_quotations
25.07% covered (danger)
25.07%
93 / 371
0.00% covered (danger)
0.00%
0 / 1
6178.64
 get_dates
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 list_quotation_analytics_by_source
0.00% covered (danger)
0.00%
0 / 118
0.00% covered (danger)
0.00%
0 / 1
1640
 list_quotation_analytics_send_budgets
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
380
 list_quotation_analytics_track_budgets
0.00% covered (danger)
0.00%
0 / 118
0.00% covered (danger)
0.00%
0 / 1
1332
 list_quotation_analytics_types_budgets
0.00% covered (danger)
0.00%
0 / 120
0.00% covered (danger)
0.00%
0 / 1
1056
 download_quotations
0.00% covered (danger)
0.00%
0 / 164
0.00% covered (danger)
0.00%
0 / 1
306
 bulk_upload
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
30
 list_bulk_upload
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 delete_number
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 get_number
81.08% covered (warning)
81.08%
30 / 37
0.00% covered (danger)
0.00%
0 / 1
11.82
 get_years
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
12
 human_filesize
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 get_files
0.00% covered (danger)
0.00%
0 / 126
0.00% covered (danger)
0.00%
0 / 1
1806
 download_file
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
56
 delete_file
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
30
 send_email_to_client
0.00% covered (danger)
0.00%
0 / 246
0.00% covered (danger)
0.00%
0 / 1
3306
 send_email_follow_ups
0.00% covered (danger)
0.00%
0 / 339
0.00% covered (danger)
0.00%
0 / 1
4422
 create_sender_identity
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
56
 get_sender_identity
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
20
 get_all_sender_identity
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 delete_sender_identity
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
20
 create_template
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 1
72
 get_email_files
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
 download_email_template_file
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 delete_email_template_file
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 update_email_template_order
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 update_email_template
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
90
 delete_template
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 get_email_template
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 update_sender_identity
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
20
 resend_verification
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 list_quotation_analytics_by_performance
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
30
 list_orders_update_logs
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 list_g3w_orders_update_logs
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 update_budget_status_rejected_manual
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 update_budget_status_rejected
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
132
 bulk_update_quotation
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
30
 move_budget_and_job
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 1
30
 list_quotation_analytics_by_types_of_budgets_created_per_week
0.00% covered (danger)
0.00%
0 / 191
0.00% covered (danger)
0.00%
0 / 1
3660
 preview_file
0.00% covered (danger)
0.00%
0 / 20
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 / 51
0.00% covered (danger)
0.00%
0 / 1
90
 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 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 list_quotation_analytics_commercial
0.00% covered (danger)
0.00%
0 / 185
0.00% covered (danger)
0.00%
0 / 1
2970
 clear_open_data
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
30
 list_quotation_analytics_order_size
0.00% covered (danger)
0.00%
0 / 193
0.00% covered (danger)
0.00%
0 / 1
4422
 send_email_template_preview
0.00% covered (danger)
0.00%
0 / 105
0.00% covered (danger)
0.00%
0 / 1
306
 list_quotation_analytics_by_types_of_budgets_company_per_week
0.00% covered (danger)
0.00%
0 / 188
0.00% covered (danger)
0.00%
0 / 1
3660
 request_permission_commercial
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 1
72
 confirm_update_commercial
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
 calculateEmailRequestSize
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
56
 list_quotation_analytics_commercial_productivity
0.00% covered (danger)
0.00%
0 / 234
0.00% covered (danger)
0.00%
0 / 1
4422
 list_quotations_deleted
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 delete_sengrid
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
 download_productivity_commercial
0.00% covered (danger)
0.00%
0 / 377
0.00% covered (danger)
0.00%
0 / 1
2450
 update_commercial_numbers
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 list_quotation_analytics_by_service_type
0.00% covered (danger)
0.00%
0 / 165
0.00% covered (danger)
0.00%
0 / 1
1260
 getIdsFromInternalQuoteIds
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 checkQuotationExistByInternalQuoteId
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
72
 addUpdateLog
37.14% covered (danger)
37.14%
13 / 35
0.00% covered (danger)
0.00%
0 / 1
41.05
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\TblCompanies;
6use App\Models\TblCompanyUsers;
7use App\Models\TblCustomerTypes;
8use App\Models\TblG3WOrdersUpdateLogs;
9use App\Models\TblQuotations;
10use App\Models\TblBulkUpload;
11use App\Models\TblFiles;
12use App\Models\TblEmailFiles;
13use App\Models\TblQuotationsLog;
14use App\Models\TblSegments;
15use App\Models\TblSources;
16use App\Models\TblUsers;
17use App\Models\TblEmailConfiguration;
18use App\Models\TblCompanyEmails;
19use App\Models\TblCcBcc;
20use App\Models\TblBudgetStatus;
21use App\Models\TblOrdersUpdateLogs;
22use App\Models\TblBlockedDomains;
23use App\Models\TblNotifications;
24use App\Models\TblBudgetTypes;
25use App\Models\TblBudgetTypeGroups;
26use App\Models\TblProjectTypes;
27use App\Models\TblOngoingJobs;
28use App\Models\TblWorkflowQuestions;
29use App\Models\TblToAcceptanceNotifications;
30use App\Models\TblCcAcceptanceNotifications;
31use App\Models\TblSendgridWebhook;
32use App\Models\TblFollowUpLogs;
33use App\Models\TblBusinessGoals;
34use App\Models\TblVisitTypes;
35use App\Models\TblVisitTypeGroups;
36use App\Models\TblLastFollowUpDate;
37use App\Models\StructureData;
38use PhpOffice\PhpSpreadsheet\Spreadsheet;
39use PhpOffice\PhpSpreadsheet\IOFactory;
40use Illuminate\Support\Facades\App;
41use Illuminate\Support\Facades\Cache;
42use Illuminate\Http\Request;
43use Illuminate\Support\Facades\DB;
44use Illuminate\Support\Facades\Storage;
45use Illuminate\Support\Facades\Log;
46use Illuminate\Support\Facades\File;
47use Illuminate\Support\Facades\Http;
48use SendGrid\Mail\Mail;
49use Illuminate\Support\Facades\Artisan;
50use function PHPUnit\Framework\isEmpty;
51use function PHPUnit\Framework\isNull;
52
53class Quotations extends Controller
54{
55    private $locale;
56    private $userId;
57    private $region;
58    private $companyIds;
59    private $companyId;
60
61    public function __construct(){
62        $this->locale = @getallheaders()['Locale-ID'];
63        $this->userId = @getallheaders()['User-ID'];
64        $this->region = @getallheaders()['Region'];
65
66        App::setLocale($this->locale);
67
68        $this->companyIds = array();
69
70        if($this->region != null && $this->region != "" && $this->region != "All"){
71            $this->region = urldecode($this->region);
72
73            $query = "SELECT
74                        b.company_id
75                    FROM
76                        tbl_company_users a
77                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
78                    WHERE
79                        a.user_id = {$this->userId}
80                        AND b.region = '{$this->region}'";
81
82            $this->companyIds = DB::select($query);
83
84            $this->companyIds = collect($this->companyIds)->pluck('company_id')->toArray();
85        }else{
86            $this->companyIds = TblCompanyUsers::where('user_id', $this->userId)->pluck('company_id')->all();
87        }
88
89        $this->companyId = implode(',', $this->companyIds);
90    }
91
92    public function create_quotation(Request $request){
93
94        try {
95
96            $data = $request->all();
97            $data['updated_at'] = date('Y-m-d H:i:s');
98
99            if(isset($data['request_date']) && isset($data['issue_date'])){
100                $requestDate = strtotime($data['request_date']);
101                $issueDate = strtotime($data['issue_date']);
102                $dateDiff = $issueDate - $requestDate;
103                $data['duration'] = round($dateDiff / (60 * 60 * 24));
104            }
105
106            $r = new Request([
107                'created_by' => $data['created_by'],
108            ]);
109
110            $result = $this->get_number($r, @$data['company_id']);
111            $id = $result->original['id'];
112
113            $files = $request->file('files');
114            if($files){
115                $uploadedFiles = [];
116
117                foreach ($files as $file) {
118                    $filename = time() . '_' . $file->getClientOriginalName();
119                    $fileSize = $file->getSize();
120                    // $fileContent = file_get_contents($file->getRealPath());
121                    // $fileHash = hash('sha256', $fileContent);                    
122
123                    $s3path = Storage::disk('s3')->putFileAs(
124                        'uploads',
125                        $file,
126                        $filename,
127                        [
128                            'ContentType' => $file->getMimeType(),
129                        ]
130                    );
131
132                    TblFiles::create(
133                        array(
134                            'quotation_id' => $id,
135                            'original_name' => $file->getClientOriginalName(),
136                            'filename' => $filename,
137                            'uploaded_by' => $data['updated_by'],
138                            // 'file' => $fileContent,
139                            'file_size' => $file->getSize(),
140                            // 'file_hash' => $fileHash,
141                            'mime_type' => $file->getMimeType(),
142                            'uploaded_at' => now(),
143                        )
144                    );
145                }
146            }
147
148            $query = "SELECT COUNT(*) as count FROM tbl_files WHERE quotation_id = ?";
149            $fileCount = DB::select($query, [$id])[0]->count;
150
151            $data['has_attachment'] = $fileCount > 0 ? 1 : 0;
152
153            $data = array_diff_key($data, array_flip(['files', '_token', 'otros_campos_no_necesarios']));
154
155            $data['for_add'] = 0;
156            TblQuotations::where('id', $id)->update($data);
157
158            $result = TblQuotations::where('id', $id)->first();
159
160            Cache::flush();
161            return response(['message' => 'OK', 'data' => $result]);
162
163        } catch (\Exception $e) {
164            return response(['message' => 'KO', 'error' => $e->getMessage()]);
165        }
166
167    }
168
169    function currency($amount, $withEuro = ''){
170
171        if($withEuro != null){
172            $withEuro = ' â‚¬';
173        }
174
175
176        return number_format($amount, 2, ',', '.') . $withEuro;
177    }
178
179
180    function send_approval_notification($amount, $budgetTypeId, $customerTypeId, $minimumOrderSize, $quoteId, $id, $companyName, $createdBy, $userId, $action, $commercialEmail, $companyId, $endpoint, $isQuestion, $questionIdsNo, $n, $locale = null){
181
182        if(!is_null($locale)){
183            $this->locale = $locale;
184        }
185
186        if($action != 1){
187            if($this->locale == 'es'){
188                $action = "actualizado";
189            }else{
190                $action = "updated";
191            }
192
193        }else{
194            if($this->locale == 'es'){
195                $action = "creado";
196            }else{
197                $action = "created";
198            }
199        }
200
201        $fendpoint = "";
202
203        if($endpoint == 'orders'){
204            if($this->locale == 'es'){
205                $fendpoint = "presupuesto";
206            }else{
207                $fendpoint = "budget";
208            }
209
210        }else{
211            if($this->locale == 'es'){
212                $fendpoint = "trabajo";
213            }else{
214                $fendpoint = "job";
215            }
216        }
217
218        $user = TblUsers::where('id', $userId)->first();
219
220        $query = "SELECT
221                    a.approver_id,
222                    a.user_id,
223                    b.name,
224                    b.email
225                FROM
226                    tbl_approvers a
227                    INNER JOIN tbl_users b ON a.user_id = b.id
228                WHERE a.company_id = {$companyId}
229                ";
230
231        if($n == 3){
232            $query = "SELECT
233                        a.approver_id,
234                        a.user_id,
235                        u.name,
236                        u.email
237                    FROM tbl_approvers a
238                    INNER JOIN tbl_users u ON a.user_id = u.id
239                    WHERE a.company_id = {$companyId}
240
241                    UNION ALL
242
243                    SELECT
244                        c.approver_id,
245                        c.user_id,
246                        u2.name,
247                        u2.email
248                    FROM tbl_approvers_v2 c
249                    INNER JOIN tbl_users u2 ON c.user_id = u2.id
250                    WHERE c.company_id = {$companyId}";
251        }
252
253        $approvers = DB::select($query);
254
255        if(count($approvers) > 0){
256            $amount = $this->currency($amount, 1);
257            $minimumOrderSize = $this->currency($minimumOrderSize, 1);
258
259            $budgetType = TblBudgetTypes::where('budget_type_id', $budgetTypeId)->first();
260            $clientType = TblCustomerTypes::where('customer_type_id', $customerTypeId)->first();
261
262            $imgpath = File::get('fireservicetitan.png');
263            $base64 = "data:image/png;base64,".base64_encode($imgpath);
264
265            $subject = __('language.send_approval_notification.subject');
266            $subject = str_replace('{{type}}', $budgetType->name, $subject);
267            $subject = str_replace('{{amount}}', $amount, $subject);
268            $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
269
270            $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
271            $href = "<a href='{$url}'>{$quoteId}</a>";
272            $cc = false;
273            foreach ($approvers as $item) {
274
275                $toEmail = $item->email;
276
277                $body = __('language.send_approval_notification.body_hello');
278                $body = str_replace('{{approver}}', $item->name, $body);
279
280                $body .= __('language.send_approval_notification.body_message');
281                $body = str_replace('{{endpoint}}', $fendpoint, $body);
282                $body = str_replace('{{creator}}', $createdBy, $body);
283                $body = str_replace('{{action}}', $action, $body);
284                $body = str_replace('{{company}}', $companyName, $body);
285                $body = str_replace('{{type}}', $budgetType->name, $body);
286                $body = str_replace('{{amount}}', $amount, $body);
287                $body = str_replace('{{quote_id}}', $href, $body);
288
289                if($isQuestion == 1){
290                    $body .= __('language.send_approval_notification.note_question');
291                }else{
292                    $body .= __('language.send_approval_notification.note');
293                }
294
295                $body = str_replace('{{company}}', $companyName, $body);
296                $body = str_replace('{{client_type}}', $clientType->name, $body);
297                $body = str_replace('{{project_type}}', $budgetType->name, $body);
298                $body = str_replace('{{amount}}', $minimumOrderSize, $body);
299
300                if($isQuestion == 1){
301                    if($questionIdsNo){
302                        $questions = TblWorkflowQuestions::whereIn('question_id', $questionIdsNo)->where('company_id', $companyId)->get();
303
304                        if($questions){
305                            $ul = "<ul>";
306                            $li = "";
307                            foreach ($questions as $item) {
308                                $li .= "<li>{$item->question}</li>";
309                            }
310                            $ul .= $li . "</ul><br><br>";
311                            $body .= $ul;
312                        }
313                    }
314                }
315
316                $content = $body;
317
318                $body .= "<p>Fire Service Titan</p>";
319                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
320
321                $html = '<!DOCTYPE html>';
322                $html .= '<html>';
323                $html .= '<head>';
324                $html .= '<meta charset="UTF-8">';
325                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
326                $html .= '</head>';
327                $html .= '<body>';
328                $html .= $body;
329                $html .= '</body>';
330                $html .= '</html>';
331
332                if($toEmail != null){
333                    $email = new \SendGrid\Mail\Mail();
334
335                    if(env('SENDGRID_STAGING')){
336                        $toEmail = $user->email;
337                        $item->user_id = $userId;
338                    }
339
340                    if($cc == false){
341                        $cc = true;
342                        if($user->email != $toEmail){
343                            if($user->email != $commercialEmail && $commercialEmail != null){
344                                $email->addBcc($user->email);
345                                $email->addBcc($commercialEmail);
346                            }else{
347                                $email->addBcc($user->email);
348                            }
349                        }
350                    }
351
352                    $email->setFrom('fire@fire.es', 'Fire Service Titan');
353                    $email->setSubject($subject);
354                    $email->addTo($toEmail);
355                    $email->addContent("text/html", $html);
356
357                    $email->addAttachment(
358                        $imgpath,
359                        "image/png",
360                        "fireservicetitan.png",
361                        "inline",
362                        "fireservicetitan"
363                    );
364
365                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
366
367                    $response = $sendgrid->send($email);
368                    if ($response->statusCode() == 202) {
369                        Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - APPROVAL EMAIL NOTIFICATION SENT');
370
371                        TblNotifications::create(
372                            array(
373                                'user_id' => $item->user_id,
374                                'content' => $content,
375                                'is_open' => 1,
376                                'created_by' => 'System',
377                                'link' => $url
378                            )
379                        );
380                    } else {
381                        $error = true;
382                        Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
383                    }
384                }
385
386            }
387        }
388    }
389
390    function send_approval_margin_notification($amount, $budgetTypeId, $customerTypeId, $minimumMargin, $quoteId, $id, $companyName, $createdBy, $userId, $action, $commercialEmail, $invoiceMargin, $companyId, $endpoint){
391
392        if($action != 1){
393            if($this->locale == 'es'){
394                $action = "actualizado";
395            }else{
396                $action = "updated";
397            }
398
399        }else{
400            if($this->locale == 'es'){
401                $action = "creado";
402            }else{
403                $action = "created";
404            }
405        }
406
407        $fendpoint = "";
408
409        if($endpoint == 'orders'){
410            if($this->locale == 'es'){
411                $fendpoint = "presupuesto";
412            }else{
413                $fendpoint = "budget";
414            }
415
416        }else{
417            if($this->locale == 'es'){
418                $fendpoint = "trabajo";
419            }else{
420                $fendpoint = "job";
421            }
422        }
423
424        $invoiceMargin = number_format($invoiceMargin, 2);
425        $minimumMargin = number_format($minimumMargin, 2);
426
427        $user = TblUsers::where('id', $userId)->first();
428
429        $query = "SELECT
430                    a.approver_id,
431                    a.user_id,
432                    b.name,
433                    b.email
434                FROM
435                    tbl_approvers a
436                    INNER JOIN tbl_users b ON a.user_id = b.id
437                WHERE a.company_id = {$companyId}
438                ";
439
440        $approvers = DB::select($query);
441
442        if(count($approvers) > 0){
443
444            $amount = $this->currency($amount, 1);
445
446            $budgetType = TblBudgetTypes::where('budget_type_id', $budgetTypeId)->first();
447            $clientType = TblCustomerTypes::where('customer_type_id', $customerTypeId)->first();
448
449            $imgpath = File::get('fireservicetitan.png');
450            $base64 = "data:image/png;base64,".base64_encode($imgpath);
451
452            $subject = __('language.send_approval_margin_notification.subject');
453            $subject = str_replace('{{type}}', $budgetType->name, $subject);
454            $subject = str_replace('{{amount}}', $amount, $subject);
455            $subject = str_replace('{{margin}}', $invoiceMargin, $subject);
456            $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
457
458            $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
459            $href = "<a href='{$url}'>{$quoteId}</a>";
460            $cc = false;
461            foreach ($approvers as $item) {
462
463                $toEmail = $item->email;
464
465                $body = __('language.send_approval_margin_notification.body_hello');
466                $body = str_replace('{{approver}}', $item->name, $body);
467
468                $body .= __('language.send_approval_margin_notification.body_message');
469                $body = str_replace('{{endpoint}}', $fendpoint, $body);
470                $body = str_replace('{{creator}}', $createdBy, $body);
471                $body = str_replace('{{action}}', $action, $body);
472                $body = str_replace('{{company}}', $companyName, $body);
473                $body = str_replace('{{type}}', $budgetType->name, $body);
474                $body = str_replace('{{amount}}', $amount, $body);
475                $body = str_replace('{{quote_id}}', $href, $body);
476                $body = str_replace('{{margin}}', $invoiceMargin, $body);
477
478                $body .= __('language.send_approval_margin_notification.note');
479                $body = str_replace('{{company}}', $companyName, $body);
480                $body = str_replace('{{client_type}}', $clientType->name, $body);
481                $body = str_replace('{{project_type}}', $budgetType->name, $body);
482                $body = str_replace('{{margin}}', $minimumMargin, $body);
483
484                $content = $body;
485
486                $body .= "<p>Fire Service Titan</p>";
487                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
488
489                $html = '<!DOCTYPE html>';
490                $html .= '<html>';
491                $html .= '<head>';
492                $html .= '<meta charset="UTF-8">';
493                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
494                $html .= '</head>';
495                $html .= '<body>';
496                $html .= $body;
497                $html .= '</body>';
498                $html .= '</html>';
499
500                if($toEmail != null){
501                    $email = new \SendGrid\Mail\Mail();
502
503                    if(env('SENDGRID_STAGING')){
504                        $toEmail = $user->email;
505                        $item->user_id = $userId;
506                    }
507
508                    if($cc == false){
509                        $cc = true;
510
511                        if($user->email != $toEmail){
512                            if($user->email != $commercialEmail && $commercialEmail != null){
513                                $email->addBcc($user->email);
514                                $email->addBcc($commercialEmail);
515                            }else{
516                                $email->addBcc($user->email);
517                            }
518                        }
519                    }
520
521                    $email->setFrom('fire@fire.es', 'Fire Service Titan');
522                    $email->setSubject($subject);
523                    $email->addTo($toEmail);
524                    $email->addContent("text/html", $html);
525
526                    $email->addAttachment(
527                        $imgpath,
528                        "image/png",
529                        "fireservicetitan.png",
530                        "inline",
531                        "fireservicetitan"
532                    );
533
534                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
535
536                    $response = $sendgrid->send($email);
537                    if ($response->statusCode() == 202) {
538                        Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - MARGIN APPROVAL EMAIL NOTIFICATION SENT');
539
540                        TblNotifications::create(
541                            array(
542                                'user_id' => $item->user_id,
543                                'content' => $content,
544                                'is_open' => 1,
545                                'created_by' => 'System',
546                                'link' => $url
547                            )
548                        );
549                    } else {
550                        $error = true;
551                        Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
552                    }
553                }
554
555            }
556        }
557    }
558
559    function approve_quotation($id){
560
561        try {
562
563            $id = addslashes($id);
564
565            $result = TblQuotations::where('id', $id)->first();
566            $company = TblCompanies::where('company_id', $result->company_id)->first();
567            $budgetType = TblBudgetTypes::where('budget_type_id', $result->budget_type_id)->first();
568
569            if($result->created_by != $result->commercial){
570                $creatorAndCommercial = array($result->created_by, $result->commercial);
571                foreach ($creatorAndCommercial as $name) {
572                    $user = TblUsers::where('name', $name)->first();
573                    if($user){
574                        $this->send_approved_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
575                    }
576                }
577            }else{
578                $user = TblUsers::where('name', $result->created_by)->first();
579                if($user){
580                    $this->send_approved_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
581                }
582            }
583
584            if ($result->for_approval == 3) {
585                $result = TblQuotations::where('id', $id)->first();
586
587                $approved = 0;
588                $rejected = 0;
589
590                if ($result->approved_by !== null) {
591                    $approved++;
592                }
593                if ($result->approved_by_v2 !== null) {
594                    $approved++;
595                }
596
597                if ($result->rejected_by !== null) {
598                    $rejected++;
599                }
600                if ($result->rejected_by_v2 !== null) {
601                    $rejected++;
602                }
603
604                if ($approved === 2) {
605                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
606                } elseif ($rejected >= 1 && ($approved + $rejected) === 2) {
607                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
608                }
609            }elseif($result->for_approval == 1){
610                TblQuotations::where('id', $id)->update(['for_approval' => null]);
611            }
612
613
614            Cache::flush();
615            return response(['message' => 'OK']);
616
617        } catch (\Exception $e) {
618            return response(['message' => 'KO', 'error' => $e->getMessage()]);
619        }
620
621    }
622
623    function send_approved_notification($userId, $username, $email, $companyName, $budgetType, $amount, $id, $quoteId, $companyId, $endpoint){
624
625        $fendpoint = "";
626
627        if($endpoint == 'orders'){
628            if($this->locale == 'es'){
629                $fendpoint = "presupuesto";
630            }else{
631                $fendpoint = "budget";
632            }
633
634        }else{
635            if($this->locale == 'es'){
636                $fendpoint = "trabajo";
637            }else{
638                $fendpoint = "job";
639            }
640        }
641
642        $query = "SELECT
643                    u.id AS user_id,
644                    u.name,
645                    u.email,
646                    u.sender_email,
647                    CASE
648                        WHEN a.user_id IS NOT NULL AND c.user_id IS NOT NULL THEN 'both'
649                        WHEN a.user_id IS NOT NULL THEN 'approvers'
650                        WHEN c.user_id IS NOT NULL THEN 'approvers_v2'
651                        ELSE 'none'
652                    END AS exists_in
653                FROM tbl_users u
654                LEFT JOIN tbl_approvers a
655                    ON u.id = a.user_id AND a.company_id = {$companyId}
656                LEFT JOIN tbl_approvers_v2 c
657                    ON u.id = c.user_id AND c.company_id = {$companyId}
658                WHERE u.id = {$this->userId}";
659
660        $user = DB::select($query);
661
662        $user = $user[0] ?? null;
663
664        $toEmail = $email;
665
666        $amount = $this->currency($amount, 1);
667
668        $imgpath = File::get('fireservicetitan.png');
669        $base64 = "data:image/png;base64,".base64_encode($imgpath);
670
671        $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
672        $href = "<a href='{$url}'>{$quoteId}</a>";
673
674        $body = __('language.send_approved_notification.body_hello');
675        $body = str_replace('{{creator}}', $username, $body);
676
677        $body .= __('language.send_approved_notification.body_message');
678        $body = str_replace('{{approver}}', $user->name, $body);
679        $body = str_replace('{{company}}', $companyName, $body);
680        $body = str_replace('{{type}}', $budgetType, $body);
681        $body = str_replace('{{amount}}', $amount, $body);
682        $body = str_replace('{{quote_id}}', $href, $body);
683        $body = str_replace('{{endpoint}}', $fendpoint, $body);
684
685        $content = $body;
686
687        $body .= "<p>Fire Service Titan</p>";
688        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
689
690        $html = '<!DOCTYPE html>';
691        $html .= '<html>';
692        $html .= '<head>';
693        $html .= '<meta charset="UTF-8">';
694        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
695        $html .= '</head>';
696        $html .= '<body>';
697        $html .= $body;
698        $html .= '</body>';
699        $html .= '</html>';
700
701        $subject = __('language.send_approved_notification.subject');
702        $subject = str_replace('{{quote_id}}', $quoteId, $subject);
703        $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
704
705        if($toEmail != null){
706            $email = new \SendGrid\Mail\Mail();
707
708            if(env('SENDGRID_STAGING')){
709                $toEmail = $user->email;
710                $userId = $this->userId;
711            }
712
713            $email->setFrom('fire@fire.es', 'Fire Service Titan');
714            $email->setSubject($subject);
715            $email->addTo($toEmail);
716            $email->addContent("text/html", $html);
717
718            $email->addAttachment(
719                $imgpath,
720                "image/png",
721                "fireservicetitan.png",
722                "inline",
723                "fireservicetitan"
724            );
725
726            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
727
728            $response = $sendgrid->send($email);
729            if ($response->statusCode() == 202) {
730                Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - APPROVED EMAIL NOTIFICATION SENT');
731
732                if($endpoint == 'orders'){
733                    if($user->exists_in == "approvers"){
734                        TblQuotations::where('id', $id)->update(
735                            array(
736                                'approved_at' => date('Y-m-d H:i:s'),
737                                'approved_by' => $user->name
738                            )
739                        );
740                    }elseif($user->exists_in == "approvers_v2"){
741                        TblQuotations::where('id', $id)->update(
742                            array(
743                                'approved_at_v2' => date('Y-m-d H:i:s'),
744                                'approved_by_v2' => $user->name
745                            )
746                        );
747                    }
748                }else{
749                    TblOngoingJobs::where('id', $id)->update(
750                        array(
751                            'approved_at' => date('Y-m-d H:i:s'),
752                            'approved_by' => $user->name
753                        )
754                    );
755                }
756
757                TblNotifications::create(
758                    array(
759                        'user_id' => $userId,
760                        'content' => $content,
761                        'is_open' => 1,
762                        'created_by' => 'System',
763                        'link' => $url
764                    )
765                );
766            } else {
767                $error = true;
768                Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
769            }
770        }
771
772    }
773
774    function reject_quotation($id){
775
776        try {
777
778            $id = addslashes($id);
779
780            $result = TblQuotations::where('id', $id)->first();
781            $company = TblCompanies::where('company_id', $result->company_id)->first();
782            $budgetType = TblBudgetTypes::where('budget_type_id', $result->budget_type_id)->first();
783
784            if($result->created_by != $result->commercial){
785                $creatorAndCommercial = array($result->created_by, $result->commercial);
786                foreach ($creatorAndCommercial as $name) {
787                    $user = TblUsers::where('name', $name)->first();
788                    if($user){
789                        $this->send_rejected_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
790                    }
791                }
792            }else{
793                $user = TblUsers::where('name', $result->created_by)->first();
794                if($user){
795                    $this->send_rejected_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
796                }
797            }
798
799            if ($result->for_approval == 3) {
800                $result = TblQuotations::where('id', $id)->first();
801
802                $approved = 0;
803                $rejected = 0;
804
805                if ($result->approved_by !== null) {
806                    $approved++;
807                }
808                if ($result->approved_by_v2 !== null) {
809                    $approved++;
810                }
811
812                if ($result->rejected_by !== null) {
813                    $rejected++;
814                }
815                if ($result->rejected_by_v2 !== null) {
816                    $rejected++;
817                }
818
819                if ($approved === 2) {
820                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
821                } elseif ($rejected >= 1 && ($approved + $rejected) === 2) {
822                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
823                }
824            }elseif($result->for_approval == 1){
825                TblQuotations::where('id', $id)->update(['for_approval' => null]);
826            }
827
828            Cache::flush();
829            return response(['message' => 'OK']);
830
831        } catch (\Exception $e) {
832            return response(['message' => 'KO', 'error' => $e->getMessage()]);
833        }
834
835    }
836
837    function send_rejected_notification($userId, $username, $email, $companyName, $budgetType, $amount, $id, $quoteId, $companyId, $endpoint){
838
839        $fendpoint = "";
840
841        if($endpoint == 'orders'){
842            if($this->locale == 'es'){
843                $fendpoint = "presupuesto";
844            }else{
845                $fendpoint = "budget";
846            }
847
848        }else{
849            if($this->locale == 'es'){
850                $fendpoint = "trabajo";
851            }else{
852                $fendpoint = "job";
853            }
854        }
855
856        $query = "SELECT
857                    u.id AS user_id,
858                    u.name,
859                    u.email,
860                    u.sender_email,
861                    CASE
862                        WHEN a.user_id IS NOT NULL AND c.user_id IS NOT NULL THEN 'both'
863                        WHEN a.user_id IS NOT NULL THEN 'approvers'
864                        WHEN c.user_id IS NOT NULL THEN 'approvers_v2'
865                        ELSE 'none'
866                    END AS exists_in
867                FROM tbl_users u
868                LEFT JOIN tbl_approvers a
869                    ON u.id = a.user_id AND a.company_id = {$companyId}
870                LEFT JOIN tbl_approvers_v2 c
871                    ON u.id = c.user_id AND c.company_id = {$companyId}
872                WHERE u.id = {$this->userId}";
873
874        $user = DB::select($query);
875
876        $user = $user[0] ?? null;
877
878        $toEmail = $email;
879        $amount = $this->currency($amount, 1);
880
881        $imgpath = File::get('fireservicetitan.png');
882        $base64 = "data:image/png;base64,".base64_encode($imgpath);
883
884        $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
885        $href = "<a href='{$url}'>{$quoteId}</a>";
886
887        $body = __('language.send_rejected_notification.body_hello');
888        $body = str_replace('{{creator}}', $username, $body);
889
890        $body .= __('language.send_rejected_notification.body_message');
891        $body = str_replace('{{approver}}', $user->name, $body);
892        $body = str_replace('{{company}}', $companyName, $body);
893        $body = str_replace('{{type}}', $budgetType, $body);
894        $body = str_replace('{{amount}}', $amount, $body);
895        $body = str_replace('{{quote_id}}', $href, $body);
896        $body = str_replace('{{endpoint}}', $fendpoint, $body);
897
898        $content = $body;
899
900        $body .= "<p>Fire Service Titan</p>";
901        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
902
903        $html = '<!DOCTYPE html>';
904        $html .= '<html>';
905        $html .= '<head>';
906        $html .= '<meta charset="UTF-8">';
907        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
908        $html .= '</head>';
909        $html .= '<body>';
910        $html .= $body;
911        $html .= '</body>';
912        $html .= '</html>';
913
914        $subject = __('language.send_rejected_notification.subject');
915        $subject = str_replace('{{quote_id}}', $quoteId, $subject);
916        $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
917
918        if($toEmail != null){
919            $email = new \SendGrid\Mail\Mail();
920
921            if(env('SENDGRID_STAGING')){
922                $toEmail = $user->email;
923                $userId = $this->userId;
924            }
925
926            $email->setFrom('fire@fire.es', 'Fire Service Titan');
927            $email->setSubject($subject);
928            $email->addTo($toEmail);
929            $email->addContent("text/html", $html);
930
931            $email->addAttachment(
932                $imgpath,
933                "image/png",
934                "fireservicetitan.png",
935                "inline",
936                "fireservicetitan"
937            );
938
939            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
940
941            $response = $sendgrid->send($email);
942            if ($response->statusCode() == 202) {
943                Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - REJECTED EMAIL NOTIFICATION SENT');
944
945                if($endpoint == 'orders'){
946
947                    if($user->exists_in == "approvers"){
948                        TblQuotations::where('id', $id)->update(
949                            array(
950                                'rejected_at' => date('Y-m-d H:i:s'),
951                                'rejected_by' => $user->name
952                            )
953                        );
954                    }elseif($user->exists_in == "approvers_v2"){
955                        TblQuotations::where('id', $id)->update(
956                            array(
957                                'rejected_at_v2' => date('Y-m-d H:i:s'),
958                                'rejected_by_v2' => $user->name
959                            )
960                        );
961                    }
962                }else{
963                    TblOngoingJobs::where('id', $id)->update(
964                        array(
965                            'rejected_at' => date('Y-m-d H:i:s'),
966                            'rejected_by' => $user->name
967                        )
968                    );
969                }
970
971                TblNotifications::create(
972                    array(
973                        'user_id' => $userId,
974                        'content' => $content,
975                        'is_open' => 1,
976                        'created_by' => 'System',
977                        'link' => $url
978                    )
979                );
980            } else {
981                $error = true;
982                Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
983            }
984        }
985
986    }
987
988    public function update_quotation(Request $request, $id){
989        $approvalMinimumOrderSize = null;
990        $approvalIsQuestion = null;
991        $approvalQuestionIdsNo = null;
992        $approvalN = null;
993        $approvalMinimumMargin = null;
994        $approvalId = null;
995        $approvalForAdd = null;
996        $approvalInvoiceMargin = null;
997        $sendApprovalNotification = false;
998        $sendApprovalMarginNotification = false;
999        $needToSendReminder = false;
1000
1001        // try {
1002
1003            $data = $request->all();
1004            $id = addslashes($id);
1005            $userId = addslashes($data['user_id']);
1006            $forApproval = null;
1007            unset($data['user_id']);
1008
1009            $r = array('amount', 'order_number', 'budget_type_id', 'acceptance_date');
1010            $job = array();
1011
1012            foreach ($data as $key => $value) {
1013                if($value == 'null'){
1014                    $data[$key] = null;
1015                }
1016
1017                if(in_array($key, $r)){
1018                    $job[$key] = $value;
1019                }
1020            }
1021
1022            $files = $request->file('files');
1023            unset($data['files']);
1024
1025            $internalFiles = $request->file('internal_files');
1026            unset($data['internal_files']);
1027
1028            $query = "
1029            SELECT
1030                SUM(CASE WHEN is_internal IS NULL THEN 1 ELSE 0 END) as external_count,
1031                SUM(CASE WHEN is_internal = 1 THEN 1 ELSE 0 END) as internal_count
1032            FROM tbl_files
1033            WHERE quotation_id = ?";
1034
1035            $counts = DB::select($query, [$id]);
1036            $fileCount = $counts[0]->external_count;
1037            $internalFileCount = $counts[0]->internal_count;
1038
1039            if($fileCount > 0 || !empty($files)){
1040                $data['has_attachment'] = 1;
1041            }
1042
1043            if($files){
1044                $totalFiles = $fileCount + count($files);
1045                if($totalFiles > 10){
1046                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
1047                }
1048            }
1049
1050            if($internalFileCount > 0 || !empty($internalFiles)){
1051                $data['has_attachment'] = 1;
1052            }
1053
1054            if($internalFiles){
1055                $totalInternalFileCount = $internalFileCount + count($internalFiles);
1056                if($totalInternalFileCount > 10){
1057                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
1058                }
1059            }
1060
1061            if(isset($data['request_date']) && isset($data['issue_date'])){
1062                $requestDate = strtotime($data['request_date']);
1063                $issueDate = strtotime($data['issue_date']);
1064                $dateDiff = $issueDate - $requestDate;
1065                $data['duration'] = round($dateDiff / (60 * 60 * 24));
1066            }
1067
1068            $result = TblQuotations::where('id', $id)->first();
1069
1070            if($result->quote_id != $data['quote_id']){
1071
1072                $c = TblQuotations::where('quote_id', (string) $data['quote_id'])->where('company_id', $result->company_id)->count();
1073
1074                if($c > 0){
1075
1076                    if($result->for_add == 0){
1077                        $latestBudget = TblQuotations::where('company_id', $result->company_id)->orderByRaw('CAST(quote_id AS DOUBLE) DESC')->first();
1078
1079                        $number = $latestBudget->quote_id;
1080                        $x = true;
1081
1082                        while ($x) {
1083
1084                            if(is_numeric(substr($number, -1))) {
1085                                $number++;
1086                            }else{
1087                                $number .= "1";
1088                            }
1089
1090                            $check = 0;
1091
1092                            $check = TblQuotations::where('company_id', $result->company_id)->where('quote_id', (string) $number)->count();
1093
1094                            if($check == 0){
1095                                $x = false;
1096                            }
1097                        }
1098
1099                        return response(['message' => 'KO', 'error' => 'quote_exists', 'number' => $number]);
1100                    }
1101
1102                    return response(['message' => 'KO', 'error' => 'quote_exists']);
1103                }
1104            }
1105
1106            $action = 0;
1107            if($result->created_by == null || $result->for_add == 1){
1108                $action = 1;
1109                $data['created_by'] = $data['updated_by'];
1110                $data['for_add'] = 0;
1111            }
1112
1113            $company = TblCompanies::where('company_id', $result->company_id)->first();
1114            $commercial = TblUsers::where('name', $data['commercial'])->first();
1115            $status = TblBudgetStatus::where('budget_status_id', $data['budget_status_id'])->first();
1116
1117            // $checkQuotation = TblQuotations::where(function($query) use ($data, $result) {
1118            //     $query->where('internal_quote_id', $data['internal_quote_id'])
1119            //         ->orWhere('internal_quote_id', 'O-25/'.$data['internal_quote_id']);
1120            // })
1121            //     ->where('company_id', $result->company_id)
1122            //     ->first();
1123
1124            // if($checkQuotation) {
1125            //     $url = "orders/" . $checkQuotation->id . "?company_id=" . $checkQuotation->company_id;
1126            //     return response([
1127            //         'message' => 'KO',
1128            //         'error' => "Presupuesto ya creado. Puedes verlo <a href='$url' target='_blank'>aquí</a>."
1129            //     ]);
1130            // }
1131
1132            $limitReminderEmails = $company->limit_reminder_emails ?? 3;
1133
1134            if($result->total_sent == $limitReminderEmails){
1135                $data['total_sent'] = 0;
1136            }
1137
1138            if($result->budget_status_id != $data['budget_status_id'] || $result->commercial != $data['commercial']){
1139                if($data['budget_status_id'] == 12){
1140                    if($company && $commercial){
1141                        $inProgressCount = TblQuotations::where('budget_status_id', 12)->where('company_id', $result->company_id)->where('commercial', $data['commercial'])->count();
1142                        if($company->process_limit <= $inProgressCount){
1143                            return response(['message' => 'KO', 'error' => 'in_progress', 'limit' => $company->process_limit]);
1144                        }
1145                    }else{
1146                        return response(['message' => 'KO', 'error' => 'in_progress', 'limit' => 0]);
1147                    }
1148                }
1149            }
1150
1151            $sendNotification = false;
1152            if($result->commercial != $data['commercial']){
1153                if(!empty($commercial)){
1154                    $createdByX = ($result->created_by == null) ? $data['created_by'] : $result->created_by;
1155                    if($createdByX != $data['commercial']){
1156                        $action = 0;
1157                        $sendNotification = true;
1158                    }
1159                }
1160            }
1161
1162            if(isset($data['amount']) || isset($data['budget_type_id']) || isset($data['customer_type_id']) || isset($data['invoice_margin']) || isset($data['question_enabled'])){
1163                if($company){
1164
1165                    $n = 0;
1166                    $invoiceMargin = 0;
1167                    $minimumMargin = 0;
1168                    $minimumOrderSize = 0;
1169
1170                    if($result->amount != $data['amount'] ||
1171                        $result->budget_type_id != $data['budget_type_id'] ||
1172                        $result->customer_type_id != $data['customer_type_id'] ||
1173                        $result->invoice_margin != $data['invoice_margin']
1174                    ){
1175                        $project = TblProjectTypes::where('company_id', $company->company_id)->where('budget_type_id', $data['budget_type_id'])->first();
1176                        $customerTypeIds = array();
1177
1178                        if($project){
1179                            if(!empty($project->customer_type_ids)){
1180                                $customerTypeIds = array_map('intval', explode(',', $project->customer_type_ids));
1181                            }
1182                            if($project->minimum_order_size != null && in_array($data['customer_type_id'], $customerTypeIds)){
1183                                if($data['amount'] >= $project->minimum_order_size){
1184                                    $data['for_approval'] = 1;
1185                                    $n = 1;
1186                                }
1187                            }
1188                            $minimumOrderSize = $project->minimum_order_size;
1189
1190                            if($project->minimum_order_size_v2 != null && in_array($data['customer_type_id'], $customerTypeIds)){
1191                                if($data['amount'] >= $project->minimum_order_size_v2){
1192                                    $data['for_approval'] = 1;
1193                                    if($n == 1){
1194                                        $data['for_approval'] = 3;
1195                                        $n = 3;
1196                                    }
1197                                }
1198                            }
1199
1200                        }else{
1201                            if(!empty($company->customer_type_ids)){
1202                                $customerTypeIds = array_map('intval', explode(',', $company->customer_type_ids));
1203                            }
1204                            if($company->minimum_order_size != null && in_array($data['customer_type_id'], $customerTypeIds)){
1205                                if($data['amount'] >= $company->minimum_order_size){
1206                                    $data['for_approval'] = 1;
1207                                    $n = 1;
1208                                }
1209                            }
1210                            $minimumOrderSize = $company->minimum_order_size;
1211
1212                            if($company->minimum_order_size_v2 != null && in_array($data['customer_type_id'], $customerTypeIds)){
1213                                if($data['amount'] >= $company->minimum_order_size_v2){
1214                                    $data['for_approval'] = 1;
1215                                    if($n == 1){
1216                                        $data['for_approval'] = 3;
1217                                        $n = 3;
1218                                    }
1219                                }
1220                            }
1221                        }
1222
1223                        if($data['budget_margin_enabled'] > 0){
1224                            $costOfLabor = $data['cost_of_labor'];
1225                            $totalCostOfJob = $data['total_cost_of_job'];
1226
1227                            if($totalCostOfJob > 0){
1228                                $invoiceMargin = $data['invoice_margin'] ?? 0;
1229                            }
1230
1231                            $minimumMargin = $company->minimum_margin;
1232                            if(!empty($company->customer_type_ids)){
1233                                $customerTypeIds = array_map('intval', explode(',', $company->customer_type_ids));
1234                            }
1235
1236                            if($project){
1237                                $minimumMargin = $project->minimum_margin;
1238                                $minimumOrderSize = $project->minimum_order_size;
1239                                if(!empty($project->customer_type_ids)){
1240                                    $customerTypeIds = array_map('intval', explode(',', $project->customer_type_ids));
1241                                }
1242                            }
1243
1244                            if($invoiceMargin < $minimumMargin && $invoiceMargin != null && $invoiceMargin != 0){
1245                                if(in_array($data['customer_type_id'], $customerTypeIds)){
1246                                    $data['for_approval'] = 1;
1247                                    $n = 2;
1248                                }
1249                            }
1250                        }
1251                    }
1252
1253                    $isQuestion = 0;
1254                    $questionIdsNo = array();
1255                    if(isset($data['question_enabled'])){
1256                        if($data['question_ids_no'] != $result->question_ids_no
1257                            || $data['budget_type_id'] != $result->budget_type_id
1258                            || $data['customer_type_id'] != $result->customer_type_id
1259                            || $data['amount'] != $result->amount){
1260                            if($data['question_enabled'] > 0 && $n == 0){
1261                                if(!empty($data['question_ids_no'])){
1262                                    $questionIdsNo = array_map('intval', explode(",", $data['question_ids_no']));
1263
1264                                    if(count($questionIdsNo) > 0){
1265                                        if($company->workflow_budget_size != null){
1266                                            if($data['amount'] >= $company->workflow_budget_size){
1267                                                $isQuestion = 1;
1268                                                $data['for_approval'] = 1;
1269                                                $n = 1;
1270                                            }
1271                                        }
1272                                        $minimumOrderSize = $company->workflow_budget_size;
1273                                    }
1274                                }
1275                            }
1276                        }
1277                    }
1278
1279                    if($n == 1 || $n == 3){
1280                        $sendApprovalNotification = true;
1281                        $approvalMinimumOrderSize = $minimumOrderSize;
1282                        $approvalId = $result->id;
1283                        $approvalForAdd = $result->for_add;
1284                        $approvalIsQuestion = $isQuestion;
1285                        $approvalQuestionIdsNo = $questionIdsNo;
1286                        $approvalN = $n;
1287                    }
1288
1289                    if($n == 2){
1290                        $sendApprovalMarginNotification = true;
1291                        $approvalMinimumMargin = $minimumMargin;
1292                        $approvalId = $result->id;
1293                        $approvalForAdd = $result->for_add;
1294                        $approvalInvoiceMargin = $invoiceMargin;
1295                    }
1296                }
1297            }
1298
1299            $data['updated_at'] = date('Y-m-d H:i:s');
1300            $job['updated_at'] = $data['updated_at'];
1301
1302            $data["g3w_warning"] = 0;
1303
1304            if($result->for_add == 1){
1305                TblCompanies::where('company_id', $result->company_id)->update(array('last_id' => $data['quote_id'], 'before_last_id' => $data['quote_id']));
1306            }
1307
1308            $forApproval = @$data['for_approval'] ?? null;
1309
1310            if($forApproval != null){
1311                $data['approved_at'] = null;
1312                $data['approved_by'] = null;
1313                $data['rejected_at'] = null;
1314                $data['rejected_by'] = null;
1315                $data['approved_at_v2'] = null;
1316                $data['approved_by_v2'] = null;
1317                $data['rejected_at_v2'] = null;
1318                $data['rejected_by_v2'] = null;
1319            }
1320
1321            $differences = $this->compareArrays($data, TblQuotations::where('id', $id)->first());
1322            $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"];
1323
1324            if(is_null(TblQuotations::where('id', $id)->first()->customer_type_id)){
1325                $needToSendReminder = true;
1326            }
1327
1328            foreach ($differences as $field => $value) {
1329                if(in_array($field, $primaryAprovalsFields)){
1330                    $needToSendReminder = true;
1331                };
1332
1333                $this->addUpdateLog($id, $userId, $field, $value["oldData"], $value["newData"]);
1334            }
1335
1336            //check if the quotation are a solicitud and the user write the internal quote id
1337            if(
1338                (TblQuotations::where('id', $id)->first()->budget_status_id == 6 || TblQuotations::where('id', $id)->first()->budget_status_id == 8)
1339                && !is_null($data["internal_quote_id"] ?? null)
1340                && TblQuotations::where('internal_quote_id', $data["internal_quote_id"])->where("company_id", $company->company_id)->exists()
1341                && (!is_null($id) && $id !== "")
1342            ){
1343                $createdAt = TblQuotations::where('id', $id)->first()->created_at;
1344                TblQuotations::where('id', $id)->first()->update(array("internal_quote_id", $data["internal_quote_id"]));
1345
1346                $this->callDeleteQuotation($id, $company->company_id, $userId, $data['updated_by']);
1347                $budget = TblQuotations::where('internal_quote_id', $data["internal_quote_id"])->where("company_id", $company->company_id)->first();
1348
1349                $id = $budget->id;
1350
1351                $dataToChange = array_intersect_key($data, array_flip([
1352                    'internal_quote_id',
1353                    'client',
1354                    'phone_number',
1355                    'email',
1356                    'source_id',
1357                    'created_by',
1358                    'updated_by',
1359                    'updated_at'
1360                ]));
1361
1362                if($data["phone_number"] === null || $data["phone_number"] === "" || empty($dataToChange["phone_number"])){
1363                    unset($dataToChange['phone_number']);
1364                }
1365
1366                $dataToChange['budget_status_id'] = $budget->budget_status_id;
1367                $dataToChange["created_at"] = $createdAt;
1368
1369                $data["g3w_warning"] = 0;
1370
1371                if(
1372                    in_array($budget->budget_status_id, [13, 14]) ||
1373                    !$dataToChange["source_id"] ||
1374                    (!$budget->budget_type_id || $budget->budget_type_id == 0 || $budget->budget_type_id == 16) ||
1375                    empty(trim($dataToChange["client"])) ||
1376                    empty(trim($dataToChange["email"]))
1377                ){
1378                    $data["g3w_warning"] = 1;
1379                }
1380
1381                TblQuotations::where('id', $id)->update($dataToChange);
1382
1383            } else {
1384                TblQuotations::where('id', $id)->update($data);
1385            }
1386
1387            TblOngoingJobs::where('quotation_id', $id)->update($job);
1388
1389            $this->update_commercial_numbers($result->company_id);
1390
1391            if($result->budget_status_id != $data['budget_status_id']
1392                && $data['budget_status_id'] == 3){
1393                $this->send_acceptance_notification($result->id, $result->company_id, $userId, $data['updated_by']);
1394
1395                TblQuotations::where('id', $id)->update(
1396                    array(
1397                        'accepted_at' => $data['updated_at'],
1398                        'accepted_by' => $data['updated_by']
1399                    )
1400                );
1401            }
1402
1403            if($files){
1404
1405                $uploadedFiles = [];
1406                $i = 0;
1407
1408                $combinedFilesSize = 0;
1409                foreach ($files as $file) {
1410                    $i++;
1411                    $origFilename = $file->getClientOriginalName();
1412                    $filename = $result->id . '-' . $result->company_id . '-FC' . time() . '-' . $origFilename;
1413
1414                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
1415
1416                    if($combinedFilesSize > 25000000){
1417                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
1418                    }
1419
1420                    if(in_array($origFilename, $uploadedFiles)){
1421                        $origFilename = $origFilename . $i;
1422                    }
1423
1424                    // $fileContent = file_get_contents($file->getRealPath());
1425                    // $fileHash = hash('sha256', $fileContent);
1426                    
1427                    $s3path = Storage::disk('s3')->putFileAs(
1428                        'uploads',
1429                        $file,
1430                        $filename,
1431                        [
1432                            'ContentType' => $file->getMimeType(),
1433                        ]
1434                    );
1435
1436                    TblFiles::create(
1437                        array(
1438                            'quotation_id' => $id,
1439                            'original_name' => $origFilename,
1440                            'filename' => $filename,
1441                            'uploaded_by' => $data['updated_by'],
1442                            // 'file' => $fileContent,
1443                            'file_size' => $file->getSize(),
1444                            // 'file_hash' => $fileHash,
1445                            'mime_type' => $file->getMimeType(),
1446                            'uploaded_at' => now(),
1447                        )
1448                    );
1449
1450                    $uploadedFiles[] = $file->getClientOriginalName();
1451                }
1452            }
1453
1454            if($internalFiles){
1455
1456                $uploadedFiles = [];
1457                $i = 0;
1458
1459                $combinedFilesSize = 0;
1460                foreach ($internalFiles as $file) {
1461                    $i++;
1462                    $origFilename = $file->getClientOriginalName();
1463                    $filename = $result->id . '-' . $result->company_id . '-FI' . time() . '-' . $origFilename;
1464
1465                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
1466
1467                    if($combinedFilesSize > 25000000){
1468                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
1469                    }
1470
1471                    if(in_array($origFilename, $uploadedFiles)){
1472                        $origFilename = $origFilename . $i;
1473                    }
1474
1475                    // $fileContent = file_get_contents($file->getRealPath());
1476                    // $fileHash = hash('sha256', $fileContent);                    
1477
1478                    $s3path = Storage::disk('s3')->putFileAs(
1479                        'uploads',
1480                        $file,
1481                        $filename,
1482                        [
1483                            'ContentType' => $file->getMimeType(),
1484                        ]
1485                    );
1486
1487                    TblFiles::create(
1488                        array(
1489                            'quotation_id' => $id,
1490                            'original_name' => $origFilename,
1491                            'filename' => $filename,
1492                            'uploaded_by' => $data['updated_by'],
1493                            // 'file' => $fileContent,
1494                            'file_size' => $file->getSize(),
1495                            // 'file_hash' => $fileHash,
1496                            'mime_type' => $file->getMimeType(),
1497                            'uploaded_at' => now(),
1498                            'is_internal' => 1
1499                        )
1500                    );
1501
1502                    $uploadedFiles[] = $file->getClientOriginalName();
1503                }
1504            }
1505
1506            $query = "SELECT
1507                        a.id,
1508                        a.quote_id,
1509                        a.company_id,
1510                        b.name company_name,
1511                        a.client,
1512                        c.name client_type,
1513                        c.customer_type_id,
1514                        a.request_date,
1515                        a.visit_date,
1516                        a.issue_date,
1517                        a.acceptance_date,
1518                        a.internal_quote_id,
1519                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
1520                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
1521                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
1522                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
1523                        -- DATEDIFF(a.issue_date, a.request_date) duration,
1524                        a.phone_number,
1525                        a.email,
1526                        a.duration,
1527                        a.order_number,
1528                        d.name 'type',
1529                        d.budget_type_id,
1530                        e.name 'status',
1531                        e.budget_status_id,
1532                        f.name source,
1533                        f.source_id,
1534                        a.amount,
1535                        g.name reason_for_not_following_up,
1536                        a.reason_for_not_following_up_id,
1537                        a.reason_for_rejection_id,
1538                        a.last_follow_up_date,
1539                        a.last_follow_up_comment,
1540                        CASE WHEN a.reason_for_rejection_id IS NULL THEN a.reason_for_rejection ELSE h.name END reason_for_rejection,
1541                        a.commercial,
1542                        a.created_by,
1543                        a.created_at,
1544                        a.updated_by,
1545                        a.for_approval,
1546                        a.box_work_g3w,
1547                        a.people_assigned_to_the_job,
1548                        a.duration_of_job_in_days,
1549                        a.estimated_cost_of_materials,
1550                        a.budget_margin_enabled,
1551                        a.question_enabled,
1552                        a.cost_of_labor,
1553                        a.total_cost_of_job,
1554                        CASE WHEN a.budget_margin_enabled > 0 THEN a.invoice_margin ELSE NULL END invoice_margin,
1555                        CASE WHEN a.budget_margin_enabled > 0 THEN a.margin_for_the_company ELSE NULL END margin_for_the_company,
1556                        a.margin_on_invoice_per_day_per_worker,
1557                        a.revenue_per_date_per_worked,
1558                        a.commission_cost,
1559                        a.commission_pct,
1560                        a.gross_margin,
1561                        a.labor_percentage,
1562                        a.question_ids,
1563                        a.question_ids_no,
1564                        a.approved_at,
1565                        a.approved_by,
1566                        a.rejected_at,
1567                        a.rejected_by,
1568                        a.approved_at_v2,
1569                        a.approved_by_v2,
1570                        a.rejected_at_v2,
1571                        a.rejected_by_v2,
1572                        a.accepted_at,
1573                        a.accepted_by,
1574                        a.is_validated,
1575                        a.resource_id,
1576                        a.x_status,
1577                        a.likehood,
1578                        a.updated_at
1579                    FROM
1580                        tbl_quotations a
1581                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
1582                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
1583                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
1584                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
1585                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
1586                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
1587                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
1588                    WHERE a.id = {$id}";
1589
1590            $result = DB::select($query);
1591
1592
1593            if($sendNotification){
1594                $this->send_notification(
1595                    $commercial->email,
1596                    $userId,
1597                    $data['quote_id'],
1598                    $id,
1599                    $status->name,
1600                    $commercial->id,
1601                    $company->name,
1602                    0,
1603                    $company->company_id,
1604                    $data['internal_quote_id']
1605                );
1606            }
1607
1608            if($sendApprovalNotification && $needToSendReminder){
1609                $this->send_approval_notification(
1610                    $data['amount'],
1611                    $data['budget_type_id'],
1612                    $data['customer_type_id'],
1613                    $approvalMinimumOrderSize,
1614                    $data['quote_id'],
1615                    $approvalId,
1616                    $company->name,
1617                    @$data['created_by'] ?? @$data['updated_by'],
1618                    $userId,
1619                    $approvalForAdd,
1620                    @$commercial->email ?? null,
1621                    $company->company_id,
1622                    'orders',
1623                    $approvalIsQuestion,
1624                    $approvalQuestionIdsNo,
1625                    $approvalN
1626                );
1627            }
1628
1629            if($sendApprovalMarginNotification && $needToSendReminder){
1630                $this->send_approval_margin_notification(
1631                    $data['amount'],
1632                    $data['budget_type_id'],
1633                    $data['customer_type_id'],
1634                    $approvalMinimumMargin,
1635                    $data['quote_id'],
1636                    $approvalId,
1637                    $company->name,
1638                    @$data['created_by'] ?? @$data['updated_by'],
1639                    $userId,
1640                    $approvalForAdd,
1641                    @$commercial->email ?? null,
1642                    $approvalInvoiceMargin,
1643                    $company->company_id,
1644                    'orders'
1645                );
1646            }
1647
1648            Cache::flush();
1649
1650            return response(['message' => 'OK', 'data' => $result, 'for_approval' => $forApproval]);
1651
1652        // } catch (\Exception $e) {
1653        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
1654        // }
1655
1656    }
1657
1658    private function compareArrays($data, $quotations) {
1659        $differences = [];
1660
1661        foreach ($data as $field => $valueData) {
1662            if (isset($quotations->$field)) {
1663                $valueQuotations = $quotations->$field;
1664
1665                $valueData = $this->convertValue($valueData);
1666                $valueQuotations = $this->convertValue($valueQuotations);
1667                if (
1668                    $valueData !== $valueQuotations &&
1669                    !is_null($valueData) &&
1670                    !is_null($valueQuotations)
1671                ) {
1672                    $differences[$field] = [
1673                        'newData' => $valueData,
1674                        'oldData' => $valueQuotations
1675                    ];
1676                }
1677            } /*else {
1678                $diferences[$field] = [
1679                    'data' => $valueData,
1680                    'quotations' => 'NO_EXISTE'
1681                ];
1682            }*/
1683        }
1684
1685        /*foreach (get_object_vars($quotations) as $field => $valueQuotations) {
1686            if (!array_key_exists($field, $data)) {
1687                $diferences[$field] = [
1688                    'data' => 'NO_EXISTE',
1689                    'quotations' => $valueQuotations
1690                ];
1691            }
1692        }*/
1693
1694        return $differences;
1695    }
1696
1697    private function convertValue($value) {
1698        if ($value === null) {
1699            return null;
1700        }
1701
1702        if (is_numeric($value)) {
1703            return (int)$value;
1704        }
1705
1706        if ($value === 'NULL' || $value === 'null') {
1707            return null;
1708        }
1709
1710        if (is_string($value)) {
1711            if (preg_match('/^(\d{4}-\d{2}-\d{2})( \d{2}:\d{2}:\d{2})?$/', $value, $matches)) {
1712                return $matches[1];
1713            }
1714        }
1715
1716        return $value;
1717    }
1718
1719    protected function callDeleteQuotation($id, $company_id, $userId, $user)
1720    {
1721        $request = new \Illuminate\Http\Request([
1722            'company_id' => $company_id,
1723            'user_id' => $userId,
1724            'updated_by' => $user,
1725            'ids' => [$id],
1726            'filterModel' => [],
1727            'sortModel' => [],
1728            'searchText' => '',
1729            'ids_not_in' => []
1730        ]);
1731
1732        return $this->delete_quotation($request, true);
1733    }
1734
1735    public function get_quotation($id){
1736
1737        try {
1738
1739            $id = addslashes($id);
1740
1741            $query = "SELECT
1742                        a.id,
1743                        a.quote_id,
1744                        a.company_id,
1745                        b.name company_name,
1746                        a.client,
1747                        c.name client_type,
1748                        c.customer_type_id,
1749                        s.name segment,
1750                        s.segment_id,
1751                        a.request_date,
1752                        a.visit_date,
1753                        a.issue_date,
1754                        a.acceptance_date,
1755                        a.internal_quote_id,
1756                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
1757                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
1758                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
1759                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
1760                        a.phone_number,
1761                        a.email,
1762                        a.duration,
1763                        a.order_number,
1764                        d.name 'type',
1765                        d.budget_type_id,
1766                        e.name 'status',
1767                        e.budget_status_id,
1768                        f.name source,
1769                        f.source_id,
1770                        a.amount,
1771                        g.name reason_for_not_following_up,
1772                        a.reason_for_not_following_up_id,
1773                        a.reason_for_rejection_id,
1774                        a.last_follow_up_date,
1775                        a.last_follow_up_comment,
1776                        CASE WHEN a.reason_for_rejection_id IS NULL THEN a.reason_for_rejection ELSE h.name END reason_for_rejection,
1777                        a.commercial,
1778                        a.created_by,
1779                        a.created_at,
1780                        a.updated_by,
1781                        a.updated_at,
1782                        a.for_approval,
1783                        a.box_work_g3w,
1784                        a.people_assigned_to_the_job,
1785                        a.duration_of_job_in_days,
1786                        a.estimated_cost_of_materials,
1787                        a.budget_margin_enabled,
1788                        a.question_enabled,
1789                        a.cost_of_labor,
1790                        a.total_cost_of_job,
1791                        CASE WHEN a.budget_margin_enabled > 0 THEN a.invoice_margin ELSE NULL END invoice_margin,
1792                        CASE WHEN a.budget_margin_enabled > 0 THEN a.margin_for_the_company ELSE NULL END margin_for_the_company,
1793                        a.margin_on_invoice_per_day_per_worker,
1794                        a.revenue_per_date_per_worked,
1795                        a.commission_cost,
1796                        a.commission_pct,
1797                        a.gross_margin,
1798                        a.labor_percentage,
1799                        a.question_ids,
1800                        a.question_ids_no,
1801                        a.approved_at,
1802                        a.approved_by,
1803                        a.rejected_at,
1804                        a.rejected_by,
1805                        a.approved_at_v2,
1806                        a.approved_by_v2,
1807                        a.rejected_at_v2,
1808                        a.rejected_by_v2,
1809                        a.accepted_at,
1810                        a.accepted_by,
1811                        a.is_validated,
1812                        a.resource_id,
1813                        a.sync_import,
1814                        a.sync_import_edited,
1815                        a.g3w_warning,
1816                        a.g3w_warning_fields
1817                    FROM
1818                        tbl_quotations a
1819                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
1820                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
1821                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
1822                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
1823                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
1824                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
1825                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
1826                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
1827                    WHERE a.id = {$id}
1828                    AND a.company_id IN ({$this->companyId})";
1829
1830            $result = DB::select($query);
1831
1832            Cache::flush();
1833            return response(['message' => 'OK', 'data' => $result]);
1834
1835        } catch (\Exception $e) {
1836            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1837        }
1838    }
1839
1840    public function get_quotation_log($id){
1841        return TblQuotationsLog::where("quotation_id", $id)->get();
1842    }
1843
1844    public function send_notification($toEmail = null, $userId, $quoteId, $id, $status, $sendUserId, $companyName, $action, $companyId, $g3wQuoteId){
1845
1846        $user = TblUsers::where('id', $userId)->first();
1847
1848        $imgpath = File::get('fireservicetitan.png');
1849
1850        $url = env('URL') . "orders/{$id}?company_id={$companyId}";
1851        $href = "<a href='{$url}'>{$quoteId}</a>";
1852
1853        $body = "";
1854        $subject = "";
1855
1856        if($g3wQuoteId){
1857            $quoteId = $quoteId . " - G3W #{$g3wQuoteId}";
1858        }
1859
1860        if($action == 1){
1861            $body = __('language.email_notification.body_created');
1862            $body = str_replace('{{creator}}', $user->name, $body);
1863            $subject = str_replace('{{quote_id}}', $quoteId, __('language.email_notification.subject_created'));
1864        }else{
1865            $body = __('language.email_notification.body_assigned');
1866            $body = str_replace('{{assignee}}', $user->name, $body);
1867            $subject = str_replace('{{quote_id}}', $quoteId, __('language.email_notification.subject_assigned'));
1868        }
1869
1870        $body = str_replace('{{quote_id}}', $href, $body);
1871        $body = str_replace('{{company}}', $companyName, $body);
1872        $body = str_replace('{{status}}', $status, $body);
1873
1874        $content = $body;
1875
1876        $body .= "<p>Fire Service Titan</p>";
1877        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
1878
1879        $html = '<!DOCTYPE html>';
1880        $html .= '<html>';
1881        $html .= '<head>';
1882        $html .= '<meta charset="UTF-8">';
1883        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
1884        $html .= '</head>';
1885        $html .= '<body>';
1886        $html .= $body;
1887        $html .= '</body>';
1888        $html .= '</html>';
1889
1890        if($toEmail != null){
1891            $email = new \SendGrid\Mail\Mail();
1892
1893            if(env('SENDGRID_STAGING')){
1894                $toEmail = $user->email;
1895            }
1896
1897            $email->setFrom('fire@fire.es', 'Fire Service Titan');
1898            $email->setSubject($subject);
1899            $email->addTo($toEmail);
1900            $email->addContent("text/html", $html);
1901
1902            $email->addAttachment(
1903                $imgpath,
1904                "image/png",
1905                "fireservicetitan.png",
1906                "inline",
1907                "fireservicetitan"
1908            );
1909
1910            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
1911
1912            $response = $sendgrid->send($email);
1913            if ($response->statusCode() == 202) {
1914                Log::channel('email_log')->info('ID:' . $quoteId . ' : ' . $status . ' : '. $toEmail .' - EMAIL NOTIFICATION SENT');
1915
1916                TblNotifications::create(
1917                    array(
1918                        'user_id' => $sendUserId,
1919                        'content' => $content,
1920                        'is_open' => 1,
1921                        'created_by' => 'System',
1922                        'link' => $url
1923                    )
1924                );
1925            } else {
1926                $error = true;
1927                Log::channel('email_log')->error('ID:' . $quoteId . ' : ' . $status . ' : '. $toEmail .' - ' . $response->body());
1928            }
1929        }
1930
1931    }
1932
1933    public function delete_quotation(Request $request, $isFromDeleteCall = false){
1934
1935        try {
1936
1937            $data = $request->all();
1938            $result = array();
1939
1940            $r = new Request([
1941                'filterModel' => $data['filterModel'],
1942                'sortModel' => $data['sortModel'],
1943                'start' => 0,
1944                'end' => 999999999,
1945                'company_id' => $data['company_id'],
1946                'user_id' => $data['user_id'],
1947                'ids' => $data['ids'],
1948                'searchText' => $data['searchText'],
1949                'ids_not_in' => $data['ids_not_in']
1950            ]);
1951
1952            $result = $this->list_quotations($r);
1953            $result = $result->original['data'];
1954
1955            $outputArray = array();
1956
1957            foreach ($result as $item) {
1958                if (isset($item->id)) {
1959                    $outputArray[] = $item->id;
1960                }
1961            }
1962
1963            $ids = implode(',', $outputArray);
1964
1965            if($outputArray){
1966
1967                TblQuotations::whereIn('id', $outputArray)->update(
1968                    array(
1969                        'updated_at' => date('Y-m-d H:i:s'),
1970                        'updated_by' => $data['updated_by'],
1971                        'for_add' => $isFromDeleteCall ? 2 : ($data['for_add'] ?? 0),
1972                        'reason_id' => (isset($data['reason_id']) ? $data['reason_id'] : null),
1973                        'reason_for_deletion' => (isset($data['reason_for_deletion']) ? $data['reason_for_deletion'] : null),
1974                    )
1975                );
1976
1977                $query = "INSERT INTO tbl_quotations_deleted
1978                        SELECT * FROM tbl_quotations WHERE id IN ({$ids})";
1979
1980                DB::select($query);
1981
1982                TblQuotations::whereIn('id', $outputArray)->delete();
1983                TblFiles::whereIn('quotation_id', $outputArray)->delete();
1984            }
1985
1986            Cache::flush();
1987            return response(['message' => 'OK', 'data' => $result]);
1988
1989        } catch (\Exception $e) {
1990            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1991        }
1992
1993    }
1994
1995    public function list_quotations(Request $request){
1996
1997        // try {
1998
1999            $data = $request->all();
2000            $companyId = addslashes($data['company_id']);
2001            $userId = addslashes($data['user_id']);
2002            $filter = $data['filterModel'];
2003            $sort = $data['sortModel'];
2004            $result = array();
2005            $subquery = "";
2006            $where = "";
2007            $having = "";
2008            $orderBy = "";
2009            $start = addslashes($data['start']);
2010            $end = addslashes($data['end']);
2011            $totalRowCount = 0;
2012            $withFilters = "";
2013            $logFilter = @$data['log_filter'];
2014
2015            $filterType = array(
2016                'contains' => "LIKE '%[value]%'",
2017                'notContains' => "NOT LIKE '%[value]%'",
2018                'equals' => "= '[value]'",
2019                'notEqual' => "<> '[value]'",
2020                'startsWith' => "LIKE '[value]%'",
2021                'endsWith' => "LIKE '%[value]'",
2022                'blank' => "IS NULL",
2023                'notBlank' => "IS NOT NULL",
2024                'lessThan' => "< [value]",
2025                'lessThanOrEqual' => "<= [value]",
2026                'greaterThan' => "> [value]",
2027                'greaterThanOrEqual' => ">= [value]",
2028                'inRange' => "BETWEEN [value1] AND [value2]",
2029                "in" => "IN ([value])"
2030            );
2031            /*if(isset($data['internal_quote_id']) && count($data['internal_quote_id']) > 0){
2032                $internalIds = implode(",", $data['internal_quote_id']);
2033                $where = " AND a.internal_quote_id IN ({$internalIds}) ";
2034            }*/
2035
2036            if(isset($data['ids']) && count($data['ids']) > 0){
2037                $quoteIds = implode(",", $data['ids']);
2038                $where = " AND a.id IN ({$quoteIds}";
2039            }
2040
2041            if(isset($data['ids_not_in']) && count($data['ids_not_in']) > 0){
2042                $quoteIds = implode(",", $data['ids_not_in']);
2043                $where = " AND a.id NOT IN ({$quoteIds}";
2044            }
2045
2046            $lasLeftJoin = "";
2047            $whereBlocked = "";
2048
2049            if(isset($data['last_follow_up_date']) && !empty($data['last_follow_up_date'])){
2050                if($data['last_follow_up_date'] == 1){
2051
2052                    $lasLeftJoin = " LEFT JOIN (
2053                        SELECT
2054                          a.id,
2055                          SUBSTRING_INDEX(
2056                            SUBSTRING_INDEX(a.email, ',', n.digit + 1),
2057                            ',',
2058                            -1
2059                          ) AS email_domain
2060                        FROM
2061                          tbl_quotations a
2062                          INNER JOIN (
2063                            SELECT
2064                              0 AS digit
2065                            UNION ALL
2066                            SELECT
2067                              1
2068                            UNION ALL
2069                            SELECT
2070                              2
2071                            UNION ALL
2072                            SELECT
2073                              3
2074                            UNION ALL
2075                            SELECT
2076                              4
2077                            UNION ALL
2078                            SELECT
2079                              5
2080                            UNION ALL
2081                            SELECT
2082                              6
2083                            UNION ALL
2084                            SELECT
2085                              7
2086                            UNION ALL
2087                            SELECT
2088                              8
2089                            UNION ALL
2090                            SELECT
2091                              9
2092                          ) n ON LENGTH(
2093                            REPLACE(a.email, ',', '')
2094                          ) <= LENGTH(a.email)- n.digit
2095                          GROUP BY a.id
2096                      ) temp ON a.id = temp.id ";
2097
2098                    $whereBlocked = " AND a.last_follow_up_date < NOW()
2099                            AND a.budget_status_id IN (2)
2100                            AND a.email IS NOT NULL
2101                            AND a.email <> ''
2102                            AND NOT EXISTS (
2103                                SELECT
2104                                1
2105                                FROM
2106                                tbl_blocked_domains bd
2107                                WHERE
2108                                temp.email_domain LIKE CONCAT('%', bd.domain, '%')
2109                                AND bd.company_id = a.company_id
2110                            )
2111                            AND a.last_follow_up_date IS NOT NULL
2112                            AND a.reason_for_not_following_up_id IS NULL
2113                            AND a.last_follow_up_date > 0
2114                            AND a.total_sent < b.limit_reminder_emails
2115                            AND a.for_add = 0 ";
2116                }
2117            }
2118
2119            if(isset($data['visit_date']) && !empty($data['visit_date'])){
2120                if($data['visit_date'] == 1){
2121                    $where = " AND DATE_FORMAT(a.visit_date, '%Y-%m-%d') <= DATE_FORMAT(NOW(), '%Y-%m-%d') ";
2122                }
2123            }
2124
2125            if($companyId != 0){
2126                $where .= " AND a.company_id = {$companyId} ";
2127            }else{
2128                $where .= " AND a.company_id IN ({$this->companyId}";
2129            }
2130
2131            $matchScoreCol = "";
2132            $matchScoreOrderBy = "";
2133
2134            if(isset($data['searchText']) && $data['searchText'] != null){
2135
2136                $availableParameters = [
2137                    'a.quote_id',
2138                    'a.internal_quote_id',
2139                    'a.box_work_g3w',
2140                    's.name',
2141                    'b.name',
2142                    'a.client',
2143                    'c.name',
2144                    'a.phone_number',
2145                    'a.email',
2146                    'a.order_number',
2147                    'a.request_date',
2148                    'a.issue_date',
2149                    'a.acceptance_date',
2150                    'a.created_at',
2151                    'a.updated_at',
2152                    'a.rejected_at',
2153                    'a.accepted_at',
2154                    'd.name',
2155                    'e.name',
2156                    'f.name',
2157                    'a.amount',
2158                    'g.name',
2159                    'a.last_follow_up_comment',
2160                    'a.x_status',
2161                    'h.name',
2162                    'a.commercial',
2163                    'a.user_commercial_by_g3w',
2164                    'a.user_create_by_g3w',
2165                    'a.created_by',
2166                    'a.updated_by',
2167                    'a.approved_by',
2168                    'a.rejected_by',
2169                    'a.accepted_by',
2170                    'a.sync_import',
2171                    'a.sync_import_edited',
2172                    'a.g3w_warning'
2173                ];
2174
2175                $searchText = addslashes($data['searchText']);
2176                $searchTextArray = explode(" ", $searchText);
2177
2178                $searchArray = array();
2179                $splitSearchArray = array();
2180                $matchScoreArray = array();
2181                $sc = 1;
2182                foreach ($availableParameters as $field) {
2183                    if($field == 'a.client' || $field == 'a.amount' || $field == 'a.created_at'){
2184                        $sc = 3;
2185                    }elseif($field == 'a.acceptance_date'){
2186                        $sc = 2;
2187                    }else{
2188                        $sc = 1;
2189                    }
2190
2191                    $l = "{$field} LIKE '%{$searchText}%'";
2192                    if($field == "a.last_follow_up_comment"){
2193                        $l = "{$field} = '{$searchText}'";
2194                    }else{
2195
2196                        $d = "IFNULL((LENGTH(LOWER({$field})) - LENGTH(REPLACE(LOWER({$field}), LOWER('{$searchText}'), ''))) / LENGTH(LOWER('{$searchText}')), 0) * {$sc}";
2197
2198                        if(count($searchTextArray) > 1){
2199                            foreach ($searchTextArray as $word) {
2200                                if(!is_numeric($word)){
2201                                    $d .= " + IFNULL((LENGTH(LOWER({$field})) - LENGTH(REPLACE(LOWER({$field}), LOWER('{$word}'), ''))) / LENGTH(LOWER('{$word}')), 0) * {$sc}";
2202                                }
2203                            }
2204                        }
2205
2206                        array_push($matchScoreArray, $d);
2207                    }
2208
2209                    if(is_numeric($searchText)){
2210                        array_push($searchArray, "({$l} OR {$field} = CAST('{$searchText}' AS UNSIGNED))");
2211                    }else{
2212                        array_push($searchArray, "({$l} OR DATE_FORMAT({$field}, '%d/%m/%Y') = DATE_FORMAT(STR_TO_DATE('{$searchText}', '%d/%m/%Y'), '%d/%m/%Y'))");
2213                    }
2214
2215                    if(count($searchTextArray) > 1){
2216                        foreach ($searchTextArray as $word) {
2217
2218                            $l = "{$field} LIKE '%{$word}%'";
2219                            if($field == "a.last_follow_up_comment"){
2220                                $l = "{$field} = '{$word}'";
2221                            }
2222
2223                            if(is_numeric($word)){
2224                                array_push($splitSearchArray, "{$l} OR {$field} = CAST('{$word}' AS UNSIGNED)");
2225                            }else{
2226                                array_push($splitSearchArray, "{$l} OR DATE_FORMAT({$field}, '%d/%m/%Y') = DATE_FORMAT(STR_TO_DATE('{$word}', '%d/%m/%Y'), '%d/%m/%Y')");
2227                            }
2228                        }
2229                    }
2230
2231                    $sc = 1;
2232                }
2233
2234                if(count($splitSearchArray) > 0){
2235                    $splitSearchArray = implode(" OR ", $splitSearchArray);
2236                    $splitSearchArray = " OR ({$splitSearchArray}";
2237                }else{
2238                    $splitSearchArray = "";
2239                }
2240
2241                $searchArray = implode(" OR ", $searchArray);
2242                $matchScoreArray = implode(",", $matchScoreArray);
2243                $matchScoreCol = ", GREATEST({$matchScoreArray}) match_score";
2244                $matchScoreOrderBy = "match_score DESC,";
2245                $where .= " AND ({$searchArray} {$splitSearchArray})";
2246            }
2247
2248            if(count($sort) > 0){
2249                $field = $sort[0]['colId'];
2250                $sortBy = $sort[0]['sort'];
2251
2252                if(strpos($field, "translate") !== false){
2253                    $field = str_replace("_translate", "", $field);
2254                }else{
2255                    if($field == "client_type"){
2256                        $field = "c.name";
2257                    }elseif($field == "segment"){
2258                        $field = "s.name";
2259                    }elseif($field == "type"){
2260                        $field = "d.name";
2261                    }elseif($field == "status"){
2262                        $field = "e.name";
2263                    }elseif($field == "source"){
2264                        $field = "g.name";
2265                    }elseif($field == "reason_for_not_following_up"){
2266                        $field = "g.name";
2267                    }elseif($field == "reason_for_rejection"){
2268                        $field = "h.name";
2269                    }elseif($field == "amount"){
2270                        $field = "CAST(a.amount AS DOUBLE)";
2271                    }elseif($field == "duration"){
2272                        $field = "CAST(a.duration AS DOUBLE)";
2273                    }elseif($field == "quote_id" || $field == "internal_quote_id"){
2274                        $field = "CAST(a.{$field} AS DOUBLE)";
2275                    }elseif($field == "company_name"){
2276                        $field = "b.name";
2277                    }
2278
2279                }
2280
2281                if($matchScoreOrderBy){
2282                    $matchScoreOrderBy = ", match_score DESC";
2283                }
2284
2285                $orderBy = " ORDER BY {$field} {$sortBy} {$matchScoreOrderBy}";
2286            }else{
2287                $orderBy = " ORDER BY {$matchScoreOrderBy} a.id DESC";
2288            }
2289
2290            foreach ($filter as $key => $data) {
2291                if(strpos($key, "translate") !== false){
2292
2293                    $field = str_replace("_translate", "", $key);
2294
2295                    if($field == "created_at"){
2296                        $field = "a.created_at";
2297                    }elseif($field == "last_follow_up_date"){
2298                        $field = "a.last_follow_up_date";
2299                    }elseif($field == "issue_date"){
2300                        $field = "a.issue_date";
2301                    }elseif($field == "request_date"){
2302                        $field = "a.request_date";
2303                    }elseif($field == "acceptance_date"){
2304                        $field = "a.acceptance_date";
2305                    }elseif($field == "internal_quote_id"){
2306                        $field = "a.internal_quote_id";
2307                    }
2308
2309                    $whereDates = "";
2310                    $z = 0;
2311
2312                    if(isset($data['filters']) && !empty($data['filters'])){
2313                        foreach ($data['filters'] as $yearKey => $yearData) {
2314                            $yearsMonths = array();
2315                            $yearsWeeks = array();
2316
2317                            if($z > 0){
2318                                $whereDates .= " OR (YEAR($field) = {$yearKey} ";
2319                            }else{
2320                                $whereDates .= " (YEAR($field) = {$yearKey} ";
2321                            }
2322
2323                            for ($i = 0; $i < count($yearData['months']); $i++) {
2324                                if($yearData['months'][$i]['isChecked']){
2325                                    array_push($yearsMonths, $yearData['months'][$i]['value']);
2326                                }
2327                            }
2328
2329                            $yearsMonths = implode("','", $yearsMonths);
2330                            $whereDates .= " AND (MONTH({$field}) IN ('{$yearsMonths}')";
2331
2332                            for ($i = 0; $i < count($yearData['weeks']); $i++) {
2333                                if($yearData['weeks'][$i]['isChecked']){
2334                                    array_push($yearsWeeks, $yearData['weeks'][$i]['value']);
2335                                }
2336                            }
2337
2338                            $yearsWeeks = implode("','", $yearsWeeks);
2339                            if($yearsWeeks != ''){
2340                                $whereDates .= " OR WEEK({$field}) IN ('{$yearsWeeks}') ";
2341                            }
2342
2343                            $whereDates .= ")) ";
2344                            $z++;
2345                        }
2346                    }
2347
2348                    $whereDataUptoToday = "";
2349                    if(isset($data['isDataUptoToday'])){
2350                        if($data['isDataUptoToday']){
2351                            $whereDates = "";
2352                            $whereDataUptoToday .= " AND {$field} < NOW() AND {$field} > 0 ";
2353                        }
2354                    }
2355
2356                    $whereBlanks = "";
2357                    if(isset($data['isBlanks'])){
2358                        if($data['isBlanks']){
2359                            $conj = "OR";
2360                            if($whereDates == ""){
2361                                $conj = "";
2362                            }
2363                            $whereBlanks .= " {$conj} {$field} IS NULL ";
2364                        }else{
2365                            $conj = "AND";
2366                            if($whereDates == ""){
2367                                $conj = "";
2368                            }
2369                            $whereBlanks .= " {$conj} {$field} IS NOT NULL ";
2370                        }
2371                    }
2372
2373                    $where .= " AND ({$whereDates} {$whereBlanks} {$whereDataUptoToday}";
2374                }else{
2375                    if($data['filterType'] == 'number'){
2376                        if(array_key_exists('operator', $data)){
2377                            if($data['condition1']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
2378                                $data['condition1']['filter'] = addslashes($data['condition1']['filter']);
2379                                $data['condition2']['filter'] = addslashes($data['condition2']['filter']);
2380
2381                                if($data['condition1']['type'] == 'inRange'){
2382                                    $data['condition1']['filterTo'] = addslashes($data['condition1']['filterTo']);
2383                                    $inRange = str_replace("[value1]", $data['condition1']['filter'], $filterType['inRange']);
2384                                    $val1 = str_replace("[value2]", $data['condition1']['filterTo'], $inRange);
2385                                }else{
2386                                    $val1 = str_replace("[value]", $data['condition1']['filter'], $filterType[$data['condition1']['type']]);
2387                                }
2388
2389                                if($data['condition2']['type'] == 'inRange'){
2390                                    $data['condition2']['filterTo'] = addslashes($data['condition2']['filterTo']);
2391                                    $inRange = str_replace("[value1]", $data['condition2']['filter'], $filterType['inRange']);
2392                                    $val2 = str_replace("[value2]", $data['condition2']['filterTo'], $inRange);
2393                                }else{
2394                                    $val2 = str_replace("[value]", $data['condition2']['filter'], $filterType[$data['condition2']['type']]);
2395                                }
2396
2397                            }else{
2398                                $val1 = $filterType[$data['condition1']['type']];
2399                                $val2 = $filterType[$data['condition2']['type']];
2400                            }
2401
2402                            $where .= " AND a.{$key} {$val1} {$data['operator']} a.{$key} {$val2} ";
2403                        }else{
2404                            if($data['type'] != 'blank' && $data['type'] != 'notBlank'){
2405                                $data['filter'] = addslashes($data['filter']);
2406
2407                                if($data['type'] == 'inRange'){
2408                                    $data['filterTo'] = addslashes($data['filterTo']);
2409                                    $inRange = str_replace("[value1]", $data['filter'], $filterType['inRange']);
2410                                    $val = str_replace("[value2]", $data['filterTo'], $inRange);
2411                                }else{
2412                                    $val = str_replace("[value]", $data['filter'], $filterType[$data['type']]);
2413                                }
2414                            }else{
2415                                $val = $filterType[$data['type']];
2416                            }
2417
2418                            $where .= " AND a.{$key} {$val} ";
2419                        }
2420                    }
2421
2422                    if($data['filterType'] == 'text'){
2423                        if(array_key_exists('operator', $data)){
2424                            if($data['condition1']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
2425                                $data['condition1']['filter'] = addslashes($data['condition1']['filter']);
2426                                $val1 = str_replace("[value]", $data['condition1']['filter'], $filterType[$data['condition1']['type']]);
2427                            }
2428
2429                            if($data['condition2']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
2430                                $data['condition2']['filter'] = addslashes($data['condition2']['filter']);
2431                                $val2 = str_replace("[value]", $data['condition2']['filter'], $filterType[$data['condition2']['type']]);
2432                            }
2433
2434                            $where .= " AND {$key} {$val1} {$data['operator']} {$key} {$val2} ";
2435                        }else{
2436                            $type = $data['type'];
2437                            $filter = $data['filter'];
2438
2439                            if (($type === 'in' || $type === 'contains') && strpos($filter, ',') !== false) {
2440                                $values = explode(',', $filter);
2441                                $escaped = array_map('addslashes', $values);
2442                                $val = "IN ('" . implode("','", $escaped) . "')";
2443                            }
2444
2445                            elseif ($type !== 'blank' && $type !== 'notBlank') {
2446                                $data['filter'] = addslashes($data['filter']);
2447                                $val = str_replace("[value]", $data['filter'], $filterType[$type]);
2448                            }
2449
2450                            else {
2451                                $val = $filterType[$type];
2452                            }
2453
2454                            $where .= " AND {$key} {$val} ";
2455
2456                        }
2457                    }
2458
2459                    if($data['filterType'] == 'set'){
2460                        $statusName = $key;
2461
2462                        if($key == "client_type"){
2463                            $statusName = "c.name";
2464                        }elseif($key == "segment"){
2465                            $statusName = "s.name";
2466                        }elseif($key == "type"){
2467                            $statusName = "d.name";
2468                        }elseif($key == "status"){
2469                            $statusName = "e.name";
2470                        }elseif($key == "source"){
2471                            $statusName = "f.name";
2472                        }elseif($key == "reason_for_not_following_up"){
2473                            $statusName = "g.name";
2474                        }elseif($key == "reason_for_rejection"){
2475                            $statusName = "h.name";
2476                        }elseif($key == "created_by"){
2477                            $statusName = "a.created_by";
2478                        }elseif($key == "has_attachment"){
2479                            $statusName = "a.has_attachment";
2480                            if($data['values']){
2481                                foreach ($data['values'] as $k => $v) {
2482                                    if($v == "No"){
2483                                        $data['values'][$k] = 0;
2484                                    }else{
2485                                        $data['values'][$k] = 1;
2486                                    }
2487                                }
2488                            }
2489                        }elseif($key == "for_approval"){
2490                            $statusName = "a.for_approval";
2491                            if($data['values']){
2492                                foreach ($data['values'] as $k => $v) {
2493                                    if($v == "No"){
2494                                        $data['values'][$k] = 0;
2495                                    }else{
2496                                        $data['values'][$k] = 1;
2497                                    }
2498                                }
2499                            }
2500                        }elseif($key == "sync_import"){
2501                            $statusName = "a.sync_import";
2502                            if($data['values']){
2503                                foreach ($data['values'] as $k => $v) {
2504                                    if($v == "Manual"){
2505                                        $data['values'][$k] = 0;
2506                                    }else{
2507                                        $data['values'][$k] = 1;
2508                                    }
2509                                }
2510                            }
2511                        }elseif($key == "g3w_warning"){
2512                            $statusName = "a.g3w_warning";
2513                            if($data['values']){
2514                                foreach ($data['values'] as $k => $v) {
2515                                    if($v == "No"){
2516                                        $data['values'][$k] = 0;
2517                                    }else{
2518                                        $data['values'][$k] = 1;
2519                                    }
2520                                }
2521                            }
2522                        }elseif($key == "company_name"){
2523                            $statusName = "b.name";
2524                        }
2525
2526                        $val = implode("','", $data['values']);
2527
2528                        if(in_array(null, $data['values'], true)){
2529                            $where .= " AND ({$statusName} IN ('{$val}') OR {$statusName} IS NULL) ";
2530                        }else{
2531                            $where .= " AND {$statusName} IN ('{$val}') ";
2532                        }
2533                    }
2534                }
2535            }
2536
2537            $whereSendToClient = $where;
2538            $where;
2539
2540            $offset = $start;
2541            $limit = $end - $start;
2542
2543            $subquery = ",(SELECT can_write FROM tbl_company_users WHERE company_id = a.company_id AND user_id = {$userId}) can_write";
2544
2545            // Quotations accepted without acceptance_date
2546            // Quotations with state "No encontrado" or "Estado no reconocido en FST"
2547            // Quotations with not comercial in out database
2548            // Phone number on null
2549            // Source on null
2550            // Client name on null
2551            // Budget Type on null
2552            if (isset($request['g3w_warning'])) {
2553                $g3w_warning = $request['g3w_warning'] == "No" ? 0 : 1;
2554                /*$where .= "
2555                AND a.sync_import = 1
2556                    AND (
2557                        a.budget_status_id IN (13, 14)
2558                        OR (
2559                            a.commercial IS NULL
2560                            OR NOT EXISTS (
2561                                SELECT 1 FROM tbl_users u WHERE u.name = a.commercial
2562                            )
2563                            OR a.phone_number IS NULL
2564                            OR a.source_id IS NULL
2565                            OR a.budget_type_id IS NULL
2566                            OR (a.client IS NULL OR TRIM(a.client) = '')
2567                            OR (a.email IS NULL OR TRIM(a.email) = '')
2568                        )
2569                    )
2570                 ";*/
2571                $where .= "
2572                AND (a.sync_import = 1 OR a.sync_import_edited = 1)
2573                AND a.g3w_warning = " . $g3w_warning;
2574            }
2575
2576
2577            $query = "SELECT
2578                        a.id,
2579                        a.quote_id,
2580                        a.internal_quote_id,
2581                        a.company_id,
2582                        b.name company_name,
2583                        a.client,
2584                        c.name client_type,
2585                        c.customer_type_id,
2586                        s.name segment,
2587                        s.segment_id,
2588                        a.request_date,
2589                        a.visit_date,
2590                        a.issue_date,
2591                        a.acceptance_date,
2592                        a.internal_quote_id,
2593                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
2594                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
2595                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
2596                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
2597                        DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate,
2598                        DATE_FORMAT(a.accepted_at, '%d/%m/%Y') accepted_at_translate,
2599                        a.phone_number,
2600                        a.email,
2601                        a.duration,
2602                        a.order_number,
2603                        d.name 'type',
2604                        d.budget_type_id,
2605                        e.name 'status',
2606                        e.budget_status_id,
2607                        f.name as source,
2608                        f.source_id,
2609                        a.amount,
2610                        g.name reason_for_not_following_up,
2611                        a.reason_for_not_following_up_id,
2612                        a.reason_for_rejection_id,
2613                        a.last_follow_up_date,
2614                        a.last_follow_up_comment,
2615                        CASE WHEN a.reason_for_rejection_id IS NULL THEN a.reason_for_rejection ELSE h.name END reason_for_rejection,
2616                        a.commercial,
2617                        a.user_commercial_by_g3w,
2618                        a.user_create_by_g3w,
2619                        a.created_by,
2620                        a.created_at,
2621                        a.updated_by,
2622                        a.updated_at,
2623                        a.total_sent,
2624                        a.has_attachment,
2625                        a.for_approval,
2626                        a.box_work_g3w,
2627                        a.people_assigned_to_the_job,
2628                        a.duration_of_job_in_days,
2629                        a.estimated_cost_of_materials,
2630                        a.budget_margin_enabled,
2631                        a.question_enabled,
2632                        a.cost_of_labor,
2633                        a.total_cost_of_job,
2634                        CASE WHEN a.budget_margin_enabled > 0 THEN a.invoice_margin ELSE NULL END invoice_margin,
2635                        CASE WHEN a.budget_margin_enabled > 0 THEN a.margin_for_the_company ELSE NULL END margin_for_the_company,
2636                        a.margin_on_invoice_per_day_per_worker,
2637                        a.revenue_per_date_per_worked,
2638                        a.commission_cost,
2639                        a.commission_pct,
2640                        a.gross_margin,
2641                        a.labor_percentage,
2642                        a.question_ids,
2643                        a.question_ids_no,
2644                        a.approved_at,
2645                        a.approved_by,
2646                        a.rejected_at,
2647                        a.rejected_by,
2648                        a.approved_at_v2,
2649                        a.approved_by_v2,
2650                        a.rejected_at_v2,
2651                        a.rejected_by_v2,
2652                        a.accepted_at,
2653                        a.accepted_by,
2654                        a.is_validated,
2655                        a.resource_id,
2656                        a.x_status,
2657                        a.likehood,
2658                        a.sync_import,
2659                        a.sync_import_edited,
2660                        a.g3w_warning,
2661                        a.g3w_warning_fields,
2662                        SUBSTRING_INDEX(a.email, '@', -1) domain
2663                        {$matchScoreCol}
2664                        {$subquery}
2665                    FROM
2666                        tbl_quotations a
2667                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2668                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2669                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2670                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2671                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2672                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2673                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2674                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2675                        {$lasLeftJoin}
2676                    WHERE a.for_add = 0 {$where} {$whereBlocked}
2677                    GROUP BY a.id
2678                    {$orderBy}
2679                    LIMIT {$offset}{$limit}
2680                    ";
2681
2682
2683            $value = Cache::get(base64_encode($query));
2684
2685            if(!$value){
2686                $result = DB::select($query);
2687
2688                Cache::put(base64_encode($query), $result, 600);
2689            }else{
2690                $result = $value;
2691            }
2692
2693            $totalQuery = "SELECT
2694                            COUNT(a.id) totalRowCount,
2695                            SUM(CAST(a.amount AS DECIMAL(10,2))) totalAmount
2696                        FROM
2697                            tbl_quotations a
2698                            LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2699                            LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2700                            LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2701                            LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2702                            LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2703                            LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2704                            LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2705                            LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2706                            {$lasLeftJoin}
2707                        WHERE a.for_add = 0
2708                        {$where} {$whereBlocked}";
2709
2710            $value = Cache::get(base64_encode($totalQuery));
2711
2712            if(!$value){
2713                $countQuery = DB::select($totalQuery);
2714
2715                Cache::put(base64_encode($totalQuery), $countQuery, 600);
2716            }else{
2717                $countQuery = $value;
2718            }
2719
2720            $totalToFollowUpQuery = "SELECT
2721                                        COUNT(DISTINCT a.id) totalRowCount
2722                                    FROM
2723                                        tbl_quotations a
2724                                    LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2725                                    LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2726                                    LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2727                                    LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2728                                    LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2729                                    LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2730                                    LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2731                                    LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2732                                    LEFT JOIN (
2733                                        SELECT
2734                                        a.id,
2735                                        SUBSTRING_INDEX(
2736                                            SUBSTRING_INDEX(a.email, ',', n.digit + 1),
2737                                            ',',
2738                                            -1
2739                                        ) AS email_domain
2740                                        FROM
2741                                        tbl_quotations a
2742                                        INNER JOIN (
2743                                            SELECT
2744                                            0 AS digit
2745                                            UNION ALL
2746                                            SELECT
2747                                            1
2748                                            UNION ALL
2749                                            SELECT
2750                                            2
2751                                            UNION ALL
2752                                            SELECT
2753                                            3
2754                                            UNION ALL
2755                                            SELECT
2756                                            4
2757                                            UNION ALL
2758                                            SELECT
2759                                            5
2760                                            UNION ALL
2761                                            SELECT
2762                                            6
2763                                            UNION ALL
2764                                            SELECT
2765                                            7
2766                                            UNION ALL
2767                                            SELECT
2768                                            8
2769                                            UNION ALL
2770                                            SELECT
2771                                            9
2772                                        ) n ON LENGTH(
2773                                            REPLACE(a.email, ',', '')
2774                                        ) <= LENGTH(a.email)- n.digit
2775                                        GROUP BY a.id
2776                                    ) temp ON a.id = temp.id
2777                                    WHERE
2778                                    a.last_follow_up_date < NOW()
2779                                    AND a.budget_status_id IN (2)
2780                                    AND a.email IS NOT NULL
2781                                    AND a.email <> ''
2782                                    AND NOT EXISTS (
2783                                        SELECT
2784                                        1
2785                                        FROM
2786                                        tbl_blocked_domains bd
2787                                        WHERE
2788                                        temp.email_domain LIKE CONCAT('%', bd.domain, '%')
2789                                        AND bd.company_id = a.company_id
2790                                    )
2791                                    AND a.last_follow_up_date IS NOT NULL
2792                                    AND a.reason_for_not_following_up_id IS NULL
2793                                    AND a.last_follow_up_date > 0
2794                                    AND a.total_sent < b.limit_reminder_emails
2795                                    AND a.for_add = 0
2796                                    {$where}";
2797
2798            $value = Cache::get(base64_encode($totalToFollowUpQuery));
2799
2800            if(!$value){
2801                $countToFollowUpQuery = DB::select($totalToFollowUpQuery);
2802
2803                Cache::put(base64_encode($totalToFollowUpQuery), $countToFollowUpQuery, 600);
2804            }else{
2805                $countToFollowUpQuery = $value;
2806            }
2807
2808            $query = "SELECT
2809                            COUNT(1) as count,
2810                            SUM(a.amount) as total_amount
2811                        FROM tbl_quotations a
2812                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2813                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2814                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2815                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2816                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2817                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2818                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2819                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2820                        WHERE a.budget_status_id = 11
2821                        AND a.email IS NOT NULL
2822                        {$whereSendToClient}
2823                        ";
2824
2825
2826
2827            $value = Cache::get(base64_encode($query));
2828
2829            if(!$value){
2830                $totalSendToClient = DB::select($query);
2831
2832                Cache::put(base64_encode($query), $totalSendToClient, 600);
2833            }else{
2834                $totalSendToClient = $value;
2835            }
2836
2837            return response([
2838                'message' => 'OK',
2839                'data' => $result,
2840                'totalAmount' => $countQuery[0]->totalAmount,
2841                'totalRowCount' => $countQuery[0]->totalRowCount,
2842                'totalToFollowUpRowCount' => $countToFollowUpQuery[0]->totalRowCount,
2843                'totalSendToClient' => $totalSendToClient[0]->count,
2844                'totalSendToClientAmount' => $totalSendToClient[0]->total_amount
2845            ]);
2846
2847        // } catch (\Exception $e) {
2848        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
2849        // }
2850
2851    }
2852
2853    public function get_dates(Request $request){
2854
2855        try {
2856
2857            $data = $request->all();
2858            $companyId = addslashes($data['company_id']);
2859
2860            $where = "";
2861            if($companyId != 0){
2862                $where = " AND a.company_id = {$companyId} ";
2863            }else{
2864                $where = " AND a.company_id IN ({$this->companyId})";
2865            }
2866
2867            $query = "SELECT
2868                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
2869                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
2870                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
2871                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
2872                        DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate,
2873                        DATE_FORMAT(a.accepted_at, '%d/%m/%Y') accepted_at_translate
2874                    FROM tbl_quotations a
2875                    WHERE a.for_add = 0 {$where}";
2876
2877            $result = DB::select($query);
2878
2879            return response([
2880                'message' => 'OK',
2881                'data' => $result
2882            ]);
2883
2884        } catch (\Exception $e) {
2885            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2886        }
2887
2888    }
2889
2890    public function list_quotation_analytics_by_source(Request $request){
2891
2892        try {
2893
2894            $data = $request->all();
2895            $companyId = addslashes($data['company_id']);
2896
2897            $where = "";
2898            $whereYear = "";
2899
2900            $dateLflArray = array();
2901            $companyIds = $this->companyIds;
2902
2903            if($companyId != 0){
2904                $companyIds = array($companyId);
2905            }
2906
2907            $field = "issue_date";
2908
2909            if(isset($data['years']) && $data['years'] != null){
2910                $years = implode(',', $data['years']);
2911                if(count($data['years']) > 0){
2912                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
2913                }
2914            }
2915
2916            foreach ($companyIds as $v) {
2917
2918                $lflWhere = " AND q.company_id = {$v} ";
2919
2920                $query = "SELECT
2921                            CONCAT(
2922                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
2923                                ' - ',
2924                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
2925                            ) AS date_like,
2926                            YEAR(q.{$field}) 'year',
2927                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
2928                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
2929                            {$v} 'company_id'
2930                        FROM
2931                            tbl_quotations q
2932                        WHERE
2933                            q.{$field} IS NOT NULL
2934                            AND q.for_add != 1
2935                            {$lflWhere}
2936                            {$whereYear}
2937                        GROUP BY YEAR(q.{$field})
2938                        ORDER BY YEAR(q.{$field}) DESC";
2939
2940                $dateLike = DB::select($query);
2941
2942                $dateLflArray[$v] = $dateLike;
2943            }
2944
2945            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
2946
2947            $isFy = true;
2948
2949            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
2950                $isFy = false;
2951                $ytdArray = array();
2952                $ytdAcceptanceArray = array();
2953                $lflCompanyIds = array();
2954                $lflCompanyIdsAcc = array();
2955                foreach ($dateLflArray as $k => $v) {
2956                    foreach ($dateLflArray[$k] as $item) {
2957                        $year = $item->year;
2958                        $now = date('m-d');
2959                        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)");
2960                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
2961                    }
2962
2963                    $ytdArray = implode(' OR ', $ytdArray);
2964                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
2965                    $ytdArray = array();
2966
2967                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
2968                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
2969                    $ytdAcceptanceArray = array();
2970                }
2971
2972                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
2973                $where .= " AND ({$lflCompanyIds}";
2974
2975                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
2976                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
2977            }
2978
2979            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
2980                $isFy = false;
2981                $lflArray = array();
2982                $ytdAcceptanceArray = array();
2983                $lflCompanyIds = array();
2984                $lflCompanyIdsAcc = array();
2985                foreach ($dateLflArray as $k => $v) {
2986                    foreach ($dateLflArray[$k] as $item) {
2987                        $year = $item->year;
2988                        $min_date_like = $item->min_date_like;
2989                        $max_date_like = $item->max_date_like;
2990                        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)");
2991                        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}')");
2992                    }
2993
2994                    $lflArray = implode(' OR ', $lflArray);
2995                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
2996                    $lflArray = array();
2997
2998                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
2999                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3000                    $ytdAcceptanceArray = array();
3001                }
3002
3003                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3004                $where .= " AND ({$lflCompanyIds}";
3005
3006                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3007                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3008            }
3009
3010            if($isFy){
3011                if($companyId != 0){
3012                    $where .= " AND q.company_id = {$companyId} ";
3013                }else{
3014                    $where .= " AND q.company_id IN ({$this->companyId})";
3015                }
3016            }
3017
3018            if(isset($data['source']) && $data['source'] != null){
3019                $where .= " AND s.name = '{$data['source']}'";
3020            }
3021
3022            if(isset($data['month']) && $data['month'] != null){
3023                $where .= " AND MONTH(q.issue_date) = '{$data['month']}'";
3024            }
3025
3026            if(isset($data['week']) && $data['week'] != null){
3027                $where .= " AND WEEK(q.issue_date) = '{$data['week']}'";
3028            }
3029
3030            if(isset($data['commercial']) && $data['commercial'] != null){
3031                $where .= " AND q.commercial = '{$data['commercial']}'";
3032            }
3033
3034            if(isset($data['created_by']) && $data['created_by'] != null){
3035                $where .= " AND q.created_by = '{$data['created_by']}'";
3036            }
3037
3038            if(isset($data['budget_type']) && $data['budget_type'] != null){
3039                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
3040            }
3041
3042            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3043                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3044            }
3045
3046            if(isset($data['budget_status']) && $data['budget_status'] != null){
3047                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3048            }
3049
3050            if(isset($data['client_type']) && $data['client_type'] != null){
3051                $where .= " AND ct.customer_type_id = {$data['client_type']}";
3052            }
3053
3054            if(isset($data['segment_id']) && $data['segment_id'] != null){
3055                $where .= " AND q.segment_id = {$data['segment_id']}";
3056            }
3057
3058            $query = "SELECT
3059                        YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) AS 'year',
3060                        LPAD(MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'month',
3061                        LPAD(WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'week',
3062                        DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') issue_date,
3063                        COUNT(
3064                            CASE WHEN q.issue_date IS NOT NULL
3065                            THEN 1 END
3066                        ) AS totalIssue,
3067                        GROUP_CONCAT(
3068                            CASE WHEN q.issue_date IS NOT NULL
3069                            THEN q.id END
3070                        ) AS groupConcatIds,
3071                        SUM(
3072                            CASE WHEN q.issue_date IS NOT NULL THEN q.amount END
3073                        ) AS revenueIssue,
3074                        COUNT(
3075                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN 1 END
3076                        ) AS totalAcceptance,
3077                        SUM(
3078                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN q.amount END
3079                        ) AS revenueAcceptance,
3080                        SUM(
3081                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN q.amount END
3082                        ) / SUM(
3083                            CASE WHEN q.issue_date IS NOT NULL THEN q.amount END
3084                        ) * 100 AS revenueAcceptanceIssuedPercentage,
3085                        COUNT(
3086                            CASE WHEN bs.name = 'Rechazado' THEN 1 END
3087                        ) AS totalRejected,
3088                        SUM(
3089                            CASE WHEN bs.name = 'Rechazado' THEN q.amount END
3090                        ) AS revenueRejected,
3091                        COUNT(
3092                            CASE WHEN bs.name = 'Rechazado - automaticamente' THEN 1 END
3093                        ) AS totalRejectedAutomatic,
3094                        SUM(
3095                            CASE WHEN bs.name = 'Rechazado - automaticamente' THEN q.amount END
3096                        ) AS revenueRejectedAutomatic
3097                    FROM
3098                        tbl_quotations q
3099                        LEFT JOIN tbl_sources s ON s.source_id = q.source_id
3100                        LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3101                        LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3102                        LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
3103                    WHERE
3104                        q.issue_date IS NOT NULL
3105                        AND q.budget_type_id != 7
3106                        AND q.budget_type_id IS NOT NULL
3107                        AND q.for_add != 1
3108                        AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3109                        {$where}
3110                        {$whereYear}
3111                        AND YEAR(q.issue_date) NOT IN (2021, 2022)
3112                    GROUP BY
3113                        YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3114                        MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3115                        WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) WITH ROLLUP
3116                    ORDER BY
3117                        YEAR DESC,
3118                        MONTH ASC,
3119                        WEEK ASC,
3120                        DATE_FORMAT(q.issue_date, '%e') ASC";
3121
3122            $value = Cache::get(base64_encode($query));
3123
3124            if(!$value){
3125                $result = DB::select($query);
3126
3127                Cache::put(base64_encode($query), $result, 600);
3128            }else{
3129                $result = $value;
3130            }
3131
3132            return response([
3133                'message' => 'OK',
3134                'data' => $result
3135            ]);
3136
3137        } catch (\Exception $e) {
3138            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3139        }
3140    }
3141
3142    public function list_quotation_analytics_send_budgets(Request $request){
3143
3144        try {
3145
3146            $data = $request->all();
3147            $companyId = addslashes($data['company_id']);
3148
3149            $where = "";
3150            $whereYear = "";
3151
3152            if($companyId != 0){
3153                $where = " AND q.company_id = {$companyId} ";
3154            }else{
3155                $where = " AND q.company_id IN ({$this->companyId}";
3156            }
3157
3158            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3159                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3160            }
3161
3162            if(isset($data['budget_status']) && $data['budget_status'] != null){
3163                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3164            }
3165
3166            if(isset($data['years']) && $data['years'] != null){
3167                $years = implode(',', $data['years']);
3168                if(count($data['years']) > 0){
3169                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3170                }
3171            }
3172
3173            $query = "SELECT
3174                            YEAR(q.issue_date) AS 'year',
3175                            MONTH(q.issue_date) AS 'month',
3176                            SUM(
3177                                CASE WHEN MONTH(request_date) = MONTH(issue_date) THEN 1 ELSE 0 END
3178                            ) totalRequest,
3179                            COUNT(
3180                                CASE WHEN q.issue_date IS NOT NULL THEN 1 END
3181                            ) AS totalIssue,
3182                            GROUP_CONCAT(
3183                                CASE WHEN q.issue_date IS NOT NULL
3184                                THEN q.id END
3185                            ) AS groupConcatIds,
3186                            SUM(
3187                                CASE WHEN MONTH(request_date) = MONTH(issue_date) THEN 1 ELSE 0 END
3188                            ) /
3189                            COUNT(
3190                                CASE WHEN q.issue_date IS NOT NULL THEN 1 END
3191                            ) * 100 issuePercentage,
3192                            AVG(
3193                                COALESCE(q.duration, 0)
3194                            ) AS averageDurationIssue,
3195                            COALESCE(
3196                                AVG(
3197                                    CASE WHEN bt.name = 'Mantenimiento' THEN COALESCE(q.duration, 0) ELSE NULL END
3198                                ), 0
3199                            ) AS averageDurationMaintenance,
3200                            COALESCE(
3201                                AVG(
3202                                    CASE WHEN bt.name = 'Nuevos' THEN COALESCE(q.duration, 0) ELSE NULL END
3203                                ), 0
3204                            ) AS averageDurationNew,
3205                            COALESCE(
3206                                AVG(
3207                                    CASE WHEN bt.name = 'Correctivos' THEN COALESCE(q.duration, 0) ELSE NULL END
3208                                ), 0
3209                            ) AS averageDurationCorretive,
3210                            COALESCE(
3211                                AVG(
3212                                    CASE WHEN bt.name = 'Anomalías' THEN COALESCE(q.duration, 0) ELSE NULL END
3213                                ), 0
3214                            ) AS averageDurationAnomalies,
3215                            COALESCE(
3216                                AVG(
3217                                    CASE WHEN bt.name = 'Precios Unitarios' THEN COALESCE(q.duration, 0) ELSE NULL END
3218                                ), 0
3219                            ) AS averageDurationUnitPrice,
3220                            COALESCE(
3221                                AVG(
3222                                    CASE WHEN bt.name = 'Instalaciones' THEN COALESCE(q.duration, 0) ELSE NULL END
3223                                ), 0
3224                            ) AS averageDurationFacilities,
3225                            COALESCE(
3226                                AVG(
3227                                    CASE WHEN bt.name = 'Alquiler' THEN COALESCE(q.duration, 0) ELSE NULL END
3228                                ), 0
3229                            ) AS averageDurationRent,
3230                            COALESCE(
3231                                AVG(
3232                                    CASE WHEN bt.name = 'OCA visita' THEN COALESCE(q.duration, 0) ELSE NULL END
3233                                ), 0
3234                            ) AS averageDurationOCA,
3235                            COALESCE(
3236                                AVG(
3237                                    CASE WHEN bt.name = 'Retirada y gestion de residuos' THEN COALESCE(q.duration, 0) ELSE NULL END
3238                                ), 0
3239                            ) AS averageDurationWRM,
3240                            COALESCE(
3241                                AVG(
3242                                    CASE WHEN bt.name = 'Formación' THEN COALESCE(q.duration, 0) ELSE NULL END
3243                                ), 0
3244                            ) AS averageDurationTraining,
3245                            COALESCE(
3246                                AVG(
3247                                    CASE WHEN bt.name = 'Anomalías de facilities' THEN COALESCE(q.duration, 0) ELSE NULL END
3248                                ), 0
3249                            ) AS averageDurationFacilityAnomalies
3250                        FROM
3251                            tbl_quotations q
3252                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3253                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_id = btg.budget_type_id
3254                        WHERE
3255                            q.issue_date IS NOT NULL
3256                            AND q.budget_type_id != 7
3257                            AND q.budget_type_id IS NOT NULL
3258                            AND q.for_add != 1
3259                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3260                            {$where}
3261                            {$whereYear}
3262                        GROUP BY
3263                            YEAR(q.issue_date),
3264                            MONTH(q.issue_date) WITH ROLLUP
3265                        ORDER BY
3266                            YEAR(q.issue_date) DESC,
3267                            MONTH(q.issue_date) ASC";
3268
3269            $sendBudgets = array();
3270            $sendBudgetsTotals = array();
3271
3272            $value = Cache::get(base64_encode($query));
3273
3274            if(!$value){
3275                $result = DB::select($query);
3276
3277                Cache::put(base64_encode($query), $result, 600);
3278            }else{
3279                $result = $value;
3280            }
3281
3282            if(count($result) > 0){
3283                for ($i = 0; $i < count($result); $i++) {
3284
3285                    if($result[$i]->year == null && $result[$i]->month == null){
3286                        $result[$i]->month = "totalGeneral";
3287                        $sendBudgetsTotals["totalGeneral"] = $result[$i];
3288                        continue;
3289                    }elseif($result[$i]->month == null && $result[$i]->year != null){
3290                        if(count($data['years']) > 0 || $whereYear == ""){
3291                            $result[$i]->month = "totalSub";
3292                        }else{
3293                            continue;
3294                        }
3295                    }else{
3296                        $result[$i]->month = sprintf("%02d", $result[$i]->month);
3297                    }
3298
3299                    $sendBudgets[$result[$i]->year][$result[$i]->month] = $result[$i];
3300                }
3301            }
3302
3303            return response([
3304                'message' => 'OK',
3305                'data' => $sendBudgets,
3306                'totals' => $sendBudgetsTotals
3307            ]);
3308
3309        } catch (\Exception $e) {
3310            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3311        }
3312    }
3313
3314    public function list_quotation_analytics_track_budgets(Request $request){
3315
3316        try {
3317
3318            $data = $request->all();
3319            $companyId = addslashes($data['company_id']);
3320
3321            $where = "";
3322            $whereYear = "";
3323            $isBetween = false;
3324
3325            $dateLflArray = array();
3326            $companyIds = $this->companyIds;
3327
3328            if($companyId != 0){
3329                $companyIds = array($companyId);
3330            }
3331
3332            if(isset($data['years']) && $data['years'] != null){
3333                $years = implode(',', $data['years']);
3334                if(count($data['years']) > 0){
3335                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3336                }
3337            }
3338
3339            $field = "issue_date";
3340
3341            foreach ($companyIds as $v) {
3342
3343                $lflWhere = " AND q.company_id = {$v} ";
3344
3345                $query = "SELECT
3346                            CONCAT(
3347                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
3348                                ' - ',
3349                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
3350                            ) AS date_like,
3351                            YEAR(q.{$field}) 'year',
3352                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
3353                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
3354                            {$v} 'company_id'
3355                        FROM
3356                            tbl_quotations q
3357                        WHERE
3358                            q.{$field} IS NOT NULL
3359                            AND q.for_add != 1
3360                            {$lflWhere}
3361                            {$whereYear}
3362                        GROUP BY YEAR(q.{$field})
3363                        ORDER BY YEAR(q.{$field}) DESC";
3364
3365                $dateLike = DB::select($query);
3366
3367                $dateLflArray[$v] = $dateLike;
3368            }
3369
3370            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
3371
3372            $isFy = true;
3373
3374            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
3375                $isFy = false;
3376                $ytdArray = array();
3377                $ytdAcceptanceArray = array();
3378                $lflCompanyIds = array();
3379                $lflCompanyIdsAcc = array();
3380                foreach ($dateLflArray as $k => $v) {
3381                    foreach ($dateLflArray[$k] as $item) {
3382                        $year = $item->year;
3383                        $now = date('m-d');
3384                        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)");
3385                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
3386                    }
3387
3388                    $ytdArray = implode(' OR ', $ytdArray);
3389                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
3390                    $ytdArray = array();
3391
3392                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3393                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3394                    $ytdAcceptanceArray = array();
3395                }
3396
3397                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3398                $where .= " AND ({$lflCompanyIds}";
3399
3400                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3401                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3402            }
3403
3404            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
3405                $isFy = false;
3406                $lflArray = array();
3407                $ytdAcceptanceArray = array();
3408                $lflCompanyIds = array();
3409                $lflCompanyIdsAcc = array();
3410                foreach ($dateLflArray as $k => $v) {
3411                    foreach ($dateLflArray[$k] as $item) {
3412                        $year = $item->year;
3413                        $min_date_like = $item->min_date_like;
3414                        $max_date_like = $item->max_date_like;
3415                        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)");
3416                        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}')");
3417                    }
3418
3419                    $lflArray = implode(' OR ', $lflArray);
3420                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
3421                    $lflArray = array();
3422
3423                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3424                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3425                    $ytdAcceptanceArray = array();
3426                }
3427
3428                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3429                $where .= " AND ({$lflCompanyIds}";
3430
3431                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3432                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3433            }
3434
3435            if($isFy){
3436                if($companyId != 0){
3437                    $where .= " AND q.company_id = {$companyId} ";
3438                }else{
3439                    $where .= " AND q.company_id IN ({$this->companyId})";
3440                }
3441            }
3442
3443            if(isset($data['source']) && $data['source'] != null){
3444                $where .= " AND s.name = '{$data['source']}'";
3445            }
3446
3447            if(isset($data['commercial']) && $data['commercial'] != null){
3448                $where .= " AND q.commercial = '{$data['commercial']}'";
3449            }
3450
3451            if(isset($data['created_by']) && $data['created_by'] != null){
3452                $where .= " AND q.created_by = '{$data['created_by']}'";
3453            }
3454
3455            if(isset($data['budget_type']) && $data['budget_type'] != null){
3456                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
3457            }
3458
3459            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3460                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3461            }
3462
3463            if(isset($data['budget_status']) && $data['budget_status'] != null){
3464                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3465            }
3466
3467            if(isset($data['client_type']) && $data['client_type'] != null){
3468                $where .= " AND ct.customer_type_id = {$data['client_type']}";
3469            }
3470
3471            if(isset($data['segment_id']) && $data['segment_id'] != null){
3472                $where .= " AND q.segment_id = {$data['segment_id']}";
3473            }
3474
3475            $query = "SELECT
3476                            YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) AS 'year',
3477                            LPAD(MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'month',
3478                            LPAD(WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'week',
3479                            DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') issue_date,
3480                            COUNT(
3481                                CASE WHEN q.issue_date IS NOT NULL
3482                                THEN 1 END
3483                            ) AS totalIssue,
3484                            GROUP_CONCAT(
3485                                CASE WHEN q.issue_date IS NOT NULL
3486                                THEN q.id END
3487                            ) AS groupConcatIds,
3488                            COUNT(
3489                                CASE WHEN {$whereAcceptanceDate}
3490                                AND bs.name = 'Aceptado' THEN 1 END) totalAccept,
3491                            COUNT(
3492                                CASE WHEN q.acceptance_date IS NOT NULL
3493                                AND {$whereAcceptanceDate}
3494                                AND bs.name = 'Aceptado'
3495                                AND DATEDIFF(q.acceptance_date, q.issue_date) <= 10 THEN 1 END
3496                            ) / COUNT(
3497                                CASE WHEN q.issue_date IS NOT NULL
3498                                THEN 1 END
3499                            ) * 100 AS percentageOfacceptanceLessThan10,
3500                            COUNT(
3501                                CASE WHEN q.acceptance_date IS NOT NULL
3502                                AND {$whereAcceptanceDate}
3503                                AND bs.name = 'Aceptado'
3504                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 10
3505                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 30 THEN 1 END
3506                            ) / COUNT(
3507                                CASE WHEN q.issue_date IS NOT NULL
3508                                THEN 1 END
3509                            ) * 100 AS percentageOfacceptanceLessThan30,
3510                            COUNT(
3511                                CASE WHEN q.acceptance_date IS NOT NULL
3512                                AND {$whereAcceptanceDate}
3513                                AND bs.name = 'Aceptado'
3514                                AND DATEDIFF(q.acceptance_date, q.issue_date) >= 30 THEN 1 END
3515                            ) / COUNT(
3516                                CASE WHEN q.issue_date IS NOT NULL
3517                                THEN 1 END
3518                            ) * 100 AS percentageOfacceptanceMoreThan30,
3519                            COUNT(CASE WHEN
3520                                {$whereAcceptanceDate} THEN 1 END
3521                            ) / COUNT(
3522                                CASE WHEN q.issue_date IS NOT NULL
3523                                THEN 1 END
3524                            ) * 100 acceptedPercentage,
3525                            COALESCE(
3526                                AVG(
3527                                    CASE WHEN q.issue_date IS NOT NULL
3528                                    AND q.acceptance_date IS NOT NULL
3529                                    AND {$whereAcceptanceDate}
3530                                    AND bs.name = 'Aceptado'
3531                                    THEN DATEDIFF(q.acceptance_date, q.issue_date) ELSE NULL END
3532                                ), 0
3533                            )
3534                            AS averageAcceptedDuration,
3535                            COALESCE(
3536                                AVG(
3537                                    CASE WHEN q.issue_date IS NOT NULL
3538                                    AND q.request_date IS NOT NULL
3539                                    THEN DATEDIFF(q.issue_date, q.request_date) ELSE NULL END
3540                                ), 0
3541                            )
3542                            AS averageRequestedDays
3543                        FROM
3544                            tbl_quotations q
3545                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3546                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3547                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
3548                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
3549                        WHERE
3550                            q.issue_date IS NOT NULL
3551                            AND q.budget_type_id != 7
3552                            AND q.budget_type_id IS NOT NULL
3553                            AND q.for_add != 1
3554                            {$where}
3555                            {$whereYear}
3556                        GROUP BY
3557                            YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3558                            MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3559                            WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) WITH ROLLUP
3560                        ORDER BY
3561                            YEAR DESC,
3562                            MONTH ASC,
3563                            WEEK ASC,
3564                            DATE_FORMAT(q.issue_date, '%e') ASC";
3565
3566            $value = Cache::get(base64_encode($query));
3567
3568            if(!$value){
3569                $result = DB::select($query);
3570
3571                Cache::put(base64_encode($query), $result, 600);
3572            }else{
3573                $result = $value;
3574            }
3575
3576            return response([
3577                'message' => 'OK',
3578                'data' => $result
3579            ]);
3580
3581        } catch (\Exception $e) {
3582            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3583        }
3584    }
3585
3586    public function list_quotation_analytics_types_budgets(Request $request){
3587
3588        try {
3589
3590            $data = $request->all();
3591            $companyId = addslashes($data['company_id']);
3592
3593            $where = "";
3594            $whereYear = "";
3595            $isBetween = false;
3596
3597            $dateLflArray = array();
3598            $companyIds = $this->companyIds;
3599
3600            if($companyId != 0){
3601                $companyIds = array($companyId);
3602            }
3603
3604            if(isset($data['years']) && $data['years'] != null){
3605                $years = implode(',', $data['years']);
3606                if(count($data['years']) > 0){
3607                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3608                }
3609            }
3610
3611            $field = "issue_date";
3612
3613            foreach ($companyIds as $v) {
3614
3615                $lflWhere = " AND q.company_id = {$v} ";
3616
3617                $query = "SELECT
3618                            CONCAT(
3619                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
3620                                ' - ',
3621                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
3622                            ) AS date_like,
3623                            YEAR(q.{$field}) 'year',
3624                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
3625                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
3626                            {$v} 'company_id'
3627                        FROM
3628                            tbl_quotations q
3629                        WHERE
3630                            q.{$field} IS NOT NULL
3631                            AND q.for_add != 1
3632                            {$lflWhere}
3633                            {$whereYear}
3634                        GROUP BY YEAR(q.{$field})
3635                        ORDER BY YEAR(q.{$field}) DESC";
3636
3637                $dateLike = DB::select($query);
3638
3639                $dateLflArray[$v] = $dateLike;
3640            }
3641
3642            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
3643
3644            $isFy = true;
3645
3646            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
3647                $isFy = false;
3648                $ytdArray = array();
3649                $ytdAcceptanceArray = array();
3650                $lflCompanyIds = array();
3651                $lflCompanyIdsAcc = array();
3652                foreach ($dateLflArray as $k => $v) {
3653                    foreach ($dateLflArray[$k] as $item) {
3654                        $year = $item->year;
3655                        $now = date('m-d');
3656                        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)");
3657                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
3658                    }
3659
3660                    $ytdArray = implode(' OR ', $ytdArray);
3661                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
3662                    $ytdArray = array();
3663
3664                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3665                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3666                    $ytdAcceptanceArray = array();
3667                }
3668
3669                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3670                $where .= " AND ({$lflCompanyIds}";
3671
3672                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3673                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3674            }
3675
3676            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
3677                $isFy = false;
3678                $lflArray = array();
3679                $ytdAcceptanceArray = array();
3680                $lflCompanyIds = array();
3681                $lflCompanyIdsAcc = array();
3682                foreach ($dateLflArray as $k => $v) {
3683                    foreach ($dateLflArray[$k] as $item) {
3684                        $year = $item->year;
3685                        $min_date_like = $item->min_date_like;
3686                        $max_date_like = $item->max_date_like;
3687                        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)");
3688                        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}')");
3689                    }
3690
3691                    $lflArray = implode(' OR ', $lflArray);
3692                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
3693                    $lflArray = array();
3694
3695                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3696                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3697                    $ytdAcceptanceArray = array();
3698                }
3699
3700                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3701                $where .= " AND ({$lflCompanyIds}";
3702
3703                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3704                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3705            }
3706
3707            if($isFy){
3708                if($companyId != 0){
3709                    $where .= " AND q.company_id = {$companyId} ";
3710                }else{
3711                    $where .= " AND q.company_id IN ({$this->companyId})";
3712                }
3713            }
3714
3715            if(isset($data['budget_status']) && $data['budget_status'] != null){
3716                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3717            }
3718
3719            if(isset($data['segment_id']) && $data['segment_id'] != null){
3720                $where .= " AND q.segment_id = {$data['segment_id']}";
3721            }
3722
3723            $query = "SELECT
3724                            YEAR(q.issue_date) AS 'year',
3725                            bt.name,
3726                            COUNT(
3727                                CASE WHEN q.issue_date IS NOT NULL
3728                                THEN 1 END
3729                            ) AS totalIssue,
3730                            GROUP_CONCAT(
3731                                CASE WHEN q.issue_date IS NOT NULL
3732                                THEN q.id END
3733                            ) AS groupConcatIds,
3734                            COUNT(CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN 1 END) totalAccept,
3735                            COUNT(
3736                                CASE WHEN q.acceptance_date IS NOT NULL
3737                                AND {$whereAcceptanceDate}
3738                                AND bs.name = 'Aceptado'
3739                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 10 THEN 1 END
3740                            ) / COUNT(
3741                                CASE WHEN q.issue_date IS NOT NULL
3742                                THEN 1 END
3743                            ) * 100 AS percentageOfacceptanceLessThan10,
3744                            COUNT(
3745                                CASE WHEN q.acceptance_date IS NOT NULL
3746                                AND {$whereAcceptanceDate}
3747                                AND bs.name = 'Aceptado'
3748                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 10
3749                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 30 THEN 1 END
3750                            ) / COUNT(
3751                                CASE WHEN q.issue_date IS NOT NULL
3752                                THEN 1 END
3753                            ) * 100 AS percentageOfacceptanceLessThan30,
3754                            COUNT(
3755                                CASE WHEN q.acceptance_date IS NOT NULL
3756                                AND {$whereAcceptanceDate}
3757                                AND bs.name = 'Aceptado'
3758                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 30 THEN 1 END
3759                            ) / COUNT(
3760                                CASE WHEN q.issue_date IS NOT NULL
3761                                THEN 1 END
3762                            ) * 100 AS percentageOfacceptanceMoreThan30,
3763                            COUNT(CASE WHEN {$whereAcceptanceDate} THEN 1 END) / COUNT(
3764                                CASE WHEN q.issue_date IS NOT NULL
3765                                THEN 1 END
3766                            ) * 100 acceptedPercentage,
3767                            COALESCE(
3768                                AVG(
3769                                    CASE WHEN q.issue_date IS NOT NULL
3770                                    AND q.acceptance_date IS NOT NULL
3771                                    AND {$whereAcceptanceDate}
3772                                    AND bs.name = 'Aceptado'
3773                                    THEN DATEDIFF(q.acceptance_date, q.issue_date) ELSE NULL END
3774                                ), 0
3775                            )
3776                            AS averageAcceptedDuration,
3777                            COALESCE(
3778                                AVG(
3779                                    CASE WHEN q.issue_date IS NOT NULL
3780                                    AND q.request_date IS NOT NULL
3781                                    AND q.issue_date > q.request_date
3782                                    THEN DATEDIFF(q.issue_date, q.request_date) ELSE NULL END
3783                                ), 0
3784                            )
3785                            AS averageRequestedDays
3786                        FROM
3787                            tbl_quotations q
3788                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3789                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3790                        WHERE
3791                            q.issue_date IS NOT NULL
3792                            AND q.budget_type_id != 7
3793                            AND q.budget_type_id IS NOT NULL
3794                            AND q.for_add != 1
3795                            {$where}
3796                            {$whereYear}
3797                        GROUP BY
3798                            YEAR(q.issue_date),
3799                            bt.name WITH ROLLUP";
3800
3801            $value = Cache::get(base64_encode($query));
3802
3803            if(!$value){
3804                $result = DB::select($query);
3805
3806                Cache::put(base64_encode($query), $result, 600);
3807            }else{
3808                $result = $value;
3809            }
3810
3811            $typesBudgets = array();
3812            $typesBudgetsTotals = array();
3813
3814            if(count($result) > 0){
3815                for ($i = 0; $i < count($result); $i++) {
3816
3817                    if($result[$i]->year == null && $result[$i]->name == null){
3818                        $result[$i]->name = "totalGeneral";
3819                        $typesBudgetsTotals["totalGeneral"] = $result[$i];
3820                        continue;
3821                    }elseif($result[$i]->name == null && $result[$i]->year != null){
3822                        if(count($data['years']) > 0 || $whereYear == ""){
3823                            $result[$i]->name = "totalSub";
3824                        }else{
3825                            continue;
3826                        }
3827                    }
3828
3829                    $typesBudgets[$result[$i]->year][$result[$i]->name] = $result[$i];
3830                }
3831            }
3832
3833            return response([
3834                'message' => 'OK',
3835                'data' => $typesBudgets,
3836                'totals' => $typesBudgetsTotals
3837            ]);
3838
3839        } catch (\Exception $e) {
3840            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3841        }
3842    }
3843
3844    function download_quotations(Request $request){
3845        ini_set('max_execution_time', 123456);
3846        $data = $request->all();
3847        $companyId = addslashes($data['company_id']);
3848        $userId = addslashes($data['user_id']);
3849
3850        $where = "";
3851
3852        $query = "SELECT
3853                b.name
3854            FROM tbl_users a
3855            LEFT JOIN tbl_roles b
3856                ON a.role_id = b.role_id
3857            WHERE a.id = {$userId}";
3858
3859        $role = DB::select($query);
3860
3861        $r = new Request([
3862            'filterModel' => $data['filterModel'],
3863            'sortModel' => $data['sortModel'],
3864            'start' => 0,
3865            'end' => 999999999,
3866            'company_id' => $data['company_id'],
3867            'user_id' => $data['user_id'],
3868            'ids' => $data['ids'],
3869            'searchText' => $data['searchText'],
3870            'ids_not_in' => $data['ids_not_in']
3871        ]);
3872
3873        $result = $this->list_quotations($r);
3874
3875        $spreadsheet = new Spreadsheet();
3876        $worksheet   = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, "Inputs");
3877        $spreadsheet->addSheet($worksheet, 0);
3878        $col         = range('A', 'Z');
3879
3880        for($i = 0; $i < 26; $i++){
3881            $worksheet->getColumnDimension($col[$i])->setAutoSize(true);
3882            if($i != 1){
3883                $worksheet->getStyle($col[$i])
3884                    ->getAlignment()
3885                    ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
3886            }
3887        }
3888
3889        $worksheet->getColumnDimension("AB")->setAutoSize(true);
3890        $worksheet->getStyle("AB")
3891            ->getAlignment()
3892            ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
3893
3894        $l = 1;
3895        $worksheet->setCellValue('A' . $l, __('language.ID'));
3896        $worksheet->setCellValue('B' . $l, __('language.INTERNAL_ID'));
3897        $worksheet->setCellValue('C' . $l, __('language.CLIENT'));
3898        $worksheet->setCellValue('D' . $l, __('language.AMOUNT'));
3899        $worksheet->setCellValue('E' . $l, __('language.INVOICE_MARGIN'));
3900        $worksheet->setCellValue('F' . $l, __('language.MARGIN_FOR_THE_COMPANY'));
3901        $worksheet->setCellValue('G' . $l, __('language.TYPE'));
3902        $worksheet->setCellValue('H' . $l, __('language.STATUS'));
3903        $worksheet->setCellValue('I' . $l, __('language.CREATED_BY'));
3904        $worksheet->setCellValue('J' . $l, __('language.COMMERCIAL'));
3905        $worksheet->setCellValue('K' . $l, __('language.CREATED_AT'));
3906        $worksheet->setCellValue('L' . $l, __('language.ACCEPTANCE_DATE'));
3907        $worksheet->setCellValue('M' . $l, __('language.REQUEST_DATE'));
3908        $worksheet->setCellValue('N' . $l, __('language.ISSUE_DATE'));
3909        $worksheet->setCellValue('O' . $l, __('language.DURATION'));
3910        $worksheet->setCellValue('P' . $l, __('language.CLIENT_TYPE'));
3911        $worksheet->setCellValue('Q' . $l, __('language.SEGMENT'));
3912        $worksheet->setCellValue('R' . $l, __('language.LIKEHOOD'));
3913        $worksheet->setCellValue('S' . $l, __('language.SOURCE'));
3914        $worksheet->setCellValue('T' . $l, __('language.LAST_FOLLOW_UP_DATE'));
3915        $worksheet->setCellValue('U' . $l, __('language.REASON_FOR_NOT_FOLLOWING_UP'));
3916        $worksheet->setCellValue('V' . $l, __('language.REASON_FOR_REJECTION'));
3917        $worksheet->setCellValue('W' . $l, __('language.EMAIL'));
3918        $worksheet->setCellValue('X' . $l, __('language.EMAIL_STATUS'));
3919        $worksheet->setCellValue('Y' . $l, __('language.PHONE_NUMBER'));
3920        $worksheet->setCellValue('Z' . $l, __('language.ORDER_NUMBER'));
3921        $worksheet->setCellValue('AA' . $l, __('language.BOX_WORK_G3W'));
3922        $worksheet->setCellValue('AB' . $l, __('language.APPROVAL_REQUIRED'));
3923        $worksheet->setCellValue('AC' . $l, __('language.FILES_COUNT'));
3924        $worksheet->setCellValue('AD' . $l, __('language.ACCEPTED_BY'));
3925        $worksheet->setCellValue('AE' . $l, __('language.ACCEPTED_AT'));
3926        $worksheet->setCellValue('AF' . $l, "Origen");
3927        $worksheet->setCellValue('AG' . $l, "Origen Edit");
3928        $worksheet->setCellValue('AH' . $l, __('language.G3W_WARNING'));
3929        $worksheet->setCellValue('AI' . $l, __('language.COMPANY_NAME'));
3930
3931        $styleArray = [
3932            'font' => [
3933                'bold' => true,
3934            ]
3935        ];
3936
3937        $worksheet->getStyle('A1:AH1')
3938            ->getFill()
3939            ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
3940            ->getStartColor()
3941            ->setARGB('523779');
3942
3943        $worksheet->getStyle('A1:AH1')
3944            ->getFont()
3945            ->getColor()
3946            ->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
3947
3948        $worksheet->getStyle('A1:AH1')->applyFromArray($styleArray);
3949
3950        $l = 2;
3951        $result = $result->original['data'];
3952
3953        for ($i = 0; $i < count($result); $i++) {
3954
3955            if($result[$i]->request_date){
3956                $result[$i]->request_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->request_date);
3957            }
3958
3959            if($result[$i]->issue_date){
3960                $result[$i]->issue_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->issue_date);
3961            }
3962
3963            if($result[$i]->acceptance_date){
3964                $result[$i]->acceptance_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->acceptance_date);
3965            }
3966
3967            if($result[$i]->last_follow_up_date){
3968                $result[$i]->last_follow_up_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->last_follow_up_date);
3969            }
3970
3971            if($result[$i]->created_at){
3972                $result[$i]->created_at = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->created_at);
3973            }
3974
3975            if($result[$i]->accepted_at){
3976                $result[$i]->accepted_at = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->accepted_at);
3977            }
3978
3979            $worksheet->setCellValue('A' . $l, $result[$i]->quote_id);
3980            $worksheet->setCellValue('B' . $l, $result[$i]->internal_quote_id);
3981            $worksheet->setCellValue('C' . $l, $result[$i]->client);
3982            $worksheet->setCellValue('D' . $l, $result[$i]->amount);
3983            $worksheet->setCellValue('E' . $l, $result[$i]->invoice_margin);
3984            $worksheet->setCellValue('F' . $l, $result[$i]->margin_for_the_company);
3985            $worksheet->setCellValue('G' . $l, $result[$i]->type);
3986            $worksheet->setCellValue('H' . $l, $result[$i]->status);
3987            $worksheet->setCellValue('I' . $l, $result[$i]->created_by);
3988            $worksheet->setCellValue('J' . $l, $result[$i]->commercial);
3989            $worksheet->setCellValue('K' . $l, $result[$i]->created_at);
3990
3991            $worksheet->getStyle('K' . $l)
3992                ->getNumberFormat()
3993                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
3994
3995            $worksheet->setCellValue('L' . $l, $result[$i]->acceptance_date);
3996
3997            $worksheet->getStyle('L' . $l)
3998                ->getNumberFormat()
3999                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4000
4001            $worksheet->setCellValue('M' . $l, $result[$i]->request_date);
4002
4003            $worksheet->getStyle('M' . $l)
4004                ->getNumberFormat()
4005                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4006
4007            $worksheet->setCellValue('N' . $l, $result[$i]->issue_date);
4008
4009            $worksheet->getStyle('N' . $l)
4010                ->getNumberFormat()
4011                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4012
4013            $worksheet->setCellValue('O' . $l, '=DATEDIF(J'.$l.',K'.$l.',"d")');
4014            $worksheet->setCellValue('P' . $l, $result[$i]->client_type);
4015            $worksheet->setCellValue('Q' . $l, $result[$i]->segment);
4016            $worksheet->setCellValue('R' . $l, $result[$i]->likehood);
4017            $worksheet->setCellValue('S' . $l, $result[$i]->source);
4018            $worksheet->setCellValue('T' . $l, $result[$i]->last_follow_up_date);
4019
4020            $worksheet->getStyle('T' . $l)
4021                ->getNumberFormat()
4022                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4023
4024            $worksheet->setCellValue('U' . $l, $result[$i]->reason_for_not_following_up);
4025            $worksheet->setCellValue('V' . $l, $result[$i]->reason_for_rejection);
4026            $worksheet->setCellValue('W' . $l, $result[$i]->email);
4027            $worksheet->setCellValue('X' . $l, $result[$i]->x_status);
4028            $worksheet->setCellValue('Y' . $l, $result[$i]->phone_number);
4029            $worksheet->setCellValue('Z' . $l, $result[$i]->order_number);
4030            $worksheet->setCellValue('AA' . $l, $result[$i]->box_work_g3w);
4031            $worksheet->setCellValue('AB' . $l, ($result[$i]->for_approval == 1 || $result[$i]->for_approval == 3) ? __('language.YES') : __('language.NO'));
4032            $worksheet->setCellValue('AC' . $l, $result[$i]->has_attachment == 1 ? __('language.YES') : __('language.NO'));
4033            $worksheet->setCellValue('AD' . $l, $result[$i]->accepted_by);
4034            $worksheet->setCellValue('AE' . $l, $result[$i]->accepted_at);
4035
4036            $worksheet->getStyle('AE' . $l)
4037                ->getNumberFormat()
4038                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4039
4040            $worksheet->setCellValue('AF' . $l, $result[$i]->sync_import == 1 ? 'G3W' : 'Manual');
4041            $worksheet->setCellValue('AG' . $l, $result[$i]->sync_import_edited == 1 ? 'G3W' : 'Manual');
4042            $worksheet->setCellValue('AH' . $l, $result[$i]->g3w_warning == 1 ? 'Sí' : 'No');
4043            $worksheet->setCellValue('AI' . $l, $result[$i]->company_name);
4044            $l++;
4045
4046        }
4047
4048        if($role[0]->name == 'Regular'){
4049            $worksheet->removeColumn('D');
4050            $worksheet->removeColumn('W');
4051            $worksheet->removeColumn('X');
4052        }
4053
4054        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
4055        ob_start();
4056        $writer->save('php://output');
4057        $file = ob_get_contents();
4058        ob_end_clean();
4059
4060        return response($file);
4061    }
4062
4063    function bulk_upload(Request $request){
4064
4065        try {
4066
4067            $data = $request->all();
4068            $file = $request->file('file');
4069            $exte = 'Xlsx';
4070            $companyId = $data['company_id'];
4071
4072            if($file->getMimeType() == 'application/vnd.ms-excel'){
4073                $exte = 'Xls';
4074            }
4075
4076            $destination_path = env('BULK_UPLOAD_FILE_DESTINATION', 'E:/bulk_upload/');
4077            $filename         = $file->getClientOriginalName();
4078
4079            if(file_exists($destination_path . $filename)){
4080                $filename = pathinfo($filename, PATHINFO_FILENAME) . '-' . uniqid() . '.' . pathinfo($filename, PATHINFO_EXTENSION);
4081            }
4082
4083            $file->move($destination_path, $filename);
4084
4085            TblBulkUpload::create(
4086                array(
4087                    'company_id' => $companyId,
4088                    'filename' => $filename,
4089                    'status' => 'Uploading...',
4090                    'is_running' => 1,
4091                    'uploaded_by' => $data['created_by']
4092                )
4093            );
4094
4095            $command = "php BulkUploadQuotations.php '{$data['created_by']}' '{$exte}' '{$destination_path}' '{$filename}{$companyId}";
4096            exec($command . ' > /dev/null &');
4097
4098            $query = "";
4099            $isRunning = 0;
4100
4101            if($companyId == 0){
4102                $query = "SELECT * FROM tbl_bulk_upload ORDER BY started_at DESC";
4103                $isRunning = TblBulkUpload::where('is_running', 1)->count();
4104            }else{
4105                $query = "SELECT * FROM tbl_bulk_upload WHERE company_id = {$companyId} ORDER BY started_at DESC";
4106                $isRunning = TblBulkUpload::where('is_running', 1)->where('company_id', $companyId)->count();
4107            }
4108
4109            $result = DB::select($query);
4110
4111            return response(['message' => 'OK', 'data' => $result, 'is_running' => $isRunning]);
4112
4113        } catch (\Exception $e) {
4114            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4115        }
4116    }
4117
4118    function list_bulk_upload($companyId){
4119
4120        try {
4121
4122            $companyId = addslashes($companyId);
4123            $query = "";
4124            $isRunning = 0;
4125
4126            if($companyId == 0){
4127                $query = "SELECT * FROM tbl_bulk_upload ORDER BY started_at DESC";
4128                $isRunning = TblBulkUpload::where('is_running', 1)->count();
4129            }else{
4130                $query = "SELECT * FROM tbl_bulk_upload WHERE company_id = {$companyId} ORDER BY started_at DESC";
4131                $isRunning = TblBulkUpload::where('is_running', 1)->where('company_id', $companyId)->count();
4132            }
4133
4134            $result = DB::select($query);
4135
4136            return response(['message' => 'OK', 'data' => $result, 'is_running' => $isRunning]);
4137
4138        } catch (\Exception $e) {
4139            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4140        }
4141
4142    }
4143
4144    function delete_number(Request $request, $id){
4145
4146        try {
4147
4148            $id = addslashes($id);
4149            $data = $request->all();
4150
4151            $r = TblQuotations::where('id', $id)->first();
4152            $updatedAt = date('Y-m-d H:i:s');
4153            $query = "INSERT INTO tbl_quotations_deleted (id, quote_id, company_id, for_add, created_by, updated_by, updated_at)
4154                        SELECT id, quote_id, company_id, 1, created_by, '{$data['updated_by']}', '{$updatedAt}' FROM tbl_quotations WHERE id = {$id}";
4155
4156            DB::select($query);
4157
4158            TblQuotations::where('id', $id)->delete();
4159
4160            $latestBudget = TblQuotations::where('company_id', $r->company_id)->orderByRaw('id DESC')->pluck('quote_id')->first();
4161
4162            $query = "UPDATE tbl_companies SET last_id = '{$latestBudget}' WHERE company_id = {$r->company_id}";
4163            DB::select($query);
4164
4165            return response(['message' => 'OK']);
4166
4167        } catch (\Exception $e) {
4168            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4169        }
4170
4171    }
4172
4173    function get_number(Request $request, $companyId, $n = null){
4174
4175        try {
4176
4177            $companyId = addslashes($companyId);
4178            $data = $request->all();
4179            $latestBudget = array();
4180            $number = 0;
4181            $beforeLastId = null;
4182
4183            $x = true;
4184
4185            if($companyId == 0){
4186                $latestBudget = TblQuotations::orderByRaw('CAST(quote_id AS DOUBLE) DESC')->pluck('quote_id')->first();
4187            }else{
4188                $latestBudget = TblCompanies::where('company_id', $companyId)->pluck('last_id')->first();
4189
4190                if($latestBudget == null){
4191                    $latestBudget = TblQuotations::where('company_id', $companyId)->orderByRaw('id DESC')->pluck('quote_id')->first();
4192                    $beforeLastId = $latestBudget;
4193                }
4194            }
4195
4196            $number = $latestBudget;
4197
4198            while ($x) {
4199
4200                if(is_numeric(substr($number, -1))) {
4201                    $number++;
4202                }else{
4203                    $number .= "1";
4204                }
4205
4206                $check = 0;
4207
4208                if($companyId == 0){
4209                    $check = TblQuotations::where('quote_id', (string) $number)->count();
4210                }else{
4211                    $check = TblQuotations::where('company_id', $companyId)->where('quote_id', (string) $number)->count();
4212                }
4213
4214                if($check == 0){
4215                    $x = false;
4216                }
4217            }
4218
4219            $result = null;
4220
4221            if($n == null){
4222                $result = TblQuotations::create(array('quote_id' => $number, 'company_id' => $companyId, 'for_add' => 1, 'created_by' => $data['created_by']));
4223            }
4224
4225            if($beforeLastId == null){
4226                $beforeLastId = $number;
4227            }
4228
4229            $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}";
4230            DB::select($query);
4231
4232            return response([
4233                'message' => 'OK',
4234                'number' => $number,
4235                'id' => ($result !=  null) ? $result->id : null
4236            ]);
4237
4238
4239        } catch (\Exception $e) {
4240            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4241        }
4242
4243    }
4244
4245    function get_years(Request $request){
4246
4247        try {
4248
4249            $data = $request->all();
4250            $companyId = addslashes($data['company_id']);
4251            $where = "";
4252
4253            if($companyId != 0){
4254                $where = " AND company_id = {$companyId} ";
4255            }else{
4256                $where = " AND company_id IN ({$this->companyId}";
4257            }
4258
4259            $query = "SELECT
4260                        CONCAT(
4261                            DATE_FORMAT((SELECT MIN(issue_date) FROM tbl_quotations WHERE issue_date IS NOT NULL {$where}), '%c/%e/'), YEAR(issue_date),
4262                            ' - ',
4263                            DATE_FORMAT((SELECT MAX(issue_date) FROM tbl_quotations WHERE issue_date IS NOT NULL {$where}), '%c/%e/'), YEAR(issue_date)
4264                        ) AS date_like,
4265                        YEAR(issue_date) 'year'
4266                        FROM tbl_quotations
4267                        WHERE issue_date IS NOT NULL {$where}
4268                        GROUP BY YEAR(issue_date)
4269                        ORDER BY YEAR(issue_date) DESC";
4270
4271            $issueDate = DB::select($query);
4272
4273            $query = "SELECT
4274                        CONCAT(
4275                            DATE_FORMAT((SELECT MIN(created_at) FROM tbl_quotations WHERE created_at IS NOT NULL {$where}), '%c/%e/'), YEAR(created_at),
4276                            ' - ',
4277                            DATE_FORMAT((SELECT MAX(created_at) FROM tbl_quotations WHERE created_at IS NOT NULL {$where}), '%c/%e/'), YEAR(created_at)
4278                        ) AS date_like,
4279                        YEAR(created_at) 'year'
4280                        FROM tbl_quotations
4281                        WHERE created_at IS NOT NULL {$where}
4282                        GROUP BY YEAR(created_at)
4283                        ORDER BY YEAR(created_at) DESC";
4284
4285            $createdAt = DB::select($query);
4286
4287            $query = "SELECT
4288                        CONCAT(
4289                            DATE_FORMAT((SELECT MIN(acceptance_date) FROM tbl_quotations WHERE acceptance_date IS NOT NULL {$where}), '%c/%e/'), YEAR(acceptance_date),
4290                            ' - ',
4291                            DATE_FORMAT((SELECT MAX(acceptance_date) FROM tbl_quotations WHERE acceptance_date IS NOT NULL {$where}), '%c/%e/'), YEAR(acceptance_date)
4292                        ) AS date_like,
4293                        YEAR(acceptance_date) 'year'
4294                        FROM tbl_quotations
4295                        WHERE acceptance_date IS NOT NULL {$where}
4296                        GROUP BY YEAR(acceptance_date)
4297                        ORDER BY YEAR(acceptance_date) DESC";
4298
4299            $acceptanceDate = DB::select($query);
4300
4301            return response([
4302                'message' => 'OK',
4303                'data' => $issueDate,
4304                'created_at' => $createdAt,
4305                'acceptance_date' => $acceptanceDate
4306            ]);
4307
4308
4309        } catch (\Exception $e) {
4310            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4311        }
4312
4313    }
4314
4315    function human_filesize($bytes, $decimals = 2) {
4316        $size = ['B', 'KB', 'MB'];
4317
4318        $factor = floor((strlen($bytes) - 1) / 3);
4319        return number_format($bytes / pow(1024, $factor), 2, ',', '.') . $size[$factor];
4320    }
4321
4322    function get_files($quoteId){
4323
4324        try {
4325
4326            $quoteId = addslashes($quoteId);
4327
4328            $quoteId = (int)$quoteId;
4329            $query = "
4330            SELECT
4331                file_id,
4332                quotation_id,
4333                quote_id,
4334                original_name,
4335                filename,
4336                uploaded_by,
4337                uploaded_at,
4338                is_internal,
4339                file_size,
4340                file_hash,
4341                mime_type
4342            FROM tbl_files
4343            WHERE quotation_id = ?
4344            AND is_internal IS NULL";
4345
4346            $result = DB::select($query, [$quoteId]);
4347
4348            foreach ($result as $file) {
4349                if($file->file_size > 0) {
4350                    $file->filesize = $this->human_filesize($file->file_size);
4351                } else {            
4352                    $path = "uploads/" . $file->filename;
4353
4354                    if (Storage::disk('s3')->exists($path)) {
4355                        $fileSizeBytes = Storage::disk('s3')->size($path);
4356                    } else {
4357                        $fileSizeBytes = 0;
4358                    }
4359
4360                    $file->filesize = $this->human_filesize($fileSizeBytes);
4361                }
4362
4363                $file->original_name = $file->original_name . " ({$file->filesize})";
4364            }
4365
4366            $query = "
4367            SELECT
4368                file_id,
4369                quotation_id,
4370                quote_id,
4371                original_name,
4372                filename,
4373                uploaded_by,
4374                uploaded_at,
4375                is_internal,
4376                file_size,
4377                file_hash,
4378                mime_type
4379            FROM tbl_files
4380            WHERE quotation_id = ?
4381            AND is_internal = 1";
4382
4383            $internal = DB::select($query, [$quoteId]);
4384
4385            foreach ($internal as $file) {
4386                if($file->file_size > 0) {
4387                    $file->filesize = $this->human_filesize($file->file_size);
4388                } else {
4389                    $path = "uploads/" . $file->filename;
4390
4391                    if (Storage::disk('s3')->exists($path)) {
4392                        $fileSizeBytes = Storage::disk('s3')->size($path);
4393                    } else {
4394                        $fileSizeBytes = 0;
4395                    }
4396
4397                    $file->filesize = $this->human_filesize($fileSizeBytes);
4398                }
4399
4400                $file->original_name = $file->original_name . " ({$file->filesize})";
4401            }
4402
4403            $job = TblOngoingJobs::where('quotation_id', $quoteId)->first();
4404            $order = TblQuotations::where('id', $quoteId)->first();
4405
4406            $emails = explode(",", str_replace(" ", "", $order->email));
4407
4408            $sendGrid = TblSendgridWebhook::where('quotation_id', $quoteId)->where('x_message_id', $order->x_message_id)->first();
4409
4410            $uniqueEvents = array();
4411            $currentEvents = array();
4412            $status = 2;
4413
4414            $xStatus = "processed";
4415
4416            if($sendGrid){
4417                $emailErrors = array('deferred', 'bounce', 'dropped', 'spamreport', 'invalid');
4418                $events = json_decode($sendGrid->json_body, true);
4419                $xMessageId = $sendGrid->x_message_id;
4420                $isDelivered = 0;
4421                $isProcessed = 0;
4422                $isError = 0;
4423
4424                foreach ($emails as $email) {
4425
4426                    $emailEvents = array_filter($events, fn($event) => strtolower($event['email']) === strtolower($email));
4427
4428                    $statuses = array_unique(array_column($emailEvents, 'event'));
4429                    $eventCount = count($statuses);
4430
4431                    if ($eventCount === 1 && in_array('processed', $statuses)) {
4432                        $xStatus = "processed";
4433                    }
4434
4435                    if ($eventCount == 2) {
4436                        if (in_array('processed', $statuses) && in_array('delivered', $statuses)) {
4437                            $xStatus = "delivered";
4438                        }
4439
4440                        foreach ($emailErrors as $e) {
4441                            if (in_array('processed', $statuses) && in_array($e, $statuses)) {
4442                                $xStatus = $e;
4443                            }
4444                        }
4445
4446                    }elseif($eventCount > 2){
4447                        if (in_array('processed', $statuses) && in_array('delivered', $statuses)) {
4448                            $xStatus = "delivered";
4449                        }
4450
4451                        if($xStatus != "delivered"){
4452                            foreach ($emailErrors as $e) {
4453                                if (in_array('processed', $statuses) && in_array($e, $statuses)) {
4454                                    $xStatus = $e;
4455                                }
4456                            }
4457                        }
4458                    }
4459
4460
4461                    if($xStatus == "processed"){
4462                        $isProcessed++;
4463                    }elseif($xStatus == "delivered"){
4464                        $isDelivered++;
4465                    }else{
4466                        $isError++;
4467                    }
4468
4469                    foreach ($emailEvents as $event) {
4470                        $key = strtolower($event['email']) . '|' . $event['event'];
4471                        if (!isset($uniqueEvents[$key])) {
4472                            $uniqueEvents[$key] = $event;
4473                        }
4474                    }
4475                }
4476
4477                if($uniqueEvents){
4478                    foreach (array_values($uniqueEvents) as $d) {
4479                        $d['created_at'] = date('Y-m-d H:i:s', $d['timestamp']);
4480
4481                        if(isset($d['response'])){
4482                            $d['error'] = $d['response'];
4483                        }
4484
4485                        if(isset($d['reason'])){
4486                            $d['error'] = $d['reason'];
4487                        }
4488
4489                        array_push($currentEvents, $d);
4490                    }
4491                }
4492
4493
4494
4495                if(count($emails) == $isDelivered){
4496                    $status = 1;
4497                    $xStatus = "Completed";
4498                }elseif($isProcessed > 0){
4499                    $status = 2;
4500                    $xStatus = "Processing";
4501                }elseif($isError > 0){
4502                    $status = 3;
4503
4504                    if($xStatus == "bounce"){
4505                        $xStatus = "Error - Bounce";
4506                    }else{
4507                        $xStatus = "Error";
4508                    }
4509                }
4510            }
4511
4512            $z = 0;
4513
4514            if($order->x_status != $xStatus){
4515                TblQuotations::where('id', $order->id)->update(
4516                    array(
4517                        'x_status' => $xStatus
4518                    )
4519                );
4520                $z = 1;
4521                Cache::flush();
4522            }
4523
4524            if(empty($currentEvents)){
4525                $status = 0;
4526            }
4527
4528            $followUpLogs = TblFollowUpLogs::where('quotation_id', $quoteId)->orderBy('created_at', 'desc')->get();
4529
4530            $projectTypes = TblProjectTypes::where('company_id', $order->company_id)->get();
4531
4532            $sendgridFollowUpLogs = array();
4533
4534            if($order->y_message_id){
4535                $sendgridFollowUpLogs = TblSendgridWebhook::where('x_message_id', $order->y_message_id)->first();
4536
4537                if($sendgridFollowUpLogs){
4538                    $sendgridFollowUpLogs = json_decode($sendgridFollowUpLogs->json_body, true);
4539                    foreach ($sendgridFollowUpLogs as &$item) {
4540                        $item['created_at'] = date("Y-m-d H:i:s", $item['timestamp']);
4541                    }
4542                }
4543            }
4544
4545            return response([
4546                'message' => 'OK',
4547                'data' => $result,
4548                'followUpLogs' => $followUpLogs,
4549                'sendgridFollowUpLogs' => $sendgridFollowUpLogs,
4550                'internal' => $internal,
4551                'projectTypes' => $projectTypes,
4552                'currentEvents' => array(
4553                    'status' => $status,
4554                    'email' => $currentEvents,
4555                    $uniqueEvents,
4556                    $xStatus
4557                ),
4558                'job' => $job,
4559                'isUpdated' => $z
4560            ]);
4561
4562        } catch (\Exception $e) {
4563            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4564        }
4565
4566    }
4567
4568    public function download_file($fileId) {
4569        try {
4570            $fileId = addslashes($fileId);
4571            $file = TblFiles::where('file_id', $fileId)->first();
4572
4573            if (!$file) {
4574                return response()->json([
4575                    'message' => 'KO',
4576                    'error' => 'Archivo no encontrado'
4577                ], 404);
4578            }
4579
4580            if (!is_null($file->file_hash) && !empty($file->file)) {
4581                $fileContent = $file->file;
4582                $mimeType = $file->mime_type ?? 'application/octet-stream';
4583                $filename = $file->original_name ?? $file->filename ?? 'download';
4584
4585                return response($fileContent)
4586                    ->header('Content-Type', $mimeType)
4587                    ->header('Content-Disposition', 'attachment; filename="' . $filename . '"')
4588                    ->header('Content-Length', strlen($fileContent))
4589                    ->header('Cache-Control', 'no-cache, no-store, must-revalidate');
4590
4591            }
4592            else {
4593                $filePath = Storage::disk('s3')->get("uploads/" . $file->filename);
4594                // $filePath = storage_path('app/public/uploads/' . $file->filename);                
4595
4596                if (!Storage::disk('s3')->exists("uploads/" . $file->filename)) {
4597                    return response()->json([
4598                        'message' => 'KO',
4599                        'error' => 'Archivo físico no encontrado: ' . $file->filename
4600                    ], 404);
4601                }
4602
4603                $fileSize = filesize($filePath);
4604                $mimeType = mime_content_type($filePath) ?: 'application/octet-stream';
4605                $filename = $file->original_name ?? $file->filename;
4606
4607                $fileContent = file_get_contents($filePath);
4608
4609                return response($fileContent)
4610                    ->header('Content-Type', $mimeType)
4611                    ->header('Content-Disposition', 'attachment; filename="' . $filename . '"')
4612                    ->header('Content-Length', $fileSize)
4613                    ->header('Cache-Control', 'no-cache, no-store, must-revalidate');
4614            }
4615
4616        } catch (\Exception $e) {
4617            \Log::error('Error downloading file: ' . $e->getMessage());
4618            return response()->json([
4619                'message' => 'KO',
4620                'error' => 'Error interno del servidor: ' . $e->getMessage()
4621            ], 500);
4622        }
4623    }
4624
4625    function delete_file($fileId){
4626
4627        try {
4628
4629            $fileId = addslashes($fileId);
4630            $file = TblFiles::where('file_id', $fileId)->first();
4631            $result = TblFiles::where('file_id', $fileId)->first();
4632
4633            if($result){
4634                TblFiles::where('file_id', $fileId)->delete();
4635                $path = storage_path('app/public/uploads/' . $result->filename);
4636                Storage::disk('public')->delete('uploads/' . $result->filename);
4637
4638                if(!env('SENDGRID_STAGING')){
4639                    Storage::disk('s3')->delete('uploads/' . $result->filename);
4640                }
4641            }
4642
4643            $fileCount = TblFiles::where('quotation_id', $file->quotation_id)->count();
4644            $data = array();
4645            if($fileCount > 0){
4646                $data['has_attachment'] = 1;
4647            }else{
4648                $data['has_attachment'] = 0;
4649            }
4650
4651            TblQuotations::where('quote_id', $file->quote_id)->update($data);
4652
4653            return response(['message' => 'OK']);
4654
4655        } catch (\Exception $e) {
4656            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4657        }
4658    }
4659
4660    function send_email_to_client(Request $request){
4661
4662        try {
4663
4664            $data = $request->all();
4665
4666            // $id = addslashes($data['id']);
4667            $userId = addslashes($data['user_id']);
4668            $companyId = addslashes($data['company_id']);
4669
4670            $isResend = null;
4671
4672            if(isset($data['is_resend'])){
4673                $isResend = 1;
4674                unset($data['is_resend']);
4675            }
4676
4677            // $result = TblQuotations::where('id', $id)->first();
4678
4679            $where = "";
4680            $emailTemplateId = addslashes($data['email_template_id']);
4681            unset($data['email_template_id']);
4682
4683            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
4684            $limit = 0;
4685
4686            if($companyId == 0){
4687                $limit = 20;
4688            }else{
4689                $emailCompany = TblCompanies::where('company_id', $companyId)->first();
4690
4691                if($emailCompany->limit_send != null){
4692                    $limit = $emailCompany->limit_send;
4693                }
4694            }
4695
4696            if(isset($data['ids']) && count($data['ids']) > 0){
4697                $quoteIds = implode(",", $data['ids']);
4698                $where = " a.id IN ({$quoteIds}) AND ";
4699            }
4700
4701            if(isset($data['ids_not_in']) && count($data['ids_not_in']) > 0){
4702                $quoteIds = implode(",", $data['ids_not_in']);
4703                $where = " a.id NOT IN ({$quoteIds}) AND ";
4704            }
4705
4706            $r = new Request([
4707                'filterModel' => $data['filterModel'],
4708                'sortModel' => $data['sortModel'],
4709                'start' => 0,
4710                'end' => 999999999,
4711                'company_id' => $data['company_id'],
4712                'user_id' => $data['user_id'],
4713                'ids' => $data['ids'],
4714                'searchText' => $data['searchText'],
4715                'ids_not_in' => $data['ids_not_in']
4716            ]);
4717
4718            $listQuotations = $this->list_quotations($r);
4719            $d = $listQuotations->original['data'];
4720            $result = array();
4721
4722            for ($i = 0; $i < count($d); $i++) {
4723                if($d[$i]->email != null
4724                    && ($d[$i]->budget_status_id == 11 || $isResend == 1)
4725                ){
4726                    array_push($result, $d[$i]);
4727                }
4728            }
4729
4730            if(count($result) == 0){
4731                return response(['message' => 'OK', $d]);
4732            }
4733
4734            $user   = TblUsers::where('id', $userId)->first();
4735            $error  = false;
4736
4737            $availableParameters = [
4738                'quote_id',
4739                'company_id',
4740                'client',
4741                'client_type',
4742                'phone_number',
4743                'email',
4744                'issue_date',
4745                'request_date',
4746                'duration',
4747                'invoice_number',
4748                'type',
4749                'acceptance_date',
4750                'status',
4751                'source',
4752                'amount',
4753                'reason_for_not_following_up',
4754                'last_follow_up_date',
4755                'last_follow_up_comment',
4756                'reason_for_rejection_id',
4757                'reason_for_rejection',
4758                'commercial',
4759                'created_at',
4760                'created_by',
4761                'updated_at',
4762                'updated_by'
4763            ];
4764
4765            $dateParameters = [
4766                'issue_date',
4767                'request_date',
4768                'acceptance_date',
4769                'last_follow_up_date',
4770                'created_at',
4771                'updated_at',
4772            ];
4773
4774            if($this->locale == 'es'){
4775                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
4776            }
4777
4778            if($this->locale == 'es'){
4779                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
4780            }
4781
4782            for ($i = 0; $i < count($result); $i++) {
4783
4784                $body = $emailTemplate->html;
4785                if(isset($data['html'])){
4786                    $body = $data['html'];
4787                }
4788                $subject = $emailTemplate->subject;
4789                $commercialUser = $result[$i]->commercial;
4790
4791                if($result[$i]->email != null){
4792
4793                    if(env('SENDGRID_STAGING')){
4794                        $toEmail = $user->email;
4795                    }else{
4796                        $toEmail = $result[$i]->email;
4797                    }
4798
4799                    preg_match_all('/{{(.*?)}}/', $body, $matches);
4800
4801                    $parameters = $matches[1];
4802
4803                    foreach ($parameters as $parameter) {
4804
4805                        if(in_array($parameter, $dateParameters)){
4806                            if($result[$i]->{$parameter}){
4807                                $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
4808                            }
4809                        }
4810
4811                        if(in_array($parameter, $availableParameters)){
4812                            $body = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $body);
4813                        }
4814                    }
4815
4816                    preg_match_all('/{{(.*?)}}/', $subject, $matches);
4817
4818                    $parameters = $matches[1];
4819
4820                    foreach ($parameters as $parameter) {
4821
4822                        if(in_array($parameter, $dateParameters)){
4823                            if($result[$i]->{$parameter}){
4824                                $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
4825                            }
4826                        }
4827
4828                        if(in_array($parameter, $availableParameters)){
4829                            $subject = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $subject);
4830                        }
4831                    }
4832
4833                    $email = new \SendGrid\Mail\Mail();
4834
4835                    // $imgpath = \File::get('fireservicetitan.png');
4836                    // $base64 = "data:image/png;base64,".base64_encode($imgpath);
4837                    // $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
4838
4839                    // $email->addAttachment(
4840                    //     $imgpath,
4841                    //     "image/png",
4842                    //     "fireservicetitan.png",
4843                    //     "inline",
4844                    //     "fireservicetitan"
4845                    // );
4846
4847                    $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
4848
4849                    foreach ($templateFiles as $item) {
4850                        $f = storage_path('app/public/uploads/' . $item->filename);
4851
4852                        if (file_exists($f)) {
4853                            $imgpath = file_get_contents($f);
4854                            $base64 = "data:image/png;base64," . base64_encode($imgpath);
4855                            $mimeType = mime_content_type($f);
4856
4857                            $email->addAttachment(
4858                                $imgpath,
4859                                $mimeType,
4860                                str_replace(' ', '', $item->original_name),
4861                                "inline",
4862                                str_replace(' ', '', $item->original_name),
4863                            );
4864
4865                            $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
4866                        } else {
4867                            Log::channel('email_failed_log')->error("File not found: " . $f);
4868                        }
4869                    }
4870
4871                    $html = '<!DOCTYPE html>';
4872                    $html .= '<html>';
4873                    $html .= '<head>';
4874                    $html .= '<meta charset="UTF-8">';
4875                    $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
4876                    $html .= '</head>';
4877                    $html .= '<body>';
4878                    $html .= $body;
4879                    $html .= '</body>';
4880                    $html .= '</html>';
4881
4882                    if($toEmail != null){
4883
4884                        $toEmail = explode(",", $toEmail);
4885                        $toEmail = array_map('trim', $toEmail);
4886
4887                        $companyEmail = null;
4888
4889                        $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}'";
4890                        $commercialEmail = DB::select($queryUsers);
4891
4892                        if(count($commercialEmail) > 0){
4893                            $companyEmail = $commercialEmail[0];
4894                        }else{
4895                            if($emailTemplate->from_id != null){
4896                                $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
4897                            }else{
4898                                $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result[$i]->company_id)->first();
4899                            }
4900                        }
4901
4902                        if(!$companyEmail){
4903                            return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
4904                        }
4905
4906                        $ccBcc = TblCcBcc::where('company_id', $result[$i]->company_id)->get();
4907
4908                        $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
4909                        $email->setSubject($subject);
4910
4911                        foreach ($toEmail as $clientEmail) {
4912                            $isValid = $this->isEmailValid($clientEmail);
4913                            if($isValid){
4914                                $email->addTo($clientEmail);
4915                            }
4916                        }
4917
4918                        if(env('SENDGRID_STAGING')){
4919
4920                        }else{
4921                            if(!in_array($user->email, $toEmail)){
4922                                $email->addCc($user->email);
4923                            }
4924
4925                            if(count($ccBcc) > 0){
4926                                foreach ($ccBcc as $data) {
4927                                    if(!in_array($data->email, $toEmail) && $user->email != $data->email){
4928                                        $email->addBcc($data->email);
4929                                    }
4930                                }
4931                            }
4932                        }
4933
4934                        $email->addContent("text/html", $html);
4935
4936                        $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
4937
4938                        $files = TblFiles::where('quotation_id', $result[$i]->id)->where('is_internal', null)->get();
4939                        $requestSize = $this->calculateEmailRequestSize($email);
4940
4941                        foreach ($files as $key => $value) {
4942                            $fileContent = null;
4943                            $fileSize = 0;
4944                            $fileName = null;
4945
4946                            if (Storage::disk('s3')->exists("uploads/" . $files[$key]->filename)) {                                
4947                                $fileContent = Storage::disk('s3')->get("uploads/" . $files[$key]->filename);                                
4948                                $fileSize = (int) ceil(strlen($fileContent) / 1048576);                                
4949                                $fileName = $files[$key]->original_name;                                                            
4950                            }
4951                            else if ($files[$key]->file) {
4952                                $fileContent = $files[$key]->file;
4953
4954                                if (is_string($fileContent) && base64_decode($fileContent, true)) {
4955                                    $fileContent = base64_decode($fileContent);
4956                                }
4957
4958                                $fileSize = strlen($fileContent) / 1048576;
4959                                $fileSize = (int) ceil($fileSize);
4960                                $fileName = $files[$key]->original_name ?: $files[$key]->file_name ?: 'file';
4961                            }
4962
4963                            if ($fileContent && $fileSize > 0) {
4964                                if ($requestSize + $fileSize < 25) {
4965                                    $attachment = new \SendGrid\Mail\Attachment();
4966                                    $attachment->setFilename($fileName);
4967                                    $attachment->setDisposition("attachment");
4968
4969                                    $attachment->setContent(base64_encode($fileContent));
4970
4971                                    $email->addAttachment($attachment);
4972                                    $requestSize = $this->calculateEmailRequestSize($email);
4973                                }
4974                            }
4975                        }
4976
4977                        $response = $sendgrid->send($email);
4978                        if ($response->statusCode() == 202) {
4979                            $messageId = null;
4980
4981                            foreach ($response->headers() as $header) {
4982                                if (strpos(strtolower($header), 'x-message-id:') === 0) {
4983                                    $messageId = trim(substr($header, strpos($header, ':') + 1));
4984                                    break;
4985                                }
4986                            }
4987
4988                            $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;
4989                            $result[$i]->last_follow_up_comment = $result[$i]->last_follow_up_comment . "\n" . $comment;
4990
4991                            TblQuotations::where('id', $result[$i]->id)->update(
4992                                array(
4993                                    'last_follow_up_comment' => $result[$i]->last_follow_up_comment,
4994                                    'budget_status_id' => 2,
4995                                    'x_message_id' => $messageId,
4996                                    'x_status' => 'Processing',
4997                                    'updated_by' => $user->name,
4998                                    'updated_at' => date('Y-m-d H:i:s')
4999                                )
5000                            );
5001
5002                            $jsonBody = array();
5003
5004                            foreach ($toEmail as $clientEmail) {
5005                                $isValid = $this->isEmailValid($clientEmail);
5006                                $eventStatus = "processed";
5007                                $eventResponse = "";
5008                                if(!$isValid){
5009                                    $eventStatus = "invalid";
5010                                    $eventResponse = "Invalid email address";
5011                                }
5012
5013                                array_push(
5014                                    $jsonBody,
5015                                    array(
5016                                        'email' =>  $clientEmail,
5017                                        'event' => $eventStatus,
5018                                        'sg_message_id' => $messageId,
5019                                        'smtp-id' => $messageId,
5020                                        'timestamp' => strtotime(date('Y-m-d H:i:s')),
5021                                        'response' => $eventResponse
5022                                    )
5023                                );
5024                            }
5025
5026                            TblSendgridWebhook::create(
5027                                array(
5028                                    'quotation_id' => $result[$i]->id,
5029                                    'type' => 'sendToClient',
5030                                    'json_body' => json_encode($jsonBody),
5031                                    'x_message_id' => $messageId
5032                                )
5033                            );
5034
5035                            Log::channel('email_log')->info("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - EMAIL MANUALLY SENT');
5036                        } else {
5037                            $error = true;
5038                            Log::channel('email_failed_log')->error("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - ' . $response->body());
5039                        }
5040                    }
5041                }
5042            }
5043
5044            $this->update_commercial_numbers($companyId);
5045
5046            Cache::flush();
5047            return response(['message' => 'OK', $result]);
5048
5049        } catch (\Exception $e) {
5050            Log::channel('email_failed_log')->error($e->getMessage());
5051            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5052        }
5053
5054    }
5055
5056    function send_email_follow_ups(Request $request, $automaticSendLimit = null){
5057
5058        try {
5059
5060            $data = $request->all();
5061
5062            $startedAt = date('Y-m-d H:i:s');
5063            $toEmail = "";
5064            $userId = addslashes($data['user_id']);
5065            $companyId = addslashes($data['company_id']);
5066            $emailTemplateId = addslashes($data['email_template_id']);
5067            unset($data['email_template_id']);
5068
5069            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
5070            $limit = 0;
5071
5072            $blockedDomains = array();
5073            $workingDays = 10;
5074            $limitReminderEmails = 3;
5075
5076            if($companyId == 0){
5077                $limit = 20;
5078            }else{
5079                $emailCompany = TblCompanies::where('company_id', $companyId)->first();
5080                $workingDays = $emailCompany->last_follow_up_date ?? 10;
5081                $limitReminderEmails = $emailCompany->limit_reminder_emails ?? 3;
5082
5083                if($emailCompany->limit_send != null){
5084                    $limit = $emailCompany->limit_send;
5085                }
5086            }
5087
5088            $r = new Request([
5089                'filterModel' => $data['filterModel'],
5090                'sortModel' => $data['sortModel'],
5091                'start' => 0,
5092                'end' => 999999999,
5093                'company_id' => $data['company_id'],
5094                'user_id' => $data['user_id'],
5095                'ids' => $data['ids'],
5096                'searchText' => $data['searchText'],
5097                'ids_not_in' => $data['ids_not_in'],
5098                'last_follow_up_date' => 1
5099            ]);
5100
5101            $listQuotations = $this->list_quotations($r);
5102            $d = $listQuotations->original['data'];
5103            $result = array();
5104
5105            if($automaticSendLimit != null){
5106                $limit = $automaticSendLimit;
5107            }
5108
5109            $l = 0;
5110            for ($i = 0; $i < count($d); $i++) {
5111                if($d[$i]->email != null
5112                    && $d[$i]->budget_status_id == 2
5113                    && $d[$i]->reason_for_not_following_up_id == null
5114                    && $d[$i]->total_sent < $limitReminderEmails
5115                    && $d[$i]->last_follow_up_date != null
5116                    && $d[$i]->last_follow_up_date < date('Y-m-d H:i:s')
5117                    && $d[$i]->last_follow_up_date > 0
5118                ){
5119                    if($l == $limit){
5120                        break;
5121                    }
5122                    array_push($result, $d[$i]);
5123                    $l++;
5124                }
5125            }
5126
5127            if(count($result) == 0){
5128                return response(['message' => 'OK']);
5129            }
5130
5131            $user   = TblUsers::where('id', $userId)->first();
5132            $error  = false;
5133
5134            $sentBy = $user->name;
5135
5136            $availableParameters = [
5137                'quote_id',
5138                'company_id',
5139                'client',
5140                'client_type',
5141                'phone_number',
5142                'email',
5143                'issue_date',
5144                'request_date',
5145                'duration',
5146                'invoice_number',
5147                'type',
5148                'acceptance_date',
5149                'status',
5150                'source',
5151                'amount',
5152                'reason_for_not_following_up',
5153                'last_follow_up_date',
5154                'last_follow_up_comment',
5155                'reason_for_rejection_id',
5156                'reason_for_rejection',
5157                'commercial',
5158                'created_at',
5159                'created_by',
5160                'updated_at',
5161                'updated_by'
5162            ];
5163
5164            $dateParameters = [
5165                'issue_date',
5166                'request_date',
5167                'acceptance_date',
5168                'last_follow_up_date',
5169                'created_at',
5170                'updated_at',
5171            ];
5172
5173
5174
5175            if($this->locale == 'es'){
5176                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
5177            }
5178
5179            $totalSent = 0;
5180            $totalSentIds = array();
5181            $totalFailedIds = array();
5182            $totalErrorIds = array();
5183            $currentQuotationId = null;
5184
5185            for ($i = 0; $i < count($result); $i++) {$budgetTypeId = $result[$i]->budget_type_id;
5186                $currentQuotationId = $result[$i]->quote_id;
5187                $body = $emailTemplate->html;
5188                if(isset($data['html'])){
5189                    $body = $data['html'];
5190                }
5191                $subject = $emailTemplate->subject;
5192                $commercialUser = $result[$i]->commercial;
5193
5194                $blockedDomains = TblBlockedDomains::where('company_id', $result[$i]->company_id)->pluck('domain')->toArray();
5195
5196                if(env('SENDGRID_STAGING')){
5197                    $toEmail = $user->email;
5198                }else{
5199                    $toEmail = $result[$i]->email;
5200                }
5201
5202                preg_match_all('/{{(.*?)}}/', $body, $matches);
5203
5204                $parameters = $matches[1];
5205
5206                foreach ($parameters as $parameter) {
5207
5208                    if(in_array($parameter, $dateParameters)){
5209                        if($result[$i]->{$parameter}){
5210                            $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
5211                        }
5212                    }
5213
5214                    if(in_array($parameter, $availableParameters)){
5215                        $body = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $body);
5216                    }
5217                }
5218
5219                preg_match_all('/{{(.*?)}}/', $subject, $matches);
5220
5221                $parameters = $matches[1];
5222
5223                foreach ($parameters as $parameter) {
5224
5225                    if(in_array($parameter, $dateParameters)){
5226                        if($result[$i]->{$parameter}){
5227                            $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
5228                        }
5229                    }
5230
5231                    if(in_array($parameter, $availableParameters)){
5232                        $subject = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $subject);
5233                    }
5234                }
5235
5236                $email = new \SendGrid\Mail\Mail();
5237
5238                $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
5239
5240                foreach ($templateFiles as $item) {
5241                    $f = storage_path('app/public/uploads/' . $item->filename);
5242
5243                    if (file_exists($f)) {
5244                        $imgpath = file_get_contents($f);
5245                        $base64 = "data:image/png;base64," . base64_encode($imgpath);
5246                        $mimeType = mime_content_type($f);
5247
5248                        $email->addAttachment(
5249                            $imgpath,
5250                            $mimeType,
5251                            str_replace(' ', '', $item->original_name),
5252                            "inline",
5253                            str_replace(' ', '', $item->original_name),
5254                        );
5255
5256                        $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
5257                    } else {
5258                        Log::channel('email_failed_log')->error("File not found: " . $f);
5259                    }
5260                }
5261
5262                $html = '<!DOCTYPE html>';
5263                $html .= '<html>';
5264                $html .= '<head>';
5265                $html .= '<meta charset="UTF-8">';
5266                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
5267                $html .= '</head>';
5268                $html .= '<body>';
5269                $html .= $body;
5270                $html .= '</body>';
5271                $html .= '</html>';
5272
5273                if($automaticSendLimit != null){
5274                    $sentBy = "System";
5275                }
5276
5277                if($toEmail != null){
5278
5279                    $toEmail = explode(",", $toEmail);
5280                    $toEmail = array_map('trim', $toEmail);
5281
5282                    $companyEmail = null;
5283
5284                    $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}'";
5285                    $commercialEmail = DB::select($queryUsers);
5286
5287                    if(count($commercialEmail) > 0){
5288                        $companyEmail = $commercialEmail[0];
5289                    }else{
5290                        if($emailTemplate->from_id != null){
5291                            $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
5292                        }else{
5293                            $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result[$i]->company_id)->first();
5294                        }
5295                    }
5296
5297                    if(!$companyEmail){
5298                        return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
5299                    }
5300
5301                    $ccBcc = TblCcBcc::where('company_id', $result[$i]->company_id)->get();
5302
5303                    $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
5304                    $email->setSubject($subject);
5305
5306                    $s = 0;
5307                    $addTo = array();
5308                    foreach ($toEmail as $clientEmail) {
5309                        $isValid = $this->isEmailValid($clientEmail);
5310                        if($isValid){
5311                            $domain = substr($clientEmail, strpos($clientEmail, '@') + 1);
5312
5313                            if(!in_array($domain, $blockedDomains)){
5314                                $email->addTo($clientEmail);
5315                                array_push($addTo, $clientEmail);
5316                                $s++;
5317                            }
5318                        }else{
5319                            TblFollowUpLogs::create(
5320                                array(
5321                                    'quotation_id' => $result[$i]->id,
5322                                    'email' => $clientEmail,
5323                                    'sent_by' => $sentBy,
5324                                    'status' => 'Invalid email'
5325                                )
5326                            );
5327                        }
5328                    }
5329
5330                    if($s == 0){
5331                        array_push($totalFailedIds, $result[$i]->id);
5332                        Log::channel('email_failed_log')->error($s. 'ID:' . $result[$i]->id . ' - ' . json_encode($toEmail));
5333                        continue;
5334                    }
5335
5336                    if(env('SENDGRID_STAGING')){
5337
5338                    }else{
5339                        if(count($ccBcc) > 0){
5340                            foreach ($ccBcc as $data) {
5341                                if(!in_array($data->email, $toEmail)){
5342                                    $email->addBcc($data->email);
5343                                }
5344                            }
5345                        }
5346                    }
5347
5348                    $email->addContent("text/html", $html);
5349
5350                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5351
5352                    $files = TblFiles::where('quotation_id', $result[$i]->id)->where('is_internal', null)->get();
5353                    $requestSize = $this->calculateEmailRequestSize($email);
5354
5355                    foreach ($files as $key => $value) {
5356                        if ($files[$key]->filename && Storage::disk('s3')->exists("uploads/" . $files[$key]->filename)) {
5357                                                        
5358                            $fileContent = Storage::disk('s3')->get("uploads/" . $files[$key]->filename);
5359                            $fileSize = strlen($fileContent) / 1048576;
5360                            $fileSize = (int) ceil($fileSize);
5361
5362                            $originalName = $files[$key]->original_name ?: basename($files[$key]->filename);
5363                        }
5364                        else if ($files[$key]->file) {
5365                            $fileContent = $files[$key]->file;
5366
5367                            if (is_string($fileContent) && base64_decode($fileContent, true)) {
5368                                $fileContent = base64_decode($fileContent);
5369                            }
5370
5371                            $fileSize = strlen($fileContent) / 1048576;
5372                            $fileSize = (int) ceil($fileSize);
5373
5374                            $originalName = $files[$key]->original_name ?: ($files[$key]->file_name ?: 'file');
5375                        }
5376                        else {
5377                            continue;
5378                        }
5379
5380                        if($fileSize > 0){
5381                            if($requestSize + $fileSize < 25){
5382                                $attachment = new \SendGrid\Mail\Attachment();
5383                                $attachment->setFilename($originalName);
5384                                $attachment->setDisposition("attachment");
5385
5386                                $attachment->setContent(base64_encode($fileContent));
5387
5388                                if ($files[$key]->mime_type) {
5389                                    $attachment->setType($files[$key]->mime_type);
5390                                }
5391
5392                                $email->addAttachment($attachment);
5393                                $requestSize = $this->calculateEmailRequestSize($email);
5394                            } else {
5395                                Log::warning("File omitted due to size limit: " . $originalName);
5396                            }
5397                        }
5398                    }
5399
5400                    $response = $sendgrid->send($email);
5401                    if ($response->statusCode() == 202) {
5402
5403                        $messageId = null;
5404
5405                        foreach ($response->headers() as $header) {
5406                            if (strpos(strtolower($header), 'x-message-id:') === 0) {
5407                                $messageId = trim(substr($header, strpos($header, ':') + 1));
5408                                break;
5409                            }
5410                        }
5411
5412                        $lastFollowUp = TblLastFollowUpDate::where('company_id', $companyId)->where('budget_type_id', $budgetTypeId)->first();
5413                        $workingDaysN = $workingDays;
5414                        if($lastFollowUp != null){
5415                            if($lastFollowUp->last_follow_up_date){
5416                                $workingDaysN = $lastFollowUp->last_follow_up_date;
5417                            }
5418                        }
5419
5420                        $comment = "Email automático enviado el " . date('Y-m-d H:i:s') . " por usuario " . $sentBy;
5421                        $result[$i]->last_follow_up_comment = $result[$i]->last_follow_up_comment . "\n" . $comment;
5422                        $date = strtotime("{$workingDaysN} weekdays");
5423                        $result[$i]->last_follow_up_date = date('Y-m-d H:i:s', $date);
5424                        $totalSentQ = $result[$i]->total_sent + 1;
5425
5426                        array_push($totalSentIds, $result[$i]->id);
5427
5428                        foreach ($addTo as $addToEmail) {
5429                            TblFollowUpLogs::create(
5430                                array(
5431                                    'quotation_id' => $result[$i]->id,
5432                                    'email' => $addToEmail,
5433                                    'sent_by' => $sentBy,
5434                                    'status' => 'OK'
5435                                )
5436                            );
5437                        }
5438
5439                        if($totalSentQ >= $limitReminderEmails){
5440                            $result[$i]->reason_for_not_following_up_id = 3;
5441                            $result[$i]->last_follow_up_date = null;
5442                        }
5443
5444                        TblQuotations::where('id', $result[$i]->id)->update(
5445                            array(
5446                                'last_follow_up_comment' => $result[$i]->last_follow_up_comment,
5447                                'last_follow_up_date' => $result[$i]->last_follow_up_date,
5448                                'total_sent' => $result[$i]->total_sent + 1,
5449                                'y_message_id' => $messageId,
5450                                'y_status' => 'Processing',
5451                                'reason_for_not_following_up_id' => $result[$i]->reason_for_not_following_up_id,
5452                                'updated_by' => $sentBy,
5453                                'updated_at' => date('Y-m-d H:i:s')
5454                            )
5455                        );
5456
5457                        $jsonBody = array();
5458
5459                        foreach ($toEmail as $clientEmail) {
5460                            $isValid = $this->isEmailValid($clientEmail);
5461                            $eventStatus = "processed";
5462                            $eventResponse = "";
5463                            if(!$isValid){
5464                                $eventStatus = "invalid";
5465                                $eventResponse = "Invalid email address";
5466                            }
5467
5468                            array_push(
5469                                $jsonBody,
5470                                array(
5471                                    'email' =>  $clientEmail,
5472                                    'event' => $eventStatus,
5473                                    'sg_message_id' => $messageId,
5474                                    'smtp-id' => $messageId,
5475                                    'timestamp' => strtotime(date('Y-m-d H:i:s')),
5476                                    'response' => $eventResponse
5477                                )
5478                            );
5479                        }
5480
5481                        TblSendgridWebhook::create(
5482                            array(
5483                                'quotation_id' => $result[$i]->id,
5484                                'type' => 'followUps',
5485                                'json_body' => json_encode($jsonBody),
5486                                'x_message_id' => $messageId
5487                            )
5488                        );
5489
5490                        Log::channel('email_log')->info("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - EMAIL SENT');
5491                        $totalSent++;
5492                        $workingDays = 10;
5493                    } else {
5494                        $error = true;
5495                        array_push($totalErrorIds, $result[$i]->id);
5496                        Log::channel('email_failed_log')->error("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - ' . $response->body());
5497
5498                        foreach ($addTo as $addToEmail) {
5499                            TblFollowUpLogs::create(
5500                                array(
5501                                    'quotation_id' => $result[$i]->id,
5502                                    'email' => $addToEmail,
5503                                    'sent_by' => $sentBy,
5504                                    'status' => $response->body()
5505                                )
5506                            );
5507                        }
5508                    }
5509
5510                    $body = "";
5511                    $subject = "";
5512                }
5513            }
5514            Cache::flush();
5515
5516            Log::channel('send_email_follow_ups')->info(
5517                json_encode(
5518                    array(
5519                        "success" => $totalSentIds,
5520                        "failed" => $totalFailedIds,
5521                        "error" => $totalErrorIds
5522                    )
5523                )
5524            );
5525
5526            $this->update_commercial_numbers($companyId);
5527
5528            if($error){
5529                return response(['message' => 'KO']);
5530            }else{
5531
5532                if($automaticSendLimit != null){
5533                    TblOrdersUpdateLogs::create(
5534                        array(
5535                            'company_id' => $companyId,
5536                            'to_process' => 'Orders',
5537                            'status' => 'success',
5538                            'follow_ups_affected_rows' => $totalSent,
5539                            'processed_by' => $sentBy,
5540                            'started_at' => $startedAt,
5541                            'ended_at' => date('Y-m-d H:i:s')
5542                        )
5543                    );
5544                }
5545
5546                return response(['message' => 'OK', 'data' => $totalSent . ' ' . __('language.total_follow_up_sent')]);
5547            }
5548
5549        } catch (\Throwable $e) {
5550            Log::channel('email_failed_log')->error($e->getMessage());
5551            return response(['message' => 'KO', 'error' => $e->getMessage(), 'quotation_id' => $currentQuotationId]);
5552        }
5553    }
5554
5555    function create_sender_identity(Request $request){
5556
5557        try {
5558
5559            $data = $request->all();
5560            $sData = $data;
5561            $companyId = $data['company_id'];
5562            $createdBy = $data['created_by'];
5563            unset($data['company_id']);
5564            unset($data['created_by']);
5565
5566            $sender = TblCompanyEmails::where('from_email', $data['from_email'])->where('verified', 1)->count();
5567
5568            if($sender > 0){
5569                TblCompanyEmails::create($sData);
5570                return response(['message' => 'OK', 'data' => $data, 'is_verified' => 'yes']);
5571            }
5572
5573            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5574            $data['reply_to'] = $data['from_email'];
5575            $data['reply_to_name'] = $data['from_name'];
5576            $requestBody = $data;
5577            $error  = false;
5578
5579            $response = $sendgrid->client->verified_senders()->post($requestBody);
5580
5581            if ($response->statusCode() == 201) {
5582                $x = json_decode($response->body());
5583
5584                $data['company_id'] = $companyId;
5585                $data['created_by'] = $createdBy;
5586                $data['response_id'] = $x->id;
5587                TblCompanyEmails::create($data);
5588                Log::channel('email_log')->info('EMAIL: ' . $data['from_email'] . ' - VERIFICATION SENT');
5589            } else {
5590                $error = true;
5591                Log::channel('email_log')->error('REQUEST BODY: - ' . $response->body());
5592            }
5593
5594            $response = json_decode($response->body());
5595
5596            if($error){
5597                if($response->errors[0]->message == "already exists" && $response->errors[0]->field == "from_email"){
5598                    TblCompanyEmails::create($sData);
5599                    return response(['message' => 'OK', 'data' => $data, 'is_verified' => 'yes']);
5600                }
5601
5602                $errMessage = $response->errors[0]->field . ': ' . $response->errors[0]->message;
5603                return response(['message' => 'KO', 'error' => $errMessage]);
5604            }else{
5605                return response(['message' => 'OK', 'data' => $response, 'is_verified' => 'no']);
5606            }
5607
5608        } catch (\Exception $e) {
5609            Log::channel('email_log')->error('EMAIL:' . $data['from_email'] . ' - ' . $e->getMessage());
5610            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5611        }
5612    }
5613
5614    function get_sender_identity($companyId){
5615
5616        try {
5617
5618            $companyId = addslashes($companyId);
5619
5620            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5621
5622            $response = $sendgrid->client->verified_senders()->get();
5623
5624            if ($response->statusCode() == 200) {
5625                $x = json_decode($response->body())->results;
5626
5627                foreach ($x as $item) {
5628                    TblCompanyEmails::where('from_email', $item->from_email)->update(array(
5629                        'verified' => $item->verified,
5630                        'reply_to' => $item->reply_to,
5631                        'response_id' => $item->id
5632                    ));
5633                }
5634            }
5635
5636            $companyEmails = TblCompanyEmails::where('company_id', $companyId)->get();
5637
5638            return response(['message' => 'OK', 'data' => $companyEmails]);
5639
5640        } catch (\Exception $e) {
5641            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5642        }
5643    }
5644
5645    function get_all_sender_identity($companyId){
5646
5647        try {
5648
5649            $companyId = addslashes($companyId);
5650
5651            $query = "SELECT
5652                        id,
5653                        response_id,
5654                        nickname,
5655                        CONCAT(nickname, ' - ', from_email) from_email,
5656                        from_name,
5657                        reply_to,
5658                        reply_to_name,
5659                        address,
5660                        address2,
5661                        state,
5662                        city,
5663                        country,
5664                        zip,
5665                        verified,
5666                        locked,
5667                        is_active,
5668                        created_by,
5669                        created_at,
5670                        updated_by,
5671                        updated_at
5672                    FROM
5673                        tbl_company_emails
5674                    WHERE
5675                        company_id != {$companyId}
5676                        AND from_email NOT IN (
5677                        SELECT
5678                            from_email
5679                        FROM
5680                            tbl_company_emails
5681                        WHERE
5682                            company_id = {$companyId}
5683                        )
5684                    ";
5685
5686            $companyEmails = DB::select($query);
5687
5688            return response(['message' => 'OK', 'data' => $companyEmails]);
5689
5690        } catch (\Exception $e) {
5691            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5692        }
5693    }
5694
5695    function delete_sender_identity(Request $request){
5696
5697        try {
5698
5699            $data = $request->all();
5700            $responseId = addslashes($data['response_id']);
5701            $id = addslashes($data['id']);
5702
5703            $sender = TblCompanyEmails::where('response_id', $responseId)->count();
5704
5705            if($sender > 1){
5706                TblCompanyEmails::where('id', $id)->delete();
5707            }else{
5708                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5709
5710                $response = $sendgrid->client->verified_senders()->_($responseId)->delete();
5711
5712                if ($response->statusCode() == 204) {
5713                    TblCompanyEmails::where('response_id', $responseId)->delete();
5714                }
5715            }
5716
5717
5718            return response(['message' => 'OK']);
5719
5720        } catch (\Exception $e) {
5721            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5722        }
5723    }
5724
5725    function create_template(Request $request){
5726
5727        try {
5728
5729            $data = $request->all();
5730
5731            $files = $request->file('files');
5732            unset($data['files']);
5733
5734            if($files){
5735                $totalFileCount = count($files);
5736                if($totalFileCount > 2){
5737                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
5738                }
5739            }
5740
5741            $result = TblEmailConfiguration::create($data);
5742            $id = $result->id;
5743
5744            $directory = 'public/uploads';
5745            $origFilename = 'fireservicetitan.png';
5746            $file = 'public/uploads/fireservicetitan.png';
5747
5748            $sourcePath = public_path($origFilename);
5749            $destinationPath = 'public/uploads/' . $origFilename;
5750
5751            $filename = $id . '-EI' . time() . '-' . $origFilename;
5752
5753            Storage::putFileAs($directory, new \Illuminate\Http\File($sourcePath), $filename);
5754            Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5755
5756            TblEmailFiles::create(
5757                array(
5758                    'email_template_id' => $id,
5759                    'original_name' => $origFilename,
5760                    'filename' => $filename,
5761                    'uploaded_by' => $data['created_by']
5762                )
5763            );
5764
5765            if($files){
5766
5767                $uploadedFiles = [];
5768                $i = 0;
5769
5770                $combinedFilesSize = 0;
5771
5772                foreach ($files as $file) {
5773                    $i++;
5774
5775                    $origFilename = str_replace(" ", "", $file->getClientOriginalName());
5776
5777                    $filename = $id . '-EI' . time() . '-' . $origFilename;
5778
5779                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
5780
5781                    if($combinedFilesSize > 25000000){
5782                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
5783                    }
5784
5785                    Storage::putFileAs($directory, $file, $filename);
5786                    Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5787
5788                    if(in_array($origFilename, $uploadedFiles)){
5789                        $origFilename = $origFilename . $i;
5790                    }
5791
5792                    TblEmailFiles::create(
5793                        array(
5794                            'email_template_id' => $id,
5795                            'original_name' => $origFilename,
5796                            'filename' => $filename,
5797                            'uploaded_by' => $data['created_by']
5798                        )
5799                    );
5800
5801                    $uploadedFiles[] = $file->getClientOriginalName();
5802                }
5803            }
5804
5805            return response(['message' => 'OK']);
5806
5807        } catch (\Exception $e) {
5808            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5809        }
5810    }
5811
5812    function get_email_files($emailTemplateId){
5813
5814        try {
5815
5816            $emailTemplateId = addslashes($emailTemplateId);
5817
5818            $result = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
5819
5820            foreach ($result as $key => $value) {
5821                $path = storage_path('app/public/uploads/' . $result[$key]->filename);
5822
5823                if (File::exists($path)) {
5824                    $fileSizeBytes = File::size($path);
5825                    $result[$key]->filesize = $this->human_filesize($fileSizeBytes);
5826                    $result[$key]->original_name = $result[$key]->original_name . " ({$result[$key]->filesize})";
5827                    $result[$key]->img = "data:image/png;base64,".base64_encode(file_get_contents($path));
5828                }
5829            }
5830
5831            return response(['message' => 'OK', 'data' => $result]);
5832
5833        } catch (\Exception $e) {
5834            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5835        }
5836    }
5837
5838    function download_email_template_file($fileId){
5839
5840        try {
5841
5842            $fileId = addslashes($fileId);
5843
5844            $result = TblEmailFiles::where('file_id', $fileId)->first();
5845
5846            if($result){
5847                $path = storage_path('app/public/uploads/' . $result->filename);
5848
5849                if (!Storage::disk('public')->exists('uploads/' . $result->filename)) {
5850                    return response(['message' => 'KO']);
5851                }
5852
5853                return response()->download($path);
5854            }
5855
5856            return response(['message' => 'KO']);
5857
5858        } catch (\Exception $e) {
5859            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5860        }
5861
5862    }
5863
5864    function delete_email_template_file($fileId){
5865
5866        try {
5867
5868            $fileId = addslashes($fileId);
5869            $file = TblEmailFiles::where('file_id', $fileId)->first();
5870            $result = TblEmailFiles::where('file_id', $fileId)->first();
5871
5872            if($result){
5873                TblEmailFiles::where('file_id', $fileId)->delete();
5874                $path = storage_path('app/public/uploads/' . $result->filename);
5875                Storage::disk('public')->delete('uploads/' . $result->filename);
5876            }
5877
5878            return response(['message' => 'OK']);
5879
5880        } catch (\Exception $e) {
5881            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5882        }
5883    }
5884
5885    function update_email_template_order(Request $request, $id){
5886
5887        try {
5888
5889            $id = addslashes($id);
5890            $data = $request->all();
5891
5892            foreach ($data as $item) {
5893                TblEmailFiles::where('file_id', $item['file_id'])->update(array('order' => $item['order']));
5894            }
5895
5896        } catch (\Exception $e) {
5897            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5898        }
5899
5900    }
5901
5902
5903    function update_email_template(Request $request, $id){
5904
5905        try {
5906
5907            $data = $request->all();
5908
5909            $id = addslashes($id);
5910
5911            $files = $request->file('files');
5912            unset($data['files']);
5913
5914            $fileCount = TblEmailFiles::where('email_template_id', $id)->count();
5915
5916            if($files){
5917                $totalFileCount = $fileCount + count($files);
5918                if($totalFileCount > 3){
5919                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
5920                }
5921            }
5922
5923            if(isset($data['cron_default'])){
5924                TblEmailConfiguration::where('company_id', $data['company_id'])->where('cron_default', 1)->update(array('cron_default' => 0));
5925            }
5926
5927            $data['updated_at'] = date('Y-m-d H:i:s');
5928            TblEmailConfiguration::where('id', $id)->update($data);
5929
5930            if($files){
5931
5932                $directory = 'public/uploads';
5933                $uploadedFiles = [];
5934                $i = 0;
5935
5936                $combinedFilesSize = 0;
5937                foreach ($files as $file) {
5938                    $i++;
5939                    $origFilename = str_replace(" ", "", $file->getClientOriginalName());
5940                    $filename = $id . '-EI' . time() . '-' . $origFilename;
5941
5942                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
5943
5944                    if($combinedFilesSize > 25000000){
5945                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
5946                    }
5947
5948                    Storage::putFileAs($directory, $file, $filename);
5949                    Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5950
5951                    if(in_array($origFilename, $uploadedFiles)){
5952                        $origFilename = $origFilename . $i;
5953                    }
5954
5955                    TblEmailFiles::create(
5956                        array(
5957                            'email_template_id' => $id,
5958                            'original_name' => $origFilename,
5959                            'filename' => $filename,
5960                            'uploaded_by' => $data['updated_by']
5961                        )
5962                    );
5963
5964                    $uploadedFiles[] = $file->getClientOriginalName();
5965                }
5966            }
5967
5968            return response(['message' => 'OK']);
5969
5970        } catch (\Exception $e) {
5971            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5972        }
5973
5974    }
5975
5976    function delete_template($id){
5977
5978        try {
5979
5980            $id = addslashes($id);
5981
5982            TblEmailConfiguration::where('id', $id)->delete();
5983
5984            return response(['message' => 'OK']);
5985
5986        } catch (\Exception $e) {
5987            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5988        }
5989
5990    }
5991
5992    function get_email_template($companyId){
5993
5994        try {
5995
5996            $companyId = addslashes($companyId);
5997
5998            $where = "";
5999            if($companyId != 0){
6000                $where = " a.company_id = {$companyId} ";
6001            }else{
6002                $where = " a.company_id IN ({$this->companyId}";
6003            }
6004
6005            $query = "SELECT
6006                        a.id,
6007                        a.from_id,
6008                        CASE
6009                            WHEN a.type = 'followUps' THEN 'Follow-ups'
6010                            WHEN a.type = 'sendToClient' THEN 'Send to client'
6011                        END types,
6012                        (SELECT from_email FROM tbl_company_emails WHERE id = a.from_id) from_email,
6013                        CASE WHEN {$companyId} = 0 THEN CONCAT(b.name, ' - ', a.name) ELSE a.name END `name`,
6014                        a.subject,
6015                        a.html,
6016                        a.is_active,
6017                        a.type,
6018                        a.created_by,
6019                        a.created_at,
6020                        a.updated_by,
6021                        a.updated_at,
6022                        a.cron_default
6023                    FROM tbl_email_configuration a
6024                    LEFT JOIN tbl_companies b
6025                        ON b.company_id = a.company_id
6026                    WHERE {$where}
6027                    ORDER BY a.id DESC";
6028
6029            $result = DB::select($query);
6030
6031            return response(['message' => 'OK', 'data' => $result]);
6032
6033        } catch (\Exception $e) {
6034            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6035        }
6036
6037    }
6038
6039    function update_sender_identity(Request $request, $responseId){
6040
6041        try {
6042
6043            $data = $request->all();
6044            $companyId = $data['company_id'];
6045            $updatedBy = $data['updated_by'];
6046            $active = $data['is_active'];
6047            $id = addslashes($data['id']);
6048            unset($data['id']);
6049            unset($data['company_id']);
6050            unset($data['updated_by']);
6051            unset($data['is_active']);
6052
6053            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
6054            $data['reply_to'] = $data['from_email'];
6055            $data['reply_to_name'] = $data['from_name'];
6056            $requestBody = $data;
6057            $error  = false;
6058
6059            $response = $sendgrid->client->verified_senders()->_($responseId)->patch($requestBody);
6060
6061            if ($response->statusCode() == 200) {
6062                $x = json_decode($response->body());
6063
6064                $data['updated_by'] = $updatedBy;
6065                $data['updated_at'] = date('Y-m-d H:i:s');
6066                $data['is_active'] = $active;
6067
6068                TblCompanyEmails::where('company_id', $companyId)->update(array('is_active' => 0));
6069                TblCompanyEmails::where('id', $id)->update($data);
6070
6071                Log::channel('email_log')->info('EMAIL: ' . $data['from_email'] . ' - UPDATED');
6072            } else {
6073                $error = true;
6074                Log::channel('email_log')->error('REQUEST BODY: - ' . $response->body());
6075            }
6076
6077            $response = json_decode($response->body());
6078
6079            if($error){
6080                $errMessage = @$response->errors[0]->field . ': ' . @$response->errors[0]->message;
6081                return response(['message' => 'KO', 'error' => $errMessage]);
6082            }else{
6083                return response(['message' => 'OK', 'data' => $response]);
6084            }
6085
6086        } catch (\Exception $e) {
6087            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6088        }
6089
6090    }
6091
6092    function resend_verification($id){
6093
6094        try {
6095
6096            $id = addslashes($id);
6097
6098            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
6099
6100            $response = $sendgrid->client->verified_senders()->resend()->_($id)->post();
6101
6102            if ($response->statusCode() == 204) {
6103                return response(['message' => 'OK']);
6104            }else{
6105                $response = json_decode($response->body());
6106                $errMessage = $response->errors[0]->error_id . ': ' . $response->errors[0]->message;
6107                return response(['message' => 'KO', 'error' => $errMessage]);
6108            }
6109
6110        } catch (\Exception $e) {
6111            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6112        }
6113    }
6114
6115    function list_quotation_analytics_by_performance(Request $request){
6116
6117        try {
6118
6119            $data = $request->all();
6120            $companyId = addslashes($data['company_id']);
6121            $where  = "";
6122
6123            if($companyId != 0){
6124                $where .= " AND company_id = {$companyId} AND for_add = 0 ";
6125            }else{
6126                $where .= " AND company_id IN ({$this->companyId}) AND for_add = 0 ";
6127            }
6128
6129            if(isset($data['budget_status']) && $data['budget_status'] != null){
6130                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
6131            }
6132
6133            $latestYear = TblQuotations::max(DB::raw('YEAR(issue_date)'));
6134            $md = date('m-d');
6135
6136            $query = "SELECT
6137                        q.years,
6138                        q.totalIssue,
6139                        (q.total_acceptance_percentage - q.totalAcceptancePercentage) / q.totalAcceptancePercentage * 100 totalAcceptancePercentage,
6140                        q.totalAccept
6141                    FROM
6142                        (
6143                        SELECT
6144                            YEAR(a.issue_date) years,
6145                            (b.total_issued - COUNT(a.issue_date)) / COUNT(a.issue_date) * 100 totalIssue,
6146                            COUNT(
6147                                CASE WHEN a.acceptance_date IS NOT NULL
6148                                AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6149                                AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6150                                AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6151                                AND a.budget_status_id = 3 THEN 1 END
6152                            ) / COUNT(a.issue_date) * 100 totalAcceptancePercentage,
6153                            b.total_acceptance_percentage,
6154                            (b.total_acceptance -
6155                                COUNT(
6156                                    CASE WHEN a.acceptance_date IS NOT NULL
6157                                    AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6158                                    AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6159                                    AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6160                                    AND a.budget_status_id = 3 THEN 1 END)
6161                                    ) / COUNT(
6162                                            CASE WHEN a.acceptance_date IS NOT NULL
6163                                            AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6164                                            AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6165                                            AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6166                                            AND a.budget_status_id = 3 THEN 1 END
6167                            ) * 100 totalAccept
6168                        FROM
6169                            tbl_quotations a
6170                            JOIN (
6171                            SELECT
6172                                YEAR(issue_date) current_year,
6173                                COUNT(issue_date) total_issued,
6174                                COUNT(
6175                                    CASE WHEN acceptance_date IS NOT NULL
6176                                    AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6177                                    AND CONCAT(YEAR(acceptance_date), '-{$md}')
6178                                    AND YEAR(acceptance_date) = YEAR(issue_date)
6179                                    AND budget_status_id = 3 THEN 1 END
6180                                ) total_acceptance,
6181                                COUNT(
6182                                    CASE WHEN acceptance_date IS NOT NULL
6183                                    AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6184                                    AND CONCAT(YEAR(acceptance_date), '-{$md}')
6185                                    AND YEAR(acceptance_date) = YEAR(issue_date)
6186                                    AND budget_status_id = 3 THEN 1 END
6187                                ) / COUNT(issue_date) * 100 total_acceptance_percentage
6188                            FROM
6189                                tbl_quotations
6190                            WHERE
6191                                issue_date IS NOT NULL
6192                                AND YEAR(issue_date) = {$latestYear}
6193                                AND DATE_FORMAT(issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(issue_date), '-01-01')
6194                                AND CONCAT(YEAR(issue_date), '-{$md}')
6195                                {$where}
6196                            GROUP by
6197                                1
6198                            ) b
6199                        WHERE
6200                            a.issue_date IS NOT NULL
6201                            AND a.budget_type_id != 7
6202                            AND a.budget_type_id IS NOT NULL
6203                            AND {$latestYear} > YEAR(a.issue_date)
6204                            AND DATE_FORMAT(a.issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.issue_date), '-01-01')
6205                            AND CONCAT(YEAR(a.issue_date), '-{$md}')
6206                        GROUP BY
6207                            1
6208                        ORDER BY
6209                            YEAR(issue_date) DESC
6210                        ) q
6211                    ";
6212
6213            $resultYtd = DB::select($query);
6214
6215            $query = "SELECT
6216                        YEAR(issue_date) years,
6217                        COUNT(issue_date) totalIssue,
6218                        COUNT(
6219                            CASE WHEN acceptance_date IS NOT NULL
6220                            AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6221                            AND CONCAT(YEAR(acceptance_date), '-{$md}')
6222                            AND YEAR(acceptance_date) = YEAR(issue_date)
6223                            AND budget_status_id = 3 THEN 1 END
6224                        ) totalAccept,
6225                        COUNT(
6226                            CASE WHEN acceptance_date IS NOT NULL
6227                            AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6228                            AND CONCAT(YEAR(acceptance_date), '-{$md}')
6229                            AND YEAR(acceptance_date) = YEAR(issue_date)
6230                            AND budget_status_id = 3 THEN 1 END
6231                        ) / COUNT(issue_date) * 100 totalAcceptancePercentage
6232                    FROM
6233                        tbl_quotations
6234                    WHERE
6235                        issue_date IS NOT NULL
6236                        AND budget_type_id != 7
6237                        AND budget_type_id IS NOT NULL
6238                        AND DATE_FORMAT(issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(issue_date), '-01-01')
6239                        AND CONCAT(YEAR(issue_date), '-{$md}')
6240                        {$where}
6241                    GROUP BY
6242                        1
6243                    ORDER BY
6244                        YEAR(issue_date) DESC
6245                    ";
6246
6247            $resultYears = DB::select($query);
6248
6249            return response(['message' => 'OK', 'ytdData' => $resultYtd, 'yearsData' => $resultYears]);
6250
6251        } catch (\Exception $e) {
6252            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6253        }
6254    }
6255
6256    function list_orders_update_logs($companyId){
6257
6258        try {
6259
6260            $where = "";
6261
6262            if($companyId != 0){
6263                $where .= " a.company_id = {$companyId}";
6264            }else{
6265                $where .= " a.company_id IN ({$this->companyId})";
6266            }
6267
6268            $query = "SELECT
6269                        a.id,
6270                        b.name company,
6271                        a.to_process,
6272                        a.rejected_affected_rows,
6273                        a.for_add_deleted_affected_rows,
6274                        a.month_change_affected_rows,
6275                        a.follow_ups_affected_rows,
6276                        a.sync_succesfull,
6277                        a.sync_error,
6278                        a.sync_error_message,
6279                        a.sync_success_ids,
6280                        a.cleared_email_errors,
6281                        a.remaining_email_errors,
6282                        CASE
6283                            WHEN a.rejected_affected_rows IS NOT NULL THEN a.rejected_affected_rows
6284                            WHEN a.for_add_deleted_affected_rows IS NOT NULL THEN a.for_add_deleted_affected_rows
6285                            WHEN a.month_change_affected_rows IS NOT NULL THEN a.month_change_affected_rows
6286                            WHEN a.follow_ups_affected_rows IS NOT NULL THEN a.follow_ups_affected_rows
6287                        END totals,
6288                        a.status,
6289                        a.processed_by,
6290                        a.started_at,
6291                        a.ended_at,
6292                        a.rejected_automatically_ids
6293                    FROM `tbl_orders_update_logs` a
6294                    LEFT JOIN tbl_companies b
6295                        ON a.company_id = b.company_id
6296                    WHERE {$where}
6297                    ORDER BY started_at DESC";
6298
6299            $result = DB::select($query);
6300
6301            return response(['message' => 'OK', 'data' => $result]);
6302
6303        } catch (\Exception $e) {
6304            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6305        }
6306
6307    }
6308
6309    function list_g3w_orders_update_logs($companyId){
6310
6311        try {
6312            $result = TblG3WOrdersUpdateLogs::where("company_id", $companyId)->get();
6313
6314            return response(['message' => 'OK', 'data' => $result]);
6315
6316        } catch (\Exception $e) {
6317            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6318        }
6319
6320    }
6321
6322    function update_budget_status_rejected_manual(Request $request){
6323
6324        try {
6325
6326            $data = $request->all();
6327
6328            $update = $this->update_budget_status_rejected($data['company_id'], $data['processed_by']);
6329
6330            if($update){
6331                return response(['message' => 'OK']);
6332            }else{
6333                return response(['message' => 'KO']);
6334            }
6335
6336        } catch (\Exception $e) {
6337            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6338        }
6339    }
6340
6341    function update_budget_status_rejected($companyId = null, $processedBy = "System"){
6342
6343        try {
6344
6345            $startedAt = date('Y-m-d H:i:s');
6346            $companyId = addslashes($companyId);
6347            $where = "";
6348
6349            $budgetTypes = TblBudgetTypes::get();
6350
6351            if(count($budgetTypes) > 0){
6352
6353                $companies = array();
6354
6355                if($companyId != 0){
6356                    $companies = TblCompanies::where('company_id', $companyId)->get();
6357                    $where = "AND company_id = {$companyId}";
6358                }else{
6359                    $companies = TblCompanies::get();
6360                }
6361
6362                for ($i = 0; $i < count($budgetTypes); $i++) {
6363
6364                    $days = $budgetTypes[$i]->duration;
6365                    $id = $budgetTypes[$i]->budget_type_id;
6366
6367                    if($days == null || $days == 0){
6368                        continue;
6369                    }
6370
6371                    for ($c = 0; $c < count($companies); $c++) {
6372                        $companyId = $companies[$c]->company_id;
6373
6374                        $query = "SELECT
6375                                    GROUP_CONCAT(id) ids
6376                                FROM
6377                                    tbl_quotations
6378                                WHERE
6379                                    budget_type_id = {$id}
6380                                AND budget_status_id IN (1, 2, 11)
6381                                AND DATEDIFF(NOW(), issue_date) >= {$days}
6382                                AND for_add = 0
6383                                {$where}";
6384
6385                        $result = DB::select($query);
6386
6387                        if(count($result) > 0){
6388
6389                            $ids = $result[0]->ids;
6390
6391                            if($ids != null || $ids != ""){
6392                                $query = "UPDATE
6393                                            tbl_quotations
6394                                        SET
6395                                            budget_status_id = 7
6396                                        WHERE
6397                                            id IN ({$ids})";
6398
6399                                DB::select($query);
6400
6401                                TblOrdersUpdateLogs::create(
6402                                    array(
6403                                        'company_id' => $companyId,
6404                                        'to_process' => 'Orders',
6405                                        'status' => 'success',
6406                                        'rejected_automatically_ids' => $ids,
6407                                        'processed_by' => $processedBy,
6408                                        'started_at' => $startedAt,
6409                                        'ended_at' => date('Y-m-d H:i:s')
6410                                    )
6411                                );
6412                            }
6413                        }
6414                    }
6415                }
6416            }
6417
6418            Cache::flush();
6419
6420            return response(['message' => 'OK']);
6421
6422        } catch (\Exception $e) {
6423
6424            TblOrdersUpdateLogs::create(
6425                array(
6426                    'company_id' => $companyId,
6427                    'to_process' => 'Orders',
6428                    'status' => $e->getMessage(),
6429                    'processed_by' => $processedBy,
6430                    'started_at' => $startedAt,
6431                    'ended_at' => date('Y-m-d H:i:s')
6432                )
6433            );
6434
6435            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6436        }
6437
6438    }
6439
6440    function bulk_update_quotation(Request $request){
6441
6442        // try {
6443
6444            $data = $request->all();
6445
6446            $r = new Request([
6447                'filterModel' => $data['filterModel'],
6448                'sortModel' => $data['sortModel'],
6449                'start' => 0,
6450                'end' => 999999999,
6451                'company_id' => $data['company_id'],
6452                'user_id' => $data['user_id'],
6453                'ids' => $data['ids'],
6454                'searchText' => $data['searchText'],
6455                'ids_not_in' => $data['ids_not_in']
6456            ]);
6457
6458            $listQuotations = $this->list_quotations($r);
6459            $d = $listQuotations->original['data'];
6460
6461            if(count($d) > 0){
6462                if(isset($data['last_follow_up_date']) && $data['last_follow_up_date'] == 1){
6463                    unset($data['last_follow_up_date']);
6464                }
6465                // unset($data['last_follow_up_date']);
6466                unset($data['filterModel']);
6467                unset($data['sortModel']);
6468                unset($data['start']);
6469                unset($data['end']);
6470                unset($data['company_id']);
6471                unset($data['user_id']);
6472                unset($data['ids']);
6473                unset($data['searchText']);
6474                unset($data['ids_not_in']);
6475
6476                $result = array();
6477                for ($i = 0; $i < count($d); $i++) {
6478                    array_push($result, $d[$i]->id);
6479                }
6480
6481                TblQuotations::whereIn('id', $result)->update($data);
6482
6483                Cache::flush();
6484            }
6485
6486            return response(['message' => 'OK', $data]);
6487
6488        // } catch (\Exception $e) {
6489        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
6490        // }
6491
6492    }
6493
6494    function move_budget_and_job(Request $request){
6495
6496        try {
6497
6498            $data = $request->all();
6499            $id = addslashes($data['id']);
6500            $companyId = addslashes($data['company_id']);
6501
6502            unset($data['id']);
6503            unset($data['company_id']);
6504
6505            $budget = TblQuotations::where('id', $id)->first();
6506
6507            $quotationId = $budget->id;
6508            $companyIdJob = $budget->company_id;
6509
6510            $query = "SELECT
6511                        COUNT(1) total
6512                    FROM tbl_company_users a
6513                    LEFT JOIN tbl_users b
6514                        ON a.user_id = b.id
6515                    WHERE a.company_id = {$companyId}
6516                    AND b.name = '{$budget->commercial}'
6517                    ORDER BY b.name ASC";
6518
6519            $result = DB::select($query);
6520
6521            $commercial = $budget->commercial;
6522
6523            if($result[0]->total == 0){
6524                $commercial = $data['created_by'];
6525            }
6526
6527            $r = new Request([
6528                'created_by' => $commercial,
6529            ]);
6530
6531            $result = $this->get_number($r, $companyId, 1);
6532            $newNumber = $result->original['number'];
6533
6534            TblQuotations::where('id', $id)->update(
6535                array(
6536                    'quote_id' => $newNumber,
6537                    'company_id' => $companyId,
6538                    'from_company_id' => $budget->company_id,
6539                    'commercial' => $commercial,
6540                )
6541            );
6542
6543            $job = TblOngoingJobs::where('quotation_id', $quotationId)->first();
6544
6545            $jobId = null;
6546
6547            if($job){
6548                $jobId = $job->id;
6549
6550                $query = "SELECT
6551                            COUNT(1) total
6552                        FROM tbl_company_users a
6553                        LEFT JOIN tbl_users b
6554                            ON a.user_id = b.id
6555                        WHERE a.company_id = {$companyId}
6556                        AND b.name = '{$job->responsible_for_work}'
6557                        ORDER BY b.name ASC";
6558
6559                $result = DB::select($query);
6560
6561                $responsibleForWork = $job->responsible_for_work;
6562
6563                if($result[0]->total == 0){
6564                    $responsibleForWork = $data['created_by'];
6565                }
6566
6567                TblOngoingJobs::where('quotation_id', $id)->update(
6568                    array(
6569                        'quote_id' => $newNumber,
6570                        'company_id' => $companyId,
6571                        'responsible_for_work' => $responsibleForWork,
6572                    )
6573                );
6574            }
6575
6576            Cache::flush();
6577
6578            return response([
6579                'message' => 'OK',
6580                'quotation_id' => $quotationId,
6581                'job_id' => $jobId
6582            ]);
6583
6584        } catch (\Exception $e) {
6585            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6586        }
6587    }
6588
6589    function list_quotation_analytics_by_types_of_budgets_created_per_week(Request $request){
6590
6591        try {
6592
6593            $data = $request->all();
6594            $companyId = addslashes($data['company_id']);
6595            $field = $data['field'];
6596
6597            $where = "";
6598            $whereYear = "";
6599            $dateLflArray = array();
6600            $companyIds = $this->companyIds;
6601
6602            if($companyId != 0){
6603                $companyIds = array($companyId);
6604            }
6605
6606            $acc = "";
6607            if($field == 'acceptance_date'){
6608                $acc = " AND q.acceptance_date IS NOT NULL ";
6609                // $field = 'created_at';
6610
6611                if(@$data['data_to_display'] == 4){
6612                    $field = 'created_at';
6613                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
6614                }
6615            }else{
6616                $field = 'created_at';
6617                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
6618            }
6619
6620            if(isset($data['years']) && $data['years'] != null){
6621                $years = implode(',', $data['years']);
6622                if(count($data['years']) > 0){
6623                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
6624                }
6625            }
6626
6627            foreach ($companyIds as $v) {
6628
6629                $lflWhere = " AND q.company_id = {$v} ";
6630
6631                $query = "SELECT
6632                            CONCAT(
6633                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
6634                                ' - ',
6635                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
6636                            ) AS date_like,
6637                            YEAR(q.{$field}) 'year',
6638                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
6639                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
6640                            {$v} 'company_id'
6641                        FROM
6642                            tbl_quotations q
6643                        WHERE
6644                            q.{$field} IS NOT NULL
6645                            AND q.for_add != 1
6646                            {$lflWhere}
6647                            {$whereYear}
6648                        GROUP BY YEAR(q.{$field})
6649                        ORDER BY YEAR(q.{$field}) DESC";
6650
6651                $dateLike = DB::select($query);
6652
6653                $dateLflArray[$v] = $dateLike;
6654            }
6655
6656            $isFy = true;
6657
6658            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
6659                $isFy = false;
6660                $ytdArray = array();
6661                $ytdAcceptanceArray = array();
6662                $lflCompanyIds = array();
6663                foreach ($dateLflArray as $k => $v) {
6664                    foreach ($dateLflArray[$k] as $item) {
6665                        $year = $item->year;
6666                        $now = date('m-d');
6667                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
6668                    }
6669
6670                    $ytdArray = implode(' OR ', $ytdArray);
6671                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
6672                    $ytdArray = array();
6673                }
6674
6675                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
6676                $where .= " AND ({$lflCompanyIds}";
6677            }
6678
6679            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
6680                $isFy = false;
6681                $lflArray = array();
6682                $ytdAcceptanceArray = array();
6683                $lflCompanyIds = array();
6684                foreach ($dateLflArray as $k => $v) {
6685                    foreach ($dateLflArray[$k] as $item) {
6686                        $year = $item->year;
6687                        $min_date_like = $item->min_date_like;
6688                        $max_date_like = $item->max_date_like;
6689                        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}')");
6690                    }
6691
6692                    $lflArray = implode(' OR ', $lflArray);
6693                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
6694                    $lflArray = array();
6695                }
6696
6697                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
6698                $where .= " AND ({$lflCompanyIds}";
6699            }
6700
6701            if($isFy){
6702                if($companyId != 0){
6703                    $where .= " AND q.company_id = {$companyId} ";
6704                }else{
6705                    $where .= " AND q.company_id IN ({$this->companyId})";
6706                }
6707            }
6708
6709            if(isset($data['source']) && $data['source'] != null){
6710                $where .= " AND s.name = '{$data['source']}'";
6711            }
6712
6713            if(isset($data['month']) && $data['month'] != null){
6714                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
6715            }
6716
6717            if(isset($data['week']) && $data['week'] != null){
6718                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
6719            }
6720
6721            if(isset($data['commercial']) && $data['commercial'] != null){
6722                $where .= " AND q.commercial = '{$data['commercial']}'";
6723            }
6724
6725            if(isset($data['created_by']) && $data['created_by'] != null){
6726                $where .= " AND q.created_by = '{$data['created_by']}'";
6727            }
6728
6729            if(isset($data['budget_type']) && $data['budget_type'] != null){
6730                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
6731            }
6732
6733            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
6734                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
6735            }
6736
6737            if(isset($data['budget_status']) && $data['budget_status'] != null){
6738                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
6739            }
6740
6741            if(isset($data['client_type']) && $data['client_type'] != null){
6742                $where .= " AND ct.customer_type_id = {$data['client_type']}";
6743            }
6744
6745
6746            if(isset($data['segment_id']) && $data['segment_id'] != null){
6747                $where .= " AND q.segment_id = {$data['segment_id']}";
6748            }
6749
6750            $col = "1";
6751
6752            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
6753                if($data['data_to_display'] == 1){
6754                    $col = "1";
6755                }
6756
6757                if($data['data_to_display'] == 2){
6758                    $col = "q.amount";
6759                }
6760            }
6761
6762            $budgetTypes = TblBudgetTypes::orderByRaw("ISNULL(priority), priority ASC")->get();
6763            $cols = "";
6764            foreach ($budgetTypes as $item) {
6765                if($item->name == '' || $item->name == null){
6766                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} ELSE 0 END), 0) AS 'Otros'";
6767                }else{
6768                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN {$col} ELSE 0 END), 0) AS '{$item->name}'";
6769                }
6770            }
6771
6772            $budgetTypeGroups = TblBudgetTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
6773
6774            $colsGroups = ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} END), 0) AS Otros";
6775
6776            foreach ($budgetTypeGroups as $item) {
6777                $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6778                $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}'";
6779                $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}'";
6780            }
6781
6782            $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";
6783
6784            $col = $colsGroups . $cols;
6785
6786            if(@$data['data_to_display'] == 3){
6787
6788                $cols = "";
6789                foreach ($budgetTypes as $item) {
6790                    if($item->name == '' || $item->name == null){
6791                        $cols .= ",COALESCE(
6792                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount ELSE 0 END) /
6793                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 ELSE 0 END) * 100 , 0
6794                                    ) AS 'Otros'";
6795                    }else{
6796                        $cols .= ",COALESCE(
6797                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN q.amount ELSE 0 END) /
6798                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN 1 ELSE 0 END), 0
6799                                    ) AS '{$item->name}'";
6800                    }
6801                }
6802
6803                $colsGroups = ",COALESCE(
6804                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount END)) /
6805                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 END))
6806                            , 0) Otros";
6807
6808                foreach ($budgetTypeGroups as $item) {
6809                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6810                    $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}'";
6811                    $colsGroups .= ",COALESCE(
6812                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.amount END)) /
6813                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN 1 END))
6814                                    , 0) '{$budgetTypeGroupName}'";
6815                }
6816
6817                $colsGroups .= ",COALESCE(
6818                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.amount END)) /
6819                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END))
6820                                , 0) total";
6821
6822                $col = $colsGroups . $cols;
6823            }
6824
6825            if(@$data['data_to_display'] == 4){
6826
6827                $cols = "";
6828
6829                foreach ($budgetTypes as $item) {
6830
6831                    if($item->name == '' || $item->name == null){
6832                        $cols .= ",COALESCE(
6833                                        SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) /
6834                                        SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 ELSE 0 END) * 100 , 0
6835                                ) AS 'Otros'";
6836                    }else{
6837                        $cols .= ", COALESCE(
6838                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.acceptance_date IS NOT NULL THEN 1 END) /
6839                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.created_at IS NOT NULL THEN 1 END) * 100, 0
6840                                ) AS '{$item->name}'";
6841                    }
6842                }
6843
6844                $colsGroups = ",COALESCE(
6845                                    (SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 END)) /
6846                                    (SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 END)) * 100
6847                                    , 0) Otros";
6848
6849                foreach ($budgetTypeGroups as $item) {
6850                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6851                    $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}'";
6852                    $colsGroups .= ",COALESCE(
6853                                        (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)) /
6854                                        (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
6855                                    , 0) '{$budgetTypeGroupName}'";
6856                }
6857
6858                $colsGroups .= ",COALESCE(
6859                                    (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)) /
6860                                    (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
6861                                    , 0) total";
6862
6863                $col = $colsGroups . $cols;
6864            }
6865
6866            $query  = "SELECT
6867                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
6868                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
6869                            LPAD(WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'week',
6870                            DATE_FORMAT(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY), '%W, %M %e') 'namedate',
6871                            GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.id END) groupConcatIds
6872                            {$col}
6873                        FROM
6874                            tbl_quotations q
6875                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
6876                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
6877                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
6878                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
6879                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
6880                        WHERE
6881                            q.{$field} IS NOT NULL
6882                            AND q.for_add != 1
6883                            AND q.budget_type_id IS NOT NULL
6884                            AND q.budget_type_id != 7
6885                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
6886                            AND q.acceptance_date != '0000-00-00 00:00:00'
6887                            {$where}
6888                            {$whereYear}
6889                        GROUP BY
6890                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
6891                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
6892                            WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) WITH ROLLUP
6893                        ORDER BY
6894                            YEAR DESC,
6895                            MONTH ASC,
6896                            WEEK ASC,
6897                            DATE_FORMAT(q.{$field}, '%e') ASC";
6898            // return $query;
6899            $result = DB::select($query);
6900
6901            $query = "SELECT
6902                        btg.budget_type_group_id,
6903                        btg.name,
6904                        (
6905                            SELECT
6906                                GROUP_CONCAT(COALESCE(bt.name, '') ORDER BY ISNULL(bt.priority), bt.priority ASC SEPARATOR '|')
6907                            FROM
6908                                tbl_budget_types bt
6909                            WHERE
6910                                bt.budget_type_group_id = btg.budget_type_group_id
6911                        ) budget_types
6912                        FROM
6913                            tbl_budget_type_groups btg
6914                        ORDER BY
6915                            ISNULL(btg.priority),
6916                            btg.priority ASC";
6917
6918            $budgetTypeGroups = DB::select($query);
6919
6920            foreach ($budgetTypeGroups as $item) {
6921                $item->group_key_name = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6922                $item->budget_types = explode("|", $item->budget_types);
6923            }
6924
6925            return response([
6926                'message' => 'OK',
6927                'data' => $result,
6928                'budgetTypeGroups' => $budgetTypeGroups
6929            ]);
6930
6931        } catch (\Exception $e) {
6932            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6933        }
6934    }
6935
6936    public function preview_file($id){
6937        
6938        try {
6939
6940            $file = TblFiles::where("file_id", $id)->first();
6941            
6942            if (!$file) {
6943                return response()->json([
6944                    'message' => 'KO',
6945                    'error' => __('language.file_not_found')
6946                ], 404);
6947            }                                
6948                        
6949            if (!Storage::disk('s3')->exists("uploads/" . $file->filename)) {                
6950                return response()->json(['message' => 'File not found'], 404);
6951            }
6952            
6953            $url = Storage::disk('s3')->temporaryUrl(
6954                "uploads/" . $file->filename,
6955                now()->addMinutes(5)
6956            );
6957
6958            return response()->json([
6959                'url' => $url
6960            ]);
6961
6962        } catch (\Exception $e) {
6963            return response()->json([
6964                'message' => 'KO',
6965                'error' => $e->getMessage()
6966            ], 500);
6967        }
6968    }
6969
6970    function get_past_added_quotation(Request $request){
6971
6972        try {
6973
6974            $data = $request->all();
6975            $keyword = addslashes($data['keyword']);
6976            $result = array();
6977
6978            if(isset($keyword) && !empty($keyword)){
6979                $array = explode(' ', $keyword);
6980
6981                $where = "";
6982
6983                $availableParameters = array('client', 'email');
6984
6985                $searchTextArray = explode(" ", $keyword);
6986
6987                $searchArray = array();
6988                $matchScoreArray = array();
6989                foreach ($availableParameters as $field) {
6990                    foreach ($searchTextArray as $word) {
6991                        array_push($searchArray, "({$field} LIKE '%{$word}%')");
6992                        array_push($matchScoreArray, "CASE WHEN {$field} LIKE '%{$word}%' THEN 1 ELSE 0 END");
6993                    }
6994                }
6995
6996                $searchArray = implode(" OR ", $searchArray);
6997                $matchScoreArray = implode(" + ", $matchScoreArray);
6998                $matchScoreCol = "({$matchScoreArray})";
6999                $where .= " AND ({$searchArray}";
7000
7001                $query = "SELECT
7002                            id,
7003                            client,
7004                            segment_id,
7005                            CONCAT(`client`, ' - ', email) `client_email`,
7006                            email,
7007                            phone_number,
7008                            customer_type_id,
7009                            {$matchScoreCol} match_score
7010                        FROM tbl_quotations
7011                        WHERE for_add = 0
7012                        AND email IS NOT NULL AND phone_number IS NOT NULL
7013                        {$where}
7014                        GROUP BY client, email
7015                        ORDER BY match_score DESC, client ASC
7016                        ";
7017
7018                $result = DB::select($query);
7019            }
7020
7021            return response(['message' => 'OK', 'data' => $result]);
7022
7023        } catch (\Exception $e) {
7024            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7025        }
7026    }
7027
7028    function send_acceptance_notification($quotationId, $companyId, $userId, $updatedBy){
7029
7030        $budget = TblQuotations::where('id', $quotationId)->first();
7031
7032        if($budget != null){
7033            $to = TblToAcceptanceNotifications::where('company_id', $companyId)->get();
7034            $cc = TblCcAcceptanceNotifications::where('company_id', $companyId)->get();
7035
7036            if(count($to) > 0 && count($cc) > 0){
7037
7038                $company = TblCompanies::where('company_id', $companyId)->first();
7039
7040                $quoteId = $budget->quote_id;
7041                $amount = $this->currency($budget->amount, 1);
7042
7043                $url = env('URL') . "orders/{$quotationId}?company_id={$companyId}";
7044                $href = "<a href='{$url}'>{$quoteId}</a>";
7045
7046                $imgpath = File::get('fireservicetitan.png');
7047                $base64 = "data:image/png;base64,".base64_encode($imgpath);
7048
7049                $body = __('language.send_acceptance_notification.body_hello');
7050                $body .= __('language.send_acceptance_notification.body_message');
7051
7052                $body = str_replace('{{client}}', $budget->client, $body);
7053                $body = str_replace('{{username}}', $updatedBy, $body);
7054                $body = str_replace('{{company}}', $company->name, $body);
7055                $body = str_replace('{{amount}}', $amount, $body);
7056                $body = str_replace('{{quote_id}}', $href, $body);
7057
7058                $body .= "<p>Fire Service Titan</p>";
7059                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
7060
7061                $html = '<!DOCTYPE html>';
7062                $html .= '<html>';
7063                $html .= '<head>';
7064                $html .= '<meta charset="UTF-8">';
7065                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
7066                $html .= '</head>';
7067                $html .= '<body>';
7068                $html .= $body;
7069                $html .= '</body>';
7070                $html .= '</html>';
7071
7072
7073                $subject = __('language.send_acceptance_notification.subject');
7074                $subject = str_replace('{{quote_id}}', $quoteId, $subject);
7075
7076                $email = new \SendGrid\Mail\Mail();
7077
7078                $user = TblUsers::where('id', $userId)->first();
7079
7080                if(env('SENDGRID_STAGING')){
7081                    $email->addTo($user->email);
7082                }else{
7083
7084                    $emails = array();
7085
7086                    foreach ($to as $item) {
7087                        if(!in_array($item->email, $emails)){
7088                            array_push($emails, $item->email);
7089                            $email->addTo($item->email);
7090                        }
7091                    }
7092
7093                    foreach ($cc as $item) {
7094                        if(!in_array($item->email, $emails)){
7095                            array_push($emails, $item->email);
7096                            $email->addCc($item->email);
7097                        }
7098                    }
7099
7100                    $email->addCc($user->email);
7101                    array_push($emails, $user->email);
7102
7103                    $ccUser = TblUsers::where('name', $budget->commercial)->first();
7104
7105                    if($ccUser){
7106                        if(!in_array($ccUser->email, $emails)){
7107                            $email->addCc($ccUser->email);
7108                        }
7109                    }
7110                }
7111
7112                $email->setFrom('fire@fire.es', 'Fire Service Titan');
7113                $email->setSubject($subject);
7114                $email->addContent("text/html", $html);
7115
7116                $email->addAttachment(
7117                    $imgpath,
7118                    "image/png",
7119                    "fireservicetitan.png",
7120                    "inline",
7121                    "fireservicetitan"
7122                );
7123
7124                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
7125
7126                $response = $sendgrid->send($email);
7127                if ($response->statusCode() == 202) {
7128
7129                    $comment = "Email de aprobación automática enviada al equipo de opearciones el " . date('Y-m-d H:i:s');
7130                    $budget->last_follow_up_comment = $budget->last_follow_up_comment . "\n" . $comment;
7131
7132                    TblQuotations::where('id', $quotationId)->update(
7133                        array(
7134                            'last_follow_up_comment' => $budget->last_follow_up_comment
7135                        )
7136                    );
7137
7138                    Log::channel('email_log')->info('ID:' . $quoteId . ' - ACCEPTANCE EMAIL NOTIFICATION SENT');
7139                } else {
7140                    $error = true;
7141                    Log::channel('email_log')->error('ID:' . $quoteId . ' - ' . $response->body());
7142                }
7143
7144            }
7145        }
7146    }
7147
7148    function get_total_quotations_by_budget_status(Request $request){
7149
7150        try {
7151
7152            $data = $request->all();
7153
7154            $companyId = addslashes($data['company_id']);
7155
7156            $where = "";
7157
7158            if($companyId != 0){
7159                $where = " AND a.company_id = {$companyId} ";
7160            }else{
7161                $where = " AND a.company_id IN ({$this->companyId}";
7162            }
7163
7164            $user = null;
7165
7166            if(isset($data['commercial'])){
7167                if($data['commercial'] != 'All'){
7168                    $user = TblUsers::where('name', $data['commercial'])->first();
7169                }
7170            }else{
7171                $user = TblUsers::where('id', $this->userId)->first();
7172            }
7173
7174            $totalPendingFollowUps = 0;
7175            $totalRequestAndVisit = 0;
7176            $totalError = 0;
7177            $totalG3WError = 0;
7178
7179            $d = false;
7180
7181            if($user != null){
7182                $where .= " AND a.commercial = '{$user->name}";
7183                $d = true;
7184            }
7185
7186            if($data['commercial'] == 'All'){
7187                $d = true;
7188            }
7189
7190            if($d){
7191                $query = "SELECT
7192                            COUNT(DISTINCT a.id) total
7193                        FROM
7194                            tbl_quotations a
7195                            LEFT JOIN (
7196                                SELECT
7197                                a.id,
7198                                SUBSTRING_INDEX(
7199                                    SUBSTRING_INDEX(a.email, ',', n.digit + 1),
7200                                    ',',
7201                                    -1
7202                                ) AS email_domain
7203                                FROM
7204                                tbl_quotations a
7205                                INNER JOIN (
7206                                    SELECT
7207                                    0 AS digit
7208                                    UNION ALL
7209                                    SELECT
7210                                    1
7211                                    UNION ALL
7212                                    SELECT
7213                                    2
7214                                    UNION ALL
7215                                    SELECT
7216                                    3
7217                                    UNION ALL
7218                                    SELECT
7219                                    4
7220                                    UNION ALL
7221                                    SELECT
7222                                    5
7223                                    UNION ALL
7224                                    SELECT
7225                                    6
7226                                    UNION ALL
7227                                    SELECT
7228                                    7
7229                                    UNION ALL
7230                                    SELECT
7231                                    8
7232                                    UNION ALL
7233                                    SELECT
7234                                    9
7235                                ) n ON LENGTH(
7236                                    REPLACE(a.email, ',', '')
7237                                ) <= LENGTH(a.email)- n.digit
7238                                GROUP BY a.id
7239                            ) temp ON a.id = temp.id
7240                            LEFT JOIN tbl_companies b
7241                                ON a.company_id = b.company_id
7242                        WHERE
7243                            a.last_follow_up_date < NOW()
7244                            AND a.budget_status_id IN (2)
7245                            AND a.email IS NOT NULL
7246                            AND a.email <> ''
7247                            AND NOT EXISTS (
7248                                SELECT
7249                                1
7250                                FROM
7251                                tbl_blocked_domains bd
7252                                WHERE
7253                                temp.email_domain LIKE CONCAT('%', bd.domain, '%')
7254                                AND bd.company_id = a.company_id
7255                            )
7256                            AND a.last_follow_up_date IS NOT NULL
7257                            AND a.reason_for_not_following_up_id IS NULL
7258                            AND a.last_follow_up_date > 0
7259                            AND a.total_sent < b.limit_reminder_emails
7260                            AND a.for_add = 0 {$where}";
7261
7262                    $result = DB::select($query);
7263
7264                    $totalPendingFollowUps = $result[0]->total;
7265
7266                    $query = "SELECT
7267                                COUNT(1) total
7268                            FROM
7269                                tbl_quotations a
7270                            WHERE
7271                                a.budget_status_id IN (6, 8, 12)
7272                                {$where}
7273                            ";
7274
7275                    $result = DB::select($query);
7276
7277                    $totalRequestAndVisit = $result[0]->total;
7278
7279                    $query = "SELECT
7280                                COUNT(1) total
7281                            FROM
7282                                tbl_quotations a
7283                            WHERE
7284                                a.x_status LIKE '%Error%'
7285                                {$where}
7286                            ";
7287
7288                    $result = DB::select($query);
7289
7290                    $totalError = $result[0]->total;
7291
7292                    $query = "SELECT
7293                                COUNT(1) total
7294                                FROM
7295                                    tbl_quotations a
7296                                WHERE
7297                                    a.g3w_warning = 1
7298                                    AND a.sync_import = 1
7299                                    {$where}
7300                                ";
7301
7302                    $result = DB::select($query);
7303
7304                    $totalG3WError = $result[0]->total;
7305            }
7306
7307            return response([
7308                'message' => 'OK',
7309                'userId' => ($user) ? $user->id : null,
7310                'totalPendingFollowUps' => $totalPendingFollowUps,
7311                'totalRequestAndVisit' => $totalRequestAndVisit,
7312                'totalError' => $totalError,
7313                'totalG3WError' => $totalG3WError
7314            ]);
7315
7316
7317        } catch (\Exception $e) {
7318            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7319        }
7320
7321    }
7322
7323    function sendgrid_webhook_receiver(Request $request){
7324
7325        try {
7326
7327            $data = $request->all();
7328
7329            $jsonBody = array();
7330            $order = array();
7331            $orderEmails = array();
7332
7333            Log::channel('email_log')->info('WEBHOOK: ' . json_encode($data));
7334
7335            $quoteId = null;
7336
7337            foreach ($data as $item) {
7338                $matches = explode(".", $item['sg_message_id']);
7339                $messageId = $matches[0];
7340
7341                Log::channel('email_log')->info('MESSAGE-ID: ' . $messageId);
7342
7343                $result = TblSendgridWebhook::where('x_message_id', $messageId)->first();
7344                $quoteId = $result->quotation_id;
7345                Log::channel('email_log')->info('SENDGRID-BODY: ' . json_encode($result));
7346
7347                if(empty($order)){
7348                    $order = TblQuotations::where('x_message_id', $messageId)->first();
7349                    $quoteId = $order->id;
7350                    // if(env('SENDGRID_STAGING')){
7351                    //     $user = TblUsers::where('name', $order->updated_by)->first();
7352
7353                    //     $orderEmails = array($user->email);
7354                    // }else{
7355                        $orderEmails = explode(",", $order->email);
7356                    // }
7357                }
7358
7359                // if(in_array($item['email'], $orderEmails)){
7360                    if($result->json_body == null){
7361                        array_push($jsonBody, $item);
7362                    }else{
7363                        $jsonBody = json_decode($result->json_body);
7364                        array_push($jsonBody, $item);
7365                    }
7366                // }
7367
7368                Log::channel('email_log')->info('JSON-BODY: ' . json_encode($jsonBody));
7369
7370                TblSendgridWebhook::where('x_message_id', $messageId)->update(
7371                    array(
7372                        'json_body' => json_encode($jsonBody),
7373                        'updated_at' => date('Y-m-d H:i:s')
7374                    )
7375                );
7376
7377                if($quoteId != null){
7378                    $this->get_files($quoteId);
7379                }
7380
7381                Cache::flush();
7382            }
7383
7384        } catch (\Exception $e) {
7385            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7386        }
7387
7388    }
7389
7390    function isEmailValid($email) {
7391        // Regular expression pattern for email validation
7392        $pattern = '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/';
7393
7394        // Check if the email matches the pattern
7395        if (preg_match($pattern, $email)) {
7396            return true; // Valid email
7397        } else {
7398            return false; // Invalid email
7399        }
7400    }
7401
7402    function list_email_status($companyId){
7403
7404        try {
7405
7406            $companyId = addslashes($companyId);
7407
7408            $where = "";
7409            if($companyId != 0){
7410                $where = " company_id = {$companyId} ";
7411            }else{
7412                $where = " company_id IN ({$this->companyId})";
7413            }
7414
7415            $query = "SELECT DISTINCT x_status FROM tbl_quotations WHERE {$where} AND x_status IS NOT NULL";
7416            $result = DB::select($query);
7417
7418            return response([
7419                'message' => 'OK',
7420                'data' => $result,
7421            ]);
7422
7423
7424        } catch (\Exception $e) {
7425            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7426        }
7427
7428    }
7429
7430    function list_quotation_analytics_commercial(Request $request){
7431
7432        try {
7433
7434            $data = $request->all();
7435            $companyId = addslashes($data['company_id']);
7436            $field = $data['field'];
7437
7438            $where = "";
7439            $whereYear = "";
7440            $dateLflArray = array();
7441            $companyIds = $this->companyIds;
7442            $whereQ = "";
7443
7444            $acc = "";
7445            if($field == 'acceptance_date'){
7446                $acc = " AND q.acceptance_date IS NOT NULL ";
7447                // $field = 'created_at';
7448
7449                if(@$data['data_to_display'] == 4){
7450                    $field = 'created_at';
7451                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7452                    $whereQ .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7453                }
7454            }else{
7455                $field = 'created_at';
7456                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7457                $whereQ .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7458            }
7459
7460            if(isset($data['years']) && $data['years'] != null){
7461                $years = implode(',', $data['years']);
7462                if(count($data['years']) > 0){
7463                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
7464                }
7465            }
7466
7467            if($companyId != 0){
7468                $companyIds = array($companyId);
7469            }
7470
7471            foreach ($companyIds as $v) {
7472
7473                $lflWhere = " AND q.company_id = {$v} ";
7474
7475                $query = "SELECT
7476                            CONCAT(
7477                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
7478                                ' - ',
7479                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
7480                            ) AS date_like,
7481                            YEAR(q.{$field}) 'year',
7482                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
7483                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
7484                            {$v} 'company_id'
7485                        FROM
7486                            tbl_quotations q
7487                        WHERE
7488                            q.{$field} IS NOT NULL
7489                            AND q.for_add != 1
7490                            {$lflWhere}
7491                            {$whereYear}
7492                        GROUP BY YEAR(q.{$field})
7493                        ORDER BY YEAR(q.{$field}) DESC";
7494
7495                $dateLike = DB::select($query);
7496
7497                $dateLflArray[$v] = $dateLike;
7498            }
7499
7500            $isFy = true;
7501
7502            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
7503                $isFy = false;
7504                $ytdArray = array();
7505                $ytdAcceptanceArray = array();
7506                $lflCompanyIds = array();
7507                foreach ($dateLflArray as $k => $v) {
7508                    foreach ($dateLflArray[$k] as $item) {
7509                        $year = $item->year;
7510                        $now = date('m-d');
7511                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
7512                    }
7513
7514                    $ytdArray = implode(' OR ', $ytdArray);
7515                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
7516                    $ytdArray = array();
7517                }
7518
7519                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7520                $where .= " AND ({$lflCompanyIds}";
7521                $whereQ .= " AND ({$lflCompanyIds}";
7522            }
7523
7524            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
7525                $isFy = false;
7526                $lflArray = array();
7527                $ytdAcceptanceArray = array();
7528                $lflCompanyIds = array();
7529                foreach ($dateLflArray as $k => $v) {
7530                    foreach ($dateLflArray[$k] as $item) {
7531                        $year = $item->year;
7532                        $min_date_like = $item->min_date_like;
7533                        $max_date_like = $item->max_date_like;
7534                        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}')");
7535                    }
7536
7537                    $lflArray = implode(' OR ', $lflArray);
7538                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
7539                    $lflArray = array();
7540                }
7541
7542                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7543                $where .= " AND ({$lflCompanyIds}";
7544                $whereQ .= " AND ({$lflCompanyIds}";
7545            }
7546
7547            if($isFy){
7548                if($companyId != 0){
7549                    $where .= " AND q.company_id = {$companyId} ";
7550                    $whereQ .= " AND q.company_id = {$companyId} ";
7551                }else{
7552                    $where .= " AND q.company_id IN ({$this->companyId})";
7553                    $whereQ .= " AND q.company_id IN ({$this->companyId})";
7554                }
7555            }
7556
7557            if(isset($data['source']) && $data['source'] != null){
7558                $where .= " AND s.name = '{$data['source']}'";
7559            }
7560
7561            if(isset($data['month']) && $data['month'] != null){
7562                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
7563            }
7564
7565            if(isset($data['week']) && $data['week'] != null){
7566                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
7567            }
7568
7569            if(isset($data['commercial']) && $data['commercial'] != null){
7570                $where .= " AND q.commercial = '{$data['commercial']}'";
7571            }
7572
7573            if(isset($data['created_by']) && $data['created_by'] != null){
7574                $where .= " AND q.created_by = '{$data['created_by']}'";
7575            }
7576
7577            if(isset($data['budget_type']) && $data['budget_type'] != null){
7578                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
7579            }
7580
7581            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
7582                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
7583            }
7584
7585            if(isset($data['budget_status']) && $data['budget_status'] != null){
7586                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
7587            }
7588
7589            if(isset($data['client_type']) && $data['client_type'] != null){
7590                $where .= " AND ct.customer_type_id = {$data['client_type']}";
7591            }
7592
7593            if(isset($data['segment_id']) && $data['segment_id'] != null){
7594                $where .= " AND q.segment_id = {$data['segment_id']}";
7595            }
7596
7597            $col = "1";
7598
7599            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
7600                if($data['data_to_display'] == 1){
7601                    $col = "1";
7602                }
7603
7604                if($data['data_to_display'] == 2){
7605                    $col = "q.amount";
7606                }
7607            }
7608
7609            $query = "SELECT
7610                        q.commercial 'name',
7611                        COUNT(q.commercial) totalCommercial
7612                    FROM tbl_quotations q
7613                    WHERE
7614                        q.for_add = 0
7615                        AND q.{$field} IS NOT NULL
7616                        {$whereQ}
7617                    GROUP BY q.commercial
7618                    HAVING COUNT(q.commercial) > 0
7619                    ORDER BY totalCommercial DESC";
7620
7621            $resultCommercials = DB::select($query);
7622
7623            $now = TblQuotations::whereIn('company_id', $this->companyIds)->orderBy($field, 'DESC')->pluck($field)->first();
7624            $weekNumber = date('W', strtotime($now));
7625            $thisWeek = date('Y-m-d', strtotime($now . " - " . (date('N', strtotime($now)) - 1) . " days"));
7626
7627            $query = "SELECT
7628                        q.commercial 'name',
7629                        COUNT(q.commercial) totalCommercial
7630                    FROM tbl_quotations q
7631                    WHERE
7632                        q.for_add = 0
7633                        AND q.{$field} IS NOT NULL
7634                        AND YEARWEEK(q.{$field}, 1) = YEARWEEK(NOW(), 1)
7635                        {$whereQ}
7636                    GROUP BY q.commercial
7637                    HAVING COUNT(q.commercial) > 0
7638                    ORDER BY totalCommercial DESC";
7639
7640            $resultCommercialsOrder = DB::select($query);
7641
7642            $namesToRemove = array();
7643
7644            foreach ($resultCommercialsOrder as $item) {
7645                $namesToRemove[$item->name] = true;
7646            }
7647
7648            $resultArray = [];
7649            foreach ($resultCommercials as $item) {
7650                if (!isset($namesToRemove[$item->name])) {
7651                    $resultArray[] = $item;
7652                }
7653            }
7654
7655            $resultCommercials = array_merge($resultCommercialsOrder, $resultArray);
7656
7657            $cols = "";
7658
7659            $colsGroupConcatIds = "";
7660
7661            foreach ($resultCommercials as $item) {
7662                $cols .= ",COALESCE(
7663                    SUM(
7664                        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
7665                    ), 0
7666                ) '{$item->name}'";
7667
7668                $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}'";
7669            }
7670
7671            $cols .= ",COALESCE(
7672                SUM(
7673                    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
7674                ), 0
7675            ) total";
7676
7677            if(@$data['data_to_display'] == 3){
7678
7679                $cols = "";
7680
7681                foreach ($resultCommercials as $item) {
7682                    $cols .= ",COALESCE(
7683                        (
7684                            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)
7685                        ) /
7686                        (
7687                            SUM(CASE WHEN q.commercial = '{$item->name}' AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END)
7688                        )
7689                    , 0) '{$item->name}'";
7690                }
7691
7692                $cols .= ",COALESCE(
7693                    (
7694                        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)
7695                    ) /
7696                    (
7697                        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)
7698                    )
7699                , 0) total";
7700            }
7701
7702            if(@$data['data_to_display'] == 4){
7703
7704                $cols = "";
7705
7706                foreach ($resultCommercials as $item) {
7707                    $cols .= ",COALESCE(
7708                        (
7709                            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)
7710                        ) /
7711                        (
7712                            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)
7713                        ) * 100
7714                    , 0) '{$item->name}'";
7715                }
7716
7717                $cols .= ",COALESCE(
7718                    (
7719                        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)
7720                    ) /
7721                    (
7722                        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)
7723                    ) * 100
7724                , 0) total";
7725            }
7726
7727            $query  = "SELECT
7728                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
7729                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
7730                            LPAD(WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'week',
7731                            DATE_FORMAT(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY), '%W, %M %e') 'namedate',
7732                            GROUP_CONCAT(
7733                                CASE WHEN q.{$field} IS NOT NULL
7734                                THEN q.id END
7735                            ) AS groupConcatIds
7736                            {$colsGroupConcatIds}
7737                            {$cols}
7738                        FROM
7739                            tbl_quotations q
7740                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
7741                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
7742                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
7743                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
7744                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
7745                        WHERE
7746                            q.{$field} IS NOT NULL
7747                            AND q.for_add != 1
7748                            AND q.budget_type_id != 7
7749                            AND q.budget_type_id IS NOT NULL
7750                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
7751                            {$where}
7752                            {$whereYear}
7753                        GROUP BY
7754                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
7755                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
7756                            WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) WITH ROLLUP
7757                        ORDER BY
7758                            YEAR DESC,
7759                            MONTH ASC,
7760                            WEEK ASC,
7761                            DATE_FORMAT(q.{$field}, '%e') ASC";
7762
7763            $value = Cache::get(base64_encode($query));
7764
7765            if(!$value){
7766                $result = DB::select($query);
7767
7768                Cache::put(base64_encode($query), $result, 600);
7769            }else{
7770                $result = $value;
7771            }
7772
7773            return response([
7774                'message' => 'OK',
7775                'data' => $result,
7776                'commercials' => $resultCommercials
7777            ]);
7778
7779        } catch (\Exception $e) {
7780            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7781        }
7782    }
7783
7784    function clear_open_data($companyId){
7785
7786        try {
7787
7788            $companyIds = array($companyId);
7789            if($companyId == 0){
7790                $companyIds = $this->companyIds;
7791            }
7792
7793            $user = TblUsers::where('id', $this->userId)->first();
7794
7795            if(count($companyIds) > 0){
7796
7797                foreach ($companyIds as $id) {
7798                    $startedAt = date('Y-m-d H:i:s');
7799                    $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')");
7800
7801                    TblOrdersUpdateLogs::create(
7802                        array(
7803                            'company_id' => $id,
7804                            'to_process' => 'Orders',
7805                            'status' => 'success',
7806                            'for_add_deleted_affected_rows' => $affectedRows,
7807                            'processed_by' => $user->name,
7808                            'started_at' => $startedAt,
7809                            'ended_at' => date('Y-m-d H:i:s')
7810                        )
7811                    );
7812                }
7813            }
7814
7815            return response([
7816                'message' => 'OK',
7817            ]);
7818
7819        } catch (\Exception $e) {
7820            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7821        }
7822
7823    }
7824
7825    function list_quotation_analytics_order_size(Request $request){
7826
7827        try {
7828
7829            $data = $request->all();
7830            $companyId = addslashes($data['company_id']);
7831            $field = $data['field'];
7832
7833            $where = "";
7834            $dateLflArray = array();
7835            $whereYear = "";
7836            $companyIds = $this->companyIds;
7837
7838            if($field == 'acceptance_date'){
7839                if(@$data['data_to_display'] == 4){
7840                    $field = 'created_at';
7841                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7842                }
7843            }else{
7844                $field = 'created_at';
7845                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7846            }
7847
7848            if(isset($data['years']) && $data['years'] != null){
7849                $years = implode(',', $data['years']);
7850                if(count($data['years']) > 0){
7851                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
7852                }
7853            }
7854
7855            if($companyId != 0){
7856                $companyIds = array($companyId);
7857            }
7858
7859            foreach ($companyIds as $v) {
7860
7861                $lflWhere = " AND q.company_id = {$v} ";
7862
7863                $query = "SELECT
7864                            CONCAT(
7865                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
7866                                ' - ',
7867                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
7868                            ) AS date_like,
7869                            YEAR(q.{$field}) 'year',
7870                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
7871                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
7872                            {$v} 'company_id'
7873                        FROM
7874                            tbl_quotations q
7875                        WHERE
7876                            q.{$field} IS NOT NULL
7877                            AND q.for_add != 1
7878                            {$lflWhere}
7879                            {$whereYear}
7880                        GROUP BY YEAR(q.{$field})
7881                        ORDER BY YEAR(q.{$field}) DESC";
7882
7883                $dateLike = DB::select($query);
7884
7885                $dateLflArray[$v] = $dateLike;
7886            }
7887
7888            $isFy = true;
7889
7890            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
7891                $isFy = false;
7892                $ytdArray = array();
7893                $ytdAcceptanceArray = array();
7894                $lflCompanyIds = array();
7895                foreach ($dateLflArray as $k => $v) {
7896                    foreach ($dateLflArray[$k] as $item) {
7897                        $year = $item->year;
7898                        $now = date('m-d');
7899                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
7900                    }
7901
7902                    $ytdArray = implode(' OR ', $ytdArray);
7903                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
7904                    $ytdArray = array();
7905                }
7906
7907                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7908                $where .= " AND ({$lflCompanyIds}";
7909            }
7910
7911            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
7912                $isFy = false;
7913                $lflArray = array();
7914                $ytdAcceptanceArray = array();
7915                $lflCompanyIds = array();
7916                foreach ($dateLflArray as $k => $v) {
7917                    foreach ($dateLflArray[$k] as $item) {
7918                        $year = $item->year;
7919                        $min_date_like = $item->min_date_like;
7920                        $max_date_like = $item->max_date_like;
7921                        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}')");
7922                    }
7923
7924                    $lflArray = implode(' OR ', $lflArray);
7925                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
7926                    $lflArray = array();
7927                }
7928
7929                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7930                $where .= " AND ({$lflCompanyIds}";
7931            }
7932
7933            if($isFy){
7934                if($companyId != 0){
7935                    $where .= " AND q.company_id = {$companyId} ";
7936                }else{
7937                    $where .= " AND q.company_id IN ({$this->companyId})";
7938                }
7939            }
7940
7941            if(isset($data['source']) && $data['source'] != null){
7942                $where .= " AND s.name = '{$data['source']}'";
7943            }
7944
7945            if(isset($data['source']) && $data['source'] != null){
7946                $where .= " AND s.name = '{$data['source']}'";
7947            }
7948
7949            if(isset($data['commercial']) && $data['commercial'] != null){
7950                $where .= " AND q.commercial = '{$data['commercial']}'";
7951            }
7952
7953            if(isset($data['created_by']) && $data['created_by'] != null){
7954                $where .= " AND q.created_by = '{$data['created_by']}'";
7955            }
7956
7957            if(isset($data['budget_type']) && $data['budget_type'] != null){
7958                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
7959            }
7960
7961            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
7962                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
7963            }
7964
7965            if(isset($data['budget_status']) && $data['budget_status'] != null){
7966                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
7967            }
7968
7969            if(isset($data['client_type']) && $data['client_type'] != null){
7970                $where .= " AND ct.customer_type_id = {$data['client_type']}";
7971            }
7972
7973            if(isset($data['segment_id']) && $data['segment_id'] != null){
7974                $where .= " AND q.segment_id = {$data['segment_id']}";
7975            }
7976
7977            $col = "q.one";
7978
7979            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
7980                if($data['data_to_display'] == 1){
7981                    $col = "q.one";
7982                }
7983
7984                if($data['data_to_display'] == 2){
7985                    $col = "q.amount";
7986                }
7987            }
7988
7989            if((isset($data['start_date']) && $data['start_date'] != null) && isset($data['end_date']) && $data['end_date'] != null){
7990                $where .= " AND q.{$field} BETWEEN '{$data['start_date']}' AND '{$data['end_date']}";
7991            }elseif((isset($data['start_date']) && $data['start_date'] == null || $data['start_date'] == "") && isset($data['end_date']) && $data['end_date'] != null){
7992                $where .= " AND q.{$field} = '{$data['end_date']}";
7993            }
7994
7995            $whereQ = $where;
7996
7997            $sortBy = array(
7998                0 => 'q.amount < 100',
7999                1 => 'q.amount BETWEEN 100 AND 500',
8000                2 => 'q.amount BETWEEN 500 AND 2000',
8001                3 => 'q.amount BETWEEN 2000 AND 10000',
8002                4 => 'q.amount BETWEEN 10000 AND 30000',
8003                5 => 'q.amount BETWEEN 30000 AND 100000',
8004                6 => 'q.amount BETWEEN 100000 AND 999999999999'
8005            );
8006
8007            $query = "SELECT
8008                        q.commercial 'name',
8009                        COUNT(q.commercial) totalCommercial
8010                    FROM tbl_quotations q
8011                    LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8012                    LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8013                    LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8014                    LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8015                    WHERE
8016                        q.for_add = 0
8017                        AND q.{$field} IS NOT NULL
8018                        AND q.for_add != 1
8019                        AND q.budget_type_id != 7
8020                        AND q.budget_type_id IS NOT NULL
8021                        {$whereQ}
8022                        {$whereYear}
8023                    GROUP BY q.commercial
8024                    HAVING COUNT(q.commercial) > 0
8025                    ORDER BY totalCommercial DESC";
8026
8027            $resultCommercials = DB::select($query);
8028
8029            if(isset($data['sort_by'])){
8030                if($data['sort_by'] != 7){
8031                    $s = $sortBy[$data['sort_by']];
8032                    $whereQ .= " AND {$s} ";
8033                }
8034            }
8035
8036            $num = "COUNT(1)";
8037
8038            if(@$data['data_to_display'] == 2){
8039                $num = "SUM(q.amount)";
8040            }
8041
8042            if(@$data['data_to_display'] == 3){
8043                $num = "SUM(q.amount) / COUNT(1)";
8044            }
8045
8046            if(@$data['data_to_display'] == 4){
8047                $num = "(SUM(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) / COUNT(q.created_at) * 100)";
8048            }
8049
8050            $query = "SELECT
8051                    q.commercial 'name',
8052                    COUNT(q.commercial) totalCommercial,
8053                    {$num} num
8054                FROM tbl_quotations q
8055                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8056                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8057                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8058                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8059                WHERE
8060                    q.for_add = 0
8061                    AND q.{$field} IS NOT NULL
8062                    AND q.for_add != 1
8063                    AND q.budget_type_id != 7
8064                    AND q.budget_type_id IS NOT NULL
8065                    {$whereQ}
8066                    {$whereYear}
8067                GROUP BY q.commercial
8068                HAVING COUNT(q.commercial) > 0
8069                ORDER BY num DESC";
8070
8071            $resultCommercialsOrder = DB::select($query);
8072
8073            foreach ($resultCommercialsOrder as $item) {
8074                $namesToRemove[$item->name] = true;
8075            }
8076
8077            $resultArray = [];
8078            foreach ($resultCommercials as $item) {
8079                if (!isset($namesToRemove[$item->name])) {
8080                    $resultArray[] = $item;
8081                }
8082            }
8083
8084            $resultCommercials = array_merge($resultCommercialsOrder, $resultArray);
8085
8086            $cols = "";
8087
8088            $colsGroupConcatIds = "";
8089
8090            foreach ($resultCommercials as $item) {
8091                $cols .= ",COALESCE(
8092                    SUM(
8093                        CASE WHEN q.commercial = '{$item->name}' THEN {$col} ELSE 0 END
8094                    ), 0
8095                ) '{$item->name}'";
8096
8097                $colsGroupConcatIds .= ",GROUP_CONCAT(CASE WHEN q.commercial = '{$item->name}' THEN q.id END) 'groupConcatIds-{$item->name}'";
8098            }
8099
8100            $cols .= ",COALESCE(
8101                SUM(
8102                    CASE WHEN q.commercial IS NOT NULL THEN {$col} ELSE 0 END
8103                ), 0
8104            ) total";
8105
8106            $range = "CASE
8107                        WHEN amount < 100 THEN '< 100€'
8108                        WHEN amount BETWEEN 100 AND 500 THEN '100€ - 500€'
8109                        WHEN amount BETWEEN 500 AND 2000 THEN '500€ - 2k€'
8110                        WHEN amount BETWEEN 2000 AND 10000 THEN '2k€ - 10k€'
8111                        WHEN amount BETWEEN 10000 AND 30000 THEN '10k€ - 30k€'
8112                        WHEN amount BETWEEN 30000 AND 100000 THEN '30k€ - 100k€'
8113                        WHEN amount BETWEEN 100000 AND 999999999999 THEN '> 100k€'
8114                    END AS amount_range";
8115
8116            if(@$data['data_to_display'] == 3){
8117
8118                $range = "CASE
8119                            WHEN SUM(amount) / COUNT(1) < 100 THEN '< 100€'
8120                            WHEN SUM(amount) / COUNT(1) BETWEEN 100 AND 500 THEN '100€ - 500€'
8121                            WHEN SUM(amount) / COUNT(1) BETWEEN 500 AND 2000 THEN '500€ - 2k€'
8122                            WHEN SUM(amount) / COUNT(1) BETWEEN 2000 AND 10000 THEN '2k€ - 10k€'
8123                            WHEN SUM(amount) / COUNT(1) BETWEEN 10000 AND 30000 THEN '10k€ - 30k€'
8124                            WHEN SUM(amount) / COUNT(1) BETWEEN 30000 AND 100000 THEN '30k€ - 100k€'
8125                            WHEN SUM(amount) / COUNT(1) BETWEEN 100000 AND 999999999999 THEN '> 100k€'
8126                        END AS amount_range";
8127
8128                $cols = "";
8129
8130                foreach ($resultCommercials as $item) {
8131                    $cols .= ",COALESCE(
8132                        (
8133                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.amount END)
8134                        ) /
8135                        (
8136                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.one END)
8137                        )
8138                    , 0) '{$item->name}'";
8139                }
8140
8141                $cols .= ",COALESCE(
8142                    (
8143                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.amount END)
8144                    ) /
8145                    (
8146                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.one END)
8147                    )
8148                , 0) total";
8149            }
8150
8151            if(@$data['data_to_display'] == 4){
8152
8153                $cols = "";
8154
8155                foreach ($resultCommercials as $item) {
8156                    $cols .= ",COALESCE(
8157                        (
8158                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.acceptanceDate END)
8159                        ) /
8160                        (
8161                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.createdAt END)
8162                        ) * 100
8163                    , 0) '{$item->name}'";
8164                }
8165
8166                $cols .= ",COALESCE(
8167                    (
8168                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.acceptanceDate END)
8169                    ) /
8170                    (
8171                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.createdAt END)
8172                    ) * 100
8173                , 0) total";
8174            }
8175
8176            $query  = "WITH amount_ranges AS (
8177                            SELECT '< 100€' AS amount_range
8178                            UNION ALL SELECT '100€ - 500€'
8179                            UNION ALL SELECT '500€ - 2k€'
8180                            UNION ALL SELECT '2k€ - 10k€'
8181                            UNION ALL SELECT '10k€ - 30k€'
8182                            UNION ALL SELECT '30k€ - 100k€'
8183                            UNION ALL SELECT '> 100k€'
8184                        )
8185
8186                        SELECT
8187                            ar.amount_range,
8188                             GROUP_CONCAT(
8189                                q.id
8190                            ) AS groupConcatIds
8191                            {$colsGroupConcatIds}
8192                            {$cols}
8193                        FROM
8194                            amount_ranges ar
8195                        LEFT JOIN (
8196                            SELECT
8197                                commercial,
8198                                GROUP_CONCAT(
8199                                    CASE WHEN q.{$field} IS NOT NULL THEN id END
8200                                ) id,
8201                                amount AS amount,
8202                                COUNT(CASE WHEN q.created_at IS NOT NULL THEN 1 END) createdAt,
8203                                COUNT(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 END) acceptanceDate,
8204                                COUNT(1) AS one,
8205                                {$range}
8206                            FROM
8207                                tbl_quotations q
8208                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8209                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8210                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8211                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8212                            WHERE
8213                                q.{$field} IS NOT NULL
8214                                AND q.for_add = 0
8215                                AND (bt.budget_type_group IS NOT NULL OR bt.name IS NULL)
8216                                AND q.for_add != 1
8217                                AND q.budget_type_id != 7
8218                                AND q.budget_type_id IS NOT NULL
8219                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
8220                                {$where}
8221                                {$whereYear}
8222                            GROUP BY
8223                                commercial,
8224                                id
8225                        ) AS q ON ar.amount_range = q.amount_range
8226                        GROUP BY
8227                            ar.amount_range WITH ROLLUP
8228                        ORDER BY
8229                            CASE
8230                                WHEN ar.amount_range = '< 100€' THEN 1
8231                                WHEN ar.amount_range = '100€ - 500€' THEN 2
8232                                WHEN ar.amount_range = '500€ - 2k€' THEN 3
8233                                WHEN ar.amount_range = '2k€ - 10k€' THEN 4
8234                                WHEN ar.amount_range = '10k€ - 30k€' THEN 5
8235                                WHEN ar.amount_range = '30k€ - 100k€' THEN 6
8236                                ELSE 7
8237                            END";
8238
8239            $value = Cache::get(base64_encode($query));
8240
8241            if(!$value){
8242                $result = DB::select($query);
8243
8244                Cache::put(base64_encode($query), $result, 600);
8245            }else{
8246                $result = $value;
8247            }
8248
8249            return response([
8250                'message' => 'OK',
8251                'data' => $result,
8252                'commercials' => $resultCommercials
8253            ]);
8254
8255        } catch (\Exception $e) {
8256            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8257        }
8258
8259    }
8260
8261    function send_email_template_preview($emailTemplateId){
8262
8263        try {
8264
8265            $emailTemplateId = addslashes($emailTemplateId);
8266
8267            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
8268
8269            $user   = TblUsers::where('id', $this->userId)->first();
8270            $error  = false;
8271
8272            $toEmail = $user->email;
8273
8274            $availableParameters = [
8275                'quote_id',
8276                'company_id',
8277                'client',
8278                'client_type',
8279                'phone_number',
8280                'email',
8281                'issue_date',
8282                'request_date',
8283                'duration',
8284                'invoice_number',
8285                'type',
8286                'acceptance_date',
8287                'status',
8288                'source',
8289                'amount',
8290                'reason_for_not_following_up',
8291                'last_follow_up_date',
8292                'last_follow_up_comment',
8293                'reason_for_rejection_id',
8294                'reason_for_rejection',
8295                'commercial',
8296                'created_at',
8297                'created_by',
8298                'updated_at',
8299                'updated_by'
8300            ];
8301
8302            $dateParameters = [
8303                'issue_date',
8304                'request_date',
8305                'acceptance_date',
8306                'last_follow_up_date',
8307                'created_at',
8308                'updated_at',
8309            ];
8310
8311            if($this->locale == 'es'){
8312                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
8313            }
8314
8315            if($this->locale == 'es'){
8316                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
8317            }
8318
8319            $body = $emailTemplate->html;
8320            $subject = $emailTemplate->subject;
8321
8322            preg_match_all('/{{(.*?)}}/', $body, $matches);
8323
8324            $parameters = $matches[1];
8325
8326            $result = TblQuotations::where('for_add', 0)->whereIn('company_id', $this->companyIds)->first();
8327
8328            foreach ($parameters as $parameter) {
8329
8330                if(in_array($parameter, $dateParameters)){
8331                    if($result->{$parameter}){
8332                        $result->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result->{$parameter})));
8333                    }
8334                }
8335
8336                if(in_array($parameter, $availableParameters)){
8337                    $body = str_replace('{{' . $parameter . '}}', $result->{$parameter}, $body);
8338                }
8339            }
8340
8341            preg_match_all('/{{(.*?)}}/', $subject, $matches);
8342
8343            $parameters = $matches[1];
8344
8345            foreach ($parameters as $parameter) {
8346
8347                if(in_array($parameter, $dateParameters)){
8348                    if($result->{$parameter}){
8349                        $result->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result->{$parameter})));
8350                    }
8351                }
8352
8353                if(in_array($parameter, $availableParameters)){
8354                    $subject = str_replace('{{' . $parameter . '}}', $result->{$parameter}, $subject);
8355                }
8356            }
8357
8358
8359            $email = new \SendGrid\Mail\Mail();
8360
8361            $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
8362
8363            foreach ($templateFiles as $item) {
8364                $f = storage_path('app/public/uploads/' . $item->filename);
8365                $imgpath = file_get_contents($f);
8366                $mimeType = mime_content_type($f);
8367
8368                $email->addAttachment(
8369                    $imgpath,
8370                    $mimeType,
8371                    str_replace(' ', '', $item->original_name),
8372                    "inline",
8373                    str_replace(' ', '', $item->original_name),
8374                );
8375
8376                $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
8377            }
8378
8379            $html = '<!DOCTYPE html>';
8380            $html .= '<html>';
8381            $html .= '<head>';
8382            $html .= '<meta charset="UTF-8">';
8383            $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
8384            $html .= '</head>';
8385            $html .= '<body>';
8386            $html .= $body;
8387            $html .= '</body>';
8388            $html .= '</html>';
8389
8390            if($toEmail != null){
8391
8392                $companyEmail = null;
8393
8394                if($emailTemplate->from_id != null){
8395                    $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
8396                }else{
8397                    $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result->company_id)->first();
8398                }
8399
8400                if(!$companyEmail){
8401                    return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
8402                }
8403
8404                $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
8405                $email->setSubject($subject);
8406                $email->addTo($toEmail);
8407                $email->addContent("text/html", $html);
8408
8409                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
8410
8411                $response = $sendgrid->send($email);
8412                if ($response->statusCode() == 202) {
8413                    return response(['message' => 'OK']);
8414                }
8415            }
8416
8417            return response(['message' => 'KO']);
8418
8419        } catch (\Exception $e) {
8420            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8421        }
8422
8423    }
8424
8425    function list_quotation_analytics_by_types_of_budgets_company_per_week(Request $request){
8426
8427        try {
8428
8429            $data = $request->all();
8430            $companyId = addslashes($data['company_id']);
8431            $field = $data['field'];
8432
8433            $where = "";
8434            $whereYear = "";
8435            $dateLflArray = array();
8436            $companyIds = $this->companyIds;
8437
8438            $acc = "";
8439            if($field == 'acceptance_date'){
8440                $acc = " AND q.acceptance_date IS NOT NULL ";
8441                // $field = 'created_at';
8442
8443                if(@$data['data_to_display'] == 4){
8444                    $field = 'created_at';
8445                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8446                }
8447            }else{
8448                $field = 'created_at';
8449                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8450            }
8451
8452            if($companyId != 0){
8453                $companyIds = array($companyId);
8454            }
8455
8456            if(isset($data['years']) && $data['years'] != null){
8457                $years = implode(',', $data['years']);
8458                if(count($data['years']) > 0){
8459                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
8460                }
8461            }
8462
8463            foreach ($companyIds as $v) {
8464
8465                $lflWhere = " AND q.company_id = {$v} ";
8466
8467                $query = "SELECT
8468                            CONCAT(
8469                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
8470                                ' - ',
8471                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
8472                            ) AS date_like,
8473                            YEAR(q.{$field}) 'year',
8474                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
8475                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
8476                            {$v} 'company_id'
8477                        FROM
8478                            tbl_quotations q
8479                        WHERE
8480                            q.{$field} IS NOT NULL
8481                            AND q.for_add != 1
8482                            {$lflWhere}
8483                            {$whereYear}
8484                        GROUP BY YEAR(q.{$field})
8485                        ORDER BY YEAR(q.{$field}) DESC";
8486
8487                $dateLike = DB::select($query);
8488
8489                $dateLflArray[$v] = $dateLike;
8490            }
8491
8492            $isFy = true;
8493
8494            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
8495                $isFy = false;
8496                $ytdArray = array();
8497                $ytdAcceptanceArray = array();
8498                $lflCompanyIds = array();
8499                foreach ($dateLflArray as $k => $v) {
8500                    foreach ($dateLflArray[$k] as $item) {
8501                        $year = $item->year;
8502                        $now = date('m-d');
8503                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
8504                    }
8505
8506                    $ytdArray = implode(' OR ', $ytdArray);
8507                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
8508                    $ytdArray = array();
8509                }
8510
8511                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8512                $where .= " AND ({$lflCompanyIds}";
8513            }
8514
8515            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
8516                $isFy = false;
8517                $lflArray = array();
8518                $ytdAcceptanceArray = array();
8519                $lflCompanyIds = array();
8520                foreach ($dateLflArray as $k => $v) {
8521                    foreach ($dateLflArray[$k] as $item) {
8522                        $year = $item->year;
8523                        $min_date_like = $item->min_date_like;
8524                        $max_date_like = $item->max_date_like;
8525                        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}')");
8526                    }
8527
8528                    $lflArray = implode(' OR ', $lflArray);
8529                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
8530                    $lflArray = array();
8531                }
8532
8533                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8534                $where .= " AND ({$lflCompanyIds}";
8535            }
8536
8537            if($isFy){
8538                if($companyId != 0){
8539                    $where .= " AND q.company_id = {$companyId} ";
8540                }else{
8541                    $where .= " AND q.company_id IN ({$this->companyId})";
8542                }
8543            }
8544
8545            if(isset($data['source']) && $data['source'] != null){
8546                $where .= " AND s.name = '{$data['source']}'";
8547            }
8548
8549            if(isset($data['month']) && $data['month'] != null){
8550                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
8551            }
8552
8553            if(isset($data['week']) && $data['week'] != null){
8554                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
8555            }
8556
8557            if(isset($data['commercial']) && $data['commercial'] != null){
8558                $where .= " AND q.commercial = '{$data['commercial']}'";
8559            }
8560
8561            if(isset($data['created_by']) && $data['created_by'] != null){
8562                $where .= " AND q.created_by = '{$data['created_by']}'";
8563            }
8564
8565            if(isset($data['budget_type']) && $data['budget_type'] != null){
8566                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
8567            }
8568
8569            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
8570                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
8571            }
8572
8573            if(isset($data['budget_status']) && $data['budget_status'] != null){
8574                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
8575            }
8576
8577            if(isset($data['client_type']) && $data['client_type'] != null){
8578                $where .= " AND ct.customer_type_id = {$data['client_type']}";
8579            }
8580
8581            if(isset($data['segment_id']) && $data['segment_id'] != null){
8582                $where .= " AND q.segment_id = {$data['segment_id']}";
8583            }
8584
8585            $col = "1";
8586
8587            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
8588                if($data['data_to_display'] == 1){
8589                    $col = "1";
8590                }
8591
8592                if($data['data_to_display'] == 2){
8593                    $col = "q.amount";
8594                }
8595            }
8596
8597            $budgetTypes = TblBudgetTypes::orderByRaw("ISNULL(priority), priority ASC")->get();
8598            $cols = "";
8599            foreach ($budgetTypes as $item) {
8600                if($item->name == '' || $item->name == null){
8601                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} ELSE 0 END), 0) AS 'Otros'";
8602                }else{
8603                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN {$col} ELSE 0 END), 0) AS '{$item->name}'";
8604                }
8605            }
8606
8607            $budgetTypeGroups = TblBudgetTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
8608
8609            $colsGroups = ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} END), 0) AS Otros";
8610
8611            foreach ($budgetTypeGroups as $item) {
8612                $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8613                $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}'";
8614                $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}'";
8615            }
8616
8617            $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";
8618
8619            $col = $colsGroups . $cols;
8620
8621            if(@$data['data_to_display'] == 3){
8622
8623                $cols = "";
8624                foreach ($budgetTypes as $item) {
8625                    if($item->name == '' || $item->name == null){
8626                        $cols .= ",COALESCE(
8627                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount ELSE 0 END) /
8628                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 ELSE 0 END) * 100
8629                                    , 0) AS 'Otros'";
8630                    }else{
8631                        $cols .= ", COALESCE(
8632                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN q.amount ELSE 0 END) /
8633                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN 1 ELSE 0 END)
8634                                    , 0) AS '{$item->name}'";
8635                    }
8636                }
8637
8638                $colsGroups = ",COALESCE(
8639                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount END)) /
8640                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 END))
8641                            , 0) Otros";
8642
8643                foreach ($budgetTypeGroups as $item) {
8644                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8645                    $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}'";
8646                    $colsGroups .= ",COALESCE(
8647                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.amount END)) /
8648                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN 1 END))
8649                                    , 0) '{$budgetTypeGroupName}'";
8650                }
8651
8652                $colsGroups .= ",COALESCE(
8653                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.amount END)) /
8654                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END))
8655                                , 0) total";
8656
8657                $col = $colsGroups . $cols;
8658            }
8659
8660            if(@$data['data_to_display'] == 4){
8661
8662                $cols = "";
8663
8664                foreach ($budgetTypes as $item) {
8665
8666                    if($item->name == '' || $item->name == null){
8667                        $cols .= ",COALESCE(
8668                                        SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) /
8669                                        SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 ELSE 0 END) * 100
8670                                    , 0) AS 'Otros'";
8671                    }else{
8672                        $cols .= ", COALESCE(
8673                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.acceptance_date IS NOT NULL THEN 1 END) /
8674                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.created_at IS NOT NULL THEN 1 END) * 100
8675                                    , 0) AS '{$item->name}'";
8676                    }
8677                }
8678
8679                $colsGroups = ",COALESCE(
8680                                    (SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 END)) /
8681                                    (SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 END)) * 100
8682                                , 0) Otros";
8683
8684                foreach ($budgetTypeGroups as $item) {
8685                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8686                    $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}'";
8687                    $colsGroups .= ",COALESCE(
8688                                        (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)) /
8689                                        (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
8690                                    , 0) '{$budgetTypeGroupName}'";
8691                }
8692
8693                $colsGroups .= ",COALESCE(
8694                                    (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)) /
8695                                    (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
8696                                    , 0) total";
8697
8698                $col = $colsGroups . $cols;
8699            }
8700
8701            $query  = "SELECT
8702                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
8703                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
8704                            q.company_id,
8705                            c.name 'companyName',
8706                            GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.id END) groupConcatIds
8707                            {$col}
8708                        FROM
8709                            tbl_quotations q
8710                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8711                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8712                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8713                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
8714                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8715                            LEFT JOIN tbl_companies c ON q.company_id = c.company_id
8716                        WHERE
8717                            q.{$field} IS NOT NULL
8718                            AND q.for_add != 1
8719                            AND q.budget_type_id != 7
8720                            AND q.budget_type_id IS NOT NULL
8721                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
8722                            AND q.acceptance_date != '0000-00-00 00:00:00'
8723                            {$where}
8724                            {$whereYear}
8725                        GROUP BY
8726                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
8727                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
8728                            q.company_id WITH ROLLUP
8729                        ORDER BY
8730                            YEAR DESC,
8731                            MONTH ASC,
8732                            q.company_id ASC,
8733                            DATE_FORMAT(q.{$field}, '%e') ASC";
8734
8735            $result = DB::select($query);
8736
8737            $query = "SELECT
8738                        btg.budget_type_group_id,
8739                        btg.name,
8740                        (
8741                            SELECT
8742                                GROUP_CONCAT(COALESCE(bt.name, '') ORDER BY ISNULL(bt.priority), bt.priority ASC SEPARATOR '|')
8743                            FROM
8744                                tbl_budget_types bt
8745                            WHERE
8746                                bt.budget_type_group_id = btg.budget_type_group_id
8747                        ) budget_types
8748                        FROM
8749                            tbl_budget_type_groups btg
8750                        ORDER BY
8751                            ISNULL(btg.priority),
8752                            btg.priority ASC";
8753
8754            $budgetTypeGroups = DB::select($query);
8755
8756            foreach ($budgetTypeGroups as $item) {
8757                $item->group_key_name = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8758                $item->budget_types = explode("|", $item->budget_types);
8759            }
8760
8761            return response([
8762                'message' => 'OK',
8763                'data' => $result,
8764                'budgetTypeGroups' => $budgetTypeGroups
8765            ]);
8766
8767        } catch (\Exception $e) {
8768            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8769        }
8770    }
8771
8772    function request_permission_commercial(Request $request){
8773
8774        try {
8775
8776            $data = $request->all();
8777
8778            $id = addslashes($data['id']);
8779            $requestedBy = $data['requested_by'];
8780            $body = "";
8781
8782            $result = TblQuotations::where('id', $id)->first();
8783
8784            $subject = __('language.request_permission_commercial.subject');
8785            $subject = str_replace('{{quote_id}}', $result->quote_id, $subject);
8786            $subject = str_replace('{{username}}', $requestedBy, $subject);
8787
8788            $email = new \SendGrid\Mail\Mail();
8789
8790            $imgpath = File::get('fireservicetitan.png');
8791
8792            $email->addAttachment(
8793                $imgpath,
8794                "image/png",
8795                "fireservicetitan.png",
8796                "inline",
8797                "fireservicetitan"
8798            );
8799
8800            $url = env('URL') . "orders/{$id}?company_id={$result->company_id}";
8801            $href = "<a href='{$url}'>{$result->quote_id}</a>";
8802
8803            $user = TblUsers::where('name', $requestedBy)->first();
8804
8805            $urlClick = env('URL') . "update?confirm_request={$id}&requested_by={$user->id}&quote_id={$result->quote_id}";
8806            $company = TblCompanies::where('company_id', $result->company_id)->first();
8807
8808            $body .= __('language.request_permission_commercial.body_hello');
8809            $body .= __('language.request_permission_commercial.body_message');
8810
8811            $amount = $this->currency($result->amount, 1);
8812
8813            $body = str_replace('{{commercial}}', $result->commercial, $body);
8814            $body = str_replace('{{company}}', $company->name, $body);
8815            $body = str_replace('{{client}}', $result->client, $body);
8816            $body = str_replace('{{amount}}', $amount, $body);
8817            $body = str_replace('{{quote_id}}', $href, $body);
8818            $body = str_replace('{{click}}', $urlClick, $body);
8819            $body = str_replace('{{username}}', $requestedBy, $body);
8820
8821            $body .= "<p>Fire Service Titan</p>";
8822            $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
8823
8824            $html = '<!DOCTYPE html>';
8825            $html .= '<html>';
8826            $html .= '<head>';
8827            $html .= '<meta charset="UTF-8">';
8828            $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
8829            $html .= '</head>';
8830            $html .= '<body>';
8831            $html .= $body;
8832            $html .= '</body>';
8833            $html .= '</html>';
8834
8835            $user = TblUsers::where('id', $this->userId)->first();
8836
8837            if(env('SENDGRID_STAGING')){
8838                $email->addTo($user->email);
8839            }else{
8840                $email->addTo("luis.collar@fire.es");
8841
8842                $user = TblUsers::where('name', $result->created_by)->first();
8843                if($user && $user->email != "luis.collar@fire.es"){
8844                    $email->addTo($user->email);
8845                }
8846
8847                if($result->created_by != $result->commercial){
8848                    $user = TblUsers::where('name', $result->commercial)->first();
8849                    if($user->email != "luis.collar@fire.es"){
8850                        $email->addTo($user->email);
8851                    }
8852                }
8853            }
8854
8855            $email->setFrom("titan@fire.es");
8856            $email->setSubject($subject);
8857
8858            $email->addContent("text/html", $html);
8859
8860            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
8861
8862            $response = $sendgrid->send($email);
8863            if ($response->statusCode() == 202) {
8864                return response(['message' => 'OK']);
8865            }
8866
8867            return response(['message' => 'KO']);
8868
8869        } catch (\Exception $e) {
8870            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8871        }
8872
8873    }
8874
8875    function confirm_update_commercial(Request $request){
8876
8877        try {
8878            sleep(3);
8879            $data = $request->all();
8880            $id = addslashes($data['id']);
8881            $userId = addslashes($data['requested_by']);
8882
8883            $user = TblUsers::where('id', $userId)->first();
8884
8885            if($user){
8886
8887                TblQuotations::where('id', $data['id'])->update(
8888                    array(
8889                        'commercial' => $user->name,
8890                        'updated_at' => date('Y-m-d H:i:s')
8891                    )
8892                );
8893
8894            }else{
8895                return response(['message' => 'KO', 'error' => 'invalid_user']);
8896            }
8897
8898            return response(['message' => 'OK']);
8899
8900        } catch (\Exception $e) {
8901            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8902        }
8903    }
8904
8905    function calculateEmailRequestSize(Mail $email){
8906
8907        $size = 0;
8908
8909        // Add size of 'from', 'to', 'subject', 'content'
8910        $from = $email->getFrom();
8911        $size += strlen(json_encode([
8912            'from' => $from->getEmail() . ' ' . $from->getName(),
8913            'subject' => $email->getSubject()
8914        ]));
8915
8916        // Add size of 'to' (recipients)
8917        $personalizations = $email->getPersonalization();
8918        foreach ($personalizations as $personalization) {
8919            foreach ($personalization->getTos() as $to) {
8920                $size += strlen($to->getEmail() . ' ' . $to->getName());
8921            }
8922        }
8923
8924        // Add size of content
8925        foreach ($email->getContents() as $content) {
8926            $size += strlen($content->getValue());
8927        }
8928
8929        // Add size of attachments (if any)
8930
8931        if($email->getAttachments() != null && $email->getAttachments() != ""){
8932            foreach ($email->getAttachments() as $attachment) {
8933                $size += strlen($attachment->getContent()); // Base64 encoded size
8934                $size += strlen($attachment->getFilename());
8935                $size += strlen($attachment->getType());
8936            }
8937        }
8938
8939        $sizeInMegabytes = $size / 1048576; // 1 MB = 1,048,576 bytes
8940
8941        return (int) ceil($sizeInMegabytes);
8942    }
8943
8944    public function list_quotation_analytics_commercial_productivity(Request $request){
8945
8946        // try {
8947
8948            $data = $request->all();
8949            $companyId = addslashes($data['company_id']);
8950
8951            $where = "";
8952            $whereYear = "";
8953            $whereVisit = "";
8954
8955            $dateLflArray = array();
8956            $companyIds = $this->companyIds;
8957
8958            if($companyId != 0){
8959                $companyIds = array($companyId);
8960            }
8961
8962            $field = "issue_date";
8963
8964            if(isset($data['years']) && $data['years'] != null){
8965                $years = implode(',', $data['years']);
8966                if(count($data['years']) > 0){
8967                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
8968                }
8969            }
8970
8971            foreach ($companyIds as $v) {
8972
8973                $lflWhere = " AND q.company_id = {$v} ";
8974
8975                $query = "SELECT
8976                            CONCAT(
8977                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
8978                                ' - ',
8979                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
8980                            ) AS date_like,
8981                            YEAR(q.{$field}) 'year',
8982                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
8983                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
8984                            {$v} 'company_id'
8985                        FROM
8986                            tbl_quotations q
8987                        WHERE
8988                            q.{$field} IS NOT NULL
8989                            AND q.for_add != 1
8990                            {$lflWhere}
8991                            {$whereYear}
8992                        GROUP BY YEAR(q.{$field})
8993                        ORDER BY YEAR(q.{$field}) DESC";
8994
8995                $dateLike = DB::select($query);
8996
8997                if(count($dateLike) > 0){
8998                    $dateLflArray[$v] = $dateLike;
8999                }
9000            }
9001
9002            $whereAcceptanceDate = "";
9003
9004            if(isset($data['source']) && $data['source'] != null){
9005                $where .= " AND s.name = '{$data['source']}'";
9006            }
9007
9008            if(isset($data['month']) && $data['month'] != null){
9009                $where .= " AND MONTH(q.created_at) = '{$data['month']}'";
9010            }
9011
9012            if(isset($data['week']) && $data['week'] != null){
9013                $where .= " AND WEEK(q.created_at) = '{$data['week']}'";
9014            }
9015
9016            if(isset($data['commercial']) && $data['commercial'] != null){
9017                $commercial = implode("','", $data['commercial']);
9018                if(count($data['commercial']) > 0){
9019                    $where .= " AND q.commercial IN ('{$commercial}') ";
9020                    $whereVisit .= " AND q.commercial IN ('{$commercial}') ";
9021                }
9022            }
9023
9024            if(isset($data['created_by']) && $data['created_by'] != null){
9025                $created_by = implode("','", $data['created_by']);
9026                if(count($data['created_by']) > 0){
9027                    $where .= " AND q.created_by IN ('{$created_by}')";
9028                }
9029            }
9030
9031            if(isset($data['budget_type']) && $data['budget_type'] != null){
9032                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
9033            }
9034
9035            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
9036                $budgetTypeGroupIds = implode(",", $data['budget_type_group']);
9037                if(count($data['budget_type_group']) > 0){
9038                    $where .= " AND bt.budget_type_group_id IN ({$budgetTypeGroupIds})";
9039                }
9040            }
9041
9042            if(isset($data['budget_status']) && $data['budget_status'] != null){
9043                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
9044            }
9045
9046            if(isset($data['client_type']) && $data['client_type'] != null){
9047                $where .= " AND ct.customer_type_id = {$data['client_type']}";
9048            }
9049
9050            if(isset($data['segment_id']) && $data['segment_id'] != null){
9051                $where .= " AND q.segment_id = {$data['segment_id']}";
9052            }
9053
9054            if(isset($data['role_id']) && $data['role_id'] != null){
9055                $roleId = implode(",", $data['role_id']);
9056                if(count($data['role_id']) > 0){
9057                    $where .= " AND r.role_id IN ({$roleId})";
9058                    $whereVisit .= " AND r.role_id IN ({$roleId}";
9059                }
9060            }
9061
9062            $groupByFilter = 2;
9063            if(isset($data['group_by']) && $data['group_by'] != null){
9064                $groupByFilter = $data['group_by'];
9065            }
9066
9067            $groupBy = "1, 2, 3, q.commercial, budget_type";
9068
9069            if($groupByFilter == 1){
9070                $groupBy = "1, q.commercial, 2, 3, budget_type";
9071            }
9072
9073            if($groupByFilter == 3){
9074                $groupBy = "1, budget_type, q.commercial, 2, 3";
9075            }
9076
9077            $aggregatedBy = 1;
9078            $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', LPAD(q.week, 2, 0) AS 'week', ";
9079            $aggregatedByCalc = " / 4";
9080            if(isset($data['aggregated_by']) && $data['aggregated_by'] != null){
9081                $aggregatedBy = $data['aggregated_by'];
9082                if($data['aggregated_by'] == 1){
9083
9084                    $groupBy = "1, 2, 3, q.commercial, budget_type";
9085
9086                    if($groupByFilter == 1){
9087                        $groupBy = "1, q.commercial, 2, 3, budget_type";
9088                    }
9089
9090                    if($groupByFilter == 3){
9091                        $groupBy = "1, budget_type, q.commercial, 2, 3";
9092                    }
9093
9094                    $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', LPAD(q.week, 2, 0) AS 'week', ";
9095                }elseif($data['aggregated_by'] == 2){
9096                    $groupBy = "1, 2, q.commercial, budget_type";
9097
9098                    if($groupByFilter == 1){
9099                        $groupBy = "1, q.commercial, 2, budget_type";
9100                    }
9101
9102                    if($groupByFilter == 3){
9103                        $groupBy = "1, budget_type, q.commercial, 2";
9104                    }
9105
9106                    $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', NULL AS 'week',";
9107                    $aggregatedByCalc = "";
9108                }elseif($data['aggregated_by'] == 3){
9109                    $groupBy = "1, q.commercial, budget_type";
9110
9111                    if($groupByFilter == 3){
9112                        $groupBy = "1, budget_type, q.commercial";
9113                    }
9114
9115                    $aggregatedCol = "NULL AS 'month', NULL AS 'week',";
9116                    $aggregatedByCalc = " * 12";
9117                }
9118            }
9119
9120            $whereAcceptanceDate = $where;
9121            $whereCreatedAt = $where;
9122
9123            $isFy = true;
9124
9125            if($companyId != 0){
9126                $where .= " AND q.company_id = {$companyId} ";
9127                $whereCreatedAt .= " AND q.company_id = {$companyId} ";
9128                $whereAcceptanceDate .= " AND q.company_id = {$companyId} ";
9129                $whereVisit .= " AND q.company_id = {$companyId} ";
9130            }else{
9131                $where .= " AND q.company_id IN ({$this->companyId}";
9132                $whereCreatedAt .= " AND q.company_id IN ({$this->companyId}";
9133                $whereAcceptanceDate .= " AND q.company_id IN ({$this->companyId}";
9134                $whereVisit .= " AND q.company_id IN ({$this->companyId}";
9135            }
9136
9137            if(isset($data['campaign']) && $data['campaign'] != null){
9138                $campaign = implode("','", $data['campaign']);
9139                if(count($data['campaign']) > 0){
9140                    $whereVisit .= " AND q.campaign IN ('{$campaign}')";
9141                }
9142            }
9143
9144            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
9145                $isFy = false;
9146                $now = date('m-d');
9147
9148                $where .= " AND q.{$field} BETWEEN DATE_FORMAT(q.{$field}, '%Y-01-01') AND DATE_FORMAT(q.{$field}, '%Y-{$now}') ";
9149                $whereCreatedAt .= " AND q.created_at BETWEEN DATE_FORMAT(q.created_at, '%Y-01-01') AND DATE_FORMAT(q.created_at, '%Y-{$now}') ";
9150                $whereAcceptanceDate .= " AND q.acceptance_date BETWEEN DATE_FORMAT(q.acceptance_date, '%Y-01-01') AND DATE_FORMAT(q.acceptance_date, '%Y-{$now}') ";
9151                $whereVisit .= " AND q.visit_date BETWEEN DATE_FORMAT(q.visit_date, '%Y-01-01') AND DATE_FORMAT(q.visit_date, '%Y-{$now}') ";
9152            }
9153
9154            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
9155                $isFy = false;
9156                $lflArray = array();
9157                $ytdAcceptanceArray = array();
9158                $lflCompanyIds = array();
9159                $lflCompanyIdsAcc = array();
9160                foreach ($dateLflArray as $k => $v) {
9161                    foreach ($dateLflArray[$k] as $item) {
9162                        $year = $item->year;
9163                        $min_date_like = $item->min_date_like;
9164                        $max_date_like = $item->max_date_like;
9165                        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}')");
9166                        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}')");
9167                    }
9168
9169                    $lflArray = implode(' OR ', $lflArray);
9170                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
9171                    $lflArray = array();
9172
9173                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
9174                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
9175                    $ytdAcceptanceArray = array();
9176                }
9177
9178                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
9179                $where .= " AND ({$lflCompanyIds}";
9180
9181                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
9182                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
9183            }
9184
9185            $orderBy = "CASE WHEN q.commercial IS NULL OR q.budget_type IS NULL THEN q.priority END DESC, q.priority ASC,";
9186
9187            if(isset($data['order_by'])){
9188                $col = $data['order_by']['column'];
9189                $sort = $data['order_by']['sort'];
9190
9191                if(!empty($sort) || $sort != null){
9192                    $orderBy = "CASE WHEN q.commercial IS NULL OR q.budget_type IS NULL THEN {$col} END DESC, {$col} {$sort},";
9193                }
9194            }
9195
9196
9197            $visitTypes = TblVisitTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
9198
9199            $visitCols = "";
9200            $visitMainTableCols = "";
9201            $visitSubMainTableCols = "";
9202            $visitSubTableCols = "";
9203            $visitMainCols = "";
9204
9205            $visitCall = array("Visita", "Llamada");
9206
9207            foreach ($visitCall as $value) {
9208                foreach ($visitTypes as $item) {
9209                    $visitTypeNames = $value . $item->visit_type_group_id;
9210                    $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}'";
9211                    $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}'";
9212                    $visitMainTableCols .= ",COALESCE(SUM(q.total{$visitTypeNames}), 0) AS 'total{$visitTypeNames}'";
9213                    $visitMainTableCols .= ",GROUP_CONCAT(q.groupConcatIds{$visitTypeNames})  AS 'groupConcatIds{$visitTypeNames}'";
9214                    $visitSubMainTableCols .= ",q.total{$visitTypeNames}";
9215                    $visitSubMainTableCols .= ",q.groupConcatIds{$visitTypeNames}";
9216                    $visitSubTableCols .= ",0 AS total{$visitTypeNames}";
9217                    $visitSubTableCols .= ",NULL AS groupConcatIds{$visitTypeNames}";
9218                    $visitMainCols .= ",COALESCE(SUM(q.total{$visitTypeNames}), 0) total{$visitTypeNames}";
9219                    $visitMainCols .= ",GROUP_CONCAT(q.groupConcatIds{$visitTypeNames}) groupConcatIds{$visitTypeNames}";
9220                }
9221            }
9222
9223
9224            $businessGoalsDefault = TblBusinessGoals::where('is_default', 1)->where('budget_type_group_id', 999999999)->first();
9225
9226            $businessGoalsDefault->issue_objective = $businessGoalsDefault->issue_objective ?? 1;
9227            $businessGoalsDefault->acceptance_objective = $businessGoalsDefault->acceptance_objective ?? 1;
9228            $businessGoalsDefault->new_objective = $businessGoalsDefault->new_objective ?? 1;
9229            $businessGoalsDefault->is_amount = $businessGoalsDefault->is_amount ?? 1;
9230
9231            $gO = "";
9232
9233            if($groupByFilter != 3){
9234                $gO = "ORDER BY
9235                        1 DESC,
9236                        2 ASC,
9237                        3 ASC,
9238                        q.commercial ASC,
9239                        {$orderBy}
9240                        DATE_FORMAT(q.namedate, '%e') ASC";
9241            }else{
9242                $gO = "ORDER BY
9243                        1 DESC,
9244                        2 ASC,
9245                        3 ASC,
9246                        budget_type ASC,
9247                        q.commercial ASC";
9248            }
9249
9250            $query = "WITH business_goal_objective_users AS (
9251                        SELECT
9252                            bg.user_id,
9253                            bg.issue_objective,
9254                            bg.acceptance_objective,
9255                            bg.new_objective,
9256                            bg.is_amount
9257                        FROM tbl_business_goals bg
9258                        WHERE bg.budget_type_group_id = 999999999
9259                    ), business_goal_objective_roles AS (
9260                        SELECT
9261                            bg.role_id,
9262                            bg.issue_objective,
9263                            bg.acceptance_objective,
9264                            bg.new_objective,
9265                            bg.is_amount
9266                        FROM tbl_business_goals bg
9267                        WHERE bg.budget_type_group_id = 999999999
9268                    )
9269
9270                    SELECT
9271                        q.year,
9272                        {$aggregatedCol}
9273                        q.namedate created_at,
9274                        q.commercial,
9275                        q.budget_type,
9276                        COALESCE(SUM(q.issue_date), 0) totalIssue,
9277                        COALESCE(SUM(q.created_at), 0) totalCreatedAt,
9278                        GROUP_CONCAT(q.groupConcatIds) groupConcatIds,
9279                        SUM(q.totalIssueObjective) totalIssueObjective,
9280                        CASE
9281                            WHEN SUM(q.totalIssueObjective) BETWEEN 1 AND 70 THEN 'text-danger'
9282                            WHEN SUM(q.totalIssueObjective) BETWEEN 70 AND 90 THEN 'text-warning'
9283                        END textIssueColor,
9284                        SUM(q.revenueIssue) revenueIssue,
9285                        SUM(q.totalIssueObjectiveMonthly) totalIssueObjectiveMonthly,
9286                        SUM(q.totalIssueObjectiveYearly) totalIssueObjectiveYearly,
9287                        COALESCE(SUM(q.acceptance_date), 0) totalAcceptance,
9288                        GROUP_CONCAT(q.groupConcatCreatedAtIds) groupConcatCreatedAtIds,
9289                        SUM(q.totalIssueLessThan5) AS totalIssueLessThan5,
9290                        GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) AS groupConcatIdsIssueLessThan5,
9291                        GROUP_CONCAT(q.groupConcatAcceptanceIds) groupConcatAcceptanceIds,
9292                        SUM(q.totalAcceptanceObjective) totalAcceptanceObjective,
9293                        SUM(q.totalAcceptanceObjectiveMonthly) totalAcceptanceObjectiveMonthly,
9294                        SUM(q.totalAcceptanceObjectiveYearly) totalAcceptanceObjectiveYearly,
9295                        CASE
9296                            WHEN SUM(q.totalAcceptanceObjective) BETWEEN 1 AND 70 THEN 'text-danger'
9297                            WHEN SUM(q.totalAcceptanceObjective) BETWEEN 70 AND 90 THEN 'text-warning'
9298                        END textAcceptanceColor,
9299                        SUM(q.revenueAcceptance) revenueAcceptance,
9300                        COALESCE(SUM(q.totalRejected), 0) totalRejected,
9301                        GROUP_CONCAT(q.groupConcatRejectedIds) groupConcatRejectedIds,
9302                        SUM(q.revenueRejected) revenueRejected,
9303                        COALESCE(SUM(q.totalNew)) totalNew,
9304                        GROUP_CONCAT(q.groupConcatNewIds) groupConcatNewIds,
9305                        SUM(q.totalNewObjective) totalNewObjective,
9306                        SUM(q.totalNewObjectiveMonthly) totalNewObjectiveMonthly,
9307                        SUM(q.totalNewObjectiveYearly) totalNewObjectiveYearly,
9308                        CASE
9309                            WHEN SUM(q.totalNewObjective) BETWEEN 1 AND 70 THEN 'text-danger'
9310                            WHEN SUM(q.totalNewObjective) BETWEEN 70 AND 90 THEN 'text-warning'
9311                        END textNewColor,
9312                        SUM(q.revenueNew) revenueNew,
9313                        COALESCE(SUM(q.totalVisit), 0) totalVisit,
9314                        GROUP_CONCAT(q.groupConcatVisitIds) groupConcatVisitIds,
9315                        COALESCE(SUM(q.totalCall), 0) totalCall,
9316                        GROUP_CONCAT(q.groupConcatCallIds) groupConcatCallIds,
9317                        SUM(q.is_amountIssue) AS is_amountIssue,
9318                        SUM(q.is_amountNew) AS is_amountNew,
9319                        SUM(q.is_amountAcceptance) AS is_amountAcceptance,
9320                        SUM(q.issueObjective) AS issueObjective,
9321                        SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9322                        SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9323                        SUM(q.newObjective) AS newObjective,
9324                        SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9325                        SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9326                        SUM(q.acceptanceObjective) AS acceptanceObjective,
9327                        SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9328                        SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9329                        {$visitMainCols}
9330                    FROM
9331                    (
9332                        SELECT
9333                            q.year,
9334                            q.month,
9335                            q.week,
9336                            q.namedate,
9337                            SUM(q.issue_date) AS issue_date,
9338                            q.acceptance_date,
9339                            q.created_at,
9340                            q.commercial,
9341                            q.budget_type,
9342                            GROUP_CONCAT(q.groupConcatIds) AS groupConcatIds,
9343                            CASE
9344                                WHEN q.is_amountIssue > 0 THEN
9345                                    SUM(q.revenueIssue / q.issueObjective) * 100
9346                                ELSE
9347                                    SUM(q.issue_date / q.issueObjective) * 100
9348                                END
9349                            AS totalIssueObjective,
9350                            CASE
9351                                WHEN q.is_amountIssue > 0 THEN
9352                                    SUM(q.revenueIssue / q.issueObjectiveMonthly) * 100
9353                                ELSE
9354                                    SUM(q.issue_date / q.issueObjectiveMonthly) * 100
9355                                END
9356                            AS totalIssueObjectiveMonthly,
9357                            CASE
9358                                WHEN q.is_amountIssue > 0 THEN
9359                                    SUM(q.revenueIssue / q.issueObjectiveYearly) * 100
9360                                ELSE
9361                                    SUM(q.issue_date / q.issueObjectiveYearly) * 100
9362                                END
9363                            AS totalIssueObjectiveYearly,
9364                            SUM(q.revenueIssue) revenueIssue,
9365                            GROUP_CONCAT(q.groupConcatCreatedAtIds) AS groupConcatCreatedAtIds,
9366                            SUM(q.totalIssueLessThan5) totalIssueLessThan5,
9367                            GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) groupConcatIdsIssueLessThan5,
9368                            GROUP_CONCAT(q.groupConcatAcceptanceIds) AS groupConcatAcceptanceIds,
9369                            SUM(q.acceptanceObjective) totalAcceptanceObjective,
9370                            SUM(q.acceptanceObjectiveMonthly) totalAcceptanceObjectiveMonthly,
9371                            SUM(q.acceptanceObjectiveYearly) totalAcceptanceObjectiveYearly,
9372                            q.revenueAcceptance,
9373                            SUM(q.totalRejected) AS totalRejected,
9374                            GROUP_CONCAT(q.groupConcatRejectedIds) AS groupConcatRejectedIds,
9375                            SUM(q.revenueRejected) revenueRejected,
9376                            SUM(q.totalNew) AS totalNew,
9377                            GROUP_CONCAT(q.groupConcatNewIds) AS groupConcatNewIds,
9378                            CASE
9379                                WHEN q.is_amountNew > 0 THEN
9380                                    SUM(q.revenueNew / q.newObjective) * 100
9381                                ELSE
9382                                    SUM(q.totalNew / q.newObjective) * 100
9383                                END
9384                            AS totalNewObjective,
9385                             CASE
9386                                WHEN q.is_amountNew > 0 THEN
9387                                    SUM(q.revenueNew / q.newObjectiveMonthly) * 100
9388                                ELSE
9389                                    SUM(q.totalNew / q.newObjectiveMonthly) * 100
9390                                END
9391                            AS totalNewObjectiveMonthly,
9392                             CASE
9393                                WHEN q.is_amountNew > 0 THEN
9394                                    SUM(q.revenueNew / q.newObjectiveYearly) * 100
9395                                ELSE
9396                                    SUM(q.totalNew / q.newObjectiveYearly) * 100
9397                                END
9398                            AS totalNewObjectiveYearly,
9399                            SUM(q.revenueNew) revenueNew,
9400                            q.totalVisit,
9401                            q.groupConcatVisitIds,
9402                            q.totalCall,
9403                            q.groupConcatCallIds,
9404                            q.priority,
9405                            SUM(q.is_amountIssue) AS is_amountIssue,
9406                            SUM(q.is_amountNew) AS is_amountNew,
9407                            SUM(q.is_amountAcceptance) AS is_amountAcceptance,
9408                            SUM(q.issueObjective) AS issueObjective,
9409                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9410                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9411                            SUM(q.newObjective) AS newObjective,
9412                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9413                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9414                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9415                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9416                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9417                            {$visitSubMainTableCols}
9418                        FROM (
9419                            SELECT
9420                                YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'year',
9421                                MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'month',
9422                                WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'week',
9423                                DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') namedate,
9424                                COUNT(CASE WHEN q.issue_date IS NOT NULL THEN 1 END) issue_date,
9425                                0 acceptance_date,
9426                                0 created_at,
9427                                q.commercial,
9428                                btg.name budget_type,
9429                                GROUP_CONCAT(CASE WHEN q.issue_date IS NOT NULL THEN q.id END) AS groupConcatIds,
9430
9431                                SUM(CASE WHEN q.issue_date IS NOT NULL THEN q.amount END) AS revenueIssue,
9432                                NULL groupConcatCreatedAtIds,
9433                                0 totalIssueLessThan5,
9434                                NULL groupConcatIdsIssueLessThan5,
9435                                NULL groupConcatAcceptanceIds,
9436
9437                                0 revenueAcceptance,
9438                                COUNT(CASE WHEN bs.name = 'Rechazado' THEN 1 END) AS totalRejected,
9439                                GROUP_CONCAT(DISTINCT CASE WHEN bs.name = 'Rechazado' THEN q.id END) AS groupConcatRejectedIds,
9440                                COALESCE(SUM(CASE WHEN bs.name = 'Rechazado' THEN q.amount END), 0) AS revenueRejected,
9441                                COUNT(CASE WHEN ct.name = 'Nuevo' THEN 1 END) AS totalNew,
9442                                GROUP_CONCAT(DISTINCT CASE WHEN ct.name = 'Nuevo' THEN q.id END) AS groupConcatNewIds,
9443
9444                                COALESCE(SUM(CASE WHEN ct.name = 'Nuevo' THEN q.amount END), 0) revenueNew,
9445                                0 totalVisit,
9446                                NULL groupConcatVisitIds,
9447                                0 totalCall,
9448                                NULL groupConcatCallIds,
9449                                btg.priority,
9450                                CAST(
9451                                    CASE
9452                                        WHEN bg.issue_objective IS NOT NULL THEN bg.is_amount
9453                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.is_amount
9454                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.is_amount
9455                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.is_amount
9456                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.is_amount
9457                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9458                                    END
9459                                AS DOUBLE) AS is_amountIssue,
9460                                CAST(
9461                                    CASE
9462                                        WHEN bg.new_objective IS NOT NULL THEN bg.is_amount
9463                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.is_amount
9464                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.is_amount
9465                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.is_amount
9466                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.is_amount
9467                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9468                                    END
9469                                AS DOUBLE) AS is_amountNew,
9470                                0 is_amountAcceptance,
9471                                CAST(
9472                                    CASE
9473                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9474                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9475                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9476                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9477                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9478                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9479                                    END {$aggregatedByCalc}
9480                                AS DOUBLE) AS issueObjective,
9481                                CAST(
9482                                    CASE
9483                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9484                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9485                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9486                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9487                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9488                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9489                                    END
9490                                AS DOUBLE) AS issueObjectiveMonthly,
9491                                CAST(
9492                                    CASE
9493                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9494                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9495                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9496                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9497                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9498                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9499                                    END * 12
9500                                AS DOUBLE) AS issueObjectiveYearly,
9501                                CAST(
9502                                    CASE
9503                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9504                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9505                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9506                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9507                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9508                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9509                                    END {$aggregatedByCalc}
9510                                AS DOUBLE) AS newObjective,
9511                                CAST(
9512                                    CASE
9513                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9514                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9515                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9516                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9517                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9518                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9519                                    END
9520                                AS DOUBLE) AS newObjectiveMonthly,
9521                                CAST(
9522                                    CASE
9523                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9524                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9525                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9526                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9527                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9528                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9529                                    END * 12
9530                                AS DOUBLE) AS newObjectiveYearly,
9531                                0 acceptanceObjective,
9532                                0 acceptanceObjectiveMonthly,
9533                                0 acceptanceObjectiveYearly
9534                                {$visitSubTableCols}
9535                            FROM
9536                            tbl_quotations q
9537                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9538                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9539                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9540                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9541                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9542                                LEFT JOIN tbl_users u ON q.commercial = u.name
9543                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9544                                LEFT JOIN tbl_business_goals bg ON bg.budget_type_group_id = btg.budget_type_group_id AND bg.user_id = u.id
9545                                LEFT JOIN tbl_business_goals bg1 ON bg1.budget_type_group_id = btg.budget_type_group_id AND bg1.role_id = r.role_id
9546                                LEFT JOIN tbl_business_goals bgde ON bgde.budget_type_group_id = btg.budget_type_group_id AND bgde.is_default = 1
9547                                LEFT JOIN business_goal_objective_users bgou ON bgou.user_id = u.id
9548                                LEFT JOIN business_goal_objective_roles bgor ON bgor.role_id = r.role_id
9549                            WHERE
9550                                q.budget_type_id != 7
9551                                AND q.budget_type_id IS NOT NULL
9552                                AND q.for_add != 1
9553                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9554                                AND bt.include = 1
9555                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9556                                {$where}
9557                                {$whereYear}
9558                            GROUP BY
9559                                {$groupBy}
9560                        ) q
9561                        GROUP BY
9562                            {$groupBy} WITH ROLLUP
9563
9564                        UNION ALL
9565
9566                        SELECT
9567                            q.year,
9568                            q.month,
9569                            q.week,
9570                            q.namedate,
9571                            q.issue_date,
9572                            SUM(q.acceptance_date) AS acceptance_date,
9573                            q.created_at,
9574                            q.commercial,
9575                            q.budget_type,
9576                            q.groupConcatIds,
9577                            q.issueObjective totalIssueObjective,
9578                            q.issueObjectiveMonthly totalIssueObjectiveMonthly,
9579                            q.issueObjectiveYearly totalIssueObjectiveYearly,
9580                            q.revenueIssue,
9581                            q.groupConcatCreatedAtIds,
9582                            q.totalIssueLessThan5,
9583                            q.groupConcatIdsIssueLessThan5,
9584                            GROUP_CONCAT(q.groupConcatAcceptanceIds) AS groupConcatAcceptanceIds,
9585                            CASE
9586                                WHEN q.is_amountAcceptance > 0 THEN
9587                                    SUM(q.revenueAcceptance / q.acceptanceObjective) * 100
9588                                ELSE
9589                                    SUM(q.acceptance_date / q.acceptanceObjective) * 100
9590                                END
9591                            AS totalAcceptanceObjective,
9592                            CASE
9593                                WHEN q.is_amountAcceptance > 0 THEN
9594                                    SUM(q.revenueAcceptance / q.acceptanceObjectiveMonthly) * 100
9595                                ELSE
9596                                    SUM(q.acceptance_date / q.acceptanceObjectiveMonthly) * 100
9597                                END
9598                            AS totalAcceptanceObjectiveMonthly,
9599                            CASE
9600                                WHEN q.is_amountAcceptance > 0 THEN
9601                                    SUM(q.revenueAcceptance / q.acceptanceObjectiveYearly) * 100
9602                                ELSE
9603                                    SUM(q.acceptance_date / q.acceptanceObjectiveYearly) * 100
9604                                END
9605                            AS totalAcceptanceObjectiveYearly,
9606                            SUM(q.revenueAcceptance) revenueAcceptance,
9607                            q.totalRejected,
9608                            q.groupConcatRejectedIds,
9609                            q.revenueRejected,
9610                            q.totalNew,
9611                            q.groupConcatNewIds,
9612                            q.newObjective totalNewObjective,
9613                            q.newObjectiveMonthly totalNewObjectiveMonthly,
9614                            q.newObjectiveYearly totalNewObjectiveYearly,
9615                            q.revenueNew,
9616                            q.totalVisit,
9617                            q.groupConcatVisitIds,
9618                            q.totalCall,
9619                            q.groupConcatCallIds,
9620                            q.priority,
9621                            SUM(q.is_amountIssue) AS is_amountIssue,
9622                            q.is_amountNew,
9623                            q.is_amountAcceptance,
9624                            SUM(q.issueObjective) AS issueObjective,
9625                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9626                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9627                            SUM(q.newObjective) AS newObjective,
9628                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9629                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9630                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9631                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9632                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9633                            {$visitSubMainTableCols}
9634                        FROM (
9635                            SELECT
9636                                YEAR(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'year',
9637                                MONTH(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'month',
9638                                WEEK(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'week',
9639                                DATE_FORMAT(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY), '%W, %M %e') namedate,
9640                                0 issue_date,
9641                                COUNT(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 END) acceptance_date,
9642                                0 created_at,
9643                                q.commercial,
9644                                btg.name budget_type,
9645                                NULL groupConcatIds,
9646
9647                                0 revenueIssue,
9648                                NULL groupConcatCreatedAtIds,
9649                                0 totalIssueLessThan5,
9650                                NULL groupConcatIdsIssueLessThan5,
9651                                GROUP_CONCAT(CASE WHEN q.acceptance_date IS NOT NULL THEN q.id END) AS groupConcatAcceptanceIds,
9652
9653                                COALESCE(SUM(CASE WHEN q.acceptance_date IS NOT NULL THEN q.amount END), 0) AS revenueAcceptance,
9654                                0 totalRejected,
9655                                NULL groupConcatRejectedIds,
9656                                0 revenueRejected,
9657                                0 totalNew,
9658                                NULL groupConcatNewIds,
9659                                NULL totalNewObjective,
9660                                NULL totalNewObjectiveMonthly,
9661                                NULL totalNewObjectiveYearly,
9662                                0 revenueNew,
9663                                0 totalVisit,
9664                                NULL groupConcatVisitIds,
9665                                0 totalCall,
9666                                NULL groupConcatCallIds,
9667                                btg.priority,
9668                                0 is_amountIssue,
9669                                0 is_amountNew,
9670                                CAST(
9671                                    CASE
9672                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.is_amount
9673                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.is_amount
9674                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.is_amount
9675                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.is_amount
9676                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.is_amount
9677                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9678                                    END
9679                                AS DOUBLE) AS is_amountAcceptance,
9680                                0 issueObjective,
9681                                0 issueObjectiveMonthly,
9682                                0 issueObjectiveYearly,
9683                                0 newObjective,
9684                                0 newObjectiveMonthly,
9685                                0 newObjectiveYearly,
9686                                CAST(
9687                                    CASE
9688                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
9689                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
9690                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
9691                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
9692                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
9693                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
9694                                    END {$aggregatedByCalc}
9695                                AS DOUBLE) AS acceptanceObjective,
9696                                CAST(
9697                                    CASE
9698                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
9699                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
9700                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
9701                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
9702                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
9703                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
9704                                    END
9705                                AS DOUBLE) AS acceptanceObjectiveMonthly,
9706                                CAST(
9707                                    CASE
9708                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
9709                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
9710                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
9711                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
9712                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
9713                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
9714                                    END * 12
9715                                AS DOUBLE) AS acceptanceObjectiveYearly
9716                                {$visitSubTableCols}
9717                            FROM
9718                            tbl_quotations q
9719                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9720                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9721                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9722                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9723                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9724                                LEFT JOIN tbl_users u ON q.commercial = u.name
9725                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9726                                LEFT JOIN tbl_business_goals bg ON bg.budget_type_group_id = btg.budget_type_group_id AND bg.user_id = u.id
9727                                LEFT JOIN tbl_business_goals bg1 ON bg1.budget_type_group_id = btg.budget_type_group_id AND bg1.role_id = r.role_id
9728                                LEFT JOIN tbl_business_goals bgde ON bgde.budget_type_group_id = btg.budget_type_group_id AND bgde.is_default = 1
9729                                LEFT JOIN business_goal_objective_users bgou ON bgou.user_id = u.id
9730                                LEFT JOIN business_goal_objective_roles bgor ON bgor.role_id = r.role_id
9731                            WHERE
9732                                q.budget_type_id != 7
9733                                AND q.budget_type_id IS NOT NULL
9734                                AND q.for_add != 1
9735                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9736                                AND bt.include = 1
9737                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9738                                {$whereAcceptanceDate}
9739                                {$whereYear}
9740                            GROUP BY
9741                                {$groupBy}
9742                        ) q
9743                        GROUP BY
9744                            {$groupBy} WITH ROLLUP
9745
9746                        UNION ALL
9747
9748                        SELECT
9749                            q.year,
9750                            q.month,
9751                            q.week,
9752                            q.namedate,
9753                            q.issue_date,
9754                            q.acceptance_date,
9755                            SUM(q.created_at) AS created_at,
9756                            q.commercial,
9757                            q.budget_type,
9758                            q.groupConcatIds,
9759                            q.issueObjective totalIssueObjective,
9760                            q.issueObjectiveMonthly totalIssueObjectiveMonthly,
9761                            q.issueObjectiveYearly totalIssueObjectiveYearly,
9762                            q.revenueIssue,
9763                            GROUP_CONCAT(q.groupConcatCreatedAtIds) AS groupConcatCreatedAtIds,
9764                            SUM(q.totalIssueLessThan5) AS totalIssueLessThan5,
9765                            GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) AS groupConcatIdsIssueLessThan5,
9766                            NULL groupConcatAcceptanceIds,
9767                            0 totalAcceptanceObjective,
9768                            0 totalAcceptanceObjectiveMonthly,
9769                            0 totalAcceptanceObjectiveYearly,
9770                            SUM(q.revenueAcceptance) revenueAcceptance,
9771                            q.totalRejected,
9772                            q.groupConcatRejectedIds,
9773                            q.revenueRejected,
9774                            q.totalNew,
9775                            q.groupConcatNewIds,
9776                            q.newObjective totalNewObjective,
9777                            q.newObjectiveMonthly totalNewObjectiveMonthly,
9778                            q.newObjectiveYearly totalNewObjectiveYearly,
9779                            q.revenueNew,
9780                            q.totalVisit,
9781                            q.groupConcatVisitIds,
9782                            q.totalCall,
9783                            q.groupConcatCallIds,
9784                            q.priority,
9785                            SUM(q.is_amountIssue) AS is_amountIssue,
9786                            q.is_amountNew,
9787                            q.is_amountAcceptance,
9788                            SUM(q.issueObjective) AS issueObjective,
9789                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9790                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9791                            SUM(q.newObjective) AS newObjective,
9792                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9793                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9794                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9795                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9796                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9797                            {$visitSubMainTableCols}
9798                        FROM (
9799                            SELECT
9800                                YEAR(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'year',
9801                                MONTH(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'month',
9802                                WEEK(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'week',
9803                                DATE_FORMAT(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY), '%W, %M %e') namedate,
9804                                0 issue_date,
9805                                0 acceptance_date,
9806                                COUNT(CASE WHEN q.created_at IS NOT NULL THEN 1 END) created_at,
9807                                q.commercial,
9808                                btg.name budget_type,
9809                                NULL groupConcatIds,
9810
9811                                0 revenueIssue,
9812                                GROUP_CONCAT(CASE WHEN q.created_at IS NOT NULL THEN q.id END) AS groupConcatCreatedAtIds,
9813                                COUNT(CASE WHEN ABS(DATEDIFF(q.created_at, q.issue_date)) < 5 THEN 1 END) AS totalIssueLessThan5,
9814                                GROUP_CONCAT(CASE WHEN ABS(DATEDIFF(q.created_at, q.issue_date)) < 5 THEN q.id END) AS groupConcatIdsIssueLessThan5,
9815                                NULL groupConcatAcceptanceIds,
9816
9817                                0 AS revenueAcceptance,
9818                                0 totalRejected,
9819                                NULL groupConcatRejectedIds,
9820                                0 revenueRejected,
9821                                0 totalNew,
9822                                NULL groupConcatNewIds,
9823                                NULL totalNewObjective,
9824                                NULL totalNewObjectiveMonthly,
9825                                NULL totalNewObjectiveYearly,
9826                                0 revenueNew,
9827                                0 totalVisit,
9828                                NULL groupConcatVisitIds,
9829                                0 totalCall,
9830                                NULL groupConcatCallIds,
9831                                btg.priority,
9832                                0 is_amountIssue,
9833                                0 is_amountNew,
9834                                0 is_amountAcceptance,
9835                                0 issueObjective,
9836                                0 issueObjectiveMonthly,
9837                                0 issueObjectiveYearly,
9838                                0 newObjective,
9839                                0 newObjectiveMonthly,
9840                                0 newObjectiveYearly,
9841                                0 acceptanceObjective,
9842                                0 acceptanceObjectiveMonthly,
9843                                0 acceptanceObjectiveYearly
9844                                {$visitSubTableCols}
9845                            FROM
9846                            tbl_quotations q
9847                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9848                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9849                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9850                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9851                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9852                                LEFT JOIN tbl_users u ON q.commercial = u.name
9853                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9854                            WHERE
9855                                q.budget_type_id != 7
9856                                AND q.budget_type_id IS NOT NULL
9857                                AND q.for_add != 1
9858                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9859                                AND bt.include = 1
9860                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9861                                {$whereCreatedAt}
9862                                {$whereYear}
9863                            GROUP BY
9864                                {$groupBy}
9865                        ) q
9866                        GROUP BY
9867                            {$groupBy} WITH ROLLUP
9868
9869                        UNION ALL
9870
9871                        SELECT
9872                            YEAR(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) YEAR,
9873                            MONTH(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) MONTH,
9874                            WEEK(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) WEEK,
9875                            DATE_FORMAT(DATE_ADD(visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY), '%W, %M %e') namedate,
9876                            0 issue_date,
9877                            0 acceptance_date,
9878                            0 created_at,
9879                            commercial,
9880                            NULL budget_type,
9881                            NULL groupConcatIds,
9882                            NULL totalIssueObjective,
9883                            NULL totalIssueObjectiveMonthly,
9884                            NULL totalIssueObjectiveYearly,
9885                            0 revenueIssue,
9886                            NULL groupConcatCreatedAtIds,
9887                            0 totalIssueLessThan5,
9888                            NULL groupConcatIdsIssueLessThan5,
9889                            NULL groupConcatAcceptanceIds,
9890                            NULL totalAcceptanceObjective,NULL totalAcceptanceObjectiveMonthly,
9891                            NULL totalAcceptanceObjectiveYearly,
9892                            0 revenueAcceptance,
9893                            0 totalRejected,
9894                            NULL groupConcatRejectedIds,
9895                            0 revenueRejected,
9896                            0 totalNew,
9897                            NULL groupConcatNewIds,
9898                            NULL totalNewObjective,NULL totalNewObjectiveMonthly,
9899                            NULL totalNewObjectiveYearly,
9900                            0 revenueNew,
9901                            COUNT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Visita' THEN 1 END) totalVisit,
9902                            GROUP_CONCAT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Visita' THEN q.id END) AS groupConcatVisitIds,
9903                            COUNT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Llamada' THEN 1 END) totalCall,
9904                            GROUP_CONCAT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Llamada' THEN q.id END) AS groupConcatCallIds,
9905                            0 priority,
9906                            0 is_amountIssue,
9907                            0 is_amountNew,
9908                            0 is_amountAcceptance,
9909                            0 issueObjective,
9910                            0 issueObjectiveMonthly,
9911                            0 issueObjectiveYearly,
9912                            0 newObjective,
9913                            0 newObjectiveMontly,
9914                            0 newObjectiveYearly,
9915                            0 acceptanceObjective,
9916                            0 acceptanceObjectiveMonthly,
9917                            0 acceptanceObjectiveYearly
9918                            {$visitCols}
9919                        FROM
9920                            tbl_pipelines q
9921                        LEFT JOIN tbl_users u ON q.commercial = u.name
9922                        LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9923                        LEFT JOIN tbl_visit_types v ON q.visit_type_id = v.visit_type_id
9924                        WHERE q.visit_date IS NOT NULL
9925                            {$whereVisit}
9926                        GROUP BY
9927                            {$groupBy}
9928                             WITH ROLLUP
9929                    ) q
9930                    WHERE
9931                        q.year NOT IN (2021, 2022)
9932                    GROUP BY
9933                        {$groupBy}
9934                    {$gO}";
9935
9936            $value = Cache::get(base64_encode($query));
9937
9938            if(!$value){
9939                $result = DB::select($query);
9940
9941                $structureData = new StructureData();
9942                $result = $structureData->parse($result, $groupByFilter, $aggregatedBy);
9943
9944                Cache::put(base64_encode($query), $result, 600);
9945            }else{
9946                $result = $value;
9947            }
9948
9949            return response([
9950                'message' => 'OK',
9951                'data' => $result
9952            ]);
9953
9954        // } catch (\Exception $e) {
9955        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
9956        // }
9957    }
9958
9959    function list_quotations_deleted($companyId){
9960
9961        try {
9962
9963            $companyId = addslashes($companyId);
9964            $where = "";
9965
9966            if($companyId != 0){
9967                $where = " a.company_id = {$companyId} ";
9968            }else{
9969                $where = " a.company_id IN ({$this->companyId})";
9970            }
9971
9972            $query = "SELECT
9973                        a.id,
9974                        a.quote_id,
9975                        a.company_id,
9976                        b.name company_name,
9977                        a.created_by,
9978                        a.updated_by,
9979                        a.updated_at,
9980                        a.for_add,
9981                        c.name reason,
9982                        a.reason_for_deletion
9983                    FROM tbl_quotations_deleted a
9984                    LEFT JOIN tbl_companies b
9985                        ON a.company_id = b.company_id
9986                    LEFT JOIN tbl_reasons c
9987                        ON a.reason_id = c.reason_id
9988                    WHERE {$where}
9989                    ORDER BY a.updated_at DESC";
9990
9991            $result = DB::select($query);
9992
9993            return response([
9994                'message' => 'OK',
9995                'data' => $result
9996            ]);
9997        } catch (\Exception $e) {
9998            return response(['message' => 'KO', 'error' => $e->getMessage()]);
9999        }
10000    }
10001
10002    function delete_sengrid($id){
10003
10004        try {
10005
10006            $id = addslashes($id);
10007
10008            $order = TblQuotations::where('id', $id)->first();
10009
10010            if($order){
10011                if($order->x_message_id != null){
10012                    TblSendgridWebhook::where('quotation_id', $id)->where('x_message_id', $order->x_message_id)->delete();
10013
10014                    TblQuotations::where('id', $id)->update(
10015                        array(
10016                            'x_message_id' => null,
10017                            'x_status' => null
10018                        )
10019                    );
10020
10021                    Cache::flush();
10022                }
10023            }
10024
10025            return response([
10026                'message' => 'OK'
10027            ]);
10028
10029        } catch (\Exception $e) {
10030            return response(['message' => 'KO', 'error' => $e->getMessage()]);
10031        }
10032    }
10033
10034    function download_productivity_commercial(Request $request){
10035
10036        try {
10037
10038            ini_set('max_execution_time', 123456);
10039
10040            $data = $request->all();
10041
10042            $result = $this->list_quotation_analytics_commercial_productivity($request);
10043            $result = $result->original['data'];
10044
10045            $spreadsheet = new Spreadsheet();
10046            $worksheet   = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, "Inputs");
10047            $spreadsheet->addSheet($worksheet, 0);
10048            $col         = range('A', 'Z');
10049
10050            for($i = 0; $i < 26; $i++){
10051                $worksheet->getColumnDimension($col[$i])->setAutoSize(true);
10052                if($i != 1){
10053                    $worksheet->getStyle($col[$i])
10054                        ->getAlignment()
10055                        ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
10056                }
10057            }
10058
10059            $l = 1;
10060            $worksheet->setCellValue('A' . $l, "Años");
10061
10062            if($data['group_by'] == 1){
10063                $worksheet->setCellValue('B' . $l, "Comercials");
10064                $worksheet->setCellValue('C' . $l, "Meses");
10065                $worksheet->setCellValue('D' . $l, "Semanas");
10066            }else{
10067                $worksheet->setCellValue('B' . $l, "Meses");
10068                $worksheet->setCellValue('C' . $l, "Semanas");
10069                $worksheet->setCellValue('D' . $l, "Comercials");
10070            }
10071
10072            $worksheet->setCellValue('E' . $l, "Categorías de presupuesto");
10073            $worksheet->setCellValue('F' . $l, "Presupuestos emitidos (#)");
10074            $worksheet->setCellValue('G' . $l, "Presupuestos emitidos (€)");
10075            $worksheet->setCellValue('H' . $l, "Presupuestos emitidos (Objetivo)");
10076            $worksheet->setCellValue('I' . $l, "Presupuestos aceptados (#)");
10077            $worksheet->setCellValue('J' . $l, "Presupuestos aceptados (€)");
10078            $worksheet->setCellValue('K' . $l, "Presupuestos aceptados (Objetivo)");
10079            $worksheet->setCellValue('L' . $l, "Presupuestos rechazados (#)");
10080            $worksheet->setCellValue('M' . $l, "Presupuestos rechazados (€)");
10081            $worksheet->setCellValue('N' . $l, "Presupuestos emitidos a nuevos clientes (#)");
10082            $worksheet->setCellValue('O' . $l, "Presupuestos emitidos a nuevos clientes (€)");
10083            $worksheet->setCellValue('P' . $l, "Presupuestos emitidos a nuevos clientes (Objetivo)");
10084            $worksheet->setCellValue('Q' . $l, "Venta (Llamada #)");
10085            $worksheet->setCellValue('R' . $l, "Venta (Visita #)");
10086            $worksheet->setCellValue('S' . $l, "Servicio (Llamada #)");
10087            $worksheet->setCellValue('T' . $l, "Servicio (Visita #)");
10088
10089            $l++;
10090
10091            foreach ($result as $item) {
10092
10093                $worksheet->setCellValue('A' . $l, $item['year']);
10094                $worksheet->setCellValue('F' . $l, $item['totalIssue']);
10095                $worksheet->setCellValue('G' . $l, $item['revenueIssue']);
10096                $worksheet->setCellValue('H' . $l, "-");
10097
10098                $worksheet->setCellValue('I' . $l, $item['totalAcceptance']);
10099                $worksheet->setCellValue('J' . $l, $item['revenueAcceptance']);
10100                $worksheet->setCellValue('K' . $l, "-");
10101
10102                $worksheet->setCellValue('L' . $l, $item['totalRejected']);
10103                $worksheet->setCellValue('M' . $l, $item['revenueRejected']);
10104
10105                $worksheet->setCellValue('N' . $l, $item['totalNew']);
10106                $worksheet->setCellValue('O' . $l, $item['revenueNew']);
10107                $worksheet->setCellValue('P' . $l, "-");
10108
10109                $worksheet->setCellValue('Q' . $l, $item['totalLlamada1']);
10110                $worksheet->setCellValue('R' . $l, $item['totalVisita1']);
10111
10112                $worksheet->setCellValue('S' . $l, $item['totalLlamada2']);
10113                $worksheet->setCellValue('T' . $l, $item['totalVisita2']);
10114
10115                $l++;
10116
10117                if($data['group_by'] == 1){
10118
10119                    if(count($item['commercials']) > 0){
10120
10121                        foreach ($item['commercials'] as $c) {
10122                            $worksheet->setCellValue('A' . $l, $item['year']);
10123
10124                            $worksheet->setCellValue('B' . $l, $c['commercial']);
10125                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10126                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10127                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10128
10129                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10130                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10131                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10132
10133                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10134                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10135
10136                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10137                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10138                            $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10139
10140                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10141                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10142
10143                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10144                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10145                            $l++;
10146
10147                            if(isset($c['budget_types']) && count($c['budget_types']) > 0){
10148                                foreach ($c['budget_types'] as $b) {
10149                                    $worksheet->setCellValue('A' . $l, $item['year']);
10150                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10151
10152                                    $worksheet->setCellValue('E' . $l, $b['name']);
10153                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10154                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10155                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10156
10157                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10158                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10159                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10160
10161                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10162                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10163
10164                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10165                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10166                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10167
10168                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10169                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10170
10171                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10172                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10173                                    $l++;
10174                                }
10175                            }
10176
10177                            if(isset($c['months']) && count($c['months']) > 0){
10178                                foreach ($c['months'] as $m) {
10179                                    $worksheet->setCellValue('A' . $l, $item['year']);
10180                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10181
10182                                    $worksheet->setCellValue('C' . $l, $m['month']);
10183                                    $worksheet->setCellValue('F' . $l, $m['totalIssue']);
10184                                    $worksheet->setCellValue('G' . $l, $m['revenueIssue']);
10185                                    $worksheet->setCellValue('H' . $l, $m['totalIssueObjectiveMonthly']);
10186
10187                                    $worksheet->setCellValue('I' . $l, $m['totalAcceptance']);
10188                                    $worksheet->setCellValue('J' . $l, $m['revenueAcceptance']);
10189                                    $worksheet->setCellValue('K' . $l, $m['totalAcceptanceObjectiveMonthly']);
10190
10191                                    $worksheet->setCellValue('L' . $l, $m['totalRejected']);
10192                                    $worksheet->setCellValue('M' . $l, $m['revenueRejected']);
10193
10194                                    $worksheet->setCellValue('N' . $l, $m['totalNew']);
10195                                    $worksheet->setCellValue('O' . $l, $m['revenueNew']);
10196                                    $worksheet->setCellValue('P' . $l, $m['totalNewObjectiveMonthly']);
10197
10198                                    $worksheet->setCellValue('Q' . $l, $m['totalLlamada1']);
10199                                    $worksheet->setCellValue('R' . $l, $m['totalVisita1']);
10200
10201                                    $worksheet->setCellValue('S' . $l, $m['totalLlamada2']);
10202                                    $worksheet->setCellValue('T' . $l, $m['totalVisita2']);
10203                                    $l++;
10204
10205                                    if(isset($m['weeks']) && count(@$m['weeks']) > 0 && count(@$m['weeks']) != 1){
10206                                        foreach ($m['weeks'] as $w) {
10207                                            $worksheet->setCellValue('A' . $l, $item['year']);
10208                                            $worksheet->setCellValue('B' . $l, $c['commercial']);
10209                                            $worksheet->setCellValue('C' . $l, $m['month']);
10210
10211                                            $worksheet->setCellValue('D' . $l, $w['created_at']);
10212                                            $worksheet->setCellValue('F' . $l, $w['totalIssue']);
10213                                            $worksheet->setCellValue('G' . $l, $w['revenueIssue']);
10214                                            $worksheet->setCellValue('H' . $l, $w['totalIssueObjective']);
10215
10216                                            $worksheet->setCellValue('I' . $l, $w['totalAcceptance']);
10217                                            $worksheet->setCellValue('J' . $l, $w['revenueAcceptance']);
10218                                            $worksheet->setCellValue('K' . $l, $w['totalAcceptanceObjective']);
10219
10220                                            $worksheet->setCellValue('L' . $l, $w['totalRejected']);
10221                                            $worksheet->setCellValue('M' . $l, $w['revenueRejected']);
10222
10223                                            $worksheet->setCellValue('N' . $l, $w['totalNew']);
10224                                            $worksheet->setCellValue('O' . $l, $w['revenueNew']);
10225                                            $worksheet->setCellValue('P' . $l, $w['totalNewObjective']);
10226
10227                                            $worksheet->setCellValue('Q' . $l, $w['totalLlamada1']);
10228                                            $worksheet->setCellValue('R' . $l, $w['totalVisita1']);
10229
10230                                            $worksheet->setCellValue('S' . $l, $w['totalLlamada2']);
10231                                            $worksheet->setCellValue('T' . $l, $w['totalVisita2']);
10232                                            $l++;
10233
10234                                            if(count($w['budget_types']) > 0){
10235                                                foreach ($w['budget_types'] as $b) {
10236                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10237                                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10238                                                    $worksheet->setCellValue('C' . $l, $m['month']);
10239
10240                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10241                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10242                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10243                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10244
10245                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10246                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10247                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10248
10249                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10250                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10251
10252                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10253                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10254                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10255
10256                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10257                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10258
10259                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10260                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10261                                                    $l++;
10262                                                }
10263                                            }
10264                                        }
10265                                    }elseif(isset($m['weeks']) && count(@$m['weeks']) == 1){
10266                                        foreach ($m['weeks'] as $w) {
10267                                            if(count($w['budget_types']) > 0){
10268                                                foreach ($w['budget_types'] as $b) {
10269                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10270                                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10271                                                    $worksheet->setCellValue('C' . $l, $m['month']);
10272
10273                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10274                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10275                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10276                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10277
10278                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10279                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10280                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10281
10282                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10283                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10284
10285                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10286                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10287                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10288
10289                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10290                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10291
10292                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10293                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10294                                                    $l++;
10295                                                }
10296                                            }
10297                                        }
10298
10299                                    }
10300                                }
10301                            }
10302                        }
10303                    }
10304                }else{
10305
10306                    if(isset($item['months']) && count($item['months']) > 0){
10307                        foreach ($item['months'] as $m) {
10308                            $worksheet->setCellValue('A' . $l, $item['year']);
10309                            $worksheet->setCellValue('B' . $l, $m['month']);
10310                            $worksheet->setCellValue('F' . $l, $m['totalIssue']);
10311                            $worksheet->setCellValue('G' . $l, $m['revenueIssue']);
10312                            $worksheet->setCellValue('H' . $l, "-");
10313
10314                            $worksheet->setCellValue('I' . $l, $m['totalAcceptance']);
10315                            $worksheet->setCellValue('J' . $l, $m['revenueAcceptance']);
10316                            $worksheet->setCellValue('K' . $l, "-");
10317
10318                            $worksheet->setCellValue('L' . $l, $m['totalRejected']);
10319                            $worksheet->setCellValue('M' . $l, $m['revenueRejected']);
10320
10321                            $worksheet->setCellValue('N' . $l, $m['totalNew']);
10322                            $worksheet->setCellValue('O' . $l, $m['revenueNew']);
10323                            $worksheet->setCellValue('P' . $l, "-");
10324
10325                            $worksheet->setCellValue('Q' . $l, $m['totalLlamada1']);
10326                            $worksheet->setCellValue('R' . $l, $m['totalVisita1']);
10327
10328                            $worksheet->setCellValue('S' . $l, $m['totalLlamada2']);
10329                            $worksheet->setCellValue('T' . $l, $m['totalVisita2']);
10330                            $l++;
10331
10332                            if(isset($m['weeks']) && count(@$m['weeks']) > 0){
10333                                foreach ($m['weeks'] as $w) {
10334                                    $worksheet->setCellValue('A' . $l, $item['year']);
10335                                    $worksheet->setCellValue('B' . $l, $m['month']);
10336
10337                                    $worksheet->setCellValue('C' . $l, $w['created_at']);
10338                                    $worksheet->setCellValue('F' . $l, $w['totalIssue']);
10339                                    $worksheet->setCellValue('G' . $l, $w['revenueIssue']);
10340                                    $worksheet->setCellValue('H' . $l, "-");
10341
10342                                    $worksheet->setCellValue('I' . $l, $w['totalAcceptance']);
10343                                    $worksheet->setCellValue('J' . $l, $w['revenueAcceptance']);
10344                                    $worksheet->setCellValue('K' . $l, "-");
10345
10346                                    $worksheet->setCellValue('L' . $l, $w['totalRejected']);
10347                                    $worksheet->setCellValue('M' . $l, $w['revenueRejected']);
10348
10349                                    $worksheet->setCellValue('N' . $l, $w['totalNew']);
10350                                    $worksheet->setCellValue('O' . $l, $w['revenueNew']);
10351                                    $worksheet->setCellValue('P' . $l, "-");
10352
10353                                    $worksheet->setCellValue('Q' . $l, $w['totalLlamada1']);
10354                                    $worksheet->setCellValue('R' . $l, $w['totalVisita1']);
10355
10356                                    $worksheet->setCellValue('S' . $l, $w['totalLlamada2']);
10357                                    $worksheet->setCellValue('T' . $l, $w['totalVisita2']);
10358                                    $l++;
10359
10360                                    if(count($w['commercials']) > 0){
10361                                        foreach ($w['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['totalIssueObjective']);
10369
10370                                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10371                                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10372                                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjective']);
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['totalNewObjective']);
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($m['commercials']) > 0){
10424                                foreach ($m['commercials'] as $c) {
10425                                    $worksheet->setCellValue('A' . $l, $item['year']);
10426                                    $worksheet->setCellValue('B' . $l, $m['month']);
10427
10428                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10429                                    $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10430                                    $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10431                                    $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10432
10433                                    $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10434                                    $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10435                                    $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10436
10437                                    $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10438                                    $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10439
10440                                    $worksheet->setCellValue('N' . $l, $c['totalNew']);
10441                                    $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10442                                    $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10443
10444                                    $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10445                                    $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10446
10447                                    $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10448                                    $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10449                                    $l++;
10450
10451                                    if(count($c['budget_types']) > 0){
10452                                        foreach ($c['budget_types'] as $b) {
10453                                            $worksheet->setCellValue('A' . $l, $item['year']);
10454                                            $worksheet->setCellValue('B' . $l, $m['month']);
10455                                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10456
10457                                            $worksheet->setCellValue('E' . $l, $b['name']);
10458                                            $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10459                                            $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10460                                            $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10461
10462                                            $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10463                                            $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10464                                            $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10465
10466                                            $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10467                                            $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10468
10469                                            $worksheet->setCellValue('N' . $l, $b['totalNew']);
10470                                            $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10471                                            $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10472
10473                                            $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10474                                            $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10475
10476                                            $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10477                                            $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10478                                            $l++;
10479                                        }
10480                                    }
10481                                }
10482                            }
10483                        }
10484                    }
10485
10486                    if(count($item['commercials']) > 0){
10487                        foreach ($item['commercials'] as $c) {
10488                            $worksheet->setCellValue('A' . $l, $item['year']);
10489
10490                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10491                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10492                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10493                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10494
10495                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10496                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10497                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10498
10499                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10500                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10501
10502                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10503                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10504                            $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10505
10506                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10507                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10508
10509                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10510                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10511                            $l++;
10512
10513                            if(count($c['budget_types']) > 0){
10514                                foreach ($c['budget_types'] as $b) {
10515                                    $worksheet->setCellValue('A' . $l, $item['year']);
10516                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10517
10518                                    $worksheet->setCellValue('E' . $l, $b['name']);
10519                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10520                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10521                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10522
10523                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10524                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10525                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10526
10527                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10528                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10529
10530                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10531                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10532                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10533
10534                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10535                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10536
10537                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10538                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10539                                    $l++;
10540                                }
10541                            }
10542                        }
10543                    }
10544                }
10545
10546                $l++;
10547            }
10548
10549            if($data['group_by'] == 1){
10550                if($data['aggregated_by'] == 3){
10551                    $worksheet->removeColumn('C');
10552                    $worksheet->removeColumn('C');
10553                }elseif($data['aggregated_by'] == 2){
10554                    $worksheet->removeColumn('D');
10555                }
10556            }else{
10557                if($data['aggregated_by'] == 3){
10558                    $worksheet->removeColumn('B');
10559                    $worksheet->removeColumn('B');
10560                }elseif($data['aggregated_by'] == 2){
10561                    $worksheet->removeColumn('C');
10562                }
10563            }
10564
10565
10566
10567            $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
10568            ob_start();
10569            $writer->save('php://output');
10570            $file = ob_get_contents();
10571            ob_end_clean();
10572
10573            return response($file);
10574
10575        } catch (\Exception $e) {
10576            return response(['message' => 'KO', 'error' => $e->getMessage()]);
10577        }
10578
10579    }
10580
10581    function update_commercial_numbers($companyId)
10582    {
10583        $phpBinary = '/usr/bin/php';
10584
10585        $artisanPath = escapeshellarg(base_path('artisan'));
10586
10587        $command = sprintf(
10588            '%s %s update:commercial-numbers %s > /dev/null 2>&1 &',
10589            $phpBinary,
10590            $artisanPath,
10591            $companyId
10592        );
10593
10594        exec($command, $output, $returnVar);
10595    }
10596
10597    function list_quotation_analytics_by_service_type(Request $request){
10598
10599        try {
10600
10601            $data = $request->all();
10602            $companyId = addslashes($data['company_id']);
10603            $where  = "";
10604
10605            if($companyId != 0){
10606                $where .= " AND c.company_id = {$companyId} ";
10607            }else{
10608                $where .= " AND c.company_id IN ({$this->companyId}";
10609            }
10610
10611            $col = "1";
10612
10613            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
10614                if($data['data_to_display'] == 1){
10615                    $col = "1";
10616                }
10617
10618                if($data['data_to_display'] == 2){
10619                    $col = "q.amount";
10620                }
10621            }
10622
10623            if(isset($data['approvals'])){
10624                $approvals = addslashes($data['approvals']);
10625
10626                if($approvals == 2){
10627                    $where .= " AND q.for_approval != 1 ";
10628                }
10629
10630                if($approvals == 3){
10631                    $where .= " AND q.for_approval > 0 ";
10632                }
10633
10634                if($approvals == 4){
10635                    $where .= " AND q.approved_by IS NOT NULL";
10636                }
10637
10638                if($approvals == 5){
10639                    $where .= " AND q.for_approval = 2 AND q.approved_by IS NULL";
10640                }
10641
10642                if($approvals == 6){
10643                    $where .= " AND q.approved_by IS NOT NULL AND q.approved_by_v2 IS NOT NULL";
10644                }
10645
10646                if($approvals == 7){
10647                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NOT NULL AND q.approved_by_v2 IS NULL";
10648                }
10649
10650                if($approvals == 8){
10651                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NULL AND q.approved_by_v2 IS NOT NULL";
10652                }
10653
10654                if($approvals == 9){
10655                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NULL AND q.approved_by_v2 IS NULL";
10656                }
10657            }
10658
10659            if(isset($data['role_id']) && $data['role_id'] != null){
10660                $roleIds = implode(",", $data['role_id']);
10661                if(count($data['role_id']) > 0){
10662                    $where .= " AND u.role_id IN ({$roleIds}, 999999999)";
10663                }
10664            }
10665
10666            if(isset($data['client_type']) && $data['client_type'] != null){
10667                $where .= " AND q.customer_type_id = {$data['client_type']}";
10668            }
10669
10670            $weekDay = "- WEEKDAY(q.date)";
10671
10672            if(isset($data['start_of_the_week']) && $data['start_of_the_week'] != null){
10673                switch ($data['start_of_the_week']) {
10674                    case 0:
10675                        $weekDay = "- WEEKDAY(q.date)";
10676                        break;
10677                    case 1:
10678                        $weekDay = "(1 - WEEKDAY(q.date))";
10679                        break;
10680                    case 2:
10681                        $weekDay = "(2 - WEEKDAY(q.date))";
10682                        break;
10683                    case 3:
10684                        $weekDay = "(3 - WEEKDAY(q.date))";
10685                        break;
10686                    case 4:
10687                        $weekDay = "(4 - WEEKDAY(q.date))";
10688                        break;
10689                    default:
10690                        $weekDay = "- WEEKDAY(q.date)";
10691                        break;
10692                }
10693            }
10694
10695            $whereDates = "";
10696
10697            if((isset($data['start_date']) && $data['start_date'] != null) && (isset($data['end_date']) && $data['end_date'] != null)){
10698                $whereDates = " AND q.date BETWEEN '{$data['start_date']}' AND '{$data['end_date']}";
10699            }
10700
10701            $query = "SELECT
10702                        q.region,
10703                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) 'year',
10704                        LPAD(MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'month',
10705                        LPAD(WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'week',
10706                        DATE_FORMAT(DATE_ADD(q.date, INTERVAL {$weekDay} DAY), '%W, %M %e') namedate,
10707
10708                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' THEN q.id END) AS groupConcatIdsTotalEnviado,
10709                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END), 0) AS totalIssueEnviado,
10710
10711                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoEnviado,
10712                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoEnviado,
10713                        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,
10714
10715                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosEnviado,
10716                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosEnviado,
10717                        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,
10718
10719                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasEnviado,
10720                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasEnviado,
10721                        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,
10722
10723                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
10724                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
10725                        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,
10726
10727                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
10728                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
10729                        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,
10730
10731                        CASE
10732                            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
10733                            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)
10734                                / 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)
10735                        END AS weightedAverageMarginForTheCompanyEnviado,
10736                        CASE
10737                            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
10738                            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)
10739                                / 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)
10740                        END AS weightedAverageInvoiceEnviado,
10741
10742                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' THEN q.id END) AS groupConcatIdsTotalAceptado,
10743                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END), 0) AS totalIssueAceptado,
10744
10745                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoAceptado,
10746                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoAceptado,
10747                        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,
10748
10749                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosAceptado,
10750                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosAceptado,
10751                        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,
10752
10753                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasAceptado,
10754                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasAceptado,
10755                        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,
10756
10757                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosAceptado,
10758                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosAceptado,
10759                        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,
10760
10761                        CASE
10762                            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
10763                            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)
10764                                / 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)
10765                        END AS weightedAverageMarginForTheCompanyAceptado,
10766                        CASE
10767                            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
10768                            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)
10769                                / 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)
10770                        END AS weightedAverageInvoiceAceptado,
10771
10772                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN 1 END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalIssuePercentage,
10773                        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,
10774                        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,
10775                        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,
10776                        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,
10777
10778                        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,
10779                        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,
10780                        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,
10781                        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,
10782                        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
10783                    FROM
10784                    (
10785                        SELECT
10786                            c.region,
10787                            q.issue_date AS DATE,
10788                            'issue' AS date_type,
10789                            q.acceptance_date,
10790                            q.issue_date,
10791                            q.id,
10792                            q.margin_for_the_company,
10793                            CASE
10794                                WHEN bt.budget_type_group_id = 4
10795                                AND q.budget_margin_enabled > 0
10796                                AND q.budget_margin_enabled IS NOT NULL
10797                                AND q.margin_for_the_company <> 0
10798                            THEN q.margin_for_the_company * q.amount
10799                            END s1,
10800                            q.invoice_margin,
10801                            CASE
10802                                WHEN bt.budget_type_group_id = 4
10803                                AND q.budget_margin_enabled > 0
10804                                AND q.budget_margin_enabled IS NOT NULL
10805                                AND q.invoice_margin <> 0
10806                            THEN q.invoice_margin * q.amount
10807                            END s2,
10808                            q.budget_type_id,
10809                            q.budget_status_id,
10810                            q.amount,
10811                            bt.budget_type_group_id,
10812                            q.budget_margin_enabled
10813                        FROM
10814                            tbl_quotations q
10815                        JOIN tbl_companies c
10816                            ON c.company_id = q.company_id
10817                        LEFT JOIN tbl_budget_types bt
10818                            ON q.budget_type_id = bt.budget_type_id
10819                        LEFT JOIN tbl_users u
10820                            ON u.name = q.created_by
10821                        LEFT JOIN tbl_roles r
10822                            ON r.role_id = u.role_id
10823                        WHERE
10824                            q.issue_date IS NOT NULL
10825                            AND q.for_add != 1
10826                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
10827                            AND (q.commercial IS NOT NULL AND q.commercial != '')
10828                            AND q.budget_type_id != 7
10829                            AND q.budget_type_id IS NOT NULL
10830                            {$where}
10831
10832                        UNION ALL
10833
10834                        SELECT
10835                            c.region,
10836                            q.acceptance_date AS DATE,
10837                            'acceptance' AS date_type,
10838                            q.acceptance_date,
10839                            q.issue_date,
10840                            q.id,
10841                            q.margin_for_the_company,
10842                            CASE
10843                                WHEN bt.budget_type_group_id = 4
10844                                AND q.budget_margin_enabled > 0
10845                                AND q.budget_margin_enabled IS NOT NULL
10846                                AND q.margin_for_the_company > 0
10847                            THEN q.margin_for_the_company * q.amount
10848                            END s1,
10849                            q.invoice_margin,
10850                            CASE
10851                                WHEN bt.budget_type_group_id = 4
10852                                AND q.budget_margin_enabled <> 0
10853                                AND q.budget_margin_enabled IS NOT NULL
10854                                AND q.invoice_margin <> 0
10855                            THEN q.invoice_margin * q.amount
10856                            END s2,
10857                            q.budget_type_id,
10858                            q.budget_status_id,
10859                            q.amount,
10860                            bt.budget_type_group_id,
10861                            q.budget_margin_enabled
10862                        FROM
10863                            tbl_quotations q
10864                        JOIN tbl_companies c
10865                            ON c.company_id = q.company_id
10866                        LEFT JOIN tbl_budget_types bt
10867                            ON q.budget_type_id = bt.budget_type_id
10868                        LEFT JOIN tbl_users u
10869                            ON u.name = q.created_by
10870                        LEFT JOIN tbl_roles r
10871                            ON r.role_id = u.role_id
10872                        WHERE
10873                            q.acceptance_date IS NOT NULL
10874                            AND q.for_add != 1
10875                            AND q.budget_type_id IS NOT NULL
10876                            AND q.budget_type_id != 7
10877                            AND q.acceptance_date != '0000-00-00 00:00:00'
10878                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
10879                            {$where}
10880                    ) AS q
10881                    WHERE q.date != '0000-00-00 00:00:00' {$whereDates}
10882                    GROUP BY
10883                        q.region,
10884                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
10885                        MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
10886                        WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) WITH ROLLUP
10887                    ORDER BY
10888                        q.region IS NULL,
10889                        q.region,
10890                        CASE WHEN q.region IS NOT NULL
10891                            AND YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
10892                            AND MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
10893                            AND WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
10894                        THEN 0
10895                        ELSE 1 END,
10896                    YEAR DESC,
10897                    MONTH ASC,
10898                    WEEK ASC";
10899
10900            $value = Cache::get(base64_encode($query));
10901
10902            if(!$value){
10903                $result = DB::select($query);
10904
10905                Cache::put(base64_encode($query), $result, 600);
10906            }else{
10907                $result = $value;
10908            }
10909
10910            $query = "SELECT
10911                        q.region,
10912                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) 'year',
10913                        LPAD(MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'month',
10914                        LPAD(WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'week',
10915                        DATE_FORMAT(DATE_ADD(q.date, INTERVAL {$weekDay} DAY), '%W, %M %e') namedate,
10916
10917                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' THEN q.id END) AS groupConcatIdsTotalEnviado,
10918                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END), 0) AS totalIssueEnviado,
10919
10920                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoEnviado,
10921                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoEnviado,
10922                        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,
10923
10924                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosEnviado,
10925                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosEnviado,
10926                        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,
10927
10928                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasEnviado,
10929                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasEnviado,
10930                        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,
10931
10932                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
10933                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
10934                        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,
10935
10936                        CASE
10937                            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
10938                            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)
10939                                / 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)
10940                        END AS weightedAverageMarginForTheCompanyEnviado,
10941                        CASE
10942                            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
10943                            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)
10944                                / 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)
10945                        END AS weightedAverageInvoiceEnviado,
10946
10947                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' THEN q.id END) AS groupConcatIdsTotalAceptado,
10948                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END), 0) AS totalIssueAceptado,
10949
10950                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoAceptado,
10951                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoAceptado,
10952                        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,
10953
10954                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosAceptado,
10955                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosAceptado,
10956                        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,
10957
10958                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasAceptado,
10959                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasAceptado,
10960                        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,
10961
10962                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosAceptado,
10963                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosAceptado,
10964                        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,
10965
10966                        CASE
10967                            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
10968                            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)
10969                                / 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)
10970                        END AS weightedAverageMarginForTheCompanyAceptado,
10971                        CASE
10972                            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
10973                            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)
10974                                / 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)
10975                        END AS weightedAverageInvoiceAceptado,
10976
10977                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalIssuePercentage,
10978                        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,
10979                        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,
10980                        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,
10981                        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,
10982
10983                        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,
10984                        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,
10985                        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,
10986                        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,
10987                        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
10988                    FROM
10989                    (
10990                        SELECT
10991                            'Total Grupo FIRE' region,
10992                            q.issue_date AS DATE,
10993                            'issue' AS date_type,
10994                            q.acceptance_date,
10995                            q.issue_date,
10996                            q.id,
10997                            q.margin_for_the_company,
10998                            CASE
10999                                WHEN bt.budget_type_group_id = 4
11000                                AND q.budget_margin_enabled > 0
11001                                AND q.budget_margin_enabled IS NOT NULL
11002                                AND q.margin_for_the_company <> 0
11003                            THEN q.margin_for_the_company * q.amount
11004                            END s1,
11005                            q.invoice_margin,
11006                            CASE
11007                                WHEN bt.budget_type_group_id = 4
11008                                AND q.budget_margin_enabled > 0
11009                                AND q.budget_margin_enabled IS NOT NULL
11010                                AND q.invoice_margin <> 0
11011                            THEN q.invoice_margin * q.amount
11012                            END s2,
11013                            q.budget_type_id,
11014                            q.budget_status_id,
11015                            q.amount,
11016                            bt.budget_type_group_id,
11017                            q.budget_margin_enabled
11018                        FROM
11019                            tbl_quotations q
11020                        JOIN tbl_companies c
11021                            ON c.company_id = q.company_id
11022                        LEFT JOIN tbl_budget_types bt
11023                            ON q.budget_type_id = bt.budget_type_id
11024                        LEFT JOIN tbl_users u
11025                            ON u.name = q.created_by
11026                        LEFT JOIN tbl_roles r
11027                            ON r.role_id = u.role_id
11028                        WHERE
11029                            q.issue_date IS NOT NULL
11030                            AND q.for_add != 1
11031                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
11032                            AND (q.commercial IS NOT NULL AND q.commercial != '')
11033                            AND q.budget_type_id != 7
11034                            AND q.budget_type_id IS NOT NULL
11035                            {$where}
11036
11037                        UNION ALL
11038
11039                        SELECT
11040                            'Total Grupo FIRE' region,
11041                            q.acceptance_date AS DATE,
11042                            'acceptance' AS date_type,
11043                            q.acceptance_date,
11044                            q.issue_date,
11045                            q.id,
11046                            q.margin_for_the_company,
11047                            CASE
11048                                WHEN bt.budget_type_group_id = 4
11049                                AND q.budget_margin_enabled > 0
11050                                AND q.budget_margin_enabled IS NOT NULL
11051                                AND q.margin_for_the_company <> 0
11052                            THEN q.margin_for_the_company * q.amount
11053                            END s1,
11054                            q.invoice_margin,
11055                            CASE
11056                                WHEN bt.budget_type_group_id = 4
11057                                AND q.budget_margin_enabled > 0
11058                                AND q.budget_margin_enabled IS NOT NULL
11059                                AND q.invoice_margin <> 0
11060                            THEN q.invoice_margin * q.amount
11061                            END s2,
11062                            q.budget_type_id,
11063                            q.budget_status_id,
11064                            q.amount,
11065                            bt.budget_type_group_id,
11066                            q.budget_margin_enabled
11067                        FROM
11068                            tbl_quotations q
11069                        JOIN tbl_companies c
11070                            ON c.company_id = q.company_id
11071                        LEFT JOIN tbl_budget_types bt
11072                            ON q.budget_type_id = bt.budget_type_id
11073                        LEFT JOIN tbl_users u
11074                            ON u.name = q.created_by
11075                        LEFT JOIN tbl_roles r
11076                            ON r.role_id = u.role_id
11077                        WHERE
11078                            q.acceptance_date IS NOT NULL
11079
11080                            AND q.for_add != 1
11081                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
11082                            AND (q.commercial IS NOT NULL AND q.commercial != '')
11083                            AND q.budget_type_id != 7
11084                            AND q.budget_type_id IS NOT NULL
11085                            {$where}
11086                    ) AS q
11087                    WHERE q.date != '0000-00-00 00:00:00' {$whereDates}
11088                    GROUP BY
11089                        q.region,
11090                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11091                        MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11092                        WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) WITH ROLLUP
11093                    ORDER BY
11094                        q.region IS NULL,
11095                        q.region,
11096                        CASE WHEN q.region IS NOT NULL
11097                            AND YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11098                            AND MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11099                            AND WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11100                        THEN 0
11101                        ELSE 1 END,
11102                    YEAR DESC,
11103                    MONTH ASC,
11104                    WEEK ASC";
11105
11106            $totalGroupValue = Cache::get(base64_encode($query));
11107
11108            if(!$totalGroupValue){
11109                $totalGroup = DB::select($query);
11110
11111                Cache::put(base64_encode($query), $totalGroup, 600);
11112            }else{
11113                $totalGroup = $totalGroupValue;
11114            }
11115
11116            array_pop($result);
11117            $merged = array_merge($result, $totalGroup);
11118
11119            return response([
11120                'message' => 'OK',
11121                'data' => $merged
11122            ]);
11123
11124        } catch (\Exception $e) {
11125            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11126        }
11127
11128    }
11129
11130    public function getIdsFromInternalQuoteIds($ids){
11131        $idsArray = array_filter(explode(',', $ids), 'is_numeric');
11132        return TblQuotations::whereIn("internal_quote_id", $idsArray)
11133            ->pluck("id")
11134            ->toArray();
11135    }
11136
11137    public function checkQuotationExistByInternalQuoteId(Request $request)
11138    {
11139        try{
11140            $idsString = $request->all()["ids"];
11141            $ids = explode(',',$idsString);
11142            $region = urldecode(@getallheaders()["Region"]);
11143            $company = TblCompanies::where("region", $region)->first();
11144
11145            if(!$company){
11146                Throw new \Exception("Region no encontrada");
11147            }
11148
11149            $companyId = $company->company_id;
11150
11151            $idsChecked = [];
11152
11153            foreach ($ids as $id){
11154                $quote = TblQuotations::where("internal_quote_id", $id)->where("company_id", $companyId)->first();
11155                if(
11156                    ($companyId === 18 || $companyId === 22)
11157                    && !$quote
11158                ){
11159                    $quote = TblQuotations::where("internal_quote_id", $id)->whereIn("company_id", [18,22])->first();
11160                }
11161                $idsChecked[$id] = $quote ? $quote->id : null;
11162            }
11163
11164            return response([
11165                'message' => 'OK',
11166                'data' => $idsChecked
11167            ]);
11168
11169        }catch (\Exception $e) {
11170            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11171        }
11172
11173    }
11174
11175    public function addUpdateLog($id, $userId, $field, $oldData, $newData){
11176        $oldRegister = null;
11177        $newRegister = null;
11178
11179        if($field == "company_id"){
11180            $oldRegister = TblCompanies::where("company_id", $oldData)->first();
11181            $newRegister = TblCompanies::where("company_id", $newData)->first();
11182        }
11183
11184        if($field == "customer_type_id"){
11185            $oldRegister = TblCustomerTypes::where("customer_type_id", $oldData)->first();
11186            $newRegister = TblCustomerTypes::where("customer_type_id", $newData)->first();
11187        }
11188
11189        if($field == "segment_id"){
11190            $oldRegister = TblSegments::where("segment_id", $oldData)->first();
11191            $newRegister = TblSegments::where("segment_id", $newData)->first();
11192        }
11193
11194        if($field == "budget_type_id"){
11195            $oldRegister = TblBudgetTypes::where("budget_type_id", $oldData)->first();
11196            $newRegister = TblBudgetTypes::where("budget_type_id", $newData)->first();
11197        }
11198
11199        if($field == "budget_status_id"){
11200            $oldRegister = TblBudgetStatus::where("budget_status_id", $oldData)->first();
11201            $newRegister = TblBudgetStatus::where("budget_status_id", $newData)->first();
11202        }
11203
11204        if($field == "source_id"){
11205            $oldRegister = TblSources::where("source_id", $oldData)->first();
11206            $newRegister = TblSources::where("source_id", $newData)->first();
11207        }
11208
11209        $oldData = $oldRegister ? $oldRegister->name : 'N/A';
11210        $newData = $newRegister ? $newRegister->name : 'N/A';
11211
11212        if(is_numeric($userId)){
11213            $userName = TblUsers::where("id", $userId)->first()->name;
11214        } else {
11215            $userName = $userId;
11216        }
11217
11218        if($oldData !== $newData){
11219            TblQuotationsLog::create(
11220                array(
11221                    'quotation_id' => $id,
11222                    'user' => $userName,
11223                    'field' => $field,
11224                    'old_value' => $oldData,
11225                    'new_value' => $newData
11226                )
11227            );
11228        }
11229    }
11230}