Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
5.84% covered (danger)
5.84%
332 / 5681
2.41% covered (danger)
2.41%
2 / 83
CRAP
0.00% covered (danger)
0.00%
0 / 1
Quotations
5.84% covered (danger)
5.84%
332 / 5681
2.41% covered (danger)
2.41%
2 / 83
1477875.07
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 / 77
0.00% covered (danger)
0.00%
0 / 1
90
 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 / 37
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 / 37
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
29.82% covered (danger)
29.82%
119 / 399
0.00% covered (danger)
0.00%
0 / 1
5351.36
 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 / 11
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
90.24% covered (success)
90.24%
37 / 41
0.00% covered (danger)
0.00%
0 / 1
8.06
 list_quotations
24.93% covered (danger)
24.93%
93 / 373
0.00% covered (danger)
0.00%
0 / 1
6314.25
 get_dates
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
12
 list_quotation_analytics_by_source
0.00% covered (danger)
0.00%
0 / 120
0.00% covered (danger)
0.00%
0 / 1
1640
 list_quotation_analytics_send_budgets
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 1
380
 list_quotation_analytics_track_budgets
0.00% covered (danger)
0.00%
0 / 120
0.00% covered (danger)
0.00%
0 / 1
1332
 list_quotation_analytics_types_budgets
0.00% covered (danger)
0.00%
0 / 122
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 / 35
0.00% covered (danger)
0.00%
0 / 1
30
 list_bulk_upload
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
 delete_number
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
6
 get_number
76.92% covered (warning)
76.92%
30 / 39
0.00% covered (danger)
0.00%
0 / 1
12.49
 get_years
0.00% covered (danger)
0.00%
0 / 34
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 / 128
0.00% covered (danger)
0.00%
0 / 1
1806
 download_file
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
56
 delete_file
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
30
 send_email_to_client
0.00% covered (danger)
0.00%
0 / 250
0.00% covered (danger)
0.00%
0 / 1
3422
 send_email_follow_ups
0.00% covered (danger)
0.00%
0 / 341
0.00% covered (danger)
0.00%
0 / 1
4422
 create_sender_identity
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
56
 get_sender_identity
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
 get_all_sender_identity
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 delete_sender_identity
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
20
 create_template
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 1
72
 get_email_files
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
20
 download_email_template_file
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
 delete_email_template_file
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 update_email_template_order
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 update_email_template
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
90
 delete_template
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 get_email_template
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 update_sender_identity
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
20
 resend_verification
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 list_quotation_analytics_by_performance
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
30
 list_orders_update_logs
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 list_g3w_orders_update_logs
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 update_budget_status_rejected_manual
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 update_budget_status_rejected
0.00% covered (danger)
0.00%
0 / 55
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 / 58
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 / 193
0.00% covered (danger)
0.00%
0 / 1
3660
 preview_file
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
20
 get_past_added_quotation
0.00% covered (danger)
0.00%
0 / 28
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 / 60
0.00% covered (danger)
0.00%
0 / 1
90
 sendgrid_webhook_receiver
0.00% covered (danger)
0.00%
0 / 35
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 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 list_quotation_analytics_commercial
0.00% covered (danger)
0.00%
0 / 187
0.00% covered (danger)
0.00%
0 / 1
2970
 clear_open_data
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
30
 list_quotation_analytics_order_size
0.00% covered (danger)
0.00%
0 / 195
0.00% covered (danger)
0.00%
0 / 1
4422
 send_email_template_preview
0.00% covered (danger)
0.00%
0 / 107
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 / 190
0.00% covered (danger)
0.00%
0 / 1
3660
 request_permission_commercial
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 1
72
 confirm_update_commercial
0.00% covered (danger)
0.00%
0 / 18
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 / 236
0.00% covered (danger)
0.00%
0 / 1
4422
 list_quotations_deleted
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
12
 delete_sengrid
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
20
 download_productivity_commercial
0.00% covered (danger)
0.00%
0 / 379
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 / 167
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 / 22
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
 setSolicitudDuplicity
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
20
 getQuoteIdOfDuplicityById
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
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            if($result->budget_status_id == 6) {
161                    $data = [
162                    "id"                     => $result->id ?? null, 
163                    "client"                 => $result->client ?? null, 
164                    "email"                  => $result->email ?? null, 
165                    "phone_number"           => $result->phone_number ?? null, 
166                    "last_follow_up_comment" => $result->last_follow_up_comment ?? null,
167                    "quote_id"               => $result->quote_id ?? null,
168                    "request_date"           => date("Y-m-d"),
169                    "updated_by"             => "IA",
170                    "user_id"                => $result->user_id ?? null,
171                    "commercial"             => $result->commercial ?? null,
172                    "budget_status_id"       => $result->budget_status_id ?? null,
173                    "internal_quote_id"      => $result->internal_quote_id ?? null
174                ];
175
176                $ch = curl_init("https://2lsarnb35o6evhgwmfedrsxk3i0lqzzq.lambda-url.eu-west-2.on.aws/checkduplicate");
177                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
178                curl_setopt($ch, CURLOPT_POST, true);
179                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
180                curl_setopt($ch, CURLOPT_HTTPHEADER, [
181                    'Content-Type: application/json'
182                ]);
183
184                $response = curl_exec($ch);
185                $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
186                
187                if (curl_errno($ch)) {
188                    error_log('Error en cURL: ' . curl_error($ch));
189                }
190
191                curl_close($ch);
192            }
193
194            Cache::flush();
195            return response(['message' => 'OK', 'data' => $result]);
196
197        } catch (\Exception $e) {
198            /** @disregard P1014 */
199            $e->exceptionCode = 'CREATE_QUOTATION_EXCEPTION'; 
200            report($e);
201            return response(['message' => 'KO', 'error' => $e->getMessage()]);
202        }
203
204    }
205
206    function currency($amount, $withEuro = ''){
207
208        if($withEuro != null){
209            $withEuro = ' â‚¬';
210        }
211
212
213        return number_format($amount, 2, ',', '.') . $withEuro;
214    }
215
216
217    function send_approval_notification($amount, $budgetTypeId, $customerTypeId, $minimumOrderSize, $quoteId, $id, $companyName, $createdBy, $userId, $action, $commercialEmail, $companyId, $endpoint, $isQuestion, $questionIdsNo, $n, $locale = null){
218
219        if(!is_null($locale)){
220            $this->locale = $locale;
221        }
222
223        if($action != 1){
224            if($this->locale == 'es'){
225                $action = "actualizado";
226            }else{
227                $action = "updated";
228            }
229
230        }else{
231            if($this->locale == 'es'){
232                $action = "creado";
233            }else{
234                $action = "created";
235            }
236        }
237
238        $fendpoint = "";
239
240        if($endpoint == 'orders'){
241            if($this->locale == 'es'){
242                $fendpoint = "presupuesto";
243            }else{
244                $fendpoint = "budget";
245            }
246
247        }else{
248            if($this->locale == 'es'){
249                $fendpoint = "trabajo";
250            }else{
251                $fendpoint = "job";
252            }
253        }
254
255        $user = TblUsers::where('id', $userId)->first();
256
257        $query = "SELECT
258                    a.approver_id,
259                    a.user_id,
260                    b.name,
261                    b.email
262                FROM
263                    tbl_approvers a
264                    INNER JOIN tbl_users b ON a.user_id = b.id
265                WHERE a.company_id = {$companyId}
266                ";
267
268        if($n == 3){
269            $query = "SELECT
270                        a.approver_id,
271                        a.user_id,
272                        u.name,
273                        u.email
274                    FROM tbl_approvers a
275                    INNER JOIN tbl_users u ON a.user_id = u.id
276                    WHERE a.company_id = {$companyId}
277
278                    UNION ALL
279
280                    SELECT
281                        c.approver_id,
282                        c.user_id,
283                        u2.name,
284                        u2.email
285                    FROM tbl_approvers_v2 c
286                    INNER JOIN tbl_users u2 ON c.user_id = u2.id
287                    WHERE c.company_id = {$companyId}";
288        }
289
290        $approvers = DB::select($query);
291
292        if(count($approvers) > 0){
293            $amount = $this->currency($amount, 1);
294            $minimumOrderSize = $this->currency($minimumOrderSize, 1);
295
296            $budgetType = TblBudgetTypes::where('budget_type_id', $budgetTypeId)->first();
297            $clientType = TblCustomerTypes::where('customer_type_id', $customerTypeId)->first();
298
299            $imgpath = File::get('fireservicetitan.png');
300            $base64 = "data:image/png;base64,".base64_encode($imgpath);
301
302            $subject = __('language.send_approval_notification.subject');
303            $subject = str_replace('{{type}}', $budgetType->name, $subject);
304            $subject = str_replace('{{amount}}', $amount, $subject);
305            $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
306
307            $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
308            $href = "<a href='{$url}'>{$quoteId}</a>";
309            $cc = false;
310            foreach ($approvers as $item) {
311
312                $toEmail = $item->email;
313
314                $body = __('language.send_approval_notification.body_hello');
315                $body = str_replace('{{approver}}', $item->name, $body);
316
317                $body .= __('language.send_approval_notification.body_message');
318                $body = str_replace('{{endpoint}}', $fendpoint, $body);
319                $body = str_replace('{{creator}}', $createdBy, $body);
320                $body = str_replace('{{action}}', $action, $body);
321                $body = str_replace('{{company}}', $companyName, $body);
322                $body = str_replace('{{type}}', $budgetType->name, $body);
323                $body = str_replace('{{amount}}', $amount, $body);
324                $body = str_replace('{{quote_id}}', $href, $body);
325
326                if($isQuestion == 1){
327                    $body .= __('language.send_approval_notification.note_question');
328                }else{
329                    $body .= __('language.send_approval_notification.note');
330                }
331
332                $body = str_replace('{{company}}', $companyName, $body);
333                $body = str_replace('{{client_type}}', $clientType->name, $body);
334                $body = str_replace('{{project_type}}', $budgetType->name, $body);
335                $body = str_replace('{{amount}}', $minimumOrderSize, $body);
336
337                if($isQuestion == 1){
338                    if($questionIdsNo){
339                        $questions = TblWorkflowQuestions::whereIn('question_id', $questionIdsNo)->where('company_id', $companyId)->get();
340
341                        if($questions){
342                            $ul = "<ul>";
343                            $li = "";
344                            foreach ($questions as $item) {
345                                $li .= "<li>{$item->question}</li>";
346                            }
347                            $ul .= $li . "</ul><br><br>";
348                            $body .= $ul;
349                        }
350                    }
351                }
352
353                $content = $body;
354
355                $body .= "<p>Fire Service Titan</p>";
356                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
357
358                $html = '<!DOCTYPE html>';
359                $html .= '<html>';
360                $html .= '<head>';
361                $html .= '<meta charset="UTF-8">';
362                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
363                $html .= '</head>';
364                $html .= '<body>';
365                $html .= $body;
366                $html .= '</body>';
367                $html .= '</html>';
368
369                if($toEmail != null){
370                    $email = new \SendGrid\Mail\Mail();
371
372                    if(env('SENDGRID_STAGING')){
373                        $toEmail = $user->email;
374                        $item->user_id = $userId;
375                    }
376
377                    if($cc == false){
378                        $cc = true;
379                        if($user->email != $toEmail){
380                            if($user->email != $commercialEmail && $commercialEmail != null){
381                                $email->addBcc($user->email);
382                                $email->addBcc($commercialEmail);
383                            }else{
384                                $email->addBcc($user->email);
385                            }
386                        }
387                    }
388
389                    $email->setFrom('fire@fire.es', 'Fire Service Titan');
390                    $email->setSubject($subject);
391                    $email->addTo($toEmail);
392                    $email->addContent("text/html", $html);
393
394                    $email->addAttachment(
395                        $imgpath,
396                        "image/png",
397                        "fireservicetitan.png",
398                        "inline",
399                        "fireservicetitan"
400                    );
401
402                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
403
404                    $response = $sendgrid->send($email);
405                    if ($response->statusCode() == 202) {
406                        Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - APPROVAL EMAIL NOTIFICATION SENT');
407
408                        TblNotifications::create(
409                            array(
410                                'user_id' => $item->user_id,
411                                'content' => $content,
412                                'is_open' => 1,
413                                'created_by' => 'System',
414                                'link' => $url
415                            )
416                        );
417                    } else {
418                        $error = true;
419                        Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
420                    }
421                }
422
423            }
424        }
425    }
426
427    function send_approval_margin_notification($amount, $budgetTypeId, $customerTypeId, $minimumMargin, $quoteId, $id, $companyName, $createdBy, $userId, $action, $commercialEmail, $invoiceMargin, $companyId, $endpoint){
428
429        if($action != 1){
430            if($this->locale == 'es'){
431                $action = "actualizado";
432            }else{
433                $action = "updated";
434            }
435
436        }else{
437            if($this->locale == 'es'){
438                $action = "creado";
439            }else{
440                $action = "created";
441            }
442        }
443
444        $fendpoint = "";
445
446        if($endpoint == 'orders'){
447            if($this->locale == 'es'){
448                $fendpoint = "presupuesto";
449            }else{
450                $fendpoint = "budget";
451            }
452
453        }else{
454            if($this->locale == 'es'){
455                $fendpoint = "trabajo";
456            }else{
457                $fendpoint = "job";
458            }
459        }
460
461        $invoiceMargin = number_format($invoiceMargin, 2);
462        $minimumMargin = number_format($minimumMargin, 2);
463
464        $user = TblUsers::where('id', $userId)->first();
465
466        $query = "SELECT
467                    a.approver_id,
468                    a.user_id,
469                    b.name,
470                    b.email
471                FROM
472                    tbl_approvers a
473                    INNER JOIN tbl_users b ON a.user_id = b.id
474                WHERE a.company_id = {$companyId}
475                ";
476
477        $approvers = DB::select($query);
478
479        if(count($approvers) > 0){
480
481            $amount = $this->currency($amount, 1);
482
483            $budgetType = TblBudgetTypes::where('budget_type_id', $budgetTypeId)->first();
484            $clientType = TblCustomerTypes::where('customer_type_id', $customerTypeId)->first();
485
486            $imgpath = File::get('fireservicetitan.png');
487            $base64 = "data:image/png;base64,".base64_encode($imgpath);
488
489            $subject = __('language.send_approval_margin_notification.subject');
490            $subject = str_replace('{{type}}', $budgetType->name, $subject);
491            $subject = str_replace('{{amount}}', $amount, $subject);
492            $subject = str_replace('{{margin}}', $invoiceMargin, $subject);
493            $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
494
495            $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
496            $href = "<a href='{$url}'>{$quoteId}</a>";
497            $cc = false;
498            foreach ($approvers as $item) {
499
500                $toEmail = $item->email;
501
502                $body = __('language.send_approval_margin_notification.body_hello');
503                $body = str_replace('{{approver}}', $item->name, $body);
504
505                $body .= __('language.send_approval_margin_notification.body_message');
506                $body = str_replace('{{endpoint}}', $fendpoint, $body);
507                $body = str_replace('{{creator}}', $createdBy, $body);
508                $body = str_replace('{{action}}', $action, $body);
509                $body = str_replace('{{company}}', $companyName, $body);
510                $body = str_replace('{{type}}', $budgetType->name, $body);
511                $body = str_replace('{{amount}}', $amount, $body);
512                $body = str_replace('{{quote_id}}', $href, $body);
513                $body = str_replace('{{margin}}', $invoiceMargin, $body);
514
515                $body .= __('language.send_approval_margin_notification.note');
516                $body = str_replace('{{company}}', $companyName, $body);
517                $body = str_replace('{{client_type}}', $clientType->name, $body);
518                $body = str_replace('{{project_type}}', $budgetType->name, $body);
519                $body = str_replace('{{margin}}', $minimumMargin, $body);
520
521                $content = $body;
522
523                $body .= "<p>Fire Service Titan</p>";
524                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
525
526                $html = '<!DOCTYPE html>';
527                $html .= '<html>';
528                $html .= '<head>';
529                $html .= '<meta charset="UTF-8">';
530                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
531                $html .= '</head>';
532                $html .= '<body>';
533                $html .= $body;
534                $html .= '</body>';
535                $html .= '</html>';
536
537                if($toEmail != null){
538                    $email = new \SendGrid\Mail\Mail();
539
540                    if(env('SENDGRID_STAGING')){
541                        $toEmail = $user->email;
542                        $item->user_id = $userId;
543                    }
544
545                    if($cc == false){
546                        $cc = true;
547
548                        if($user->email != $toEmail){
549                            if($user->email != $commercialEmail && $commercialEmail != null){
550                                $email->addBcc($user->email);
551                                $email->addBcc($commercialEmail);
552                            }else{
553                                $email->addBcc($user->email);
554                            }
555                        }
556                    }
557
558                    $email->setFrom('fire@fire.es', 'Fire Service Titan');
559                    $email->setSubject($subject);
560                    $email->addTo($toEmail);
561                    $email->addContent("text/html", $html);
562
563                    $email->addAttachment(
564                        $imgpath,
565                        "image/png",
566                        "fireservicetitan.png",
567                        "inline",
568                        "fireservicetitan"
569                    );
570
571                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
572
573                    $response = $sendgrid->send($email);
574                    if ($response->statusCode() == 202) {
575                        Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - MARGIN APPROVAL EMAIL NOTIFICATION SENT');
576
577                        TblNotifications::create(
578                            array(
579                                'user_id' => $item->user_id,
580                                'content' => $content,
581                                'is_open' => 1,
582                                'created_by' => 'System',
583                                'link' => $url
584                            )
585                        );
586                    } else {
587                        $error = true;
588                        Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
589                    }
590                }
591
592            }
593        }
594    }
595
596    function approve_quotation($id){
597
598        try {
599
600            $id = addslashes($id);
601
602            $result = TblQuotations::where('id', $id)->first();
603            $company = TblCompanies::where('company_id', $result->company_id)->first();
604            $budgetType = TblBudgetTypes::where('budget_type_id', $result->budget_type_id)->first();
605
606            if($result->created_by != $result->commercial){
607                $creatorAndCommercial = array($result->created_by, $result->commercial);
608                foreach ($creatorAndCommercial as $name) {
609                    $user = TblUsers::where('name', $name)->first();
610                    if($user){
611                        $this->send_approved_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
612                    }
613                }
614            }else{
615                $user = TblUsers::where('name', $result->created_by)->first();
616                if($user){
617                    $this->send_approved_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
618                }
619            }
620
621            if ($result->for_approval == 3) {
622                $result = TblQuotations::where('id', $id)->first();
623
624                $approved = 0;
625                $rejected = 0;
626
627                if ($result->approved_by !== null) {
628                    $approved++;
629                }
630                if ($result->approved_by_v2 !== null) {
631                    $approved++;
632                }
633
634                if ($result->rejected_by !== null) {
635                    $rejected++;
636                }
637                if ($result->rejected_by_v2 !== null) {
638                    $rejected++;
639                }
640
641                if ($approved === 2) {
642                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
643                } elseif ($rejected >= 1 && ($approved + $rejected) === 2) {
644                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
645                }
646            }elseif($result->for_approval == 1){
647                TblQuotations::where('id', $id)->update(['for_approval' => null]);
648            }
649
650
651            Cache::flush();
652            return response(['message' => 'OK']);
653
654        } catch (\Exception $e) {
655            /** @disregard P1014 */
656            $e->exceptionCode = 'APPROVE_QUOTATION_EXCEPTION'; 
657            report($e);
658            return response(['message' => 'KO', 'error' => $e->getMessage()]);
659        }
660
661    }
662
663    function send_approved_notification($userId, $username, $email, $companyName, $budgetType, $amount, $id, $quoteId, $companyId, $endpoint){
664
665        $fendpoint = "";
666
667        if($endpoint == 'orders'){
668            if($this->locale == 'es'){
669                $fendpoint = "presupuesto";
670            }else{
671                $fendpoint = "budget";
672            }
673
674        }else{
675            if($this->locale == 'es'){
676                $fendpoint = "trabajo";
677            }else{
678                $fendpoint = "job";
679            }
680        }
681
682        $query = "SELECT
683                    u.id AS user_id,
684                    u.name,
685                    u.email,
686                    u.sender_email,
687                    CASE
688                        WHEN a.user_id IS NOT NULL AND c.user_id IS NOT NULL THEN 'both'
689                        WHEN a.user_id IS NOT NULL THEN 'approvers'
690                        WHEN c.user_id IS NOT NULL THEN 'approvers_v2'
691                        ELSE 'none'
692                    END AS exists_in
693                FROM tbl_users u
694                LEFT JOIN tbl_approvers a
695                    ON u.id = a.user_id AND a.company_id = {$companyId}
696                LEFT JOIN tbl_approvers_v2 c
697                    ON u.id = c.user_id AND c.company_id = {$companyId}
698                WHERE u.id = {$this->userId}";
699
700        $user = DB::select($query);
701
702        $user = $user[0] ?? null;
703
704        $toEmail = $email;
705
706        $amount = $this->currency($amount, 1);
707
708        $imgpath = File::get('fireservicetitan.png');
709        $base64 = "data:image/png;base64,".base64_encode($imgpath);
710
711        $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
712        $href = "<a href='{$url}'>{$quoteId}</a>";
713
714        $body = __('language.send_approved_notification.body_hello');
715        $body = str_replace('{{creator}}', $username, $body);
716
717        $body .= __('language.send_approved_notification.body_message');
718        $body = str_replace('{{approver}}', $user->name, $body);
719        $body = str_replace('{{company}}', $companyName, $body);
720        $body = str_replace('{{type}}', $budgetType, $body);
721        $body = str_replace('{{amount}}', $amount, $body);
722        $body = str_replace('{{quote_id}}', $href, $body);
723        $body = str_replace('{{endpoint}}', $fendpoint, $body);
724
725        $content = $body;
726
727        $body .= "<p>Fire Service Titan</p>";
728        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
729
730        $html = '<!DOCTYPE html>';
731        $html .= '<html>';
732        $html .= '<head>';
733        $html .= '<meta charset="UTF-8">';
734        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
735        $html .= '</head>';
736        $html .= '<body>';
737        $html .= $body;
738        $html .= '</body>';
739        $html .= '</html>';
740
741        $subject = __('language.send_approved_notification.subject');
742        $subject = str_replace('{{quote_id}}', $quoteId, $subject);
743        $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
744
745        if($toEmail != null){
746            $email = new \SendGrid\Mail\Mail();
747
748            if(env('SENDGRID_STAGING')){
749                $toEmail = $user->email;
750                $userId = $this->userId;
751            }
752
753            $email->setFrom('fire@fire.es', 'Fire Service Titan');
754            $email->setSubject($subject);
755            $email->addTo($toEmail);
756            $email->addContent("text/html", $html);
757
758            $email->addAttachment(
759                $imgpath,
760                "image/png",
761                "fireservicetitan.png",
762                "inline",
763                "fireservicetitan"
764            );
765
766            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
767
768            $response = $sendgrid->send($email);
769            if ($response->statusCode() == 202) {
770                Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - APPROVED EMAIL NOTIFICATION SENT');
771
772                if($endpoint == 'orders'){
773                    if($user->exists_in == "approvers"){
774                        TblQuotations::where('id', $id)->update(
775                            array(
776                                'approved_at' => date('Y-m-d H:i:s'),
777                                'approved_by' => $user->name
778                            )
779                        );
780                    }elseif($user->exists_in == "approvers_v2"){
781                        TblQuotations::where('id', $id)->update(
782                            array(
783                                'approved_at_v2' => date('Y-m-d H:i:s'),
784                                'approved_by_v2' => $user->name
785                            )
786                        );
787                    }
788                }else{
789                    TblOngoingJobs::where('id', $id)->update(
790                        array(
791                            'approved_at' => date('Y-m-d H:i:s'),
792                            'approved_by' => $user->name
793                        )
794                    );
795                }
796
797                TblNotifications::create(
798                    array(
799                        'user_id' => $userId,
800                        'content' => $content,
801                        'is_open' => 1,
802                        'created_by' => 'System',
803                        'link' => $url
804                    )
805                );
806            } else {
807                $error = true;
808                Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
809            }
810        }
811
812    }
813
814    function reject_quotation($id){
815
816        try {
817
818            $id = addslashes($id);
819
820            $result = TblQuotations::where('id', $id)->first();
821            $company = TblCompanies::where('company_id', $result->company_id)->first();
822            $budgetType = TblBudgetTypes::where('budget_type_id', $result->budget_type_id)->first();
823
824            if($result->created_by != $result->commercial){
825                $creatorAndCommercial = array($result->created_by, $result->commercial);
826                foreach ($creatorAndCommercial as $name) {
827                    $user = TblUsers::where('name', $name)->first();
828                    if($user){
829                        $this->send_rejected_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
830                    }
831                }
832            }else{
833                $user = TblUsers::where('name', $result->created_by)->first();
834                if($user){
835                    $this->send_rejected_notification($user->id, $user->name, $user->email, $company->name, $budgetType->name, $result->amount, $id, $result->quote_id, $company->company_id, 'orders');
836                }
837            }
838
839            if ($result->for_approval == 3) {
840                $result = TblQuotations::where('id', $id)->first();
841
842                $approved = 0;
843                $rejected = 0;
844
845                if ($result->approved_by !== null) {
846                    $approved++;
847                }
848                if ($result->approved_by_v2 !== null) {
849                    $approved++;
850                }
851
852                if ($result->rejected_by !== null) {
853                    $rejected++;
854                }
855                if ($result->rejected_by_v2 !== null) {
856                    $rejected++;
857                }
858
859                if ($approved === 2) {
860                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
861                } elseif ($rejected >= 1 && ($approved + $rejected) === 2) {
862                    TblQuotations::where('id', $id)->update(['for_approval' => null]);
863                }
864            }elseif($result->for_approval == 1){
865                TblQuotations::where('id', $id)->update(['for_approval' => null]);
866            }
867
868            Cache::flush();
869            return response(['message' => 'OK']);
870
871        } catch (\Exception $e) {
872            /** @disregard P1014 */
873            $e->exceptionCode = 'REJECT_QUOTATION_EXCEPTION'; 
874            report($e);
875            return response(['message' => 'KO', 'error' => $e->getMessage()]);
876        }
877
878    }
879
880    function send_rejected_notification($userId, $username, $email, $companyName, $budgetType, $amount, $id, $quoteId, $companyId, $endpoint){
881
882        $fendpoint = "";
883
884        if($endpoint == 'orders'){
885            if($this->locale == 'es'){
886                $fendpoint = "presupuesto";
887            }else{
888                $fendpoint = "budget";
889            }
890
891        }else{
892            if($this->locale == 'es'){
893                $fendpoint = "trabajo";
894            }else{
895                $fendpoint = "job";
896            }
897        }
898
899        $query = "SELECT
900                    u.id AS user_id,
901                    u.name,
902                    u.email,
903                    u.sender_email,
904                    CASE
905                        WHEN a.user_id IS NOT NULL AND c.user_id IS NOT NULL THEN 'both'
906                        WHEN a.user_id IS NOT NULL THEN 'approvers'
907                        WHEN c.user_id IS NOT NULL THEN 'approvers_v2'
908                        ELSE 'none'
909                    END AS exists_in
910                FROM tbl_users u
911                LEFT JOIN tbl_approvers a
912                    ON u.id = a.user_id AND a.company_id = {$companyId}
913                LEFT JOIN tbl_approvers_v2 c
914                    ON u.id = c.user_id AND c.company_id = {$companyId}
915                WHERE u.id = {$this->userId}";
916
917        $user = DB::select($query);
918
919        $user = $user[0] ?? null;
920
921        $toEmail = $email;
922        $amount = $this->currency($amount, 1);
923
924        $imgpath = File::get('fireservicetitan.png');
925        $base64 = "data:image/png;base64,".base64_encode($imgpath);
926
927        $url = env('URL') . "{$endpoint}/{$id}?company_id={$companyId}";
928        $href = "<a href='{$url}'>{$quoteId}</a>";
929
930        $body = __('language.send_rejected_notification.body_hello');
931        $body = str_replace('{{creator}}', $username, $body);
932
933        $body .= __('language.send_rejected_notification.body_message');
934        $body = str_replace('{{approver}}', $user->name, $body);
935        $body = str_replace('{{company}}', $companyName, $body);
936        $body = str_replace('{{type}}', $budgetType, $body);
937        $body = str_replace('{{amount}}', $amount, $body);
938        $body = str_replace('{{quote_id}}', $href, $body);
939        $body = str_replace('{{endpoint}}', $fendpoint, $body);
940
941        $content = $body;
942
943        $body .= "<p>Fire Service Titan</p>";
944        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
945
946        $html = '<!DOCTYPE html>';
947        $html .= '<html>';
948        $html .= '<head>';
949        $html .= '<meta charset="UTF-8">';
950        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
951        $html .= '</head>';
952        $html .= '<body>';
953        $html .= $body;
954        $html .= '</body>';
955        $html .= '</html>';
956
957        $subject = __('language.send_rejected_notification.subject');
958        $subject = str_replace('{{quote_id}}', $quoteId, $subject);
959        $subject = str_replace('{{endpoint}}', ucfirst($fendpoint), $subject);
960
961        if($toEmail != null){
962            $email = new \SendGrid\Mail\Mail();
963
964            if(env('SENDGRID_STAGING')){
965                $toEmail = $user->email;
966                $userId = $this->userId;
967            }
968
969            $email->setFrom('fire@fire.es', 'Fire Service Titan');
970            $email->setSubject($subject);
971            $email->addTo($toEmail);
972            $email->addContent("text/html", $html);
973
974            $email->addAttachment(
975                $imgpath,
976                "image/png",
977                "fireservicetitan.png",
978                "inline",
979                "fireservicetitan"
980            );
981
982            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
983
984            $response = $sendgrid->send($email);
985            if ($response->statusCode() == 202) {
986                Log::channel('email_log')->info('ID:' . $quoteId . ' : '. $toEmail .' - REJECTED EMAIL NOTIFICATION SENT');
987
988                if($endpoint == 'orders'){
989
990                    if($user->exists_in == "approvers"){
991                        TblQuotations::where('id', $id)->update(
992                            array(
993                                'rejected_at' => date('Y-m-d H:i:s'),
994                                'rejected_by' => $user->name
995                            )
996                        );
997                    }elseif($user->exists_in == "approvers_v2"){
998                        TblQuotations::where('id', $id)->update(
999                            array(
1000                                'rejected_at_v2' => date('Y-m-d H:i:s'),
1001                                'rejected_by_v2' => $user->name
1002                            )
1003                        );
1004                    }
1005                }else{
1006                    TblOngoingJobs::where('id', $id)->update(
1007                        array(
1008                            'rejected_at' => date('Y-m-d H:i:s'),
1009                            'rejected_by' => $user->name
1010                        )
1011                    );
1012                }
1013
1014                TblNotifications::create(
1015                    array(
1016                        'user_id' => $userId,
1017                        'content' => $content,
1018                        'is_open' => 1,
1019                        'created_by' => 'System',
1020                        'link' => $url
1021                    )
1022                );
1023            } else {
1024                $error = true;
1025                Log::channel('email_log')->error('ID:' . $quoteId . ' : '. $toEmail .' - ' . $response->body());
1026            }
1027        }
1028
1029    }
1030
1031    public function update_quotation(Request $request, $id){
1032        $approvalMinimumOrderSize = null;
1033        $approvalIsQuestion = null;
1034        $approvalQuestionIdsNo = null;
1035        $approvalN = null;
1036        $approvalMinimumMargin = null;
1037        $approvalId = null;
1038        $approvalForAdd = null;
1039        $approvalInvoiceMargin = null;
1040        $sendApprovalNotification = false;
1041        $sendApprovalMarginNotification = false;
1042        $needToSendReminder = false;
1043
1044        // try {
1045
1046            $data = $request->all();
1047            $id = addslashes($id);
1048            $userId = addslashes($data['user_id']);
1049            $forApproval = null;
1050            unset($data['user_id']);
1051
1052            $r = array('amount', 'order_number', 'budget_type_id', 'acceptance_date');
1053            $job = array();
1054
1055            foreach ($data as $key => $value) {
1056                if($value == 'null'){
1057                    $data[$key] = null;
1058                }
1059
1060                if(in_array($key, $r)){
1061                    $job[$key] = $value;
1062                }
1063            }
1064
1065            $files = $request->file('files');
1066            unset($data['files']);
1067
1068            $internalFiles = $request->file('internal_files');
1069            unset($data['internal_files']);
1070
1071            $query = "
1072            SELECT
1073                SUM(CASE WHEN is_internal IS NULL THEN 1 ELSE 0 END) as external_count,
1074                SUM(CASE WHEN is_internal = 1 THEN 1 ELSE 0 END) as internal_count
1075            FROM tbl_files
1076            WHERE quotation_id = ?";
1077
1078            $counts = DB::select($query, [$id]);
1079            $fileCount = $counts[0]->external_count;
1080            $internalFileCount = $counts[0]->internal_count;
1081
1082            if($fileCount > 0 || !empty($files)){
1083                $data['has_attachment'] = 1;
1084            }
1085
1086            if($files){
1087                $totalFiles = $fileCount + count($files);
1088                if($totalFiles > 10){
1089                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
1090                }
1091            }
1092
1093            if($internalFileCount > 0 || !empty($internalFiles)){
1094                $data['has_attachment'] = 1;
1095            }
1096
1097            if($internalFiles){
1098                $totalInternalFileCount = $internalFileCount + count($internalFiles);
1099                if($totalInternalFileCount > 10){
1100                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
1101                }
1102            }
1103
1104            if(isset($data['request_date']) && isset($data['issue_date'])){
1105                $requestDate = strtotime($data['request_date']);
1106                $issueDate = strtotime($data['issue_date']);
1107                $dateDiff = $issueDate - $requestDate;
1108                $data['duration'] = round($dateDiff / (60 * 60 * 24));
1109            }
1110
1111            $result = TblQuotations::where('id', $id)->first();
1112
1113            if($result->quote_id != $data['quote_id']){
1114
1115                $c = TblQuotations::where('quote_id', (string) $data['quote_id'])->where('company_id', $result->company_id)->count();
1116
1117                if($c > 0){
1118
1119                    if($result->for_add == 0){
1120                        $latestBudget = TblQuotations::where('company_id', $result->company_id)->orderByRaw('CAST(quote_id AS DOUBLE) DESC')->first();
1121
1122                        $number = $latestBudget->quote_id;
1123                        $x = true;
1124
1125                        while ($x) {
1126
1127                            if(is_numeric(substr($number, -1))) {
1128                                $number++;
1129                            }else{
1130                                $number .= "1";
1131                            }
1132
1133                            $check = 0;
1134
1135                            $check = TblQuotations::where('company_id', $result->company_id)->where('quote_id', (string) $number)->count();
1136
1137                            if($check == 0){
1138                                $x = false;
1139                            }
1140                        }
1141
1142                        return response(['message' => 'KO', 'error' => 'quote_exists', 'number' => $number]);
1143                    }
1144
1145                    return response(['message' => 'KO', 'error' => 'quote_exists']);
1146                }
1147            }
1148
1149            $action = 0;
1150            if($result->created_by == null || $result->for_add == 1){
1151                $action = 1;
1152                $data['created_by'] = $data['updated_by'];
1153                $data['for_add'] = 0;
1154            }
1155
1156            $company = TblCompanies::where('company_id', $result->company_id)->first();
1157            $commercial = TblUsers::where('name', $data['commercial'])->first();
1158            $status = TblBudgetStatus::where('budget_status_id', $data['budget_status_id'])->first();
1159
1160            // $checkQuotation = TblQuotations::where(function($query) use ($data, $result) {
1161            //     $query->where('internal_quote_id', $data['internal_quote_id'])
1162            //         ->orWhere('internal_quote_id', 'O-25/'.$data['internal_quote_id']);
1163            // })
1164            //     ->where('company_id', $result->company_id)
1165            //     ->first();
1166
1167            // if($checkQuotation) {
1168            //     $url = "orders/" . $checkQuotation->id . "?company_id=" . $checkQuotation->company_id;
1169            //     return response([
1170            //         'message' => 'KO',
1171            //         'error' => "Presupuesto ya creado. Puedes verlo <a href='$url' target='_blank'>aquí</a>."
1172            //     ]);
1173            // }
1174
1175            $limitReminderEmails = $company->limit_reminder_emails ?? 3;
1176
1177            if($result->total_sent == $limitReminderEmails){
1178                $data['total_sent'] = 0;
1179            }
1180
1181            if($result->budget_status_id != $data['budget_status_id'] || $result->commercial != $data['commercial']){
1182                if($data['budget_status_id'] == 12){
1183                    if($company && $commercial){
1184                        $inProgressCount = TblQuotations::where('budget_status_id', 12)->where('company_id', $result->company_id)->where('commercial', $data['commercial'])->count();
1185                        if($company->process_limit <= $inProgressCount){
1186                            return response(['message' => 'KO', 'error' => 'in_progress', 'limit' => $company->process_limit]);
1187                        }
1188                    }else{
1189                        return response(['message' => 'KO', 'error' => 'in_progress', 'limit' => 0]);
1190                    }
1191                }
1192            }
1193
1194            $sendNotification = false;
1195            if($result->commercial != $data['commercial']){
1196                if(!empty($commercial)){
1197                    $createdByX = ($result->created_by == null) ? $data['created_by'] : $result->created_by;
1198                    if($createdByX != $data['commercial']){
1199                        $action = 0;
1200                        $sendNotification = true;
1201                    }
1202                }
1203            }
1204
1205            if(isset($data['amount']) || isset($data['budget_type_id']) || isset($data['customer_type_id']) || isset($data['invoice_margin']) || isset($data['question_enabled'])){
1206                if($company){
1207
1208                    $n = 0;
1209                    $invoiceMargin = 0;
1210                    $minimumMargin = 0;
1211                    $minimumOrderSize = 0;
1212
1213                    if($result->amount != $data['amount'] ||
1214                        $result->budget_type_id != $data['budget_type_id'] ||
1215                        $result->customer_type_id != $data['customer_type_id'] ||
1216                        $result->invoice_margin != $data['invoice_margin']
1217                    ){
1218                        $project = TblProjectTypes::where('company_id', $company->company_id)->where('budget_type_id', $data['budget_type_id'])->first();
1219                        $customerTypeIds = array();
1220
1221                        if($project){
1222                            if(!empty($project->customer_type_ids)){
1223                                $customerTypeIds = array_map('intval', explode(',', $project->customer_type_ids));
1224                            }
1225                            if($project->minimum_order_size != null && in_array($data['customer_type_id'], $customerTypeIds)){
1226                                if($data['amount'] >= $project->minimum_order_size){
1227                                    $data['for_approval'] = 1;
1228                                    $n = 1;
1229                                }
1230                            }
1231                            $minimumOrderSize = $project->minimum_order_size;
1232
1233                            if($project->minimum_order_size_v2 != null && in_array($data['customer_type_id'], $customerTypeIds)){
1234                                if($data['amount'] >= $project->minimum_order_size_v2){
1235                                    $data['for_approval'] = 1;
1236                                    if($n == 1){
1237                                        $data['for_approval'] = 3;
1238                                        $n = 3;
1239                                    }
1240                                }
1241                            }
1242
1243                        }else{
1244                            if(!empty($company->customer_type_ids)){
1245                                $customerTypeIds = array_map('intval', explode(',', $company->customer_type_ids));
1246                            }
1247                            if($company->minimum_order_size != null && in_array($data['customer_type_id'], $customerTypeIds)){
1248                                if($data['amount'] >= $company->minimum_order_size){
1249                                    $data['for_approval'] = 1;
1250                                    $n = 1;
1251                                }
1252                            }
1253                            $minimumOrderSize = $company->minimum_order_size;
1254
1255                            if($company->minimum_order_size_v2 != null && in_array($data['customer_type_id'], $customerTypeIds)){
1256                                if($data['amount'] >= $company->minimum_order_size_v2){
1257                                    $data['for_approval'] = 1;
1258                                    if($n == 1){
1259                                        $data['for_approval'] = 3;
1260                                        $n = 3;
1261                                    }
1262                                }
1263                            }
1264                        }
1265
1266                        if($data['budget_margin_enabled'] > 0){
1267                            $costOfLabor = $data['cost_of_labor'];
1268                            $totalCostOfJob = $data['total_cost_of_job'];
1269
1270                            if($totalCostOfJob > 0){
1271                                $invoiceMargin = $data['invoice_margin'] ?? 0;
1272                            }
1273
1274                            $minimumMargin = $company->minimum_margin;
1275                            if(!empty($company->customer_type_ids)){
1276                                $customerTypeIds = array_map('intval', explode(',', $company->customer_type_ids));
1277                            }
1278
1279                            if($project){
1280                                $minimumMargin = $project->minimum_margin;
1281                                $minimumOrderSize = $project->minimum_order_size;
1282                                if(!empty($project->customer_type_ids)){
1283                                    $customerTypeIds = array_map('intval', explode(',', $project->customer_type_ids));
1284                                }
1285                            }
1286
1287                            if($invoiceMargin < $minimumMargin && $invoiceMargin != null && $invoiceMargin != 0){
1288                                if(in_array($data['customer_type_id'], $customerTypeIds)){
1289                                    $data['for_approval'] = 1;
1290                                    $n = 2;
1291                                }
1292                            }
1293                        }
1294                    }
1295
1296                    $isQuestion = 0;
1297                    $questionIdsNo = array();
1298                    if(isset($data['question_enabled'])){
1299                        if($data['question_ids_no'] != $result->question_ids_no
1300                            || $data['budget_type_id'] != $result->budget_type_id
1301                            || $data['customer_type_id'] != $result->customer_type_id
1302                            || $data['amount'] != $result->amount){
1303                            if($data['question_enabled'] > 0 && $n == 0){
1304                                if(!empty($data['question_ids_no'])){
1305                                    $questionIdsNo = array_map('intval', explode(",", $data['question_ids_no']));
1306
1307                                    if(count($questionIdsNo) > 0){
1308                                        if($company->workflow_budget_size != null){
1309                                            if($data['amount'] >= $company->workflow_budget_size){
1310                                                $isQuestion = 1;
1311                                                $data['for_approval'] = 1;
1312                                                $n = 1;
1313                                            }
1314                                        }
1315                                        $minimumOrderSize = $company->workflow_budget_size;
1316                                    }
1317                                }
1318                            }
1319                        }
1320                    }
1321
1322                    if($n == 1 || $n == 3){
1323                        $sendApprovalNotification = true;
1324                        $approvalMinimumOrderSize = $minimumOrderSize;
1325                        $approvalId = $result->id;
1326                        $approvalForAdd = $result->for_add;
1327                        $approvalIsQuestion = $isQuestion;
1328                        $approvalQuestionIdsNo = $questionIdsNo;
1329                        $approvalN = $n;
1330                    }
1331
1332                    if($n == 2){
1333                        $sendApprovalMarginNotification = true;
1334                        $approvalMinimumMargin = $minimumMargin;
1335                        $approvalId = $result->id;
1336                        $approvalForAdd = $result->for_add;
1337                        $approvalInvoiceMargin = $invoiceMargin;
1338                    }
1339                }
1340            }
1341
1342            $data['updated_at'] = date('Y-m-d H:i:s');
1343            $job['updated_at'] = $data['updated_at'];
1344
1345            $data["g3w_warning"] = 0;
1346
1347            if($result->for_add == 1){
1348                TblCompanies::where('company_id', $result->company_id)->update(array('last_id' => $data['quote_id'], 'before_last_id' => $data['quote_id']));
1349            }
1350
1351            $forApproval = @$data['for_approval'] ?? null;
1352
1353            if($forApproval != null){
1354                $data['approved_at'] = null;
1355                $data['approved_by'] = null;
1356                $data['rejected_at'] = null;
1357                $data['rejected_by'] = null;
1358                $data['approved_at_v2'] = null;
1359                $data['approved_by_v2'] = null;
1360                $data['rejected_at_v2'] = null;
1361                $data['rejected_by_v2'] = null;
1362            }
1363
1364            $differences = $this->compareArrays($data, TblQuotations::where('id', $id)->first());
1365            $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"];
1366
1367            if(is_null(TblQuotations::where('id', $id)->first()->customer_type_id)){
1368                $needToSendReminder = true;
1369            }
1370
1371            foreach ($differences as $field => $value) {
1372                if(in_array($field, $primaryAprovalsFields)){
1373                    $needToSendReminder = true;
1374                };
1375
1376                $this->addUpdateLog($id, $userId, $field, $value["oldData"], $value["newData"]);
1377            }
1378
1379            //check if the quotation are a solicitud and the user write the internal quote id
1380            
1381            $budgetRequest = TblQuotations::where('id', $id)->first();
1382
1383            if(
1384                ($budgetRequest->budget_status_id == 6 || $budgetRequest->budget_status_id == 8)
1385                && (!is_null($data["internal_quote_id"] ?? null) && $data["internal_quote_id"] !== "")
1386                && TblQuotations::where('internal_quote_id', $data["internal_quote_id"])->where("company_id", $company->company_id)->exists()
1387                && (!is_null($id) && $id !== "")
1388            ){
1389                $createdAt = $budgetRequest->created_at;
1390                $lastFollowUpComment = $budgetRequest->last_follow_up_comment;
1391                
1392                TblQuotations::where('id', $id)->first()->update(array("internal_quote_id", $data["internal_quote_id"]));
1393                
1394                $budget = TblQuotations::where('internal_quote_id', $data["internal_quote_id"])->where("company_id", $company->company_id)->first();
1395                TblFiles::where('quotation_id', $id)->where('is_internal', 1)->update(array('quotation_id' => $budget->id));
1396
1397                $this->callDeleteQuotation($id, $company->company_id, $userId, $data['updated_by']);
1398
1399                $id = $budget->id;
1400
1401                $dataToChange = array_intersect_key($data, array_flip([
1402                    'internal_quote_id',
1403                    'client',
1404                    'phone_number',
1405                    'email',
1406                    'source_id',
1407                    'created_by',
1408                    'updated_by',
1409                    'updated_at',
1410                    'request_date',
1411                    'last_follow_up_comment'
1412                ]));
1413                
1414                if($data["phone_number"] === null || $data["phone_number"] === "" || empty($dataToChange["phone_number"])){
1415                    unset($dataToChange['phone_number']);
1416                }
1417
1418                $dataToChange['budget_status_id'] = $budget->budget_status_id;
1419                $dataToChange["created_at"] = $createdAt;
1420                $dataToChange["last_follow_up_comment"] = $budget->last_follow_up_comment . "\n" . $lastFollowUpComment;
1421
1422                $data["g3w_warning"] = 0;
1423
1424                if(
1425                    in_array($budget->budget_status_id, [13, 14]) ||
1426                    !$dataToChange["source_id"] ||
1427                    (!$budget->budget_type_id || $budget->budget_type_id == 0 || $budget->budget_type_id == 16) ||
1428                    empty(trim($dataToChange["client"])) ||
1429                    empty(trim($dataToChange["email"]))
1430                ){
1431                    $data["g3w_warning"] = 1;
1432                }
1433                
1434                TblQuotations::where('id', $id)->update($dataToChange);
1435
1436            } else {
1437                TblQuotations::where('id', $id)->update($data);
1438            }
1439
1440            TblOngoingJobs::where('quotation_id', $id)->update($job);
1441
1442            $this->update_commercial_numbers($result->company_id);
1443
1444            if($result->budget_status_id != $data['budget_status_id']
1445                && $data['budget_status_id'] == 3){
1446                $this->send_acceptance_notification($result->id, $result->company_id, $userId, $data['updated_by']);
1447
1448                TblQuotations::where('id', $id)->update(
1449                    array(
1450                        'accepted_at' => $data['updated_at'],
1451                        'accepted_by' => $data['updated_by']
1452                    )
1453                );
1454            }
1455
1456            if($files){
1457
1458                $uploadedFiles = [];
1459                $i = 0;
1460
1461                $combinedFilesSize = 0;
1462                foreach ($files as $file) {
1463                    $i++;
1464                    $origFilename = $file->getClientOriginalName();
1465                    $filename = $result->id . '-' . $result->company_id . '-FC' . time() . '-' . $origFilename;
1466
1467                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
1468
1469                    if($combinedFilesSize > 25000000){
1470                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
1471                    }
1472
1473                    if(in_array($origFilename, $uploadedFiles)){
1474                        $origFilename = $origFilename . $i;
1475                    }
1476
1477                    // $fileContent = file_get_contents($file->getRealPath());
1478                    // $fileHash = hash('sha256', $fileContent);
1479                    
1480                    $s3path = Storage::disk('s3')->putFileAs(
1481                        'uploads',
1482                        $file,
1483                        $filename,
1484                        [
1485                            'ContentType' => $file->getMimeType(),
1486                        ]
1487                    );
1488
1489                    TblFiles::create(
1490                        array(
1491                            'quotation_id' => $id,
1492                            'original_name' => $origFilename,
1493                            'filename' => $filename,
1494                            'uploaded_by' => $data['updated_by'],
1495                            // 'file' => $fileContent,
1496                            'file_size' => $file->getSize(),
1497                            // 'file_hash' => $fileHash,
1498                            'mime_type' => $file->getMimeType(),
1499                            'uploaded_at' => now(),
1500                        )
1501                    );
1502
1503                    $uploadedFiles[] = $file->getClientOriginalName();
1504                }
1505            }
1506
1507            if($internalFiles){
1508
1509                $uploadedFiles = [];
1510                $i = 0;
1511
1512                $combinedFilesSize = 0;
1513                foreach ($internalFiles as $file) {
1514                    $i++;
1515                    $origFilename = $file->getClientOriginalName();
1516                    $filename = $result->id . '-' . $result->company_id . '-FI' . time() . '-' . $origFilename;
1517
1518                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
1519
1520                    if($combinedFilesSize > 25000000){
1521                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
1522                    }
1523
1524                    if(in_array($origFilename, $uploadedFiles)){
1525                        $origFilename = $origFilename . $i;
1526                    }
1527
1528                    // $fileContent = file_get_contents($file->getRealPath());
1529                    // $fileHash = hash('sha256', $fileContent);                    
1530
1531                    $s3path = Storage::disk('s3')->putFileAs(
1532                        'uploads',
1533                        $file,
1534                        $filename,
1535                        [
1536                            'ContentType' => $file->getMimeType(),
1537                        ]
1538                    );
1539
1540                    TblFiles::create(
1541                        array(
1542                            'quotation_id' => $id,
1543                            'original_name' => $origFilename,
1544                            'filename' => $filename,
1545                            'uploaded_by' => $data['updated_by'],
1546                            // 'file' => $fileContent,
1547                            'file_size' => $file->getSize(),
1548                            // 'file_hash' => $fileHash,
1549                            'mime_type' => $file->getMimeType(),
1550                            'uploaded_at' => now(),
1551                            'is_internal' => 1
1552                        )
1553                    );
1554
1555                    $uploadedFiles[] = $file->getClientOriginalName();
1556                }
1557            }
1558
1559            $query = "SELECT
1560                        a.id,
1561                        a.quote_id,
1562                        a.company_id,
1563                        b.name company_name,
1564                        a.client,
1565                        c.name client_type,
1566                        c.customer_type_id,
1567                        a.request_date,
1568                        a.visit_date,
1569                        a.issue_date,
1570                        a.acceptance_date,
1571                        a.internal_quote_id,
1572                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
1573                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
1574                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
1575                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
1576                        -- DATEDIFF(a.issue_date, a.request_date) duration,
1577                        a.phone_number,
1578                        a.email,
1579                        a.duration,
1580                        a.order_number,
1581                        d.name 'type',
1582                        d.budget_type_id,
1583                        e.name 'status',
1584                        e.budget_status_id,
1585                        f.name source,
1586                        f.source_id,
1587                        a.amount,
1588                        g.name reason_for_not_following_up,
1589                        a.reason_for_not_following_up_id,
1590                        a.reason_for_rejection_id,
1591                        a.last_follow_up_date,
1592                        a.last_follow_up_comment,
1593                        CASE WHEN a.reason_for_rejection_id IS NULL THEN a.reason_for_rejection ELSE h.name END reason_for_rejection,
1594                        a.commercial,
1595                        a.created_by,
1596                        a.created_at,
1597                        a.updated_by,
1598                        a.for_approval,
1599                        a.box_work_g3w,
1600                        a.people_assigned_to_the_job,
1601                        a.duration_of_job_in_days,
1602                        a.estimated_cost_of_materials,
1603                        a.budget_margin_enabled,
1604                        a.question_enabled,
1605                        a.cost_of_labor,
1606                        a.total_cost_of_job,
1607                        CASE WHEN a.budget_margin_enabled > 0 THEN a.invoice_margin ELSE NULL END invoice_margin,
1608                        CASE WHEN a.budget_margin_enabled > 0 THEN a.margin_for_the_company ELSE NULL END margin_for_the_company,
1609                        a.margin_on_invoice_per_day_per_worker,
1610                        a.revenue_per_date_per_worked,
1611                        a.commission_cost,
1612                        a.commission_pct,
1613                        a.gross_margin,
1614                        a.labor_percentage,
1615                        a.question_ids,
1616                        a.question_ids_no,
1617                        a.approved_at,
1618                        a.approved_by,
1619                        a.rejected_at,
1620                        a.rejected_by,
1621                        a.approved_at_v2,
1622                        a.approved_by_v2,
1623                        a.rejected_at_v2,
1624                        a.rejected_by_v2,
1625                        a.accepted_at,
1626                        a.accepted_by,
1627                        a.is_validated,
1628                        a.resource_id,
1629                        a.x_status,
1630                        a.likehood,
1631                        a.updated_at
1632                    FROM
1633                        tbl_quotations a
1634                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
1635                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
1636                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
1637                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
1638                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
1639                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
1640                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
1641                    WHERE a.id = {$id}";
1642
1643            $result = DB::select($query);
1644
1645
1646            if($sendNotification){
1647                $this->send_notification(
1648                    $commercial->email,
1649                    $userId,
1650                    $data['quote_id'],
1651                    $id,
1652                    $status->name,
1653                    $commercial->id,
1654                    $company->name,
1655                    0,
1656                    $company->company_id,
1657                    $data['internal_quote_id']
1658                );
1659            }
1660
1661            if($sendApprovalNotification && $needToSendReminder){
1662                $this->send_approval_notification(
1663                    $data['amount'],
1664                    $data['budget_type_id'],
1665                    $data['customer_type_id'],
1666                    $approvalMinimumOrderSize,
1667                    $data['quote_id'],
1668                    $approvalId,
1669                    $company->name,
1670                    @$data['created_by'] ?? @$data['updated_by'],
1671                    $userId,
1672                    $approvalForAdd,
1673                    @$commercial->email ?? null,
1674                    $company->company_id,
1675                    'orders',
1676                    $approvalIsQuestion,
1677                    $approvalQuestionIdsNo,
1678                    $approvalN
1679                );
1680            }
1681
1682            if($sendApprovalMarginNotification && $needToSendReminder){
1683                $this->send_approval_margin_notification(
1684                    $data['amount'],
1685                    $data['budget_type_id'],
1686                    $data['customer_type_id'],
1687                    $approvalMinimumMargin,
1688                    $data['quote_id'],
1689                    $approvalId,
1690                    $company->name,
1691                    @$data['created_by'] ?? @$data['updated_by'],
1692                    $userId,
1693                    $approvalForAdd,
1694                    @$commercial->email ?? null,
1695                    $approvalInvoiceMargin,
1696                    $company->company_id,
1697                    'orders'
1698                );
1699            }
1700
1701            if(isset($result["budget_status_id"]) && $result["budget_status_id"] == 6) {
1702                    $data = [
1703                    "id"                     => $result["id"] ?? null, 
1704                    "client"                 => $result["client"] ?? null, 
1705                    "email"                  => $result["email"] ?? null, 
1706                    "phone_number"           => $result["phone_number"] ?? null, 
1707                    "last_follow_up_comment" => $result["last_follow_up_comment"] ?? null,
1708                    "quote_id"               => $result["quote_id"] ?? null,
1709                    "request_date"           => date("Y-m-d"),
1710                    "updated_by"             => "IA",
1711                    "user_id"                => $result["user_id"] ?? null,
1712                    "commercial"             => $result["commercial"] ?? null,
1713                    "budget_status_id"       => $result["budget_status_id"] ?? null,
1714                    "internal_quote_id"      => $result["internal_quote_id"] ?? null,
1715                ];
1716
1717                $ch = curl_init("https://2lsarnb35o6evhgwmfedrsxk3i0lqzzq.lambda-url.eu-west-2.on.aws/checkduplicate");
1718                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1719                curl_setopt($ch, CURLOPT_POST, true);
1720                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
1721                curl_setopt($ch, CURLOPT_HTTPHEADER, [
1722                    'Content-Type: application/json'
1723                ]);
1724
1725                $response = curl_exec($ch);
1726                $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1727                
1728                if (curl_errno($ch)) {
1729                    error_log('Error en cURL: ' . curl_error($ch));
1730                }
1731
1732                curl_close($ch);
1733            }
1734
1735            Cache::flush();
1736
1737            return response(['message' => 'OK', 'data' => $result, 'for_approval' => $forApproval]);
1738
1739        // } catch (\Exception $e) {
1740        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
1741        // }
1742
1743    }
1744
1745    private function compareArrays($data, $quotations) {
1746        $differences = [];
1747
1748        foreach ($data as $field => $valueData) {
1749            if (isset($quotations->$field)) {
1750                $valueQuotations = $quotations->$field;
1751
1752                $valueData = $this->convertValue($valueData);
1753                $valueQuotations = $this->convertValue($valueQuotations);
1754                if (
1755                    $valueData !== $valueQuotations &&
1756                    !is_null($valueData) &&
1757                    !is_null($valueQuotations)
1758                ) {
1759                    $differences[$field] = [
1760                        'newData' => $valueData,
1761                        'oldData' => $valueQuotations
1762                    ];
1763                }
1764            } /*else {
1765                $diferences[$field] = [
1766                    'data' => $valueData,
1767                    'quotations' => 'NO_EXISTE'
1768                ];
1769            }*/
1770        }
1771
1772        /*foreach (get_object_vars($quotations) as $field => $valueQuotations) {
1773            if (!array_key_exists($field, $data)) {
1774                $diferences[$field] = [
1775                    'data' => 'NO_EXISTE',
1776                    'quotations' => $valueQuotations
1777                ];
1778            }
1779        }*/
1780
1781        return $differences;
1782    }
1783
1784    private function convertValue($value) {
1785        if ($value === null) {
1786            return null;
1787        }
1788
1789        if (is_numeric($value)) {
1790            return (int)$value;
1791        }
1792
1793        if ($value === 'NULL' || $value === 'null') {
1794            return null;
1795        }
1796
1797        if (is_string($value)) {
1798            if (preg_match('/^(\d{4}-\d{2}-\d{2})( \d{2}:\d{2}:\d{2})?$/', $value, $matches)) {
1799                return $matches[1];
1800            }
1801        }
1802
1803        return $value;
1804    }
1805
1806    protected function callDeleteQuotation($id, $company_id, $userId, $user)
1807    {
1808        $request = new \Illuminate\Http\Request([
1809            'company_id' => $company_id,
1810            'user_id' => $userId,
1811            'updated_by' => $user,
1812            'ids' => [$id],
1813            'filterModel' => [],
1814            'sortModel' => [],
1815            'searchText' => '',
1816            'ids_not_in' => []
1817        ]);
1818
1819        return $this->delete_quotation($request, true);
1820    }
1821
1822    public function get_quotation($id){
1823
1824        try {
1825
1826            $id = addslashes($id);
1827
1828            $query = "SELECT
1829                        a.id,
1830                        a.quote_id,
1831                        a.company_id,
1832                        b.name company_name,
1833                        a.client,
1834                        c.name client_type,
1835                        c.customer_type_id,
1836                        s.name segment,
1837                        s.segment_id,
1838                        a.request_date,
1839                        a.visit_date,
1840                        a.issue_date,
1841                        a.acceptance_date,
1842                        a.internal_quote_id,
1843                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
1844                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
1845                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
1846                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
1847                        a.phone_number,
1848                        a.email,
1849                        a.duration,
1850                        a.order_number,
1851                        d.name 'type',
1852                        d.budget_type_id,
1853                        e.name 'status',
1854                        e.budget_status_id,
1855                        f.name source,
1856                        f.source_id,
1857                        a.amount,
1858                        g.name reason_for_not_following_up,
1859                        a.reason_for_not_following_up_id,
1860                        a.reason_for_rejection_id,
1861                        a.last_follow_up_date,
1862                        a.last_follow_up_comment,
1863                        CASE WHEN a.reason_for_rejection_id IS NULL THEN a.reason_for_rejection ELSE h.name END reason_for_rejection,
1864                        a.commercial,
1865                        a.created_by,
1866                        a.created_at,
1867                        a.updated_by,
1868                        a.updated_at,
1869                        a.for_approval,
1870                        a.box_work_g3w,
1871                        a.people_assigned_to_the_job,
1872                        a.duration_of_job_in_days,
1873                        a.estimated_cost_of_materials,
1874                        a.budget_margin_enabled,
1875                        a.question_enabled,
1876                        a.cost_of_labor,
1877                        a.total_cost_of_job,
1878                        CASE WHEN a.budget_margin_enabled > 0 THEN a.invoice_margin ELSE NULL END invoice_margin,
1879                        CASE WHEN a.budget_margin_enabled > 0 THEN a.margin_for_the_company ELSE NULL END margin_for_the_company,
1880                        a.margin_on_invoice_per_day_per_worker,
1881                        a.revenue_per_date_per_worked,
1882                        a.commission_cost,
1883                        a.commission_pct,
1884                        a.gross_margin,
1885                        a.labor_percentage,
1886                        a.question_ids,
1887                        a.question_ids_no,
1888                        a.approved_at,
1889                        a.approved_by,
1890                        a.rejected_at,
1891                        a.rejected_by,
1892                        a.approved_at_v2,
1893                        a.approved_by_v2,
1894                        a.rejected_at_v2,
1895                        a.rejected_by_v2,
1896                        a.accepted_at,
1897                        a.accepted_by,
1898                        a.is_validated,
1899                        a.resource_id,
1900                        a.sync_import,
1901                        a.sync_import_edited,
1902                        a.g3w_warning,
1903                        a.g3w_warning_fields,
1904                        a.id_solicitud_duplicity,
1905                        a.x_status
1906                    FROM
1907                        tbl_quotations a
1908                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
1909                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
1910                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
1911                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
1912                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
1913                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
1914                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
1915                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
1916                    WHERE a.id = {$id}
1917                    AND a.company_id IN ({$this->companyId})";
1918
1919            $result = DB::select($query);
1920
1921            Cache::flush();
1922            return response(['message' => 'OK', 'data' => $result]);
1923
1924        } catch (\Exception $e) {
1925            /** @disregard P1014 */
1926            $e->exceptionCode = 'GET_QUOTATION_EXCEPTION'; 
1927            report($e);
1928            return response(['message' => 'KO', 'error' => $e->getMessage()]);
1929        }
1930    }
1931
1932    public function get_quotation_log($id){
1933        return TblQuotationsLog::where("quotation_id", $id)->get();
1934    }
1935
1936    public function send_notification($toEmail = null, $userId, $quoteId, $id, $status, $sendUserId, $companyName, $action, $companyId, $g3wQuoteId){
1937
1938        $user = TblUsers::where('id', $userId)->first();
1939
1940        $imgpath = File::get('fireservicetitan.png');
1941
1942        $url = env('URL') . "orders/{$id}?company_id={$companyId}";
1943        $href = "<a href='{$url}'>{$quoteId}</a>";
1944
1945        $body = "";
1946        $subject = "";
1947
1948        if($g3wQuoteId){
1949            $quoteId = $quoteId . " - G3W #{$g3wQuoteId}";
1950        }
1951
1952        if($action == 1){
1953            $body = __('language.email_notification.body_created');
1954            $body = str_replace('{{creator}}', $user->name, $body);
1955            $subject = str_replace('{{quote_id}}', $quoteId, __('language.email_notification.subject_created'));
1956        }else{
1957            $body = __('language.email_notification.body_assigned');
1958            $body = str_replace('{{assignee}}', $user->name, $body);
1959            $subject = str_replace('{{quote_id}}', $quoteId, __('language.email_notification.subject_assigned'));
1960        }
1961
1962        $body = str_replace('{{quote_id}}', $href, $body);
1963        $body = str_replace('{{company}}', $companyName, $body);
1964        $body = str_replace('{{status}}', $status, $body);
1965
1966        $content = $body;
1967
1968        $body .= "<p>Fire Service Titan</p>";
1969        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
1970
1971        $html = '<!DOCTYPE html>';
1972        $html .= '<html>';
1973        $html .= '<head>';
1974        $html .= '<meta charset="UTF-8">';
1975        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
1976        $html .= '</head>';
1977        $html .= '<body>';
1978        $html .= $body;
1979        $html .= '</body>';
1980        $html .= '</html>';
1981
1982        if($toEmail != null){
1983            $email = new \SendGrid\Mail\Mail();
1984
1985            if(env('SENDGRID_STAGING')){
1986                $toEmail = $user->email;
1987            }
1988
1989            $email->setFrom('fire@fire.es', 'Fire Service Titan');
1990            $email->setSubject($subject);
1991            $email->addTo($toEmail);
1992            $email->addContent("text/html", $html);
1993
1994            $email->addAttachment(
1995                $imgpath,
1996                "image/png",
1997                "fireservicetitan.png",
1998                "inline",
1999                "fireservicetitan"
2000            );
2001
2002            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
2003
2004            $response = $sendgrid->send($email);
2005            if ($response->statusCode() == 202) {
2006                Log::channel('email_log')->info('ID:' . $quoteId . ' : ' . $status . ' : '. $toEmail .' - EMAIL NOTIFICATION SENT');
2007
2008                TblNotifications::create(
2009                    array(
2010                        'user_id' => $sendUserId,
2011                        'content' => $content,
2012                        'is_open' => 1,
2013                        'created_by' => 'System',
2014                        'link' => $url
2015                    )
2016                );
2017            } else {
2018                $error = true;
2019                Log::channel('email_log')->error('ID:' . $quoteId . ' : ' . $status . ' : '. $toEmail .' - ' . $response->body());
2020            }
2021        }
2022
2023    }
2024
2025    public function delete_quotation(Request $request, $isFromDeleteCall = false){
2026
2027        try {
2028
2029            $data = $request->all();
2030            $result = array();
2031
2032            $r = new Request([
2033                'filterModel' => $data['filterModel'],
2034                'sortModel' => $data['sortModel'],
2035                'start' => 0,
2036                'end' => 999999999,
2037                'company_id' => $data['company_id'],
2038                'user_id' => $data['user_id'],
2039                'ids' => $data['ids'],
2040                'searchText' => $data['searchText'],
2041                'ids_not_in' => $data['ids_not_in']
2042            ]);
2043
2044            $result = $this->list_quotations($r);
2045            $result = $result->original['data'];
2046
2047            $outputArray = array();
2048
2049            foreach ($result as $item) {
2050                if (isset($item->id)) {
2051                    $outputArray[] = $item->id;
2052                }
2053            }
2054
2055            $ids = implode(',', $outputArray);
2056
2057            if($outputArray){
2058
2059                TblQuotations::whereIn('id', $outputArray)->update(
2060                    array(
2061                        'updated_at' => date('Y-m-d H:i:s'),
2062                        'updated_by' => $data['updated_by'],
2063                        'for_add' => $isFromDeleteCall ? 2 : ($data['for_add'] ?? 0),
2064                        'reason_id' => (isset($data['reason_id']) ? $data['reason_id'] : null),
2065                        'reason_for_deletion' => (isset($data['reason_for_deletion']) ? $data['reason_for_deletion'] : null),
2066                    )
2067                );
2068
2069                $query = "INSERT INTO tbl_quotations_deleted
2070                        SELECT * FROM tbl_quotations WHERE id IN ({$ids})";
2071
2072                DB::select($query);
2073
2074                TblQuotations::whereIn('id', $outputArray)->delete();
2075                TblFiles::whereIn('quotation_id', $outputArray)->delete();
2076            }
2077
2078            Cache::flush();
2079            return response(['message' => 'OK', 'data' => $result]);
2080
2081        } catch (\Exception $e) {
2082            /** @disregard P1014 */
2083            $e->exceptionCode = 'DELETE_QUOTATION_EXCEPTION'; 
2084            report($e);
2085            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2086        }
2087
2088    }
2089
2090    public function list_quotations(Request $request){
2091
2092        // try {
2093
2094            $data = $request->all();
2095            $companyId = addslashes($data['company_id']);
2096            $userId = addslashes($data['user_id']);
2097            $filter = $data['filterModel'];
2098            $sort = $data['sortModel'];
2099            $result = array();
2100            $subquery = "";
2101            $where = "";
2102            $having = "";
2103            $orderBy = "";
2104            $start = addslashes($data['start']);
2105            $end = addslashes($data['end']);
2106            $totalRowCount = 0;
2107            $withFilters = "";
2108            $logFilter = @$data['log_filter'];
2109
2110            $filterType = array(
2111                'contains' => "LIKE '%[value]%'",
2112                'notContains' => "NOT LIKE '%[value]%'",
2113                'equals' => "= '[value]'",
2114                'notEqual' => "<> '[value]'",
2115                'startsWith' => "LIKE '[value]%'",
2116                'endsWith' => "LIKE '%[value]'",
2117                'blank' => "IS NULL",
2118                'notBlank' => "IS NOT NULL",
2119                'lessThan' => "< [value]",
2120                'lessThanOrEqual' => "<= [value]",
2121                'greaterThan' => "> [value]",
2122                'greaterThanOrEqual' => ">= [value]",
2123                'inRange' => "BETWEEN [value1] AND [value2]",
2124                "in" => "IN ([value])"
2125            );
2126            /*if(isset($data['internal_quote_id']) && count($data['internal_quote_id']) > 0){
2127                $internalIds = implode(",", $data['internal_quote_id']);
2128                $where = " AND a.internal_quote_id IN ({$internalIds}) ";
2129            }*/
2130
2131            if(isset($data['ids']) && count($data['ids']) > 0){
2132                $quoteIds = implode(",", $data['ids']);
2133                $where = " AND a.id IN ({$quoteIds}";
2134            }
2135
2136            if(isset($data['ids_not_in']) && count($data['ids_not_in']) > 0){
2137                $quoteIds = implode(",", $data['ids_not_in']);
2138                $where = " AND a.id NOT IN ({$quoteIds}";
2139            }
2140
2141            $lasLeftJoin = "";
2142            $whereBlocked = "";
2143
2144            if(isset($data['last_follow_up_date']) && !empty($data['last_follow_up_date'])){
2145                if($data['last_follow_up_date'] == 1){
2146
2147                    $lasLeftJoin = " LEFT JOIN (
2148                        SELECT
2149                          a.id,
2150                          SUBSTRING_INDEX(
2151                            SUBSTRING_INDEX(a.email, ',', n.digit + 1),
2152                            ',',
2153                            -1
2154                          ) AS email_domain
2155                        FROM
2156                          tbl_quotations a
2157                          INNER JOIN (
2158                            SELECT
2159                              0 AS digit
2160                            UNION ALL
2161                            SELECT
2162                              1
2163                            UNION ALL
2164                            SELECT
2165                              2
2166                            UNION ALL
2167                            SELECT
2168                              3
2169                            UNION ALL
2170                            SELECT
2171                              4
2172                            UNION ALL
2173                            SELECT
2174                              5
2175                            UNION ALL
2176                            SELECT
2177                              6
2178                            UNION ALL
2179                            SELECT
2180                              7
2181                            UNION ALL
2182                            SELECT
2183                              8
2184                            UNION ALL
2185                            SELECT
2186                              9
2187                          ) n ON LENGTH(
2188                            REPLACE(a.email, ',', '')
2189                          ) <= LENGTH(a.email)- n.digit
2190                          GROUP BY a.id
2191                      ) temp ON a.id = temp.id ";
2192
2193                    $whereBlocked = " AND a.last_follow_up_date < NOW()
2194                            AND a.budget_status_id IN (2)
2195                            AND a.email IS NOT NULL
2196                            AND a.email <> ''
2197                            AND NOT EXISTS (
2198                                SELECT
2199                                1
2200                                FROM
2201                                tbl_blocked_domains bd
2202                                WHERE
2203                                temp.email_domain LIKE CONCAT('%', bd.domain, '%')
2204                                AND bd.company_id = a.company_id
2205                            )
2206                            AND a.last_follow_up_date IS NOT NULL
2207                            AND a.reason_for_not_following_up_id IS NULL
2208                            AND a.last_follow_up_date > 0
2209                            AND a.total_sent < b.limit_reminder_emails
2210                            AND a.for_add = 0 ";
2211                }
2212            }
2213
2214            if(isset($data['visit_date']) && !empty($data['visit_date'])){
2215                if($data['visit_date'] == 1){
2216                    $where = " AND DATE_FORMAT(a.visit_date, '%Y-%m-%d') <= DATE_FORMAT(NOW(), '%Y-%m-%d') ";
2217                }
2218            }
2219
2220            if($companyId != 0){
2221                $where .= " AND a.company_id = {$companyId} ";
2222            }else{
2223                $where .= " AND a.company_id IN ({$this->companyId}";
2224            }
2225
2226            $matchScoreCol = "";
2227            $matchScoreOrderBy = "";
2228
2229            if(isset($data['searchText']) && $data['searchText'] != null){
2230
2231                $availableParameters = [
2232                    'a.quote_id',
2233                    'a.internal_quote_id',
2234                    'a.box_work_g3w',
2235                    's.name',
2236                    'b.name',
2237                    'a.client',
2238                    'c.name',
2239                    'a.phone_number',
2240                    'a.email',
2241                    'a.order_number',
2242                    'a.request_date',
2243                    'a.issue_date',
2244                    'a.acceptance_date',
2245                    'a.created_at',
2246                    'a.updated_at',
2247                    'a.rejected_at',
2248                    'a.accepted_at',
2249                    'd.name',
2250                    'e.name',
2251                    'f.name',
2252                    'a.amount',
2253                    'g.name',
2254                    'a.last_follow_up_comment',
2255                    'a.x_status',
2256                    'h.name',
2257                    'a.commercial',
2258                    'a.user_commercial_by_g3w',
2259                    'a.user_create_by_g3w',
2260                    'a.created_by',
2261                    'a.updated_by',
2262                    'a.approved_by',
2263                    'a.rejected_by',
2264                    'a.accepted_by',
2265                    'a.sync_import',
2266                    'a.sync_import_edited',
2267                    'a.g3w_warning'
2268                ];
2269
2270                $searchText = addslashes($data['searchText']);
2271                $searchTextArray = explode(" ", $searchText);
2272
2273                $searchArray = array();
2274                $splitSearchArray = array();
2275                $matchScoreArray = array();
2276                $sc = 1;
2277                foreach ($availableParameters as $field) {
2278                    if($field == 'a.client' || $field == 'a.amount' || $field == 'a.created_at'){
2279                        $sc = 3;
2280                    }elseif($field == 'a.acceptance_date'){
2281                        $sc = 2;
2282                    }else{
2283                        $sc = 1;
2284                    }
2285
2286                    $l = "{$field} LIKE '%{$searchText}%'";
2287                    if($field == "a.last_follow_up_comment"){
2288                        $l = "{$field} = '{$searchText}'";
2289                    }else{
2290
2291                        $d = "IFNULL((LENGTH(LOWER({$field})) - LENGTH(REPLACE(LOWER({$field}), LOWER('{$searchText}'), ''))) / LENGTH(LOWER('{$searchText}')), 0) * {$sc}";
2292
2293                        if(count($searchTextArray) > 1){
2294                            foreach ($searchTextArray as $word) {
2295                                if(!is_numeric($word)){
2296                                    $d .= " + IFNULL((LENGTH(LOWER({$field})) - LENGTH(REPLACE(LOWER({$field}), LOWER('{$word}'), ''))) / LENGTH(LOWER('{$word}')), 0) * {$sc}";
2297                                }
2298                            }
2299                        }
2300
2301                        array_push($matchScoreArray, $d);
2302                    }
2303
2304                    if(is_numeric($searchText)){
2305                        array_push($searchArray, "({$l} OR {$field} = CAST('{$searchText}' AS UNSIGNED))");
2306                    }else{
2307                        array_push($searchArray, "({$l} OR DATE_FORMAT({$field}, '%d/%m/%Y') = DATE_FORMAT(STR_TO_DATE('{$searchText}', '%d/%m/%Y'), '%d/%m/%Y'))");
2308                    }
2309
2310                    if(count($searchTextArray) > 1){
2311                        foreach ($searchTextArray as $word) {
2312
2313                            $l = "{$field} LIKE '%{$word}%'";
2314                            if($field == "a.last_follow_up_comment"){
2315                                $l = "{$field} = '{$word}'";
2316                            }
2317
2318                            if(is_numeric($word)){
2319                                array_push($splitSearchArray, "{$l} OR {$field} = CAST('{$word}' AS UNSIGNED)");
2320                            }else{
2321                                array_push($splitSearchArray, "{$l} OR DATE_FORMAT({$field}, '%d/%m/%Y') = DATE_FORMAT(STR_TO_DATE('{$word}', '%d/%m/%Y'), '%d/%m/%Y')");
2322                            }
2323                        }
2324                    }
2325
2326                    $sc = 1;
2327                }
2328
2329                if(count($splitSearchArray) > 0){
2330                    $splitSearchArray = implode(" OR ", $splitSearchArray);
2331                    $splitSearchArray = " OR ({$splitSearchArray}";
2332                }else{
2333                    $splitSearchArray = "";
2334                }
2335
2336                $searchArray = implode(" OR ", $searchArray);
2337                $matchScoreArray = implode(",", $matchScoreArray);
2338                $matchScoreCol = ", GREATEST({$matchScoreArray}) match_score";
2339                $matchScoreOrderBy = "match_score DESC,";
2340                $where .= " AND ({$searchArray} {$splitSearchArray})";
2341            }
2342
2343            if(count($sort) > 0){
2344                $field = $sort[0]['colId'];
2345                $sortBy = $sort[0]['sort'];
2346
2347                if(strpos($field, "translate") !== false){
2348                    $field = str_replace("_translate", "", $field);
2349                }else{
2350                    if($field == "client_type"){
2351                        $field = "c.name";
2352                    }elseif($field == "segment"){
2353                        $field = "s.name";
2354                    }elseif($field == "type"){
2355                        $field = "d.name";
2356                    }elseif($field == "status"){
2357                        $field = "e.name";
2358                    }elseif($field == "source"){
2359                        $field = "g.name";
2360                    }elseif($field == "reason_for_not_following_up"){
2361                        $field = "g.name";
2362                    }elseif($field == "reason_for_rejection"){
2363                        $field = "h.name";
2364                    }elseif($field == "amount"){
2365                        $field = "CAST(a.amount AS DOUBLE)";
2366                    }elseif($field == "duration"){
2367                        $field = "CAST(a.duration AS DOUBLE)";
2368                    }elseif($field == "quote_id" || $field == "internal_quote_id"){
2369                        $field = "CAST(a.{$field} AS DOUBLE)";
2370                    }elseif($field == "company_name"){
2371                        $field = "b.name";
2372                    }
2373
2374                }
2375
2376                if($matchScoreOrderBy){
2377                    $matchScoreOrderBy = ", match_score DESC";
2378                }
2379
2380                $orderBy = " ORDER BY {$field} {$sortBy} {$matchScoreOrderBy}";
2381            }else{
2382                $orderBy = " ORDER BY {$matchScoreOrderBy} a.id DESC";
2383            }
2384
2385            foreach ($filter as $key => $data) {      
2386                if(strpos($key, "translate") !== false){
2387
2388                    $field = str_replace("_translate", "", $key);
2389                    if($field == "created_at"){
2390                        $field = "a.created_at";
2391                    }elseif($field == "last_follow_up_date"){
2392                        $field = "a.last_follow_up_date";
2393                    }elseif($field == "issue_date"){
2394                        $field = "a.issue_date";
2395                    }elseif($field == "request_date"){
2396                        $field = "a.request_date";
2397                    }elseif($field == "acceptance_date"){
2398                        $field = "a.acceptance_date";
2399                    }elseif($field == "internal_quote_id"){
2400                        $field = "a.internal_quote_id";
2401                    }
2402
2403                    $whereDates = "";
2404                    $z = 0;
2405
2406                    if(isset($data['filters']) && !empty($data['filters'])){
2407                        foreach ($data['filters'] as $yearKey => $yearData) {
2408                            $yearsMonths = array();
2409                            $yearsWeeks = array();
2410
2411                            if($z > 0){
2412                                $whereDates .= " OR (YEAR($field) = {$yearKey} ";
2413                            }else{
2414                                $whereDates .= " (YEAR($field) = {$yearKey} ";
2415                            }
2416
2417                            for ($i = 0; $i < count($yearData['months']); $i++) {
2418                                if($yearData['months'][$i]['isChecked']){
2419                                    array_push($yearsMonths, $yearData['months'][$i]['value']);
2420                                }
2421                            }
2422
2423                            $yearsMonths = implode("','", $yearsMonths);
2424                            $whereDates .= " AND (MONTH({$field}) IN ('{$yearsMonths}')";
2425
2426                            for ($i = 0; $i < count($yearData['weeks']); $i++) {
2427                                if($yearData['weeks'][$i]['isChecked']){
2428                                    array_push($yearsWeeks, $yearData['weeks'][$i]['value']);
2429                                }
2430                            }
2431
2432                            $yearsWeeks = implode("','", $yearsWeeks);
2433                            if($yearsWeeks != ''){
2434                                $whereDates .= " OR WEEK({$field}) IN ('{$yearsWeeks}') ";
2435                            }
2436
2437                            $whereDates .= ")) ";
2438                            $z++;
2439                        }
2440                    }
2441
2442                    $whereDataUptoToday = "";
2443                    if(isset($data['isDataUptoToday'])){
2444                        if($data['isDataUptoToday']){
2445                            $whereDates = "";
2446                            $whereDataUptoToday .= " AND {$field} < NOW() AND {$field} > 0 ";
2447                        }
2448                    }
2449
2450                    $whereBlanks = "";
2451                    if(isset($data['isBlanks'])){
2452                        if($data['isBlanks']){
2453                            $conj = "OR";
2454                            if($whereDates == ""){
2455                                $conj = "";
2456                            }
2457                            $whereBlanks .= " {$conj} {$field} IS NULL ";
2458                        }else{
2459                            $conj = "AND";
2460                            if($whereDates == ""){
2461                                $conj = "";
2462                            }
2463                            $whereBlanks .= " {$conj} {$field} IS NOT NULL ";
2464                        }
2465                    }
2466
2467                    $where .= " AND ({$whereDates} {$whereBlanks} {$whereDataUptoToday}";
2468                }else{
2469                    if($data['filterType'] == 'number'){
2470                        if(array_key_exists('operator', $data)){
2471                            if($data['condition1']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
2472                                $data['condition1']['filter'] = addslashes($data['condition1']['filter']);
2473                                $data['condition2']['filter'] = addslashes($data['condition2']['filter']);
2474
2475                                if($data['condition1']['type'] == 'inRange'){
2476                                    $data['condition1']['filterTo'] = addslashes($data['condition1']['filterTo']);
2477                                    $inRange = str_replace("[value1]", $data['condition1']['filter'], $filterType['inRange']);
2478                                    $val1 = str_replace("[value2]", $data['condition1']['filterTo'], $inRange);
2479                                }else{
2480                                    $val1 = str_replace("[value]", $data['condition1']['filter'], $filterType[$data['condition1']['type']]);
2481                                }
2482
2483                                if($data['condition2']['type'] == 'inRange'){
2484                                    $data['condition2']['filterTo'] = addslashes($data['condition2']['filterTo']);
2485                                    $inRange = str_replace("[value1]", $data['condition2']['filter'], $filterType['inRange']);
2486                                    $val2 = str_replace("[value2]", $data['condition2']['filterTo'], $inRange);
2487                                }else{
2488                                    $val2 = str_replace("[value]", $data['condition2']['filter'], $filterType[$data['condition2']['type']]);
2489                                }
2490
2491                            }else{
2492                                $val1 = $filterType[$data['condition1']['type']];
2493                                $val2 = $filterType[$data['condition2']['type']];
2494                            }
2495
2496                            $where .= " AND a.{$key} {$val1} {$data['operator']} a.{$key} {$val2} ";
2497                        }else{
2498                            if($data['type'] != 'blank' && $data['type'] != 'notBlank'){
2499                                $data['filter'] = addslashes($data['filter']);
2500
2501                                if($data['type'] == 'inRange'){
2502                                    $data['filterTo'] = addslashes($data['filterTo']);
2503                                    $inRange = str_replace("[value1]", $data['filter'], $filterType['inRange']);
2504                                    $val = str_replace("[value2]", $data['filterTo'], $inRange);
2505                                }else{
2506                                    $val = str_replace("[value]", $data['filter'], $filterType[$data['type']]);
2507                                }
2508                            }else{
2509                                $val = $filterType[$data['type']];
2510                            }
2511
2512                            $where .= " AND a.{$key} {$val} ";
2513                        }
2514                    }
2515
2516                    if($data['filterType'] == 'text'){
2517                        if($key == "id"){
2518                            continue;
2519                        }
2520                        
2521                        if(array_key_exists('operator', $data)){
2522                            if($data['condition1']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
2523                                $data['condition1']['filter'] = addslashes($data['condition1']['filter']);
2524                                $val1 = str_replace("[value]", $data['condition1']['filter'], $filterType[$data['condition1']['type']]);
2525                            }
2526
2527                            if($data['condition2']['type'] != 'blank' && $data['condition2']['type'] != 'notBlank'){
2528                                $data['condition2']['filter'] = addslashes($data['condition2']['filter']);
2529                                $val2 = str_replace("[value]", $data['condition2']['filter'], $filterType[$data['condition2']['type']]);
2530                            }
2531
2532                            $where .= " AND {$key} {$val1} {$data['operator']} {$key} {$val2} ";
2533                        }else{
2534
2535                            $type = $data['type'];
2536                            $filter = $data['filter'];
2537
2538                            if (($type === 'in' || $type === 'contains') && strpos($filter, ',') !== false) {
2539                                $values = explode(',', $filter);
2540                                $escaped = array_map('addslashes', $values);
2541                                $val = "IN ('" . implode("','", $escaped) . "')";
2542                            }
2543
2544                            elseif ($type !== 'blank' && $type !== 'notBlank') {
2545                                $data['filter'] = addslashes($data['filter']);
2546                                $val = str_replace("[value]", $data['filter'], $filterType[$type]);
2547                            }
2548
2549                            else {
2550                                $val = $filterType[$type];
2551                            }
2552
2553                            $where .= " AND {$key} {$val} ";
2554
2555                        }
2556                    }
2557
2558                    if($data['filterType'] == 'set'){
2559                        $statusName = $key;
2560
2561                        if($key == "client_type"){
2562                            $statusName = "c.name";
2563                        }elseif($key == "segment"){
2564                            $statusName = "s.name";
2565                        }elseif($key == "type"){
2566                            $statusName = "d.name";
2567                        }elseif($key == "status"){
2568                            $statusName = "e.name";
2569                        }elseif($key == "source"){
2570                            $statusName = "f.name";
2571                        }elseif($key == "reason_for_not_following_up"){
2572                            $statusName = "g.name";
2573                        }elseif($key == "reason_for_rejection"){
2574                            $statusName = "h.name";
2575                        }elseif($key == "created_by"){
2576                            $statusName = "a.created_by";
2577                        }elseif($key == "has_attachment"){
2578                            $statusName = "a.has_attachment";
2579                            if($data['values']){
2580                                foreach ($data['values'] as $k => $v) {
2581                                    if($v == "No"){
2582                                        $data['values'][$k] = 0;
2583                                    }else{
2584                                        $data['values'][$k] = 1;
2585                                    }
2586                                }
2587                            }
2588                        }elseif($key == "for_approval"){
2589                            $statusName = "a.for_approval";
2590                            if($data['values']){
2591                                foreach ($data['values'] as $k => $v) {
2592                                    if($v == "No"){
2593                                        $data['values'][$k] = 0;
2594                                    }else{
2595                                        $data['values'][$k] = 1;
2596                                    }
2597                                }
2598                            }
2599                        }elseif($key == "sync_import"){
2600                            $statusName = "a.sync_import";
2601                            if($data['values']){
2602                                foreach ($data['values'] as $k => $v) {
2603                                    if($v == "Manual"){
2604                                        $data['values'][$k] = 0;
2605                                    }else{
2606                                        $data['values'][$k] = 1;
2607                                    }
2608                                }
2609                            }
2610                        }elseif($key == "g3w_warning"){
2611                            $statusName = "a.g3w_warning";
2612                            if($data['values']){
2613                                foreach ($data['values'] as $k => $v) {
2614                                    if($v == "No"){
2615                                        $data['values'][$k] = 0;
2616                                    }else{
2617                                        $data['values'][$k] = 1;
2618                                    }
2619                                }
2620                            }
2621                        }elseif($key == "company_name"){
2622                            $statusName = "b.name";
2623                        }
2624
2625                        $val = implode("','", $data['values']);
2626
2627                        if(in_array(null, $data['values'], true)){
2628                            $where .= " AND ({$statusName} IN ('{$val}') OR {$statusName} IS NULL) ";
2629                        }else{
2630                            $where .= " AND {$statusName} IN ('{$val}') ";
2631                        }
2632                    }
2633                }
2634            }
2635
2636            $whereSendToClient = $where;
2637            $where;
2638
2639            $offset = $start;
2640            $limit = $end - $start;
2641
2642            $subquery = ",(SELECT can_write FROM tbl_company_users WHERE company_id = a.company_id AND user_id = {$userId}) can_write";
2643
2644            // Quotations accepted without acceptance_date
2645            // Quotations with state "No encontrado" or "Estado no reconocido en FST"
2646            // Quotations with not comercial in out database
2647            // Phone number on null
2648            // Source on null
2649            // Client name on null
2650            // Budget Type on null
2651            if (isset($request['g3w_warning'])) {
2652                $g3w_warning = $request['g3w_warning'] == "No" ? 0 : 1;
2653                /*$where .= "
2654                AND a.sync_import = 1
2655                    AND (
2656                        a.budget_status_id IN (13, 14)
2657                        OR (
2658                            a.commercial IS NULL
2659                            OR NOT EXISTS (
2660                                SELECT 1 FROM tbl_users u WHERE u.name = a.commercial
2661                            )
2662                            OR a.phone_number IS NULL
2663                            OR a.source_id IS NULL
2664                            OR a.budget_type_id IS NULL
2665                            OR (a.client IS NULL OR TRIM(a.client) = '')
2666                            OR (a.email IS NULL OR TRIM(a.email) = '')
2667                        )
2668                    )
2669                 ";*/
2670                $where .= "
2671                AND (a.sync_import = 1 OR a.sync_import_edited = 1)
2672                AND a.g3w_warning = " . $g3w_warning;
2673            }
2674
2675
2676            $query = "SELECT
2677                        a.id,
2678                        a.quote_id,
2679                        a.internal_quote_id,
2680                        a.company_id,
2681                        b.name company_name,
2682                        a.client,
2683                        c.name client_type,
2684                        c.customer_type_id,
2685                        s.name segment,
2686                        s.segment_id,
2687                        a.request_date,
2688                        a.visit_date,
2689                        a.issue_date,
2690                        a.acceptance_date,
2691                        a.internal_quote_id,
2692                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
2693                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
2694                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
2695                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
2696                        DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate,
2697                        DATE_FORMAT(a.accepted_at, '%d/%m/%Y') accepted_at_translate,
2698                        a.phone_number,
2699                        a.email,
2700                        a.duration,
2701                        a.order_number,
2702                        d.name 'type',
2703                        d.budget_type_id,
2704                        e.name 'status',
2705                        e.budget_status_id,
2706                        f.name as source,
2707                        f.source_id,
2708                        a.amount,
2709                        g.name reason_for_not_following_up,
2710                        a.reason_for_not_following_up_id,
2711                        a.reason_for_rejection_id,
2712                        a.last_follow_up_date,
2713                        a.last_follow_up_comment,
2714                        CASE WHEN a.reason_for_rejection_id IS NULL THEN a.reason_for_rejection ELSE h.name END reason_for_rejection,
2715                        a.commercial,
2716                        a.user_commercial_by_g3w,
2717                        a.user_create_by_g3w,
2718                        a.created_by,
2719                        a.created_at,
2720                        a.updated_by,
2721                        a.updated_at,
2722                        a.total_sent,
2723                        a.has_attachment,
2724                        a.for_approval,
2725                        a.box_work_g3w,
2726                        a.people_assigned_to_the_job,
2727                        a.duration_of_job_in_days,
2728                        a.estimated_cost_of_materials,
2729                        a.budget_margin_enabled,
2730                        a.question_enabled,
2731                        a.cost_of_labor,
2732                        a.total_cost_of_job,
2733                        CASE WHEN a.budget_margin_enabled > 0 THEN a.invoice_margin ELSE NULL END invoice_margin,
2734                        CASE WHEN a.budget_margin_enabled > 0 THEN a.margin_for_the_company ELSE NULL END margin_for_the_company,
2735                        a.margin_on_invoice_per_day_per_worker,
2736                        a.revenue_per_date_per_worked,
2737                        a.commission_cost,
2738                        a.commission_pct,
2739                        a.gross_margin,
2740                        a.labor_percentage,
2741                        a.question_ids,
2742                        a.question_ids_no,
2743                        a.approved_at,
2744                        a.approved_by,
2745                        a.rejected_at,
2746                        a.rejected_by,
2747                        a.approved_at_v2,
2748                        a.approved_by_v2,
2749                        a.rejected_at_v2,
2750                        a.rejected_by_v2,
2751                        a.accepted_at,
2752                        a.accepted_by,
2753                        a.is_validated,
2754                        a.resource_id,
2755                        a.x_status,
2756                        a.likehood,
2757                        a.sync_import,
2758                        a.sync_import_edited,
2759                        a.g3w_warning,
2760                        a.g3w_warning_fields,
2761                        a.id_solicitud_duplicity,
2762                        SUBSTRING_INDEX(a.email, '@', -1) domain
2763                        {$matchScoreCol}
2764                        {$subquery}
2765                    FROM
2766                        tbl_quotations a
2767                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2768                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2769                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2770                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2771                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2772                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2773                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2774                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2775                        {$lasLeftJoin}
2776                    WHERE a.for_add = 0 {$where} {$whereBlocked}
2777                    GROUP BY a.id
2778                    {$orderBy}
2779                    LIMIT {$offset}{$limit}
2780                    ";
2781
2782            $value = Cache::get(base64_encode($query));
2783
2784            if(!$value){
2785                $result = DB::select($query);
2786
2787                Cache::put(base64_encode($query), $result, 600);
2788            }else{
2789                $result = $value;
2790            }
2791
2792            $totalQuery = "SELECT
2793                            COUNT(a.id) totalRowCount,
2794                            SUM(CAST(a.amount AS DECIMAL(10,2))) totalAmount
2795                        FROM
2796                            tbl_quotations a
2797                            LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2798                            LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2799                            LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2800                            LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2801                            LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2802                            LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2803                            LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2804                            LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2805                            {$lasLeftJoin}
2806                        WHERE a.for_add = 0
2807                        {$where} {$whereBlocked}";
2808
2809            $value = Cache::get(base64_encode($totalQuery));
2810
2811            if(!$value){
2812                $countQuery = DB::select($totalQuery);
2813
2814                Cache::put(base64_encode($totalQuery), $countQuery, 600);
2815            }else{
2816                $countQuery = $value;
2817            }
2818
2819            $totalToFollowUpQuery = "SELECT
2820                                        COUNT(DISTINCT a.id) totalRowCount
2821                                    FROM
2822                                        tbl_quotations a
2823                                    LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2824                                    LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2825                                    LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2826                                    LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2827                                    LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2828                                    LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2829                                    LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2830                                    LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2831                                    LEFT JOIN (
2832                                        SELECT
2833                                        a.id,
2834                                        SUBSTRING_INDEX(
2835                                            SUBSTRING_INDEX(a.email, ',', n.digit + 1),
2836                                            ',',
2837                                            -1
2838                                        ) AS email_domain
2839                                        FROM
2840                                        tbl_quotations a
2841                                        INNER JOIN (
2842                                            SELECT
2843                                            0 AS digit
2844                                            UNION ALL
2845                                            SELECT
2846                                            1
2847                                            UNION ALL
2848                                            SELECT
2849                                            2
2850                                            UNION ALL
2851                                            SELECT
2852                                            3
2853                                            UNION ALL
2854                                            SELECT
2855                                            4
2856                                            UNION ALL
2857                                            SELECT
2858                                            5
2859                                            UNION ALL
2860                                            SELECT
2861                                            6
2862                                            UNION ALL
2863                                            SELECT
2864                                            7
2865                                            UNION ALL
2866                                            SELECT
2867                                            8
2868                                            UNION ALL
2869                                            SELECT
2870                                            9
2871                                        ) n ON LENGTH(
2872                                            REPLACE(a.email, ',', '')
2873                                        ) <= LENGTH(a.email)- n.digit
2874                                        GROUP BY a.id
2875                                    ) temp ON a.id = temp.id
2876                                    WHERE
2877                                    a.last_follow_up_date < NOW()
2878                                    AND a.budget_status_id IN (2)
2879                                    AND a.email IS NOT NULL
2880                                    AND a.email <> ''
2881                                    AND NOT EXISTS (
2882                                        SELECT
2883                                        1
2884                                        FROM
2885                                        tbl_blocked_domains bd
2886                                        WHERE
2887                                        temp.email_domain LIKE CONCAT('%', bd.domain, '%')
2888                                        AND bd.company_id = a.company_id
2889                                    )
2890                                    AND a.last_follow_up_date IS NOT NULL
2891                                    AND a.reason_for_not_following_up_id IS NULL
2892                                    AND a.last_follow_up_date > 0
2893                                    AND a.total_sent < b.limit_reminder_emails
2894                                    AND a.for_add = 0
2895                                    {$where}";
2896
2897            $value = Cache::get(base64_encode($totalToFollowUpQuery));
2898
2899            if(!$value){
2900                $countToFollowUpQuery = DB::select($totalToFollowUpQuery);
2901
2902                Cache::put(base64_encode($totalToFollowUpQuery), $countToFollowUpQuery, 600);
2903            }else{
2904                $countToFollowUpQuery = $value;
2905            }
2906
2907            $query = "SELECT
2908                            COUNT(1) as count,
2909                            SUM(a.amount) as total_amount
2910                        FROM tbl_quotations a
2911                        LEFT JOIN tbl_companies b ON a.company_id = b.company_id
2912                        LEFT JOIN tbl_customer_types c ON a.customer_type_id = c.customer_type_id
2913                        LEFT JOIN tbl_segments s ON a.segment_id = s.segment_id
2914                        LEFT JOIN tbl_budget_types d ON a.budget_type_id = d.budget_type_id
2915                        LEFT JOIN tbl_budget_status e ON a.budget_status_id = e.budget_status_id
2916                        LEFT JOIN tbl_sources f ON a.source_id = f.source_id
2917                        LEFT JOIN tbl_reason_for_not_following_up g ON a.reason_for_not_following_up_id = g.reason_for_not_following_up_id
2918                        LEFT JOIN tbl_reason_for_rejection h ON a.reason_for_rejection_id = h.reason_for_rejection_id
2919                        WHERE a.budget_status_id = 11
2920                        AND a.email IS NOT NULL
2921                        {$whereSendToClient}
2922                        ";
2923
2924
2925
2926            $value = Cache::get(base64_encode($query));
2927
2928            if(!$value){
2929                $totalSendToClient = DB::select($query);
2930
2931                Cache::put(base64_encode($query), $totalSendToClient, 600);
2932            }else{
2933                $totalSendToClient = $value;
2934            }
2935
2936            return response([
2937                'message' => 'OK',
2938                'data' => $result,
2939                'totalAmount' => $countQuery[0]->totalAmount,
2940                'totalRowCount' => $countQuery[0]->totalRowCount,
2941                'totalToFollowUpRowCount' => $countToFollowUpQuery[0]->totalRowCount,
2942                'totalSendToClient' => $totalSendToClient[0]->count,
2943                'totalSendToClientAmount' => $totalSendToClient[0]->total_amount
2944            ]);
2945
2946        // } catch (\Exception $e) {
2947        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
2948        // }
2949
2950    }
2951
2952    public function get_dates(Request $request){
2953
2954        try {
2955
2956            $data = $request->all();
2957            $companyId = addslashes($data['company_id']);
2958
2959            $where = "";
2960            if($companyId != 0){
2961                $where = " AND a.company_id = {$companyId} ";
2962            }else{
2963                $where = " AND a.company_id IN ({$this->companyId})";
2964            }
2965
2966            $query = "SELECT
2967                        DATE_FORMAT(a.request_date, '%d/%m/%Y') request_date_translate,
2968                        DATE_FORMAT(a.issue_date, '%d/%m/%Y') issue_date_translate,
2969                        DATE_FORMAT(a.acceptance_date, '%d/%m/%Y') acceptance_date_translate,
2970                        DATE_FORMAT(a.last_follow_up_date, '%d/%m/%Y') last_follow_up_date_translate,
2971                        DATE_FORMAT(a.created_at, '%d/%m/%Y') created_at_translate,
2972                        DATE_FORMAT(a.accepted_at, '%d/%m/%Y') accepted_at_translate
2973                    FROM tbl_quotations a
2974                    WHERE a.for_add = 0 {$where}";
2975
2976            $result = DB::select($query);
2977
2978            return response([
2979                'message' => 'OK',
2980                'data' => $result
2981            ]);
2982
2983        } catch (\Exception $e) {
2984            /** @disregard P1014 */
2985            $e->exceptionCode = 'GET_DATES_EXCEPTION'; 
2986            report($e);
2987            return response(['message' => 'KO', 'error' => $e->getMessage()]);
2988        }
2989
2990    }
2991
2992    public function list_quotation_analytics_by_source(Request $request){
2993
2994        try {
2995
2996            $data = $request->all();
2997            $companyId = addslashes($data['company_id']);
2998
2999            $where = "";
3000            $whereYear = "";
3001
3002            $dateLflArray = array();
3003            $companyIds = $this->companyIds;
3004
3005            if($companyId != 0){
3006                $companyIds = array($companyId);
3007            }
3008
3009            $field = "issue_date";
3010
3011            if(isset($data['years']) && $data['years'] != null){
3012                $years = implode(',', $data['years']);
3013                if(count($data['years']) > 0){
3014                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3015                }
3016            }
3017
3018            foreach ($companyIds as $v) {
3019
3020                $lflWhere = " AND q.company_id = {$v} ";
3021
3022                $query = "SELECT
3023                            CONCAT(
3024                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
3025                                ' - ',
3026                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
3027                            ) AS date_like,
3028                            YEAR(q.{$field}) 'year',
3029                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
3030                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
3031                            {$v} 'company_id'
3032                        FROM
3033                            tbl_quotations q
3034                        WHERE
3035                            q.{$field} IS NOT NULL
3036                            AND q.for_add != 1
3037                            {$lflWhere}
3038                            {$whereYear}
3039                        GROUP BY YEAR(q.{$field})
3040                        ORDER BY YEAR(q.{$field}) DESC";
3041
3042                $dateLike = DB::select($query);
3043
3044                $dateLflArray[$v] = $dateLike;
3045            }
3046
3047            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
3048
3049            $isFy = true;
3050
3051            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
3052                $isFy = false;
3053                $ytdArray = array();
3054                $ytdAcceptanceArray = array();
3055                $lflCompanyIds = array();
3056                $lflCompanyIdsAcc = array();
3057                foreach ($dateLflArray as $k => $v) {
3058                    foreach ($dateLflArray[$k] as $item) {
3059                        $year = $item->year;
3060                        $now = date('m-d');
3061                        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)");
3062                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
3063                    }
3064
3065                    $ytdArray = implode(' OR ', $ytdArray);
3066                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
3067                    $ytdArray = array();
3068
3069                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3070                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3071                    $ytdAcceptanceArray = array();
3072                }
3073
3074                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3075                $where .= " AND ({$lflCompanyIds}";
3076
3077                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3078                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3079            }
3080
3081            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
3082                $isFy = false;
3083                $lflArray = array();
3084                $ytdAcceptanceArray = array();
3085                $lflCompanyIds = array();
3086                $lflCompanyIdsAcc = array();
3087                foreach ($dateLflArray as $k => $v) {
3088                    foreach ($dateLflArray[$k] as $item) {
3089                        $year = $item->year;
3090                        $min_date_like = $item->min_date_like;
3091                        $max_date_like = $item->max_date_like;
3092                        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)");
3093                        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}')");
3094                    }
3095
3096                    $lflArray = implode(' OR ', $lflArray);
3097                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
3098                    $lflArray = array();
3099
3100                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3101                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3102                    $ytdAcceptanceArray = array();
3103                }
3104
3105                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3106                $where .= " AND ({$lflCompanyIds}";
3107
3108                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3109                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3110            }
3111
3112            if($isFy){
3113                if($companyId != 0){
3114                    $where .= " AND q.company_id = {$companyId} ";
3115                }else{
3116                    $where .= " AND q.company_id IN ({$this->companyId})";
3117                }
3118            }
3119
3120            if(isset($data['source']) && $data['source'] != null){
3121                $where .= " AND s.name = '{$data['source']}'";
3122            }
3123
3124            if(isset($data['month']) && $data['month'] != null){
3125                $where .= " AND MONTH(q.issue_date) = '{$data['month']}'";
3126            }
3127
3128            if(isset($data['week']) && $data['week'] != null){
3129                $where .= " AND WEEK(q.issue_date) = '{$data['week']}'";
3130            }
3131
3132            if(isset($data['commercial']) && $data['commercial'] != null){
3133                $where .= " AND q.commercial = '{$data['commercial']}'";
3134            }
3135
3136            if(isset($data['created_by']) && $data['created_by'] != null){
3137                $where .= " AND q.created_by = '{$data['created_by']}'";
3138            }
3139
3140            if(isset($data['budget_type']) && $data['budget_type'] != null){
3141                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
3142            }
3143
3144            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3145                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3146            }
3147
3148            if(isset($data['budget_status']) && $data['budget_status'] != null){
3149                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3150            }
3151
3152            if(isset($data['client_type']) && $data['client_type'] != null){
3153                $where .= " AND ct.customer_type_id = {$data['client_type']}";
3154            }
3155
3156            if(isset($data['segment_id']) && $data['segment_id'] != null){
3157                $where .= " AND q.segment_id = {$data['segment_id']}";
3158            }
3159
3160            $query = "SELECT
3161                        YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) AS 'year',
3162                        LPAD(MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'month',
3163                        LPAD(WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'week',
3164                        DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') issue_date,
3165                        COUNT(
3166                            CASE WHEN q.issue_date IS NOT NULL
3167                            THEN 1 END
3168                        ) AS totalIssue,
3169                        GROUP_CONCAT(
3170                            CASE WHEN q.issue_date IS NOT NULL
3171                            THEN q.id END
3172                        ) AS groupConcatIds,
3173                        SUM(
3174                            CASE WHEN q.issue_date IS NOT NULL THEN q.amount END
3175                        ) AS revenueIssue,
3176                        COUNT(
3177                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN 1 END
3178                        ) AS totalAcceptance,
3179                        SUM(
3180                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN q.amount END
3181                        ) AS revenueAcceptance,
3182                        SUM(
3183                            CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN q.amount END
3184                        ) / SUM(
3185                            CASE WHEN q.issue_date IS NOT NULL THEN q.amount END
3186                        ) * 100 AS revenueAcceptanceIssuedPercentage,
3187                        COUNT(
3188                            CASE WHEN bs.name = 'Rechazado' THEN 1 END
3189                        ) AS totalRejected,
3190                        SUM(
3191                            CASE WHEN bs.name = 'Rechazado' THEN q.amount END
3192                        ) AS revenueRejected,
3193                        COUNT(
3194                            CASE WHEN bs.name = 'Rechazado - automaticamente' THEN 1 END
3195                        ) AS totalRejectedAutomatic,
3196                        SUM(
3197                            CASE WHEN bs.name = 'Rechazado - automaticamente' THEN q.amount END
3198                        ) AS revenueRejectedAutomatic
3199                    FROM
3200                        tbl_quotations q
3201                        LEFT JOIN tbl_sources s ON s.source_id = q.source_id
3202                        LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3203                        LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3204                        LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
3205                    WHERE
3206                        q.issue_date IS NOT NULL
3207                        AND q.budget_type_id != 7
3208                        AND q.budget_type_id IS NOT NULL
3209                        AND q.for_add != 1
3210                        AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3211                        {$where}
3212                        {$whereYear}                        
3213                    GROUP BY
3214                        YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3215                        MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3216                        WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) WITH ROLLUP
3217                    ORDER BY
3218                        YEAR DESC,
3219                        MONTH ASC,
3220                        WEEK ASC,
3221                        DATE_FORMAT(q.issue_date, '%e') ASC";
3222
3223            $value = Cache::get(base64_encode($query));
3224
3225            if(!$value){
3226                $result = DB::select($query);
3227
3228                Cache::put(base64_encode($query), $result, 600);
3229            }else{
3230                $result = $value;
3231            }
3232
3233            return response([
3234                'message' => 'OK',
3235                'data' => $result
3236            ]);
3237
3238        } catch (\Exception $e) {
3239            /** @disregard P1014 */
3240            $e->exceptionCode = 'LIST_QUOTATION_ANALYTICS_BY_SOURCE_EXCEPTION'; 
3241            report($e);
3242            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3243        }
3244    }
3245
3246    public function list_quotation_analytics_send_budgets(Request $request){
3247
3248        try {
3249
3250            $data = $request->all();
3251            $companyId = addslashes($data['company_id']);
3252
3253            $where = "";
3254            $whereYear = "";
3255
3256            if($companyId != 0){
3257                $where = " AND q.company_id = {$companyId} ";
3258            }else{
3259                $where = " AND q.company_id IN ({$this->companyId}";
3260            }
3261
3262            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3263                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3264            }
3265
3266            if(isset($data['budget_status']) && $data['budget_status'] != null){
3267                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3268            }
3269
3270            if(isset($data['years']) && $data['years'] != null){
3271                $years = implode(',', $data['years']);
3272                if(count($data['years']) > 0){
3273                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3274                }
3275            }
3276
3277            $query = "SELECT
3278                            YEAR(q.issue_date) AS 'year',
3279                            MONTH(q.issue_date) AS 'month',
3280                            SUM(
3281                                CASE WHEN MONTH(request_date) = MONTH(issue_date) THEN 1 ELSE 0 END
3282                            ) totalRequest,
3283                            COUNT(
3284                                CASE WHEN q.issue_date IS NOT NULL THEN 1 END
3285                            ) AS totalIssue,
3286                            GROUP_CONCAT(
3287                                CASE WHEN q.issue_date IS NOT NULL
3288                                THEN q.id END
3289                            ) AS groupConcatIds,
3290                            SUM(
3291                                CASE WHEN MONTH(request_date) = MONTH(issue_date) THEN 1 ELSE 0 END
3292                            ) /
3293                            COUNT(
3294                                CASE WHEN q.issue_date IS NOT NULL THEN 1 END
3295                            ) * 100 issuePercentage,
3296                            AVG(
3297                                COALESCE(q.duration, 0)
3298                            ) AS averageDurationIssue,
3299                            COALESCE(
3300                                AVG(
3301                                    CASE WHEN bt.name = 'Mantenimiento' THEN COALESCE(q.duration, 0) ELSE NULL END
3302                                ), 0
3303                            ) AS averageDurationMaintenance,
3304                            COALESCE(
3305                                AVG(
3306                                    CASE WHEN bt.name = 'Nuevos' THEN COALESCE(q.duration, 0) ELSE NULL END
3307                                ), 0
3308                            ) AS averageDurationNew,
3309                            COALESCE(
3310                                AVG(
3311                                    CASE WHEN bt.name = 'Correctivos' THEN COALESCE(q.duration, 0) ELSE NULL END
3312                                ), 0
3313                            ) AS averageDurationCorretive,
3314                            COALESCE(
3315                                AVG(
3316                                    CASE WHEN bt.name = 'Anomalías' THEN COALESCE(q.duration, 0) ELSE NULL END
3317                                ), 0
3318                            ) AS averageDurationAnomalies,
3319                            COALESCE(
3320                                AVG(
3321                                    CASE WHEN bt.name = 'Precios Unitarios' THEN COALESCE(q.duration, 0) ELSE NULL END
3322                                ), 0
3323                            ) AS averageDurationUnitPrice,
3324                            COALESCE(
3325                                AVG(
3326                                    CASE WHEN bt.name = 'Instalaciones' THEN COALESCE(q.duration, 0) ELSE NULL END
3327                                ), 0
3328                            ) AS averageDurationFacilities,
3329                            COALESCE(
3330                                AVG(
3331                                    CASE WHEN bt.name = 'Alquiler' THEN COALESCE(q.duration, 0) ELSE NULL END
3332                                ), 0
3333                            ) AS averageDurationRent,
3334                            COALESCE(
3335                                AVG(
3336                                    CASE WHEN bt.name = 'OCA visita' THEN COALESCE(q.duration, 0) ELSE NULL END
3337                                ), 0
3338                            ) AS averageDurationOCA,
3339                            COALESCE(
3340                                AVG(
3341                                    CASE WHEN bt.name = 'Retirada y gestion de residuos' THEN COALESCE(q.duration, 0) ELSE NULL END
3342                                ), 0
3343                            ) AS averageDurationWRM,
3344                            COALESCE(
3345                                AVG(
3346                                    CASE WHEN bt.name = 'Formación' THEN COALESCE(q.duration, 0) ELSE NULL END
3347                                ), 0
3348                            ) AS averageDurationTraining,
3349                            COALESCE(
3350                                AVG(
3351                                    CASE WHEN bt.name = 'Anomalías de facilities' THEN COALESCE(q.duration, 0) ELSE NULL END
3352                                ), 0
3353                            ) AS averageDurationFacilityAnomalies
3354                        FROM
3355                            tbl_quotations q
3356                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3357                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_id = btg.budget_type_id
3358                        WHERE
3359                            q.issue_date IS NOT NULL
3360                            AND q.budget_type_id != 7
3361                            AND q.budget_type_id IS NOT NULL
3362                            AND q.for_add != 1
3363                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3364                            {$where}
3365                            {$whereYear}
3366                        GROUP BY
3367                            YEAR(q.issue_date),
3368                            MONTH(q.issue_date) WITH ROLLUP
3369                        ORDER BY
3370                            YEAR(q.issue_date) DESC,
3371                            MONTH(q.issue_date) ASC";
3372
3373            $sendBudgets = array();
3374            $sendBudgetsTotals = array();
3375
3376            $value = Cache::get(base64_encode($query));
3377
3378            if(!$value){
3379                $result = DB::select($query);
3380
3381                Cache::put(base64_encode($query), $result, 600);
3382            }else{
3383                $result = $value;
3384            }
3385
3386            if(count($result) > 0){
3387                for ($i = 0; $i < count($result); $i++) {
3388
3389                    if($result[$i]->year == null && $result[$i]->month == null){
3390                        $result[$i]->month = "totalGeneral";
3391                        $sendBudgetsTotals["totalGeneral"] = $result[$i];
3392                        continue;
3393                    }elseif($result[$i]->month == null && $result[$i]->year != null){
3394                        if(count($data['years']) > 0 || $whereYear == ""){
3395                            $result[$i]->month = "totalSub";
3396                        }else{
3397                            continue;
3398                        }
3399                    }else{
3400                        $result[$i]->month = sprintf("%02d", $result[$i]->month);
3401                    }
3402
3403                    $sendBudgets[$result[$i]->year][$result[$i]->month] = $result[$i];
3404                }
3405            }
3406
3407            return response([
3408                'message' => 'OK',
3409                'data' => $sendBudgets,
3410                'totals' => $sendBudgetsTotals
3411            ]);
3412
3413        } catch (\Exception $e) {
3414            /** @disregard P1014 */
3415            $e->exceptionCode = 'LIST_QUOTATION_ANALYTICS_EXCEPTION'; 
3416            report($e);
3417            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3418        }
3419    }
3420
3421    public function list_quotation_analytics_track_budgets(Request $request){
3422
3423        try {
3424
3425            $data = $request->all();
3426            $companyId = addslashes($data['company_id']);
3427
3428            $where = "";
3429            $whereYear = "";
3430            $isBetween = false;
3431
3432            $dateLflArray = array();
3433            $companyIds = $this->companyIds;
3434
3435            if($companyId != 0){
3436                $companyIds = array($companyId);
3437            }
3438
3439            if(isset($data['years']) && $data['years'] != null){
3440                $years = implode(',', $data['years']);
3441                if(count($data['years']) > 0){
3442                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3443                }
3444            }
3445
3446            $field = "issue_date";
3447
3448            foreach ($companyIds as $v) {
3449
3450                $lflWhere = " AND q.company_id = {$v} ";
3451
3452                $query = "SELECT
3453                            CONCAT(
3454                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
3455                                ' - ',
3456                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
3457                            ) AS date_like,
3458                            YEAR(q.{$field}) 'year',
3459                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
3460                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
3461                            {$v} 'company_id'
3462                        FROM
3463                            tbl_quotations q
3464                        WHERE
3465                            q.{$field} IS NOT NULL
3466                            AND q.for_add != 1
3467                            {$lflWhere}
3468                            {$whereYear}
3469                        GROUP BY YEAR(q.{$field})
3470                        ORDER BY YEAR(q.{$field}) DESC";
3471
3472                $dateLike = DB::select($query);
3473
3474                $dateLflArray[$v] = $dateLike;
3475            }
3476
3477            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
3478
3479            $isFy = true;
3480
3481            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
3482                $isFy = false;
3483                $ytdArray = array();
3484                $ytdAcceptanceArray = array();
3485                $lflCompanyIds = array();
3486                $lflCompanyIdsAcc = array();
3487                foreach ($dateLflArray as $k => $v) {
3488                    foreach ($dateLflArray[$k] as $item) {
3489                        $year = $item->year;
3490                        $now = date('m-d');
3491                        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)");
3492                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
3493                    }
3494
3495                    $ytdArray = implode(' OR ', $ytdArray);
3496                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
3497                    $ytdArray = array();
3498
3499                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3500                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3501                    $ytdAcceptanceArray = array();
3502                }
3503
3504                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3505                $where .= " AND ({$lflCompanyIds}";
3506
3507                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3508                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3509            }
3510
3511            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
3512                $isFy = false;
3513                $lflArray = array();
3514                $ytdAcceptanceArray = array();
3515                $lflCompanyIds = array();
3516                $lflCompanyIdsAcc = array();
3517                foreach ($dateLflArray as $k => $v) {
3518                    foreach ($dateLflArray[$k] as $item) {
3519                        $year = $item->year;
3520                        $min_date_like = $item->min_date_like;
3521                        $max_date_like = $item->max_date_like;
3522                        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)");
3523                        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}')");
3524                    }
3525
3526                    $lflArray = implode(' OR ', $lflArray);
3527                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
3528                    $lflArray = array();
3529
3530                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3531                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3532                    $ytdAcceptanceArray = array();
3533                }
3534
3535                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3536                $where .= " AND ({$lflCompanyIds}";
3537
3538                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3539                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3540            }
3541
3542            if($isFy){
3543                if($companyId != 0){
3544                    $where .= " AND q.company_id = {$companyId} ";
3545                }else{
3546                    $where .= " AND q.company_id IN ({$this->companyId})";
3547                }
3548            }
3549
3550            if(isset($data['source']) && $data['source'] != null){
3551                $where .= " AND s.name = '{$data['source']}'";
3552            }
3553
3554            if(isset($data['commercial']) && $data['commercial'] != null){
3555                $where .= " AND q.commercial = '{$data['commercial']}'";
3556            }
3557
3558            if(isset($data['created_by']) && $data['created_by'] != null){
3559                $where .= " AND q.created_by = '{$data['created_by']}'";
3560            }
3561
3562            if(isset($data['budget_type']) && $data['budget_type'] != null){
3563                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
3564            }
3565
3566            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
3567                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
3568            }
3569
3570            if(isset($data['budget_status']) && $data['budget_status'] != null){
3571                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3572            }
3573
3574            if(isset($data['client_type']) && $data['client_type'] != null){
3575                $where .= " AND ct.customer_type_id = {$data['client_type']}";
3576            }
3577
3578            if(isset($data['segment_id']) && $data['segment_id'] != null){
3579                $where .= " AND q.segment_id = {$data['segment_id']}";
3580            }
3581
3582            $query = "SELECT
3583                            YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) AS 'year',
3584                            LPAD(MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'month',
3585                            LPAD(WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)), 2, 0) AS 'week',
3586                            DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') issue_date,
3587                            COUNT(
3588                                CASE WHEN q.issue_date IS NOT NULL
3589                                THEN 1 END
3590                            ) AS totalIssue,
3591                            GROUP_CONCAT(
3592                                CASE WHEN q.issue_date IS NOT NULL
3593                                THEN q.id END
3594                            ) AS groupConcatIds,
3595                            COUNT(
3596                                CASE WHEN {$whereAcceptanceDate}
3597                                AND bs.name = 'Aceptado' THEN 1 END) totalAccept,
3598                            COUNT(
3599                                CASE WHEN q.acceptance_date IS NOT NULL
3600                                AND {$whereAcceptanceDate}
3601                                AND bs.name = 'Aceptado'
3602                                AND DATEDIFF(q.acceptance_date, q.issue_date) <= 10 THEN 1 END
3603                            ) / COUNT(
3604                                CASE WHEN q.issue_date IS NOT NULL
3605                                THEN 1 END
3606                            ) * 100 AS percentageOfacceptanceLessThan10,
3607                            COUNT(
3608                                CASE WHEN q.acceptance_date IS NOT NULL
3609                                AND {$whereAcceptanceDate}
3610                                AND bs.name = 'Aceptado'
3611                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 10
3612                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 30 THEN 1 END
3613                            ) / COUNT(
3614                                CASE WHEN q.issue_date IS NOT NULL
3615                                THEN 1 END
3616                            ) * 100 AS percentageOfacceptanceLessThan30,
3617                            COUNT(
3618                                CASE WHEN q.acceptance_date IS NOT NULL
3619                                AND {$whereAcceptanceDate}
3620                                AND bs.name = 'Aceptado'
3621                                AND DATEDIFF(q.acceptance_date, q.issue_date) >= 30 THEN 1 END
3622                            ) / COUNT(
3623                                CASE WHEN q.issue_date IS NOT NULL
3624                                THEN 1 END
3625                            ) * 100 AS percentageOfacceptanceMoreThan30,
3626                            COUNT(CASE WHEN
3627                                {$whereAcceptanceDate} THEN 1 END
3628                            ) / COUNT(
3629                                CASE WHEN q.issue_date IS NOT NULL
3630                                THEN 1 END
3631                            ) * 100 acceptedPercentage,
3632                            COALESCE(
3633                                AVG(
3634                                    CASE WHEN q.issue_date IS NOT NULL
3635                                    AND q.acceptance_date IS NOT NULL
3636                                    AND {$whereAcceptanceDate}
3637                                    AND bs.name = 'Aceptado'
3638                                    THEN DATEDIFF(q.acceptance_date, q.issue_date) ELSE NULL END
3639                                ), 0
3640                            )
3641                            AS averageAcceptedDuration,
3642                            COALESCE(
3643                                AVG(
3644                                    CASE WHEN q.issue_date IS NOT NULL
3645                                    AND q.request_date IS NOT NULL
3646                                    THEN DATEDIFF(q.issue_date, q.request_date) ELSE NULL END
3647                                ), 0
3648                            )
3649                            AS averageRequestedDays
3650                        FROM
3651                            tbl_quotations q
3652                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3653                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3654                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
3655                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
3656                        WHERE
3657                            q.issue_date IS NOT NULL
3658                            AND q.budget_type_id != 7
3659                            AND q.budget_type_id IS NOT NULL
3660                            AND q.for_add != 1
3661                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3662                            {$where}
3663                            {$whereYear}
3664                        GROUP BY
3665                            YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3666                            MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)),
3667                            WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) WITH ROLLUP
3668                        ORDER BY
3669                            YEAR DESC,
3670                            MONTH ASC,
3671                            WEEK ASC,
3672                            DATE_FORMAT(q.issue_date, '%e') ASC";
3673
3674            $value = Cache::get(base64_encode($query));
3675
3676            if(!$value){
3677                $result = DB::select($query);
3678
3679                Cache::put(base64_encode($query), $result, 600);
3680            }else{
3681                $result = $value;
3682            }
3683
3684            return response([
3685                'message' => 'OK',
3686                'data' => $result
3687            ]);
3688
3689        } catch (\Exception $e) {
3690            /** @disregard P1014 */
3691            $e->exceptionCode = 'LIST_QUOTATION_ANALYTICS_TRACK_BUDGETS_EXCEPTION'; 
3692            report($e);
3693            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3694        }
3695    }
3696
3697    public function list_quotation_analytics_types_budgets(Request $request){
3698
3699        try {
3700
3701            $data = $request->all();
3702            $companyId = addslashes($data['company_id']);
3703
3704            $where = "";
3705            $whereYear = "";
3706            $isBetween = false;
3707
3708            $dateLflArray = array();
3709            $companyIds = $this->companyIds;
3710
3711            if($companyId != 0){
3712                $companyIds = array($companyId);
3713            }
3714
3715            if(isset($data['years']) && $data['years'] != null){
3716                $years = implode(',', $data['years']);
3717                if(count($data['years']) > 0){
3718                    $whereYear = " AND YEAR(q.issue_date) IN ({$years})";
3719                }
3720            }
3721
3722            $field = "issue_date";
3723
3724            foreach ($companyIds as $v) {
3725
3726                $lflWhere = " AND q.company_id = {$v} ";
3727
3728                $query = "SELECT
3729                            CONCAT(
3730                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
3731                                ' - ',
3732                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
3733                            ) AS date_like,
3734                            YEAR(q.{$field}) 'year',
3735                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
3736                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
3737                            {$v} 'company_id'
3738                        FROM
3739                            tbl_quotations q
3740                        WHERE
3741                            q.{$field} IS NOT NULL
3742                            AND q.for_add != 1
3743                            {$lflWhere}
3744                            {$whereYear}
3745                        GROUP BY YEAR(q.{$field})
3746                        ORDER BY YEAR(q.{$field}) DESC";
3747
3748                $dateLike = DB::select($query);
3749
3750                $dateLflArray[$v] = $dateLike;
3751            }
3752
3753            $whereAcceptanceDate = "q.acceptance_date IS NOT NULL ";
3754
3755            $isFy = true;
3756
3757            if(isset($data['issue_year_ytd']) && $data['issue_year_ytd'] != null && $data['issue_year_ytd'] == true){
3758                $isFy = false;
3759                $ytdArray = array();
3760                $ytdAcceptanceArray = array();
3761                $lflCompanyIds = array();
3762                $lflCompanyIdsAcc = array();
3763                foreach ($dateLflArray as $k => $v) {
3764                    foreach ($dateLflArray[$k] as $item) {
3765                        $year = $item->year;
3766                        $now = date('m-d');
3767                        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)");
3768                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
3769                    }
3770
3771                    $ytdArray = implode(' OR ', $ytdArray);
3772                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
3773                    $ytdArray = array();
3774
3775                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3776                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3777                    $ytdAcceptanceArray = array();
3778                }
3779
3780                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3781                $where .= " AND ({$lflCompanyIds}";
3782
3783                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3784                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3785            }
3786
3787            if(isset($data['issue_year_lfl']) && $data['issue_year_lfl'] != null && $data['issue_year_lfl'] == true){
3788                $isFy = false;
3789                $lflArray = array();
3790                $ytdAcceptanceArray = array();
3791                $lflCompanyIds = array();
3792                $lflCompanyIdsAcc = array();
3793                foreach ($dateLflArray as $k => $v) {
3794                    foreach ($dateLflArray[$k] as $item) {
3795                        $year = $item->year;
3796                        $min_date_like = $item->min_date_like;
3797                        $max_date_like = $item->max_date_like;
3798                        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)");
3799                        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}')");
3800                    }
3801
3802                    $lflArray = implode(' OR ', $lflArray);
3803                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
3804                    $lflArray = array();
3805
3806                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
3807                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
3808                    $ytdAcceptanceArray = array();
3809                }
3810
3811                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
3812                $where .= " AND ({$lflCompanyIds}";
3813
3814                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
3815                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
3816            }
3817
3818            if($isFy){
3819                if($companyId != 0){
3820                    $where .= " AND q.company_id = {$companyId} ";
3821                }else{
3822                    $where .= " AND q.company_id IN ({$this->companyId})";
3823                }
3824            }
3825
3826            if(isset($data['budget_status']) && $data['budget_status'] != null){
3827                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
3828            }
3829
3830            if(isset($data['segment_id']) && $data['segment_id'] != null){
3831                $where .= " AND q.segment_id = {$data['segment_id']}";
3832            }
3833
3834            $query = "SELECT
3835                            YEAR(q.issue_date) AS 'year',
3836                            bt.name,
3837                            COUNT(
3838                                CASE WHEN q.issue_date IS NOT NULL
3839                                THEN 1 END
3840                            ) AS totalIssue,
3841                            GROUP_CONCAT(
3842                                CASE WHEN q.issue_date IS NOT NULL
3843                                THEN q.id END
3844                            ) AS groupConcatIds,
3845                            COUNT(CASE WHEN {$whereAcceptanceDate} AND bs.name = 'Aceptado' THEN 1 END) totalAccept,
3846                            COUNT(
3847                                CASE WHEN q.acceptance_date IS NOT NULL
3848                                AND {$whereAcceptanceDate}
3849                                AND bs.name = 'Aceptado'
3850                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 10 THEN 1 END
3851                            ) / COUNT(
3852                                CASE WHEN q.issue_date IS NOT NULL
3853                                THEN 1 END
3854                            ) * 100 AS percentageOfacceptanceLessThan10,
3855                            COUNT(
3856                                CASE WHEN q.acceptance_date IS NOT NULL
3857                                AND {$whereAcceptanceDate}
3858                                AND bs.name = 'Aceptado'
3859                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 10
3860                                AND DATEDIFF(q.acceptance_date, q.issue_date) < 30 THEN 1 END
3861                            ) / COUNT(
3862                                CASE WHEN q.issue_date IS NOT NULL
3863                                THEN 1 END
3864                            ) * 100 AS percentageOfacceptanceLessThan30,
3865                            COUNT(
3866                                CASE WHEN q.acceptance_date IS NOT NULL
3867                                AND {$whereAcceptanceDate}
3868                                AND bs.name = 'Aceptado'
3869                                AND DATEDIFF(q.acceptance_date, q.issue_date) > 30 THEN 1 END
3870                            ) / COUNT(
3871                                CASE WHEN q.issue_date IS NOT NULL
3872                                THEN 1 END
3873                            ) * 100 AS percentageOfacceptanceMoreThan30,
3874                            COUNT(CASE WHEN {$whereAcceptanceDate} THEN 1 END) / COUNT(
3875                                CASE WHEN q.issue_date IS NOT NULL
3876                                THEN 1 END
3877                            ) * 100 acceptedPercentage,
3878                            COALESCE(
3879                                AVG(
3880                                    CASE WHEN q.issue_date IS NOT NULL
3881                                    AND q.acceptance_date IS NOT NULL
3882                                    AND {$whereAcceptanceDate}
3883                                    AND bs.name = 'Aceptado'
3884                                    THEN DATEDIFF(q.acceptance_date, q.issue_date) ELSE NULL END
3885                                ), 0
3886                            )
3887                            AS averageAcceptedDuration,
3888                            COALESCE(
3889                                AVG(
3890                                    CASE WHEN q.issue_date IS NOT NULL
3891                                    AND q.request_date IS NOT NULL
3892                                    AND q.issue_date > q.request_date
3893                                    THEN DATEDIFF(q.issue_date, q.request_date) ELSE NULL END
3894                                ), 0
3895                            )
3896                            AS averageRequestedDays
3897                        FROM
3898                            tbl_quotations q
3899                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
3900                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
3901                        WHERE
3902                            q.issue_date IS NOT NULL
3903                            AND q.budget_type_id != 7
3904                            AND q.budget_type_id IS NOT NULL
3905                            AND q.for_add != 1
3906                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
3907                            {$where}
3908                            {$whereYear}
3909                        GROUP BY
3910                            YEAR(q.issue_date),
3911                            bt.name WITH ROLLUP";
3912
3913            $value = Cache::get(base64_encode($query));
3914
3915            if(!$value){
3916                $result = DB::select($query);
3917
3918                Cache::put(base64_encode($query), $result, 600);
3919            }else{
3920                $result = $value;
3921            }
3922
3923            $typesBudgets = array();
3924            $typesBudgetsTotals = array();
3925
3926            if(count($result) > 0){
3927                for ($i = 0; $i < count($result); $i++) {
3928
3929                    if($result[$i]->year == null && $result[$i]->name == null){
3930                        $result[$i]->name = "totalGeneral";
3931                        $typesBudgetsTotals["totalGeneral"] = $result[$i];
3932                        continue;
3933                    }elseif($result[$i]->name == null && $result[$i]->year != null){
3934                        if(count($data['years']) > 0 || $whereYear == ""){
3935                            $result[$i]->name = "totalSub";
3936                        }else{
3937                            continue;
3938                        }
3939                    }
3940
3941                    $typesBudgets[$result[$i]->year][$result[$i]->name] = $result[$i];
3942                }
3943            }
3944
3945            return response([
3946                'message' => 'OK',
3947                'data' => $typesBudgets,
3948                'totals' => $typesBudgetsTotals
3949            ]);
3950
3951        } catch (\Exception $e) {
3952            /** @disregard P1014 */
3953            $e->exceptionCode = 'LIST_QUOTATION_ANALYTICS_TYPES_BUDGETS_EXCEPTION'; 
3954            report($e);
3955            return response(['message' => 'KO', 'error' => $e->getMessage()]);
3956        }
3957    }
3958
3959    function download_quotations(Request $request){
3960        ini_set('max_execution_time', 123456);
3961        $data = $request->all();
3962        $companyId = addslashes($data['company_id']);
3963        $userId = addslashes($data['user_id']);
3964
3965        $where = "";
3966
3967        $query = "SELECT
3968                b.name
3969            FROM tbl_users a
3970            LEFT JOIN tbl_roles b
3971                ON a.role_id = b.role_id
3972            WHERE a.id = {$userId}";
3973
3974        $role = DB::select($query);
3975
3976        $r = new Request([
3977            'filterModel' => $data['filterModel'],
3978            'sortModel' => $data['sortModel'],
3979            'start' => 0,
3980            'end' => 999999999,
3981            'company_id' => $data['company_id'],
3982            'user_id' => $data['user_id'],
3983            'ids' => $data['ids'],
3984            'searchText' => $data['searchText'],
3985            'ids_not_in' => $data['ids_not_in']
3986        ]);
3987
3988        $result = $this->list_quotations($r);
3989
3990        $spreadsheet = new Spreadsheet();
3991        $worksheet   = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, "Inputs");
3992        $spreadsheet->addSheet($worksheet, 0);
3993        $col         = range('A', 'Z');
3994
3995        for($i = 0; $i < 26; $i++){
3996            $worksheet->getColumnDimension($col[$i])->setAutoSize(true);
3997            if($i != 1){
3998                $worksheet->getStyle($col[$i])
3999                    ->getAlignment()
4000                    ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
4001            }
4002        }
4003
4004        $worksheet->getColumnDimension("AB")->setAutoSize(true);
4005        $worksheet->getStyle("AB")
4006            ->getAlignment()
4007            ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
4008
4009        $l = 1;
4010        $worksheet->setCellValue('A' . $l, __('language.ID'));
4011        $worksheet->setCellValue('B' . $l, __('language.INTERNAL_ID'));
4012        $worksheet->setCellValue('C' . $l, __('language.CLIENT'));
4013        $worksheet->setCellValue('D' . $l, __('language.AMOUNT'));
4014        $worksheet->setCellValue('E' . $l, __('language.INVOICE_MARGIN'));
4015        $worksheet->setCellValue('F' . $l, __('language.MARGIN_FOR_THE_COMPANY'));
4016        $worksheet->setCellValue('G' . $l, __('language.TYPE'));
4017        $worksheet->setCellValue('H' . $l, __('language.STATUS'));
4018        $worksheet->setCellValue('I' . $l, __('language.CREATED_BY'));
4019        $worksheet->setCellValue('J' . $l, __('language.COMMERCIAL'));
4020        $worksheet->setCellValue('K' . $l, __('language.CREATED_AT'));
4021        $worksheet->setCellValue('L' . $l, __('language.ACCEPTANCE_DATE'));
4022        $worksheet->setCellValue('M' . $l, __('language.REQUEST_DATE'));
4023        $worksheet->setCellValue('N' . $l, __('language.ISSUE_DATE'));
4024        $worksheet->setCellValue('O' . $l, __('language.DURATION'));
4025        $worksheet->setCellValue('P' . $l, __('language.CLIENT_TYPE'));
4026        $worksheet->setCellValue('Q' . $l, __('language.SEGMENT'));
4027        $worksheet->setCellValue('R' . $l, __('language.LIKEHOOD'));
4028        $worksheet->setCellValue('S' . $l, __('language.SOURCE'));
4029        $worksheet->setCellValue('T' . $l, __('language.LAST_FOLLOW_UP_DATE'));
4030        $worksheet->setCellValue('U' . $l, __('language.REASON_FOR_NOT_FOLLOWING_UP'));
4031        $worksheet->setCellValue('V' . $l, __('language.REASON_FOR_REJECTION'));
4032        $worksheet->setCellValue('W' . $l, __('language.EMAIL'));
4033        $worksheet->setCellValue('X' . $l, __('language.EMAIL_STATUS'));
4034        $worksheet->setCellValue('Y' . $l, __('language.PHONE_NUMBER'));
4035        $worksheet->setCellValue('Z' . $l, __('language.ORDER_NUMBER'));
4036        $worksheet->setCellValue('AA' . $l, __('language.BOX_WORK_G3W'));
4037        $worksheet->setCellValue('AB' . $l, __('language.APPROVAL_REQUIRED'));
4038        $worksheet->setCellValue('AC' . $l, __('language.FILES_COUNT'));
4039        $worksheet->setCellValue('AD' . $l, __('language.ACCEPTED_BY'));
4040        $worksheet->setCellValue('AE' . $l, __('language.ACCEPTED_AT'));
4041        $worksheet->setCellValue('AF' . $l, "Origen");
4042        $worksheet->setCellValue('AG' . $l, "Origen Edit");
4043        $worksheet->setCellValue('AH' . $l, __('language.G3W_WARNING'));
4044        $worksheet->setCellValue('AI' . $l, __('language.COMPANY_NAME'));
4045
4046        $styleArray = [
4047            'font' => [
4048                'bold' => true,
4049            ]
4050        ];
4051
4052        $worksheet->getStyle('A1:AH1')
4053            ->getFill()
4054            ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
4055            ->getStartColor()
4056            ->setARGB('523779');
4057
4058        $worksheet->getStyle('A1:AH1')
4059            ->getFont()
4060            ->getColor()
4061            ->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
4062
4063        $worksheet->getStyle('A1:AH1')->applyFromArray($styleArray);
4064
4065        $l = 2;
4066        $result = $result->original['data'];
4067
4068        for ($i = 0; $i < count($result); $i++) {
4069
4070            if($result[$i]->request_date){
4071                $result[$i]->request_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->request_date);
4072            }
4073
4074            if($result[$i]->issue_date){
4075                $result[$i]->issue_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->issue_date);
4076            }
4077
4078            if($result[$i]->acceptance_date){
4079                $result[$i]->acceptance_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->acceptance_date);
4080            }
4081
4082            if($result[$i]->last_follow_up_date){
4083                $result[$i]->last_follow_up_date = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->last_follow_up_date);
4084            }
4085
4086            if($result[$i]->created_at){
4087                $result[$i]->created_at = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->created_at);
4088            }
4089
4090            if($result[$i]->accepted_at){
4091                $result[$i]->accepted_at = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($result[$i]->accepted_at);
4092            }
4093
4094            $worksheet->setCellValue('A' . $l, $result[$i]->quote_id);
4095            $worksheet->setCellValue('B' . $l, $result[$i]->internal_quote_id);
4096            $worksheet->setCellValue('C' . $l, $result[$i]->client);
4097            $worksheet->setCellValue('D' . $l, $result[$i]->amount);
4098            $worksheet->setCellValue('E' . $l, $result[$i]->invoice_margin);
4099            $worksheet->setCellValue('F' . $l, $result[$i]->margin_for_the_company);
4100            $worksheet->setCellValue('G' . $l, $result[$i]->type);
4101            $worksheet->setCellValue('H' . $l, $result[$i]->status);
4102            $worksheet->setCellValue('I' . $l, $result[$i]->created_by);
4103            $worksheet->setCellValue('J' . $l, $result[$i]->commercial);
4104            $worksheet->setCellValue('K' . $l, $result[$i]->created_at);
4105
4106            $worksheet->getStyle('K' . $l)
4107                ->getNumberFormat()
4108                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4109
4110            $worksheet->setCellValue('L' . $l, $result[$i]->acceptance_date);
4111
4112            $worksheet->getStyle('L' . $l)
4113                ->getNumberFormat()
4114                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4115
4116            $worksheet->setCellValue('M' . $l, $result[$i]->request_date);
4117
4118            $worksheet->getStyle('M' . $l)
4119                ->getNumberFormat()
4120                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4121
4122            $worksheet->setCellValue('N' . $l, $result[$i]->issue_date);
4123
4124            $worksheet->getStyle('N' . $l)
4125                ->getNumberFormat()
4126                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4127
4128            $worksheet->setCellValue('O' . $l, '=DATEDIF(J'.$l.',K'.$l.',"d")');
4129            $worksheet->setCellValue('P' . $l, $result[$i]->client_type);
4130            $worksheet->setCellValue('Q' . $l, $result[$i]->segment);
4131            $worksheet->setCellValue('R' . $l, $result[$i]->likehood);
4132            $worksheet->setCellValue('S' . $l, $result[$i]->source);
4133            $worksheet->setCellValue('T' . $l, $result[$i]->last_follow_up_date);
4134
4135            $worksheet->getStyle('T' . $l)
4136                ->getNumberFormat()
4137                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4138
4139            $worksheet->setCellValue('U' . $l, $result[$i]->reason_for_not_following_up);
4140            $worksheet->setCellValue('V' . $l, $result[$i]->reason_for_rejection);
4141            $worksheet->setCellValue('W' . $l, $result[$i]->email);
4142            $worksheet->setCellValue('X' . $l, $result[$i]->x_status);
4143            $worksheet->setCellValue('Y' . $l, $result[$i]->phone_number);
4144            $worksheet->setCellValue('Z' . $l, $result[$i]->order_number);
4145            $worksheet->setCellValue('AA' . $l, $result[$i]->box_work_g3w);
4146            $worksheet->setCellValue('AB' . $l, ($result[$i]->for_approval == 1 || $result[$i]->for_approval == 3) ? __('language.YES') : __('language.NO'));
4147            $worksheet->setCellValue('AC' . $l, $result[$i]->has_attachment == 1 ? __('language.YES') : __('language.NO'));
4148            $worksheet->setCellValue('AD' . $l, $result[$i]->accepted_by);
4149            $worksheet->setCellValue('AE' . $l, $result[$i]->accepted_at);
4150
4151            $worksheet->getStyle('AE' . $l)
4152                ->getNumberFormat()
4153                ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
4154
4155            $worksheet->setCellValue('AF' . $l, $result[$i]->sync_import == 1 ? 'G3W' : 'Manual');
4156            $worksheet->setCellValue('AG' . $l, $result[$i]->sync_import_edited == 1 ? 'G3W' : 'Manual');
4157            $worksheet->setCellValue('AH' . $l, $result[$i]->g3w_warning == 1 ? 'Sí' : 'No');
4158            $worksheet->setCellValue('AI' . $l, $result[$i]->company_name);
4159            $l++;
4160
4161        }
4162
4163        if($role[0]->name == 'Regular'){
4164            $worksheet->removeColumn('D');
4165            $worksheet->removeColumn('W');
4166            $worksheet->removeColumn('X');
4167        }
4168
4169        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
4170        ob_start();
4171        $writer->save('php://output');
4172        $file = ob_get_contents();
4173        ob_end_clean();
4174
4175        return response($file);
4176    }
4177
4178    function bulk_upload(Request $request){
4179
4180        try {
4181
4182            $data = $request->all();
4183            $file = $request->file('file');
4184            $exte = 'Xlsx';
4185            $companyId = $data['company_id'];
4186
4187            if($file->getMimeType() == 'application/vnd.ms-excel'){
4188                $exte = 'Xls';
4189            }
4190
4191            $destination_path = env('BULK_UPLOAD_FILE_DESTINATION', 'E:/bulk_upload/');
4192            $filename         = $file->getClientOriginalName();
4193
4194            if(file_exists($destination_path . $filename)){
4195                $filename = pathinfo($filename, PATHINFO_FILENAME) . '-' . uniqid() . '.' . pathinfo($filename, PATHINFO_EXTENSION);
4196            }
4197
4198            $file->move($destination_path, $filename);
4199
4200            TblBulkUpload::create(
4201                array(
4202                    'company_id' => $companyId,
4203                    'filename' => $filename,
4204                    'status' => 'Uploading...',
4205                    'is_running' => 1,
4206                    'uploaded_by' => $data['created_by']
4207                )
4208            );
4209
4210            $command = "php BulkUploadQuotations.php '{$data['created_by']}' '{$exte}' '{$destination_path}' '{$filename}{$companyId}";
4211            exec($command . ' > /dev/null &');
4212
4213            $query = "";
4214            $isRunning = 0;
4215
4216            if($companyId == 0){
4217                $query = "SELECT * FROM tbl_bulk_upload ORDER BY started_at DESC";
4218                $isRunning = TblBulkUpload::where('is_running', 1)->count();
4219            }else{
4220                $query = "SELECT * FROM tbl_bulk_upload WHERE company_id = {$companyId} ORDER BY started_at DESC";
4221                $isRunning = TblBulkUpload::where('is_running', 1)->where('company_id', $companyId)->count();
4222            }
4223
4224            $result = DB::select($query);
4225
4226            return response(['message' => 'OK', 'data' => $result, 'is_running' => $isRunning]);
4227
4228        } catch (\Exception $e) {
4229            /** @disregard P1014 */
4230            $e->exceptionCode = 'BULK_UPLOAD_QUOTATIONS_EXCEPTION'; 
4231            report($e);
4232            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4233        }
4234    }
4235
4236    function list_bulk_upload($companyId){
4237
4238        try {
4239
4240            $companyId = addslashes($companyId);
4241            $query = "";
4242            $isRunning = 0;
4243
4244            if($companyId == 0){
4245                $query = "SELECT * FROM tbl_bulk_upload ORDER BY started_at DESC";
4246                $isRunning = TblBulkUpload::where('is_running', 1)->count();
4247            }else{
4248                $query = "SELECT * FROM tbl_bulk_upload WHERE company_id = {$companyId} ORDER BY started_at DESC";
4249                $isRunning = TblBulkUpload::where('is_running', 1)->where('company_id', $companyId)->count();
4250            }
4251
4252            $result = DB::select($query);
4253
4254            return response(['message' => 'OK', 'data' => $result, 'is_running' => $isRunning]);
4255
4256        } catch (\Exception $e) {
4257            /** @disregard P1014 */
4258            $e->exceptionCode = 'LIST_BULK_UPLOAD_EXCEPTION'; 
4259            report($e);
4260            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4261        }
4262
4263    }
4264
4265    function delete_number(Request $request, $id){
4266
4267        try {
4268
4269            $id = addslashes($id);
4270            $data = $request->all();
4271
4272            $r = TblQuotations::where('id', $id)->first();
4273            $updatedAt = date('Y-m-d H:i:s');
4274            $query = "INSERT INTO tbl_quotations_deleted (id, quote_id, company_id, for_add, created_by, updated_by, updated_at)
4275                        SELECT id, quote_id, company_id, 1, created_by, '{$data['updated_by']}', '{$updatedAt}' FROM tbl_quotations WHERE id = {$id}";
4276
4277            DB::select($query);
4278
4279            TblQuotations::where('id', $id)->delete();
4280
4281            $latestBudget = TblQuotations::where('company_id', $r->company_id)->orderByRaw('id DESC')->pluck('quote_id')->first();
4282
4283            $query = "UPDATE tbl_companies SET last_id = '{$latestBudget}' WHERE company_id = {$r->company_id}";
4284            DB::select($query);
4285
4286            return response(['message' => 'OK']);
4287
4288        } catch (\Exception $e) {
4289            /** @disregard P1014 */
4290            $e->exceptionCode = 'DELETE_QUOTATION_EXCEPTION'; 
4291            report($e);
4292            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4293        }
4294
4295    }
4296
4297    function get_number(Request $request, $companyId, $n = null){
4298
4299        try {
4300
4301            $companyId = addslashes($companyId);
4302            $data = $request->all();
4303            $latestBudget = array();
4304            $number = 0;
4305            $beforeLastId = null;
4306
4307            $x = true;
4308
4309            if($companyId == 0){
4310                $latestBudget = TblQuotations::orderByRaw('CAST(quote_id AS DOUBLE) DESC')->pluck('quote_id')->first();
4311            }else{
4312                $latestBudget = TblCompanies::where('company_id', $companyId)->pluck('last_id')->first();
4313
4314                if($latestBudget == null){
4315                    $latestBudget = TblQuotations::where('company_id', $companyId)->orderByRaw('id DESC')->pluck('quote_id')->first();
4316                    $beforeLastId = $latestBudget;
4317                }
4318            }
4319
4320            $number = $latestBudget;
4321
4322            while ($x) {
4323
4324                if(is_numeric(substr($number, -1))) {
4325                    $number++;
4326                }else{
4327                    $number .= "1";
4328                }
4329
4330                $check = 0;
4331
4332                if($companyId == 0){
4333                    $check = TblQuotations::where('quote_id', (string) $number)->count();
4334                }else{
4335                    $check = TblQuotations::where('company_id', $companyId)->where('quote_id', (string) $number)->count();
4336                }
4337
4338                if($check == 0){
4339                    $x = false;
4340                }
4341            }
4342
4343            $result = null;
4344
4345            if($n == null){
4346                $result = TblQuotations::create(array('quote_id' => $number, 'company_id' => $companyId, 'for_add' => 1, 'created_by' => $data['created_by']));
4347            }
4348
4349            if($beforeLastId == null){
4350                $beforeLastId = $number;
4351            }
4352
4353            $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}";
4354            DB::select($query);
4355
4356            return response([
4357                'message' => 'OK',
4358                'number' => $number,
4359                'id' => ($result !=  null) ? $result->id : null
4360            ]);
4361
4362
4363        } catch (\Exception $e) {
4364            /** @disregard P1014 */
4365            $e->exceptionCode = 'GET_NUMBER_EXCEPTION'; 
4366            report($e);
4367            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4368        }
4369
4370    }
4371
4372    function get_years(Request $request){
4373
4374        try {
4375
4376            $data = $request->all();
4377            $companyId = addslashes($data['company_id']);
4378            $where = "";
4379
4380            if($companyId != 0){
4381                $where = " AND company_id = {$companyId} ";
4382            }else{
4383                $where = " AND company_id IN ({$this->companyId}";
4384            }
4385
4386            $query = "SELECT
4387                        CONCAT(
4388                            DATE_FORMAT((SELECT MIN(issue_date) FROM tbl_quotations WHERE issue_date IS NOT NULL {$where}), '%c/%e/'), YEAR(issue_date),
4389                            ' - ',
4390                            DATE_FORMAT((SELECT MAX(issue_date) FROM tbl_quotations WHERE issue_date IS NOT NULL {$where}), '%c/%e/'), YEAR(issue_date)
4391                        ) AS date_like,
4392                        YEAR(issue_date) 'year'
4393                        FROM tbl_quotations
4394                        WHERE issue_date IS NOT NULL {$where}
4395                        GROUP BY YEAR(issue_date)
4396                        ORDER BY YEAR(issue_date) DESC";
4397
4398            $issueDate = DB::select($query);
4399
4400            $query = "SELECT
4401                        CONCAT(
4402                            DATE_FORMAT((SELECT MIN(created_at) FROM tbl_quotations WHERE created_at IS NOT NULL {$where}), '%c/%e/'), YEAR(created_at),
4403                            ' - ',
4404                            DATE_FORMAT((SELECT MAX(created_at) FROM tbl_quotations WHERE created_at IS NOT NULL {$where}), '%c/%e/'), YEAR(created_at)
4405                        ) AS date_like,
4406                        YEAR(created_at) 'year'
4407                        FROM tbl_quotations
4408                        WHERE created_at IS NOT NULL {$where}
4409                        GROUP BY YEAR(created_at)
4410                        ORDER BY YEAR(created_at) DESC";
4411
4412            $createdAt = DB::select($query);
4413
4414            $query = "SELECT
4415                        CONCAT(
4416                            DATE_FORMAT((SELECT MIN(acceptance_date) FROM tbl_quotations WHERE acceptance_date IS NOT NULL {$where}), '%c/%e/'), YEAR(acceptance_date),
4417                            ' - ',
4418                            DATE_FORMAT((SELECT MAX(acceptance_date) FROM tbl_quotations WHERE acceptance_date IS NOT NULL {$where}), '%c/%e/'), YEAR(acceptance_date)
4419                        ) AS date_like,
4420                        YEAR(acceptance_date) 'year'
4421                        FROM tbl_quotations
4422                        WHERE acceptance_date IS NOT NULL {$where}
4423                        GROUP BY YEAR(acceptance_date)
4424                        ORDER BY YEAR(acceptance_date) DESC";
4425
4426            $acceptanceDate = DB::select($query);
4427
4428            return response([
4429                'message' => 'OK',
4430                'data' => $issueDate,
4431                'created_at' => $createdAt,
4432                'acceptance_date' => $acceptanceDate
4433            ]);
4434
4435
4436        } catch (\Exception $e) {
4437            /** @disregard P1014 */
4438            $e->exceptionCode = 'GET_YEARS_EXCEPTION'; 
4439            report($e);
4440            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4441        }
4442
4443    }
4444
4445    function human_filesize($bytes, $decimals = 2) {
4446        $size = ['B', 'KB', 'MB'];
4447
4448        $factor = floor((strlen($bytes) - 1) / 3);
4449        return number_format($bytes / pow(1024, $factor), 2, ',', '.') . $size[$factor];
4450    }
4451
4452    function get_files($quoteId){
4453
4454        try {
4455
4456            $quoteId = addslashes($quoteId);
4457
4458            $quoteId = (int)$quoteId;
4459            $query = "
4460            SELECT
4461                file_id,
4462                quotation_id,
4463                quote_id,
4464                original_name,
4465                filename,
4466                uploaded_by,
4467                uploaded_at,
4468                is_internal,
4469                file_size,
4470                file_hash,
4471                mime_type
4472            FROM tbl_files
4473            WHERE quotation_id = ?
4474            AND is_internal IS NULL";
4475
4476            $result = DB::select($query, [$quoteId]);
4477
4478            foreach ($result as $file) {
4479                if($file->file_size > 0) {
4480                    $file->filesize = $this->human_filesize($file->file_size);
4481                } else {            
4482                    $path = "uploads/" . $file->filename;
4483
4484                    if (Storage::disk('s3')->exists($path)) {
4485                        $fileSizeBytes = Storage::disk('s3')->size($path);
4486                    } else {
4487                        $fileSizeBytes = 0;
4488                    }
4489
4490                    $file->filesize = $this->human_filesize($fileSizeBytes);
4491                }
4492
4493                $file->original_name = $file->original_name . " ({$file->filesize})";
4494            }
4495
4496            $query = "
4497            SELECT
4498                file_id,
4499                quotation_id,
4500                quote_id,
4501                original_name,
4502                filename,
4503                uploaded_by,
4504                uploaded_at,
4505                is_internal,
4506                file_size,
4507                file_hash,
4508                mime_type
4509            FROM tbl_files
4510            WHERE quotation_id = ?
4511            AND is_internal = 1";
4512
4513            $internal = DB::select($query, [$quoteId]);
4514
4515            foreach ($internal as $file) {
4516                if($file->file_size > 0) {
4517                    $file->filesize = $this->human_filesize($file->file_size);
4518                } else {
4519                    $path = "uploads/" . $file->filename;
4520
4521                    if (Storage::disk('s3')->exists($path)) {
4522                        $fileSizeBytes = Storage::disk('s3')->size($path);
4523                    } else {
4524                        $fileSizeBytes = 0;
4525                    }
4526
4527                    $file->filesize = $this->human_filesize($fileSizeBytes);
4528                }
4529
4530                $file->original_name = $file->original_name . " ({$file->filesize})";
4531            }
4532
4533            $job = TblOngoingJobs::where('quotation_id', $quoteId)->first();
4534            $order = TblQuotations::where('id', $quoteId)->first();
4535
4536            $emails = explode(",", str_replace(" ", "", $order->email));
4537
4538            $sendGrid = TblSendgridWebhook::where('quotation_id', $quoteId)->where('x_message_id', $order->x_message_id)->first();
4539
4540            $uniqueEvents = array();
4541            $currentEvents = array();
4542            $status = 2;
4543
4544            $xStatus = "processed";
4545
4546            if($sendGrid){
4547                $emailErrors = array('deferred', 'bounce', 'dropped', 'spamreport', 'invalid');
4548                $events = json_decode($sendGrid->json_body, true);
4549                $xMessageId = $sendGrid->x_message_id;
4550                $isDelivered = 0;
4551                $isProcessed = 0;
4552                $isError = 0;
4553
4554                foreach ($emails as $email) {
4555
4556                    $emailEvents = array_filter($events, fn($event) => strtolower($event['email']) === strtolower($email));
4557
4558                    $statuses = array_unique(array_column($emailEvents, 'event'));
4559                    $eventCount = count($statuses);
4560
4561                    if ($eventCount === 1 && in_array('processed', $statuses)) {
4562                        $xStatus = "processed";
4563                    }
4564
4565                    if ($eventCount == 2) {
4566                        if (in_array('processed', $statuses) && in_array('delivered', $statuses)) {
4567                            $xStatus = "delivered";
4568                        }
4569
4570                        foreach ($emailErrors as $e) {
4571                            if (in_array('processed', $statuses) && in_array($e, $statuses)) {
4572                                $xStatus = $e;
4573                            }
4574                        }
4575
4576                    }elseif($eventCount > 2){
4577                        if (in_array('processed', $statuses) && in_array('delivered', $statuses)) {
4578                            $xStatus = "delivered";
4579                        }
4580
4581                        if($xStatus != "delivered"){
4582                            foreach ($emailErrors as $e) {
4583                                if (in_array('processed', $statuses) && in_array($e, $statuses)) {
4584                                    $xStatus = $e;
4585                                }
4586                            }
4587                        }
4588                    }
4589
4590
4591                    if($xStatus == "processed"){
4592                        $isProcessed++;
4593                    }elseif($xStatus == "delivered"){
4594                        $isDelivered++;
4595                    }else{
4596                        $isError++;
4597                    }
4598
4599                    foreach ($emailEvents as $event) {
4600                        $key = strtolower($event['email']) . '|' . $event['event'];
4601                        if (!isset($uniqueEvents[$key])) {
4602                            $uniqueEvents[$key] = $event;
4603                        }
4604                    }
4605                }
4606
4607                if($uniqueEvents){
4608                    foreach (array_values($uniqueEvents) as $d) {
4609                        $d['created_at'] = date('Y-m-d H:i:s', $d['timestamp']);
4610
4611                        if(isset($d['response'])){
4612                            $d['error'] = $d['response'];
4613                        }
4614
4615                        if(isset($d['reason'])){
4616                            $d['error'] = $d['reason'];
4617                        }
4618
4619                        array_push($currentEvents, $d);
4620                    }
4621                }
4622
4623
4624
4625                if(count($emails) == $isDelivered){
4626                    $status = 1;
4627                    $xStatus = "Completed";
4628                }elseif($isProcessed > 0){
4629                    $status = 2;
4630                    $xStatus = "Processing";
4631                }elseif($isError > 0){
4632                    $status = 3;
4633
4634                    if($xStatus == "bounce"){
4635                        $xStatus = "Error - Bounce";
4636                    }else{
4637                        $xStatus = "Error";
4638                    }
4639                }
4640            }
4641
4642            $z = 0;
4643
4644            if($order->x_status != $xStatus){
4645                TblQuotations::where('id', $order->id)->update(
4646                    array(
4647                        'x_status' => $xStatus
4648                    )
4649                );
4650                $z = 1;
4651                Cache::flush();
4652            }
4653
4654            if(empty($currentEvents)){
4655                $status = 0;
4656            }
4657
4658            $followUpLogs = TblFollowUpLogs::where('quotation_id', $quoteId)->orderBy('created_at', 'desc')->get();
4659
4660            $projectTypes = TblProjectTypes::where('company_id', $order->company_id)->get();
4661
4662            $sendgridFollowUpLogs = array();
4663
4664            if($order->y_message_id){
4665                $sendgridFollowUpLogs = TblSendgridWebhook::where('x_message_id', $order->y_message_id)->first();
4666
4667                if($sendgridFollowUpLogs){
4668                    $sendgridFollowUpLogs = json_decode($sendgridFollowUpLogs->json_body, true);
4669                    foreach ($sendgridFollowUpLogs as &$item) {
4670                        $item['created_at'] = date("Y-m-d H:i:s", $item['timestamp']);
4671                    }
4672                }
4673            }
4674
4675            return response([
4676                'message' => 'OK',
4677                'data' => $result,
4678                'followUpLogs' => $followUpLogs,
4679                'sendgridFollowUpLogs' => $sendgridFollowUpLogs,
4680                'internal' => $internal,
4681                'projectTypes' => $projectTypes,
4682                'currentEvents' => array(
4683                    'status' => $status,
4684                    'email' => $currentEvents,
4685                    $uniqueEvents,
4686                    $xStatus
4687                ),
4688                'job' => $job,
4689                'isUpdated' => $z
4690            ]);
4691
4692        } catch (\Exception $e) {
4693            /** @disregard P1014 */
4694            $e->exceptionCode = 'GET_FILES_EXCEPTION'; 
4695            report($e);
4696            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4697        }
4698
4699    }
4700
4701    public function download_file($fileId) {
4702        try {
4703            $fileId = addslashes($fileId);
4704            $file = TblFiles::where('file_id', $fileId)->first();
4705
4706            if (!$file) {
4707                return response()->json([
4708                    'message' => 'KO',
4709                    'error' => 'Archivo no encontrado'
4710                ], 404);
4711            }
4712
4713            if (!is_null($file->file_hash) && !empty($file->file)) {
4714                $fileContent = $file->file;
4715                $mimeType = $file->mime_type ?? 'application/octet-stream';
4716                $filename = $file->original_name ?? $file->filename ?? 'download';
4717
4718                return response($fileContent)
4719                    ->header('Content-Type', $mimeType)
4720                    ->header('Content-Disposition', 'attachment; filename="' . $filename . '"')
4721                    ->header('Content-Length', strlen($fileContent))
4722                    ->header('Cache-Control', 'no-cache, no-store, must-revalidate');
4723
4724            }
4725            else {
4726                $filePath = Storage::disk('s3')->get("uploads/" . $file->filename);
4727                // $filePath = storage_path('app/public/uploads/' . $file->filename);                
4728
4729                if (!Storage::disk('s3')->exists("uploads/" . $file->filename)) {
4730                    return response()->json([
4731                        'message' => 'KO',
4732                        'error' => 'Archivo físico no encontrado: ' . $file->filename
4733                    ], 404);
4734                }
4735
4736                $fileSize = filesize($filePath);
4737                $mimeType = mime_content_type($filePath) ?: 'application/octet-stream';
4738                $filename = $file->original_name ?? $file->filename;
4739
4740                $fileContent = file_get_contents($filePath);
4741
4742                return response($fileContent)
4743                    ->header('Content-Type', $mimeType)
4744                    ->header('Content-Disposition', 'attachment; filename="' . $filename . '"')
4745                    ->header('Content-Length', $fileSize)
4746                    ->header('Cache-Control', 'no-cache, no-store, must-revalidate');
4747            }
4748
4749        } catch (\Exception $e) {
4750            /** @disregard P1014 */
4751            $e->exceptionCode = 'DOWNLOAD_FILE_EXCEPTION'; 
4752            report($e);
4753            \Log::error('Error downloading file: ' . $e->getMessage());
4754            return response()->json([
4755                'message' => 'KO',
4756                'error' => 'Error interno del servidor: ' . $e->getMessage()
4757            ], 500);
4758        }
4759    }
4760
4761    function delete_file($fileId){
4762
4763        try {
4764
4765            $fileId = addslashes($fileId);
4766            $file = TblFiles::where('file_id', $fileId)->first();
4767            $result = TblFiles::where('file_id', $fileId)->first();
4768
4769            if($result){
4770                TblFiles::where('file_id', $fileId)->delete();
4771                $path = storage_path('app/public/uploads/' . $result->filename);
4772                Storage::disk('public')->delete('uploads/' . $result->filename);
4773
4774                if(!env('SENDGRID_STAGING')){
4775                    Storage::disk('s3')->delete('uploads/' . $result->filename);
4776                }
4777            }
4778
4779            $fileCount = TblFiles::where('quotation_id', $file->quotation_id)->count();
4780            $data = array();
4781            if($fileCount > 0){
4782                $data['has_attachment'] = 1;
4783            }else{
4784                $data['has_attachment'] = 0;
4785            }
4786
4787            TblQuotations::where('quote_id', $file->quote_id)->update($data);
4788
4789            return response(['message' => 'OK']);
4790
4791        } catch (\Exception $e) {
4792            /** @disregard P1014 */
4793            $e->exceptionCode = 'DELETE_FILE_EXCEPTION'; 
4794            report($e);
4795            return response(['message' => 'KO', 'error' => $e->getMessage()]);
4796        }
4797    }
4798
4799    function send_email_to_client(Request $request){
4800
4801        try {
4802
4803            $data = $request->all();
4804
4805            // $id = addslashes($data['id']);
4806            $userId = addslashes($data['user_id']);
4807            $companyId = addslashes($data['company_id']);
4808
4809            $isResend = null;
4810
4811            if(isset($data['is_resend'])){
4812                $isResend = 1;
4813                unset($data['is_resend']);
4814            }
4815
4816            // $result = TblQuotations::where('id', $id)->first();
4817
4818            $where = "";
4819            $emailTemplateId = addslashes($data['email_template_id']);
4820            unset($data['email_template_id']);
4821
4822            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
4823            $limit = 21;
4824
4825            if($companyId == 0){
4826                $limit = 21;
4827            }else{
4828                $emailCompany = TblCompanies::where('company_id', $companyId)->first();
4829
4830                if($emailCompany->limit_send != null){
4831                    $limit = $emailCompany->limit_send;
4832                }
4833            }
4834
4835            if(isset($data['ids']) && count($data['ids']) > 0){
4836                $quoteIds = implode(",", $data['ids']);
4837                $where = " a.id IN ({$quoteIds}) AND ";
4838            }
4839
4840            if(isset($data['ids_not_in']) && count($data['ids_not_in']) > 0){
4841                $quoteIds = implode(",", $data['ids_not_in']);
4842                $where = " a.id NOT IN ({$quoteIds}) AND ";
4843            }
4844
4845            $r = new Request([
4846                'filterModel' => $data['filterModel'],
4847                'sortModel' => $data['sortModel'],
4848                'start' => 0,
4849                'end' => 999999999,
4850                'company_id' => $data['company_id'],
4851                'user_id' => $data['user_id'],
4852                'ids' => $data['ids'],
4853                'searchText' => $data['searchText'],
4854                'ids_not_in' => $data['ids_not_in']
4855            ]);
4856
4857            $listQuotations = $this->list_quotations($r);
4858            $d = $listQuotations->original['data'];
4859            $result = array();
4860
4861            for ($i = 0; $i < count($d); $i++) {
4862                if($d[$i]->email != null
4863                    && ($d[$i]->budget_status_id == 11 || $isResend == 1)
4864                ){
4865                    if($i == $limit){
4866                        break;
4867                    }
4868                    array_push($result, $d[$i]);
4869                }
4870            }
4871
4872            if(count($result) == 0){
4873                return response(['message' => 'OK', $d]);
4874            }
4875
4876            $user   = TblUsers::where('id', $userId)->first();
4877            $error  = false;
4878
4879            $availableParameters = [
4880                'quote_id',
4881                'company_id',
4882                'client',
4883                'client_type',
4884                'phone_number',
4885                'email',
4886                'issue_date',
4887                'request_date',
4888                'duration',
4889                'invoice_number',
4890                'type',
4891                'acceptance_date',
4892                'status',
4893                'source',
4894                'amount',
4895                'reason_for_not_following_up',
4896                'last_follow_up_date',
4897                'last_follow_up_comment',
4898                'reason_for_rejection_id',
4899                'reason_for_rejection',
4900                'commercial',
4901                'created_at',
4902                'created_by',
4903                'updated_at',
4904                'updated_by'
4905            ];
4906
4907            $dateParameters = [
4908                'issue_date',
4909                'request_date',
4910                'acceptance_date',
4911                'last_follow_up_date',
4912                'created_at',
4913                'updated_at',
4914            ];
4915
4916            if($this->locale == 'es'){
4917                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
4918            }
4919
4920            if($this->locale == 'es'){
4921                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
4922            }
4923
4924            for ($i = 0; $i < count($result); $i++) {
4925
4926                $body = $emailTemplate->html;
4927                if(isset($data['html'])){
4928                    $body = $data['html'];
4929                }
4930                $subject = $emailTemplate->subject;
4931                $commercialUser = $result[$i]->commercial;
4932
4933                if($result[$i]->email != null){
4934
4935                    if(env('SENDGRID_STAGING')){
4936                        $toEmail = $user->email;
4937                    }else{
4938                        $toEmail = $result[$i]->email;
4939                    }
4940
4941                    preg_match_all('/{{(.*?)}}/', $body, $matches);
4942
4943                    $parameters = $matches[1];
4944
4945                    foreach ($parameters as $parameter) {
4946
4947                        if(in_array($parameter, $dateParameters)){
4948                            if($result[$i]->{$parameter}){
4949                                $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
4950                            }
4951                        }
4952
4953                        if(in_array($parameter, $availableParameters)){
4954                            $body = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $body);
4955                        }
4956                    }
4957
4958                    preg_match_all('/{{(.*?)}}/', $subject, $matches);
4959
4960                    $parameters = $matches[1];
4961
4962                    foreach ($parameters as $parameter) {
4963
4964                        if(in_array($parameter, $dateParameters)){
4965                            if($result[$i]->{$parameter}){
4966                                $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
4967                            }
4968                        }
4969
4970                        if(in_array($parameter, $availableParameters)){
4971                            $subject = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $subject);
4972                        }
4973                    }
4974
4975                    $email = new \SendGrid\Mail\Mail();
4976
4977                    // $imgpath = \File::get('fireservicetitan.png');
4978                    // $base64 = "data:image/png;base64,".base64_encode($imgpath);
4979                    // $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
4980
4981                    // $email->addAttachment(
4982                    //     $imgpath,
4983                    //     "image/png",
4984                    //     "fireservicetitan.png",
4985                    //     "inline",
4986                    //     "fireservicetitan"
4987                    // );
4988
4989                    $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
4990
4991                    foreach ($templateFiles as $item) {
4992                        $f = storage_path('app/public/uploads/' . $item->filename);
4993
4994                        if (file_exists($f)) {
4995                            $imgpath = file_get_contents($f);
4996                            $base64 = "data:image/png;base64," . base64_encode($imgpath);
4997                            $mimeType = mime_content_type($f);
4998
4999                            $email->addAttachment(
5000                                $imgpath,
5001                                $mimeType,
5002                                str_replace(' ', '', $item->original_name),
5003                                "inline",
5004                                str_replace(' ', '', $item->original_name),
5005                            );
5006
5007                            $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
5008                        } else {
5009                            Log::channel('email_failed_log')->error("File not found: " . $f);
5010                        }
5011                    }
5012
5013                    $html = '<!DOCTYPE html>';
5014                    $html .= '<html>';
5015                    $html .= '<head>';
5016                    $html .= '<meta charset="UTF-8">';
5017                    $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
5018                    $html .= '</head>';
5019                    $html .= '<body>';
5020                    $html .= $body;
5021                    $html .= '</body>';
5022                    $html .= '</html>';
5023
5024                    if($toEmail != null){
5025
5026                        $toEmail = explode(",", $toEmail);
5027                        $toEmail = array_map('trim', $toEmail);
5028
5029                        $companyEmail = null;
5030
5031                        $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}'";
5032                        $commercialEmail = DB::select($queryUsers);
5033
5034                        if(count($commercialEmail) > 0){
5035                            $companyEmail = $commercialEmail[0];
5036                        }else{
5037                            if($emailTemplate->from_id != null){
5038                                $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
5039                            }else{
5040                                $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result[$i]->company_id)->first();
5041                            }
5042                        }
5043
5044                        if(!$companyEmail){
5045                            return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
5046                        }
5047
5048                        $ccBcc = TblCcBcc::where('company_id', $result[$i]->company_id)->get();
5049
5050                        $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
5051                        $email->setSubject($subject);
5052
5053                        foreach ($toEmail as $clientEmail) {
5054                            $isValid = $this->isEmailValid($clientEmail);
5055                            if($isValid){
5056                                $email->addTo($clientEmail);
5057                            }
5058                        }
5059
5060                        if(env('SENDGRID_STAGING')){
5061
5062                        }else{
5063                            if(!in_array($user->email, $toEmail)){
5064                                $email->addCc($user->email);
5065                            }
5066
5067                            if(count($ccBcc) > 0){
5068                                foreach ($ccBcc as $data) {
5069                                    if(!in_array($data->email, $toEmail) && $user->email != $data->email){
5070                                        $email->addBcc($data->email);
5071                                    }
5072                                }
5073                            }
5074                        }
5075
5076                        $email->addContent("text/html", $html);
5077
5078                        $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5079
5080                        $files = TblFiles::where('quotation_id', $result[$i]->id)->where('is_internal', null)->get();
5081                        $requestSize = $this->calculateEmailRequestSize($email);
5082
5083                        foreach ($files as $key => $value) {
5084                            $fileContent = null;
5085                            $fileSize = 0;
5086                            $fileName = null;
5087
5088                            if (Storage::disk('s3')->exists("uploads/" . $files[$key]->filename)) {                                
5089                                $fileContent = Storage::disk('s3')->get("uploads/" . $files[$key]->filename);                                
5090                                $fileSize = (int) ceil(strlen($fileContent) / 1048576);                                
5091                                $fileName = $files[$key]->original_name;                                                            
5092                            }
5093                            else if ($files[$key]->file) {
5094                                $fileContent = $files[$key]->file;
5095
5096                                if (is_string($fileContent) && base64_decode($fileContent, true)) {
5097                                    $fileContent = base64_decode($fileContent);
5098                                }
5099
5100                                $fileSize = strlen($fileContent) / 1048576;
5101                                $fileSize = (int) ceil($fileSize);
5102                                $fileName = $files[$key]->original_name ?: $files[$key]->file_name ?: 'file';
5103                            }
5104
5105                            if ($fileContent && $fileSize > 0) {
5106                                if ($requestSize + $fileSize < 25) {
5107                                    $attachment = new \SendGrid\Mail\Attachment();
5108                                    $attachment->setFilename($fileName);
5109                                    $attachment->setDisposition("attachment");
5110
5111                                    $attachment->setContent(base64_encode($fileContent));
5112
5113                                    $email->addAttachment($attachment);
5114                                    $requestSize = $this->calculateEmailRequestSize($email);
5115                                }
5116                            }
5117                        }
5118
5119                        $response = $sendgrid->send($email);
5120                        if ($response->statusCode() == 202) {
5121                            $messageId = null;
5122
5123                            foreach ($response->headers() as $header) {
5124                                if (strpos(strtolower($header), 'x-message-id:') === 0) {
5125                                    $messageId = trim(substr($header, strpos($header, ':') + 1));
5126                                    break;
5127                                }
5128                            }
5129
5130                            $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;
5131                            $result[$i]->last_follow_up_comment = $result[$i]->last_follow_up_comment . "\n" . $comment;
5132
5133                            TblQuotations::where('id', $result[$i]->id)->update(
5134                                array(
5135                                    'last_follow_up_comment' => $result[$i]->last_follow_up_comment,
5136                                    'budget_status_id' => 2,
5137                                    'x_message_id' => $messageId,
5138                                    'x_status' => 'Processing',
5139                                    'updated_by' => $user->name,
5140                                    'updated_at' => date('Y-m-d H:i:s')
5141                                )
5142                            );
5143
5144                            $jsonBody = array();
5145
5146                            foreach ($toEmail as $clientEmail) {
5147                                $isValid = $this->isEmailValid($clientEmail);
5148                                $eventStatus = "processed";
5149                                $eventResponse = "";
5150                                if(!$isValid){
5151                                    $eventStatus = "invalid";
5152                                    $eventResponse = "Invalid email address";
5153                                }
5154
5155                                array_push(
5156                                    $jsonBody,
5157                                    array(
5158                                        'email' =>  $clientEmail,
5159                                        'event' => $eventStatus,
5160                                        'sg_message_id' => $messageId,
5161                                        'smtp-id' => $messageId,
5162                                        'timestamp' => strtotime(date('Y-m-d H:i:s')),
5163                                        'response' => $eventResponse
5164                                    )
5165                                );
5166                            }
5167
5168                            TblSendgridWebhook::create(
5169                                array(
5170                                    'quotation_id' => $result[$i]->id,
5171                                    'type' => 'sendToClient',
5172                                    'json_body' => json_encode($jsonBody),
5173                                    'x_message_id' => $messageId
5174                                )
5175                            );
5176
5177                            Log::channel('email_log')->info("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - EMAIL MANUALLY SENT');
5178                        } else {
5179                            $error = true;
5180                            Log::channel('email_failed_log')->error("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - ' . $response->body());
5181                        }
5182                    }
5183                }
5184            }
5185
5186            $this->update_commercial_numbers($companyId);
5187
5188            Cache::flush();
5189            return response(['message' => 'OK', $result]);
5190
5191        } catch (\Exception $e) {
5192            /** @disregard P1014 */
5193            $e->exceptionCode = 'SEND_EMAIL_TO_CLIENT_EXCEPTION'; 
5194            report($e);
5195            Log::channel('email_failed_log')->error($e->getMessage());
5196            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5197        }
5198
5199    }
5200
5201    function send_email_follow_ups(Request $request, $automaticSendLimit = null){
5202
5203        try {
5204
5205            $data = $request->all();
5206
5207            $startedAt = date('Y-m-d H:i:s');
5208            $toEmail = "";
5209            $userId = addslashes($data['user_id']);
5210            $companyId = addslashes($data['company_id']);
5211            $emailTemplateId = addslashes($data['email_template_id']);
5212            unset($data['email_template_id']);
5213
5214            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
5215            $limit = 0;
5216
5217            $blockedDomains = array();
5218            $workingDays = 10;
5219            $limitReminderEmails = 3;
5220
5221            if($companyId == 0){
5222                $limit = 20;
5223            }else{
5224                $emailCompany = TblCompanies::where('company_id', $companyId)->first();
5225                $workingDays = $emailCompany->last_follow_up_date ?? 10;
5226                $limitReminderEmails = $emailCompany->limit_reminder_emails ?? 3;
5227
5228                if($emailCompany->limit_send != null){
5229                    $limit = $emailCompany->limit_send;
5230                }
5231            }
5232
5233            $r = new Request([
5234                'filterModel' => $data['filterModel'],
5235                'sortModel' => $data['sortModel'],
5236                'start' => 0,
5237                'end' => 999999999,
5238                'company_id' => $data['company_id'],
5239                'user_id' => $data['user_id'],
5240                'ids' => $data['ids'],
5241                'searchText' => $data['searchText'],
5242                'ids_not_in' => $data['ids_not_in'],
5243                'last_follow_up_date' => 1
5244            ]);
5245
5246            $listQuotations = $this->list_quotations($r);
5247            $d = $listQuotations->original['data'];
5248            $result = array();
5249
5250            if($automaticSendLimit != null){
5251                $limit = $automaticSendLimit;
5252            }
5253
5254            $l = 0;
5255            for ($i = 0; $i < count($d); $i++) {
5256                if($d[$i]->email != null
5257                    && $d[$i]->budget_status_id == 2
5258                    && $d[$i]->reason_for_not_following_up_id == null
5259                    && $d[$i]->total_sent < $limitReminderEmails
5260                    && $d[$i]->last_follow_up_date != null
5261                    && $d[$i]->last_follow_up_date < date('Y-m-d H:i:s')
5262                    && $d[$i]->last_follow_up_date > 0
5263                ){
5264                    if($l == $limit){
5265                        break;
5266                    }
5267                    array_push($result, $d[$i]);
5268                    $l++;
5269                }
5270            }
5271
5272            if(count($result) == 0){
5273                return response(['message' => 'OK']);
5274            }
5275
5276            $user   = TblUsers::where('id', $userId)->first();
5277            $error  = false;
5278
5279            $sentBy = $user->name;
5280
5281            $availableParameters = [
5282                'quote_id',
5283                'company_id',
5284                'client',
5285                'client_type',
5286                'phone_number',
5287                'email',
5288                'issue_date',
5289                'request_date',
5290                'duration',
5291                'invoice_number',
5292                'type',
5293                'acceptance_date',
5294                'status',
5295                'source',
5296                'amount',
5297                'reason_for_not_following_up',
5298                'last_follow_up_date',
5299                'last_follow_up_comment',
5300                'reason_for_rejection_id',
5301                'reason_for_rejection',
5302                'commercial',
5303                'created_at',
5304                'created_by',
5305                'updated_at',
5306                'updated_by'
5307            ];
5308
5309            $dateParameters = [
5310                'issue_date',
5311                'request_date',
5312                'acceptance_date',
5313                'last_follow_up_date',
5314                'created_at',
5315                'updated_at',
5316            ];
5317
5318
5319
5320            if($this->locale == 'es'){
5321                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
5322            }
5323
5324            $totalSent = 0;
5325            $totalSentIds = array();
5326            $totalFailedIds = array();
5327            $totalErrorIds = array();
5328            $currentQuotationId = null;
5329
5330            for ($i = 0; $i < count($result); $i++) {$budgetTypeId = $result[$i]->budget_type_id;
5331                $currentQuotationId = $result[$i]->quote_id;
5332                $body = $emailTemplate->html;
5333                if(isset($data['html'])){
5334                    $body = $data['html'];
5335                }
5336                $subject = $emailTemplate->subject;
5337                $commercialUser = $result[$i]->commercial;
5338
5339                $blockedDomains = TblBlockedDomains::where('company_id', $result[$i]->company_id)->pluck('domain')->toArray();
5340
5341                if(env('SENDGRID_STAGING')){
5342                    $toEmail = $user->email;
5343                }else{
5344                    $toEmail = $result[$i]->email;
5345                }
5346
5347                preg_match_all('/{{(.*?)}}/', $body, $matches);
5348
5349                $parameters = $matches[1];
5350
5351                foreach ($parameters as $parameter) {
5352
5353                    if(in_array($parameter, $dateParameters)){
5354                        if($result[$i]->{$parameter}){
5355                            $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
5356                        }
5357                    }
5358
5359                    if(in_array($parameter, $availableParameters)){
5360                        $body = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $body);
5361                    }
5362                }
5363
5364                preg_match_all('/{{(.*?)}}/', $subject, $matches);
5365
5366                $parameters = $matches[1];
5367
5368                foreach ($parameters as $parameter) {
5369
5370                    if(in_array($parameter, $dateParameters)){
5371                        if($result[$i]->{$parameter}){
5372                            $result[$i]->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result[$i]->{$parameter})));
5373                        }
5374                    }
5375
5376                    if(in_array($parameter, $availableParameters)){
5377                        $subject = str_replace('{{' . $parameter . '}}', $result[$i]->{$parameter}, $subject);
5378                    }
5379                }
5380
5381                $email = new \SendGrid\Mail\Mail();
5382
5383                $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
5384
5385                foreach ($templateFiles as $item) {
5386                    $f = storage_path('app/public/uploads/' . $item->filename);
5387
5388                    if (file_exists($f)) {
5389                        $imgpath = file_get_contents($f);
5390                        $base64 = "data:image/png;base64," . base64_encode($imgpath);
5391                        $mimeType = mime_content_type($f);
5392
5393                        $email->addAttachment(
5394                            $imgpath,
5395                            $mimeType,
5396                            str_replace(' ', '', $item->original_name),
5397                            "inline",
5398                            str_replace(' ', '', $item->original_name),
5399                        );
5400
5401                        $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
5402                    } else {
5403                        Log::channel('email_failed_log')->error("File not found: " . $f);
5404                    }
5405                }
5406
5407                $html = '<!DOCTYPE html>';
5408                $html .= '<html>';
5409                $html .= '<head>';
5410                $html .= '<meta charset="UTF-8">';
5411                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
5412                $html .= '</head>';
5413                $html .= '<body>';
5414                $html .= $body;
5415                $html .= '</body>';
5416                $html .= '</html>';
5417
5418                if($automaticSendLimit != null){
5419                    $sentBy = "System";
5420                }
5421
5422                if($toEmail != null){
5423
5424                    $toEmail = explode(",", $toEmail);
5425                    $toEmail = array_map('trim', $toEmail);
5426
5427                    $companyEmail = null;
5428
5429                    $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}'";
5430                    $commercialEmail = DB::select($queryUsers);
5431
5432                    if(count($commercialEmail) > 0){
5433                        $companyEmail = $commercialEmail[0];
5434                    }else{
5435                        if($emailTemplate->from_id != null){
5436                            $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
5437                        }else{
5438                            $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result[$i]->company_id)->first();
5439                        }
5440                    }
5441
5442                    if(!$companyEmail){
5443                        return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
5444                    }
5445
5446                    $ccBcc = TblCcBcc::where('company_id', $result[$i]->company_id)->get();
5447
5448                    $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
5449                    $email->setSubject($subject);
5450
5451                    $s = 0;
5452                    $addTo = array();
5453                    foreach ($toEmail as $clientEmail) {
5454                        $isValid = $this->isEmailValid($clientEmail);
5455                        if($isValid){
5456                            $domain = substr($clientEmail, strpos($clientEmail, '@') + 1);
5457
5458                            if(!in_array($domain, $blockedDomains)){
5459                                $email->addTo($clientEmail);
5460                                array_push($addTo, $clientEmail);
5461                                $s++;
5462                            }
5463                        }else{
5464                            TblFollowUpLogs::create(
5465                                array(
5466                                    'quotation_id' => $result[$i]->id,
5467                                    'email' => $clientEmail,
5468                                    'sent_by' => $sentBy,
5469                                    'status' => 'Invalid email'
5470                                )
5471                            );
5472                        }
5473                    }
5474
5475                    if($s == 0){
5476                        array_push($totalFailedIds, $result[$i]->id);
5477                        Log::channel('email_failed_log')->error($s. 'ID:' . $result[$i]->id . ' - ' . json_encode($toEmail));
5478                        continue;
5479                    }
5480
5481                    if(env('SENDGRID_STAGING')){
5482
5483                    }else{
5484                        if(count($ccBcc) > 0){
5485                            foreach ($ccBcc as $data) {
5486                                if(!in_array($data->email, $toEmail)){
5487                                    $email->addBcc($data->email);
5488                                }
5489                            }
5490                        }
5491                    }
5492
5493                    $email->addContent("text/html", $html);
5494
5495                    $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5496
5497                    $files = TblFiles::where('quotation_id', $result[$i]->id)->where('is_internal', null)->get();
5498                    $requestSize = $this->calculateEmailRequestSize($email);
5499
5500                    foreach ($files as $key => $value) {
5501                        if ($files[$key]->filename && Storage::disk('s3')->exists("uploads/" . $files[$key]->filename)) {
5502                                                        
5503                            $fileContent = Storage::disk('s3')->get("uploads/" . $files[$key]->filename);
5504                            $fileSize = strlen($fileContent) / 1048576;
5505                            $fileSize = (int) ceil($fileSize);
5506
5507                            $originalName = $files[$key]->original_name ?: basename($files[$key]->filename);
5508                        }
5509                        else if ($files[$key]->file) {
5510                            $fileContent = $files[$key]->file;
5511
5512                            if (is_string($fileContent) && base64_decode($fileContent, true)) {
5513                                $fileContent = base64_decode($fileContent);
5514                            }
5515
5516                            $fileSize = strlen($fileContent) / 1048576;
5517                            $fileSize = (int) ceil($fileSize);
5518
5519                            $originalName = $files[$key]->original_name ?: ($files[$key]->file_name ?: 'file');
5520                        }
5521                        else {
5522                            continue;
5523                        }
5524
5525                        if($fileSize > 0){
5526                            if($requestSize + $fileSize < 25){
5527                                $attachment = new \SendGrid\Mail\Attachment();
5528                                $attachment->setFilename($originalName);
5529                                $attachment->setDisposition("attachment");
5530
5531                                $attachment->setContent(base64_encode($fileContent));
5532
5533                                if ($files[$key]->mime_type) {
5534                                    $attachment->setType($files[$key]->mime_type);
5535                                }
5536
5537                                $email->addAttachment($attachment);
5538                                $requestSize = $this->calculateEmailRequestSize($email);
5539                            } else {
5540                                Log::warning("File omitted due to size limit: " . $originalName);
5541                            }
5542                        }
5543                    }
5544
5545                    $response = $sendgrid->send($email);
5546                    if ($response->statusCode() == 202) {
5547
5548                        $messageId = null;
5549
5550                        foreach ($response->headers() as $header) {
5551                            if (strpos(strtolower($header), 'x-message-id:') === 0) {
5552                                $messageId = trim(substr($header, strpos($header, ':') + 1));
5553                                break;
5554                            }
5555                        }
5556
5557                        $lastFollowUp = TblLastFollowUpDate::where('company_id', $companyId)->where('budget_type_id', $budgetTypeId)->first();
5558                        $workingDaysN = $workingDays;
5559                        if($lastFollowUp != null){
5560                            if($lastFollowUp->last_follow_up_date){
5561                                $workingDaysN = $lastFollowUp->last_follow_up_date;
5562                            }
5563                        }
5564
5565                        $comment = "Email automático enviado el " . date('Y-m-d H:i:s') . " por usuario " . $sentBy;
5566                        $result[$i]->last_follow_up_comment = $result[$i]->last_follow_up_comment . "\n" . $comment;
5567                        $date = strtotime("{$workingDaysN} weekdays");
5568                        $result[$i]->last_follow_up_date = date('Y-m-d H:i:s', $date);
5569                        $totalSentQ = $result[$i]->total_sent + 1;
5570
5571                        array_push($totalSentIds, $result[$i]->id);
5572
5573                        foreach ($addTo as $addToEmail) {
5574                            TblFollowUpLogs::create(
5575                                array(
5576                                    'quotation_id' => $result[$i]->id,
5577                                    'email' => $addToEmail,
5578                                    'sent_by' => $sentBy,
5579                                    'status' => 'OK'
5580                                )
5581                            );
5582                        }
5583
5584                        if($totalSentQ >= $limitReminderEmails){
5585                            $result[$i]->reason_for_not_following_up_id = 3;
5586                            $result[$i]->last_follow_up_date = null;
5587                        }
5588
5589                        TblQuotations::where('id', $result[$i]->id)->update(
5590                            array(
5591                                'last_follow_up_comment' => $result[$i]->last_follow_up_comment,
5592                                'last_follow_up_date' => $result[$i]->last_follow_up_date,
5593                                'total_sent' => $result[$i]->total_sent + 1,
5594                                'y_message_id' => $messageId,
5595                                'y_status' => 'Processing',
5596                                'reason_for_not_following_up_id' => $result[$i]->reason_for_not_following_up_id,
5597                                'updated_by' => $sentBy,
5598                                'updated_at' => date('Y-m-d H:i:s')
5599                            )
5600                        );
5601
5602                        $jsonBody = array();
5603
5604                        foreach ($toEmail as $clientEmail) {
5605                            $isValid = $this->isEmailValid($clientEmail);
5606                            $eventStatus = "processed";
5607                            $eventResponse = "";
5608                            if(!$isValid){
5609                                $eventStatus = "invalid";
5610                                $eventResponse = "Invalid email address";
5611                            }
5612
5613                            array_push(
5614                                $jsonBody,
5615                                array(
5616                                    'email' =>  $clientEmail,
5617                                    'event' => $eventStatus,
5618                                    'sg_message_id' => $messageId,
5619                                    'smtp-id' => $messageId,
5620                                    'timestamp' => strtotime(date('Y-m-d H:i:s')),
5621                                    'response' => $eventResponse
5622                                )
5623                            );
5624                        }
5625
5626                        TblSendgridWebhook::create(
5627                            array(
5628                                'quotation_id' => $result[$i]->id,
5629                                'type' => 'followUps',
5630                                'json_body' => json_encode($jsonBody),
5631                                'x_message_id' => $messageId
5632                            )
5633                        );
5634
5635                        Log::channel('email_log')->info("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - EMAIL SENT');
5636                        $totalSent++;
5637                        $workingDays = 10;
5638                    } else {
5639                        $error = true;
5640                        array_push($totalErrorIds, $result[$i]->id);
5641                        Log::channel('email_failed_log')->error("[RS-{$requestSize}] ID:" . $result[$i]->id . ' - ' . $response->body());
5642
5643                        foreach ($addTo as $addToEmail) {
5644                            TblFollowUpLogs::create(
5645                                array(
5646                                    'quotation_id' => $result[$i]->id,
5647                                    'email' => $addToEmail,
5648                                    'sent_by' => $sentBy,
5649                                    'status' => $response->body()
5650                                )
5651                            );
5652                        }
5653                    }
5654
5655                    $body = "";
5656                    $subject = "";
5657                }
5658            }
5659            Cache::flush();
5660
5661            Log::channel('send_email_follow_ups')->info(
5662                json_encode(
5663                    array(
5664                        "success" => $totalSentIds,
5665                        "failed" => $totalFailedIds,
5666                        "error" => $totalErrorIds
5667                    )
5668                )
5669            );
5670
5671            $this->update_commercial_numbers($companyId);
5672
5673            if($error){
5674                return response(['message' => 'KO']);
5675            }else{
5676
5677                if($automaticSendLimit != null){
5678                    TblOrdersUpdateLogs::create(
5679                        array(
5680                            'company_id' => $companyId,
5681                            'to_process' => 'Orders',
5682                            'status' => 'success',
5683                            'follow_ups_affected_rows' => $totalSent,
5684                            'processed_by' => $sentBy,
5685                            'started_at' => $startedAt,
5686                            'ended_at' => date('Y-m-d H:i:s')
5687                        )
5688                    );
5689                }
5690
5691                return response(['message' => 'OK', 'data' => $totalSent . ' ' . __('language.total_follow_up_sent')]);
5692            }
5693
5694        } catch (\Throwable $e) {
5695            /** @disregard P1014 */
5696            $e->exceptionCode = 'SEND_EMAIL_FOLLOW_UPS_EXCEPTION'; 
5697            report($e);
5698            Log::channel('email_failed_log')->error($e->getMessage());
5699            return response(['message' => 'KO', 'error' => $e->getMessage(), 'quotation_id' => $currentQuotationId]);
5700        }
5701    }
5702
5703    function create_sender_identity(Request $request){
5704
5705        try {
5706
5707            $data = $request->all();
5708            $sData = $data;
5709            $companyId = $data['company_id'];
5710            $createdBy = $data['created_by'];
5711            unset($data['company_id']);
5712            unset($data['created_by']);
5713
5714            $sender = TblCompanyEmails::where('from_email', $data['from_email'])->where('verified', 1)->count();
5715
5716            if($sender > 0){
5717                TblCompanyEmails::create($sData);
5718                return response(['message' => 'OK', 'data' => $data, 'is_verified' => 'yes']);
5719            }
5720
5721            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5722            $data['reply_to'] = $data['from_email'];
5723            $data['reply_to_name'] = $data['from_name'];
5724            $requestBody = $data;
5725            $error  = false;
5726
5727            $response = $sendgrid->client->verified_senders()->post($requestBody);
5728
5729            if ($response->statusCode() == 201) {
5730                $x = json_decode($response->body());
5731
5732                $data['company_id'] = $companyId;
5733                $data['created_by'] = $createdBy;
5734                $data['response_id'] = $x->id;
5735                TblCompanyEmails::create($data);
5736                Log::channel('email_log')->info('EMAIL: ' . $data['from_email'] . ' - VERIFICATION SENT');
5737            } else {
5738                $error = true;
5739                Log::channel('email_log')->error('REQUEST BODY: - ' . $response->body());
5740            }
5741
5742            $response = json_decode($response->body());
5743
5744            if($error){
5745                if($response->errors[0]->message == "already exists" && $response->errors[0]->field == "from_email"){
5746                    TblCompanyEmails::create($sData);
5747                    return response(['message' => 'OK', 'data' => $data, 'is_verified' => 'yes']);
5748                }
5749
5750                $errMessage = $response->errors[0]->field . ': ' . $response->errors[0]->message;
5751                return response(['message' => 'KO', 'error' => $errMessage]);
5752            }else{
5753                return response(['message' => 'OK', 'data' => $response, 'is_verified' => 'no']);
5754            }
5755
5756        } catch (\Exception $e) {
5757            /** @disregard P1014 */
5758            $e->exceptionCode = 'CREATE_SENDER_IDENTITY_EXCEPTION'; 
5759            report($e);
5760            Log::channel('email_log')->error('EMAIL:' . $data['from_email'] . ' - ' . $e->getMessage());
5761            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5762        }
5763    }
5764
5765    function get_sender_identity($companyId){
5766
5767        try {
5768
5769            $companyId = addslashes($companyId);
5770
5771            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5772
5773            $response = $sendgrid->client->verified_senders()->get();
5774
5775            if ($response->statusCode() == 200) {
5776                $x = json_decode($response->body())->results;
5777
5778                foreach ($x as $item) {
5779                    TblCompanyEmails::where('from_email', $item->from_email)->update(array(
5780                        'verified' => $item->verified,
5781                        'reply_to' => $item->reply_to,
5782                        'response_id' => $item->id
5783                    ));
5784                }
5785            }
5786
5787            $companyEmails = TblCompanyEmails::where('company_id', $companyId)->get();
5788
5789            return response(['message' => 'OK', 'data' => $companyEmails]);
5790
5791        } catch (\Exception $e) {
5792            /** @disregard P1014 */
5793            $e->exceptionCode = 'GET_SENDER_IDENTITY_EXCEPTION'; 
5794            report($e);
5795            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5796        }
5797    }
5798
5799    function get_all_sender_identity($companyId){
5800
5801        try {
5802
5803            $companyId = addslashes($companyId);
5804
5805            $query = "SELECT
5806                        id,
5807                        response_id,
5808                        nickname,
5809                        CONCAT(nickname, ' - ', from_email) from_email,
5810                        from_name,
5811                        reply_to,
5812                        reply_to_name,
5813                        address,
5814                        address2,
5815                        state,
5816                        city,
5817                        country,
5818                        zip,
5819                        verified,
5820                        locked,
5821                        is_active,
5822                        created_by,
5823                        created_at,
5824                        updated_by,
5825                        updated_at
5826                    FROM
5827                        tbl_company_emails
5828                    WHERE
5829                        company_id != {$companyId}
5830                        AND from_email NOT IN (
5831                        SELECT
5832                            from_email
5833                        FROM
5834                            tbl_company_emails
5835                        WHERE
5836                            company_id = {$companyId}
5837                        )
5838                    ";
5839
5840            $companyEmails = DB::select($query);
5841
5842            return response(['message' => 'OK', 'data' => $companyEmails]);
5843
5844        } catch (\Exception $e) {
5845            /** @disregard P1014 */
5846            $e->exceptionCode = 'GET_ALL_SENDER_IDENTITY_EXCEPTION'; 
5847            report($e);
5848            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5849        }
5850    }
5851
5852    function delete_sender_identity(Request $request){
5853
5854        try {
5855
5856            $data = $request->all();
5857            $responseId = addslashes($data['response_id']);
5858            $id = addslashes($data['id']);
5859
5860            $sender = TblCompanyEmails::where('response_id', $responseId)->count();
5861
5862            if($sender > 1){
5863                TblCompanyEmails::where('id', $id)->delete();
5864            }else{
5865                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
5866
5867                $response = $sendgrid->client->verified_senders()->_($responseId)->delete();
5868
5869                if ($response->statusCode() == 204) {
5870                    TblCompanyEmails::where('response_id', $responseId)->delete();
5871                }
5872            }
5873
5874
5875            return response(['message' => 'OK']);
5876
5877        } catch (\Exception $e) {
5878            /** @disregard P1014 */
5879            $e->exceptionCode = 'DELETE_SENDER_IDENTITY_EXCEPTION'; 
5880            report($e);
5881            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5882        }
5883    }
5884
5885    function create_template(Request $request){
5886
5887        try {
5888
5889            $data = $request->all();
5890
5891            $files = $request->file('files');
5892            unset($data['files']);
5893
5894            if($files){
5895                $totalFileCount = count($files);
5896                if($totalFileCount > 2){
5897                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
5898                }
5899            }
5900
5901            $result = TblEmailConfiguration::create($data);
5902            $id = $result->id;
5903
5904            $directory = 'public/uploads';
5905            $origFilename = 'fireservicetitan.png';
5906            $file = 'public/uploads/fireservicetitan.png';
5907
5908            $sourcePath = public_path($origFilename);
5909            $destinationPath = 'public/uploads/' . $origFilename;
5910
5911            $filename = $id . '-EI' . time() . '-' . $origFilename;
5912
5913            Storage::putFileAs($directory, new \Illuminate\Http\File($sourcePath), $filename);
5914            Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5915
5916            TblEmailFiles::create(
5917                array(
5918                    'email_template_id' => $id,
5919                    'original_name' => $origFilename,
5920                    'filename' => $filename,
5921                    'uploaded_by' => $data['created_by']
5922                )
5923            );
5924
5925            if($files){
5926
5927                $uploadedFiles = [];
5928                $i = 0;
5929
5930                $combinedFilesSize = 0;
5931
5932                foreach ($files as $file) {
5933                    $i++;
5934
5935                    $origFilename = str_replace(" ", "", $file->getClientOriginalName());
5936
5937                    $filename = $id . '-EI' . time() . '-' . $origFilename;
5938
5939                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
5940
5941                    if($combinedFilesSize > 25000000){
5942                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
5943                    }
5944
5945                    Storage::putFileAs($directory, $file, $filename);
5946                    Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
5947
5948                    if(in_array($origFilename, $uploadedFiles)){
5949                        $origFilename = $origFilename . $i;
5950                    }
5951
5952                    TblEmailFiles::create(
5953                        array(
5954                            'email_template_id' => $id,
5955                            'original_name' => $origFilename,
5956                            'filename' => $filename,
5957                            'uploaded_by' => $data['created_by']
5958                        )
5959                    );
5960
5961                    $uploadedFiles[] = $file->getClientOriginalName();
5962                }
5963            }
5964
5965            return response(['message' => 'OK']);
5966
5967        } catch (\Exception $e) {
5968            /** @disregard P1014 */
5969            $e->exceptionCode = 'CREATE_TEMPLATE_EXCEPTION'; 
5970            report($e);
5971            return response(['message' => 'KO', 'error' => $e->getMessage()]);
5972        }
5973    }
5974
5975    function get_email_files($emailTemplateId){
5976
5977        try {
5978
5979            $emailTemplateId = addslashes($emailTemplateId);
5980
5981            $result = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
5982
5983            foreach ($result as $key => $value) {
5984                $path = storage_path('app/public/uploads/' . $result[$key]->filename);
5985
5986                if (File::exists($path)) {
5987                    $fileSizeBytes = File::size($path);
5988                    $result[$key]->filesize = $this->human_filesize($fileSizeBytes);
5989                    $result[$key]->original_name = $result[$key]->original_name . " ({$result[$key]->filesize})";
5990                    $result[$key]->img = "data:image/png;base64,".base64_encode(file_get_contents($path));
5991                }
5992            }
5993
5994            return response(['message' => 'OK', 'data' => $result]);
5995
5996        } catch (\Exception $e) {
5997            /** @disregard P1014 */
5998            $e->exceptionCode = 'GET_EMAIL_FILES_EXCEPTION'; 
5999            report($e);
6000            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6001        }
6002    }
6003
6004    function download_email_template_file($fileId){
6005
6006        try {
6007
6008            $fileId = addslashes($fileId);
6009
6010            $result = TblEmailFiles::where('file_id', $fileId)->first();
6011
6012            if($result){
6013                $path = storage_path('app/public/uploads/' . $result->filename);
6014
6015                if (!Storage::disk('public')->exists('uploads/' . $result->filename)) {
6016                    return response(['message' => 'KO']);
6017                }
6018
6019                return response()->download($path);
6020            }
6021
6022            return response(['message' => 'KO']);
6023
6024        } catch (\Exception $e) {
6025            /** @disregard P1014 */
6026            $e->exceptionCode = 'DOWNLOAD_EMAIL_TEMPLATE_FILE_EXCEPTION'; 
6027            report($e);
6028            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6029        }
6030
6031    }
6032
6033    function delete_email_template_file($fileId){
6034
6035        try {
6036
6037            $fileId = addslashes($fileId);
6038            $file = TblEmailFiles::where('file_id', $fileId)->first();
6039            $result = TblEmailFiles::where('file_id', $fileId)->first();
6040
6041            if($result){
6042                TblEmailFiles::where('file_id', $fileId)->delete();
6043                $path = storage_path('app/public/uploads/' . $result->filename);
6044                Storage::disk('public')->delete('uploads/' . $result->filename);
6045            }
6046
6047            return response(['message' => 'OK']);
6048
6049        } catch (\Exception $e) {
6050            /** @disregard P1014 */
6051            $e->exceptionCode = 'DELETE_EMAIL_TEMPLATE_FILE_EXCEPTION'; 
6052            report($e);
6053            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6054        }
6055    }
6056
6057    function update_email_template_order(Request $request, $id){
6058
6059        try {
6060
6061            $id = addslashes($id);
6062            $data = $request->all();
6063
6064            foreach ($data as $item) {
6065                TblEmailFiles::where('file_id', $item['file_id'])->update(array('order' => $item['order']));
6066            }
6067
6068        } catch (\Exception $e) {
6069            /** @disregard P1014 */
6070            $e->exceptionCode = 'UPDATE_EMAIL_TEMPLATE_ORDER_EXCEPTION'; 
6071            report($e);
6072            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6073        }
6074
6075    }
6076
6077
6078    function update_email_template(Request $request, $id){
6079
6080        try {
6081
6082            $data = $request->all();
6083
6084            $id = addslashes($id);
6085
6086            $files = $request->file('files');
6087            unset($data['files']);
6088
6089            $fileCount = TblEmailFiles::where('email_template_id', $id)->count();
6090
6091            if($files){
6092                $totalFileCount = $fileCount + count($files);
6093                if($totalFileCount > 3){
6094                    return response(['message' => 'KO', 'error' => __('language.file_count_exceeded')]);
6095                }
6096            }
6097
6098            if(isset($data['cron_default'])){
6099                TblEmailConfiguration::where('company_id', $data['company_id'])->where('cron_default', 1)->update(array('cron_default' => 0));
6100            }
6101
6102            $data['updated_at'] = date('Y-m-d H:i:s');
6103            TblEmailConfiguration::where('id', $id)->update($data);
6104
6105            if($files){
6106
6107                $directory = 'public/uploads';
6108                $uploadedFiles = [];
6109                $i = 0;
6110
6111                $combinedFilesSize = 0;
6112                foreach ($files as $file) {
6113                    $i++;
6114                    $origFilename = str_replace(" ", "", $file->getClientOriginalName());
6115                    $filename = $id . '-EI' . time() . '-' . $origFilename;
6116
6117                    $combinedFilesSize = $combinedFilesSize + $file->getSize();
6118
6119                    if($combinedFilesSize > 25000000){
6120                        return response(['message' => 'KO', 'error' => __('language.file_size_exceeded')]);
6121                    }
6122
6123                    Storage::putFileAs($directory, $file, $filename);
6124                    Storage::disk('google')->put($filename, file_get_contents(storage_path() .'/app/public/uploads/'. $filename));
6125
6126                    if(in_array($origFilename, $uploadedFiles)){
6127                        $origFilename = $origFilename . $i;
6128                    }
6129
6130                    TblEmailFiles::create(
6131                        array(
6132                            'email_template_id' => $id,
6133                            'original_name' => $origFilename,
6134                            'filename' => $filename,
6135                            'uploaded_by' => $data['updated_by']
6136                        )
6137                    );
6138
6139                    $uploadedFiles[] = $file->getClientOriginalName();
6140                }
6141            }
6142
6143            return response(['message' => 'OK']);
6144
6145        } catch (\Exception $e) {
6146            /** @disregard P1014 */
6147            $e->exceptionCode = 'UPDATE_EMAIL_TEMPLATE_EXCEPTION'; 
6148            report($e);
6149            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6150        }
6151
6152    }
6153
6154    function delete_template($id){
6155
6156        try {
6157
6158            $id = addslashes($id);
6159
6160            TblEmailConfiguration::where('id', $id)->delete();
6161
6162            return response(['message' => 'OK']);
6163
6164        } catch (\Exception $e) {
6165            /** @disregard P1014 */
6166            $e->exceptionCode = 'DELETE_TEMPLATE_EXCEPTION'; 
6167            report($e);
6168            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6169        }
6170
6171    }
6172
6173    function get_email_template($companyId){
6174
6175        try {
6176
6177            $companyId = addslashes($companyId);
6178
6179            $where = "";
6180            if($companyId != 0){
6181                $where = " a.company_id = {$companyId} ";
6182            }else{
6183                $where = " a.company_id IN ({$this->companyId}";
6184            }
6185
6186            $query = "SELECT
6187                        a.id,
6188                        a.from_id,
6189                        CASE
6190                            WHEN a.type = 'followUps' THEN 'Follow-ups'
6191                            WHEN a.type = 'sendToClient' THEN 'Send to client'
6192                        END types,
6193                        (SELECT from_email FROM tbl_company_emails WHERE id = a.from_id) from_email,
6194                        CASE WHEN {$companyId} = 0 THEN CONCAT(b.name, ' - ', a.name) ELSE a.name END `name`,
6195                        a.subject,
6196                        a.html,
6197                        a.is_active,
6198                        a.type,
6199                        a.created_by,
6200                        a.created_at,
6201                        a.updated_by,
6202                        a.updated_at,
6203                        a.cron_default
6204                    FROM tbl_email_configuration a
6205                    LEFT JOIN tbl_companies b
6206                        ON b.company_id = a.company_id
6207                    WHERE {$where}
6208                    ORDER BY a.id DESC";
6209
6210            $result = DB::select($query);
6211
6212            return response(['message' => 'OK', 'data' => $result]);
6213
6214        } catch (\Exception $e) {
6215            /** @disregard P1014 */
6216            $e->exceptionCode = 'GET_EMAIL_TEMPLATE_EXCEPTION'; 
6217            report($e);
6218            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6219        }
6220
6221    }
6222
6223    function update_sender_identity(Request $request, $responseId){
6224
6225        try {
6226
6227            $data = $request->all();
6228            $companyId = $data['company_id'];
6229            $updatedBy = $data['updated_by'];
6230            $active = $data['is_active'];
6231            $id = addslashes($data['id']);
6232            unset($data['id']);
6233            unset($data['company_id']);
6234            unset($data['updated_by']);
6235            unset($data['is_active']);
6236
6237            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
6238            $data['reply_to'] = $data['from_email'];
6239            $data['reply_to_name'] = $data['from_name'];
6240            $requestBody = $data;
6241            $error  = false;
6242
6243            $response = $sendgrid->client->verified_senders()->_($responseId)->patch($requestBody);
6244
6245            if ($response->statusCode() == 200) {
6246                $x = json_decode($response->body());
6247
6248                $data['updated_by'] = $updatedBy;
6249                $data['updated_at'] = date('Y-m-d H:i:s');
6250                $data['is_active'] = $active;
6251
6252                TblCompanyEmails::where('company_id', $companyId)->update(array('is_active' => 0));
6253                TblCompanyEmails::where('id', $id)->update($data);
6254
6255                Log::channel('email_log')->info('EMAIL: ' . $data['from_email'] . ' - UPDATED');
6256            } else {
6257                $error = true;
6258                Log::channel('email_log')->error('REQUEST BODY: - ' . $response->body());
6259            }
6260
6261            $response = json_decode($response->body());
6262
6263            if($error){
6264                $errMessage = @$response->errors[0]->field . ': ' . @$response->errors[0]->message;
6265                return response(['message' => 'KO', 'error' => $errMessage]);
6266            }else{
6267                return response(['message' => 'OK', 'data' => $response]);
6268            }
6269
6270        } catch (\Exception $e) {
6271            /** @disregard P1014 */
6272            $e->exceptionCode = 'UPDATE_SENDER_IDENTITY_EXCEPTION'; 
6273            report($e);
6274            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6275        }
6276
6277    }
6278
6279    function resend_verification($id){
6280
6281        try {
6282
6283            $id = addslashes($id);
6284
6285            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
6286
6287            $response = $sendgrid->client->verified_senders()->resend()->_($id)->post();
6288
6289            if ($response->statusCode() == 204) {
6290                return response(['message' => 'OK']);
6291            }else{
6292                $response = json_decode($response->body());
6293                $errMessage = $response->errors[0]->error_id . ': ' . $response->errors[0]->message;
6294                return response(['message' => 'KO', 'error' => $errMessage]);
6295            }
6296
6297        } catch (\Exception $e) {
6298            /** @disregard P1014 */
6299            $e->exceptionCode = 'RESEND_VERIFICATION_EXCEPTION'; 
6300            report($e);
6301            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6302        }
6303    }
6304
6305    function list_quotation_analytics_by_performance(Request $request){
6306
6307        try {
6308
6309            $data = $request->all();
6310            $companyId = addslashes($data['company_id']);
6311            $where  = "";
6312
6313            if($companyId != 0){
6314                $where .= " AND company_id = {$companyId} AND for_add = 0 ";
6315            }else{
6316                $where .= " AND company_id IN ({$this->companyId}) AND for_add = 0 ";
6317            }
6318
6319            if(isset($data['budget_status']) && $data['budget_status'] != null){
6320                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
6321            }
6322
6323            $latestYear = TblQuotations::max(DB::raw('YEAR(issue_date)'));
6324            $md = date('m-d');
6325
6326            $query = "SELECT
6327                        q.years,
6328                        q.totalIssue,
6329                        (q.total_acceptance_percentage - q.totalAcceptancePercentage) / q.totalAcceptancePercentage * 100 totalAcceptancePercentage,
6330                        q.totalAccept
6331                    FROM
6332                        (
6333                        SELECT
6334                            YEAR(a.issue_date) years,
6335                            (b.total_issued - COUNT(a.issue_date)) / COUNT(a.issue_date) * 100 totalIssue,
6336                            COUNT(
6337                                CASE WHEN a.acceptance_date IS NOT NULL
6338                                AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6339                                AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6340                                AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6341                                AND a.budget_status_id = 3 THEN 1 END
6342                            ) / COUNT(a.issue_date) * 100 totalAcceptancePercentage,
6343                            b.total_acceptance_percentage,
6344                            (b.total_acceptance -
6345                                COUNT(
6346                                    CASE WHEN a.acceptance_date IS NOT NULL
6347                                    AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6348                                    AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6349                                    AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6350                                    AND a.budget_status_id = 3 THEN 1 END)
6351                                    ) / COUNT(
6352                                            CASE WHEN a.acceptance_date IS NOT NULL
6353                                            AND DATE_FORMAT(a.acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.acceptance_date), '-01-01')
6354                                            AND CONCAT(YEAR(a.acceptance_date), '-{$md}')
6355                                            AND YEAR(a.acceptance_date) = YEAR(a.issue_date)
6356                                            AND a.budget_status_id = 3 THEN 1 END
6357                            ) * 100 totalAccept
6358                        FROM
6359                            tbl_quotations a
6360                            JOIN (
6361                            SELECT
6362                                YEAR(issue_date) current_year,
6363                                COUNT(issue_date) total_issued,
6364                                COUNT(
6365                                    CASE WHEN acceptance_date IS NOT NULL
6366                                    AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6367                                    AND CONCAT(YEAR(acceptance_date), '-{$md}')
6368                                    AND YEAR(acceptance_date) = YEAR(issue_date)
6369                                    AND budget_status_id = 3 THEN 1 END
6370                                ) total_acceptance,
6371                                COUNT(
6372                                    CASE WHEN acceptance_date IS NOT NULL
6373                                    AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6374                                    AND CONCAT(YEAR(acceptance_date), '-{$md}')
6375                                    AND YEAR(acceptance_date) = YEAR(issue_date)
6376                                    AND budget_status_id = 3 THEN 1 END
6377                                ) / COUNT(issue_date) * 100 total_acceptance_percentage
6378                            FROM
6379                                tbl_quotations
6380                            WHERE
6381                                issue_date IS NOT NULL
6382                                AND YEAR(issue_date) = {$latestYear}
6383                                AND DATE_FORMAT(issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(issue_date), '-01-01')
6384                                AND CONCAT(YEAR(issue_date), '-{$md}')
6385                                {$where}
6386                            GROUP by
6387                                1
6388                            ) b
6389                        WHERE
6390                            a.issue_date IS NOT NULL
6391                            AND a.budget_type_id != 7
6392                            AND a.budget_type_id IS NOT NULL
6393                            AND {$latestYear} > YEAR(a.issue_date)
6394                            AND DATE_FORMAT(a.issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(a.issue_date), '-01-01')
6395                            AND CONCAT(YEAR(a.issue_date), '-{$md}')
6396                        GROUP BY
6397                            1
6398                        ORDER BY
6399                            YEAR(issue_date) DESC
6400                        ) q
6401                    ";
6402
6403            $resultYtd = DB::select($query);
6404
6405            $query = "SELECT
6406                        YEAR(issue_date) years,
6407                        COUNT(issue_date) totalIssue,
6408                        COUNT(
6409                            CASE WHEN acceptance_date IS NOT NULL
6410                            AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6411                            AND CONCAT(YEAR(acceptance_date), '-{$md}')
6412                            AND YEAR(acceptance_date) = YEAR(issue_date)
6413                            AND budget_status_id = 3 THEN 1 END
6414                        ) totalAccept,
6415                        COUNT(
6416                            CASE WHEN acceptance_date IS NOT NULL
6417                            AND DATE_FORMAT(acceptance_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(acceptance_date), '-01-01')
6418                            AND CONCAT(YEAR(acceptance_date), '-{$md}')
6419                            AND YEAR(acceptance_date) = YEAR(issue_date)
6420                            AND budget_status_id = 3 THEN 1 END
6421                        ) / COUNT(issue_date) * 100 totalAcceptancePercentage
6422                    FROM
6423                        tbl_quotations
6424                    WHERE
6425                        issue_date IS NOT NULL
6426                        AND budget_type_id != 7
6427                        AND budget_type_id IS NOT NULL
6428                        AND DATE_FORMAT(issue_date, '%Y-%m-%d') BETWEEN CONCAT(YEAR(issue_date), '-01-01')
6429                        AND CONCAT(YEAR(issue_date), '-{$md}')
6430                        {$where}
6431                    GROUP BY
6432                        1
6433                    ORDER BY
6434                        YEAR(issue_date) DESC
6435                    ";
6436
6437            $resultYears = DB::select($query);
6438
6439            return response(['message' => 'OK', 'ytdData' => $resultYtd, 'yearsData' => $resultYears]);
6440
6441        } catch (\Exception $e) {
6442            /** @disregard P1014 */
6443            $e->exceptionCode = 'LIST_QUOTATION_ANALYTICS_BY_PERFORMANCE_EXCEPTION'; 
6444            report($e);
6445            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6446        }
6447    }
6448
6449    function list_orders_update_logs($companyId){
6450
6451        try {
6452
6453            $where = "";
6454
6455            if($companyId != 0){
6456                $where .= " a.company_id = {$companyId}";
6457            }else{
6458                $where .= " a.company_id IN ({$this->companyId})";
6459            }
6460
6461            $query = "SELECT
6462                        a.id,
6463                        b.name company,
6464                        a.to_process,
6465                        a.rejected_affected_rows,
6466                        a.for_add_deleted_affected_rows,
6467                        a.month_change_affected_rows,
6468                        a.follow_ups_affected_rows,
6469                        a.sync_succesfull,
6470                        a.sync_error,
6471                        a.sync_error_message,
6472                        a.sync_success_ids,
6473                        a.cleared_email_errors,
6474                        a.remaining_email_errors,
6475                        CASE
6476                            WHEN a.rejected_affected_rows IS NOT NULL THEN a.rejected_affected_rows
6477                            WHEN a.for_add_deleted_affected_rows IS NOT NULL THEN a.for_add_deleted_affected_rows
6478                            WHEN a.month_change_affected_rows IS NOT NULL THEN a.month_change_affected_rows
6479                            WHEN a.follow_ups_affected_rows IS NOT NULL THEN a.follow_ups_affected_rows
6480                        END totals,
6481                        a.status,
6482                        a.processed_by,
6483                        a.started_at,
6484                        a.ended_at,
6485                        a.rejected_automatically_ids
6486                    FROM `tbl_orders_update_logs` a
6487                    LEFT JOIN tbl_companies b
6488                        ON a.company_id = b.company_id
6489                    WHERE {$where}
6490                    ORDER BY started_at DESC";
6491
6492            $result = DB::select($query);
6493
6494            return response(['message' => 'OK', 'data' => $result]);
6495
6496        } catch (\Exception $e) {
6497            /** @disregard P1014 */
6498            $e->exceptionCode = 'LIST_ORDERS_UPDATE_LOGS_EXCEPTION'; 
6499            report($e);
6500            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6501        }
6502
6503    }
6504
6505    function list_g3w_orders_update_logs($companyId){
6506
6507        try {
6508            $result = TblG3WOrdersUpdateLogs::where("company_id", $companyId)->get();
6509
6510            return response(['message' => 'OK', 'data' => $result]);
6511
6512        } catch (\Exception $e) {
6513            /** @disregard P1014 */
6514            $e->exceptionCode = 'LIST_G3W_ORDERS_UPDATE_LOGS_EXCEPTION'; 
6515            report($e);
6516            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6517        }
6518
6519    }
6520
6521    function update_budget_status_rejected_manual(Request $request){
6522
6523        try {
6524
6525            $data = $request->all();
6526
6527            $update = $this->update_budget_status_rejected($data['company_id'], $data['processed_by']);
6528
6529            if($update){
6530                return response(['message' => 'OK']);
6531            }else{
6532                return response(['message' => 'KO']);
6533            }
6534
6535        } catch (\Exception $e) {
6536            /** @disregard P1014 */
6537            $e->exceptionCode = 'UPDATE_BUDGET_STATUS_REJECTED_MANUAL_EXCEPTION'; 
6538            report($e);
6539            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6540        }
6541    }
6542
6543    function update_budget_status_rejected($companyId = null, $processedBy = "System"){
6544
6545        try {
6546
6547            $startedAt = date('Y-m-d H:i:s');
6548            $companyId = addslashes($companyId);
6549            $where = "";
6550
6551            $budgetTypes = TblBudgetTypes::get();
6552
6553            if(count($budgetTypes) > 0){
6554
6555                $companies = array();
6556
6557                if($companyId != 0){
6558                    $companies = TblCompanies::where('company_id', $companyId)->get();
6559                    $where = "AND company_id = {$companyId}";
6560                }else{
6561                    $companies = TblCompanies::get();
6562                }
6563
6564                for ($i = 0; $i < count($budgetTypes); $i++) {
6565
6566                    $days = $budgetTypes[$i]->duration;
6567                    $id = $budgetTypes[$i]->budget_type_id;
6568
6569                    if($days == null || $days == 0){
6570                        continue;
6571                    }
6572
6573                    for ($c = 0; $c < count($companies); $c++) {
6574                        $companyId = $companies[$c]->company_id;
6575
6576                        $query = "SELECT
6577                                    GROUP_CONCAT(id) ids
6578                                FROM
6579                                    tbl_quotations
6580                                WHERE
6581                                    budget_type_id = {$id}
6582                                AND budget_status_id IN (1, 2, 11)
6583                                AND DATEDIFF(NOW(), issue_date) >= {$days}
6584                                AND for_add = 0
6585                                {$where}";
6586
6587                        $result = DB::select($query);
6588
6589                        if(count($result) > 0){
6590
6591                            $ids = $result[0]->ids;
6592
6593                            if($ids != null || $ids != ""){
6594                                $query = "UPDATE
6595                                            tbl_quotations
6596                                        SET
6597                                            budget_status_id = 7
6598                                        WHERE
6599                                            id IN ({$ids})";
6600
6601                                DB::select($query);
6602
6603                                TblOrdersUpdateLogs::create(
6604                                    array(
6605                                        'company_id' => $companyId,
6606                                        'to_process' => 'Orders',
6607                                        'status' => 'success',
6608                                        'rejected_automatically_ids' => $ids,
6609                                        'processed_by' => $processedBy,
6610                                        'started_at' => $startedAt,
6611                                        'ended_at' => date('Y-m-d H:i:s')
6612                                    )
6613                                );
6614                            }
6615                        }
6616                    }
6617                }
6618            }
6619
6620            Cache::flush();
6621
6622            return response(['message' => 'OK']);
6623
6624        } catch (\Exception $e) {
6625            /** @disregard P1014 */
6626            $e->exceptionCode = 'UPDATE_BUDGET_STATUS_REJECTED_MANUAL_EXCEPTION'; 
6627            report($e);
6628
6629            TblOrdersUpdateLogs::create(
6630                array(
6631                    'company_id' => $companyId,
6632                    'to_process' => 'Orders',
6633                    'status' => $e->getMessage(),
6634                    'processed_by' => $processedBy,
6635                    'started_at' => $startedAt,
6636                    'ended_at' => date('Y-m-d H:i:s')
6637                )
6638            );
6639
6640            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6641        }
6642
6643    }
6644
6645    function bulk_update_quotation(Request $request){
6646
6647        // try {
6648
6649            $data = $request->all();
6650
6651            $r = new Request([
6652                'filterModel' => $data['filterModel'],
6653                'sortModel' => $data['sortModel'],
6654                'start' => 0,
6655                'end' => 999999999,
6656                'company_id' => $data['company_id'],
6657                'user_id' => $data['user_id'],
6658                'ids' => $data['ids'],
6659                'searchText' => $data['searchText'],
6660                'ids_not_in' => $data['ids_not_in']
6661            ]);
6662
6663            $listQuotations = $this->list_quotations($r);
6664            $d = $listQuotations->original['data'];
6665
6666            if(count($d) > 0){
6667                if(isset($data['last_follow_up_date']) && $data['last_follow_up_date'] == 1){
6668                    unset($data['last_follow_up_date']);
6669                }
6670                // unset($data['last_follow_up_date']);
6671                unset($data['filterModel']);
6672                unset($data['sortModel']);
6673                unset($data['start']);
6674                unset($data['end']);
6675                unset($data['company_id']);
6676                unset($data['user_id']);
6677                unset($data['ids']);
6678                unset($data['searchText']);
6679                unset($data['ids_not_in']);
6680
6681                $result = array();
6682                for ($i = 0; $i < count($d); $i++) {
6683                    array_push($result, $d[$i]->id);
6684                }
6685
6686                TblQuotations::whereIn('id', $result)->update($data);
6687
6688                Cache::flush();
6689            }
6690
6691            return response(['message' => 'OK', $data]);
6692
6693        // } catch (\Exception $e) {
6694        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
6695        // }
6696
6697    }
6698
6699    function move_budget_and_job(Request $request){
6700
6701        try {
6702
6703            $data = $request->all();
6704            $id = addslashes($data['id']);
6705            $companyId = addslashes($data['company_id']);
6706
6707            unset($data['id']);
6708            unset($data['company_id']);
6709
6710            $budget = TblQuotations::where('id', $id)->first();
6711
6712            $quotationId = $budget->id;
6713            $companyIdJob = $budget->company_id;
6714
6715            $query = "SELECT
6716                        COUNT(1) total
6717                    FROM tbl_company_users a
6718                    LEFT JOIN tbl_users b
6719                        ON a.user_id = b.id
6720                    WHERE a.company_id = {$companyId}
6721                    AND b.name = '{$budget->commercial}'
6722                    ORDER BY b.name ASC";
6723
6724            $result = DB::select($query);
6725
6726            $commercial = $budget->commercial;
6727
6728            if($result[0]->total == 0){
6729                $commercial = $data['created_by'];
6730            }
6731
6732            $r = new Request([
6733                'created_by' => $commercial,
6734            ]);
6735
6736            $result = $this->get_number($r, $companyId, 1);
6737            $newNumber = $result->original['number'];
6738
6739            TblQuotations::where('id', $id)->update(
6740                array(
6741                    'quote_id' => $newNumber,
6742                    'company_id' => $companyId,
6743                    'from_company_id' => $budget->company_id,
6744                    'commercial' => $commercial,
6745                )
6746            );
6747
6748            $job = TblOngoingJobs::where('quotation_id', $quotationId)->first();
6749
6750            $jobId = null;
6751
6752            if($job){
6753                $jobId = $job->id;
6754
6755                $query = "SELECT
6756                            COUNT(1) total
6757                        FROM tbl_company_users a
6758                        LEFT JOIN tbl_users b
6759                            ON a.user_id = b.id
6760                        WHERE a.company_id = {$companyId}
6761                        AND b.name = '{$job->responsible_for_work}'
6762                        ORDER BY b.name ASC";
6763
6764                $result = DB::select($query);
6765
6766                $responsibleForWork = $job->responsible_for_work;
6767
6768                if($result[0]->total == 0){
6769                    $responsibleForWork = $data['created_by'];
6770                }
6771
6772                TblOngoingJobs::where('quotation_id', $id)->update(
6773                    array(
6774                        'quote_id' => $newNumber,
6775                        'company_id' => $companyId,
6776                        'responsible_for_work' => $responsibleForWork,
6777                    )
6778                );
6779            }
6780
6781            Cache::flush();
6782
6783            return response([
6784                'message' => 'OK',
6785                'quotation_id' => $quotationId,
6786                'job_id' => $jobId
6787            ]);
6788
6789        } catch (\Exception $e) {
6790            /** @disregard P1014 */
6791            $e->exceptionCode = 'MOVE_BUDGET_AND_JOB_EXCEPTION'; 
6792            report($e);
6793            return response(['message' => 'KO', 'error' => $e->getMessage()]);
6794        }
6795    }
6796
6797    function list_quotation_analytics_by_types_of_budgets_created_per_week(Request $request){
6798
6799        try {
6800
6801            $data = $request->all();
6802            $companyId = addslashes($data['company_id']);
6803            $field = $data['field'];
6804
6805            $where = "";
6806            $whereYear = "";
6807            $dateLflArray = array();
6808            $companyIds = $this->companyIds;
6809
6810            if($companyId != 0){
6811                $companyIds = array($companyId);
6812            }
6813
6814            $acc = "";
6815            if($field == 'acceptance_date'){
6816                $acc = " AND q.acceptance_date IS NOT NULL ";
6817                // $field = 'created_at';
6818
6819                if(@$data['data_to_display'] == 4){
6820                    $field = 'created_at';
6821                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
6822                }
6823            }else{
6824                $field = 'created_at';
6825                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
6826            }
6827
6828            if(isset($data['years']) && $data['years'] != null){
6829                $years = implode(',', $data['years']);
6830                if(count($data['years']) > 0){
6831                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
6832                }
6833            }
6834
6835            foreach ($companyIds as $v) {
6836
6837                $lflWhere = " AND q.company_id = {$v} ";
6838
6839                $query = "SELECT
6840                            CONCAT(
6841                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
6842                                ' - ',
6843                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
6844                            ) AS date_like,
6845                            YEAR(q.{$field}) 'year',
6846                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
6847                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
6848                            {$v} 'company_id'
6849                        FROM
6850                            tbl_quotations q
6851                        WHERE
6852                            q.{$field} IS NOT NULL
6853                            AND q.for_add != 1
6854                            {$lflWhere}
6855                            {$whereYear}
6856                        GROUP BY YEAR(q.{$field})
6857                        ORDER BY YEAR(q.{$field}) DESC";
6858
6859                $dateLike = DB::select($query);
6860
6861                $dateLflArray[$v] = $dateLike;
6862            }
6863
6864            $isFy = true;
6865
6866            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
6867                $isFy = false;
6868                $ytdArray = array();
6869                $ytdAcceptanceArray = array();
6870                $lflCompanyIds = array();
6871                foreach ($dateLflArray as $k => $v) {
6872                    foreach ($dateLflArray[$k] as $item) {
6873                        $year = $item->year;
6874                        $now = date('m-d');
6875                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
6876                    }
6877
6878                    $ytdArray = implode(' OR ', $ytdArray);
6879                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
6880                    $ytdArray = array();
6881                }
6882
6883                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
6884                $where .= " AND ({$lflCompanyIds}";
6885            }
6886
6887            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
6888                $isFy = false;
6889                $lflArray = array();
6890                $ytdAcceptanceArray = array();
6891                $lflCompanyIds = array();
6892                foreach ($dateLflArray as $k => $v) {
6893                    foreach ($dateLflArray[$k] as $item) {
6894                        $year = $item->year;
6895                        $min_date_like = $item->min_date_like;
6896                        $max_date_like = $item->max_date_like;
6897                        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}')");
6898                    }
6899
6900                    $lflArray = implode(' OR ', $lflArray);
6901                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
6902                    $lflArray = array();
6903                }
6904
6905                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
6906                $where .= " AND ({$lflCompanyIds}";
6907            }
6908
6909            if($isFy){
6910                if($companyId != 0){
6911                    $where .= " AND q.company_id = {$companyId} ";
6912                }else{
6913                    $where .= " AND q.company_id IN ({$this->companyId})";
6914                }
6915            }
6916
6917            if(isset($data['source']) && $data['source'] != null){
6918                $where .= " AND s.name = '{$data['source']}'";
6919            }
6920
6921            if(isset($data['month']) && $data['month'] != null){
6922                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
6923            }
6924
6925            if(isset($data['week']) && $data['week'] != null){
6926                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
6927            }
6928
6929            if(isset($data['commercial']) && $data['commercial'] != null){
6930                $where .= " AND q.commercial = '{$data['commercial']}'";
6931            }
6932
6933            if(isset($data['created_by']) && $data['created_by'] != null){
6934                $where .= " AND q.created_by = '{$data['created_by']}'";
6935            }
6936
6937            if(isset($data['budget_type']) && $data['budget_type'] != null){
6938                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
6939            }
6940
6941            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
6942                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
6943            }
6944
6945            if(isset($data['budget_status']) && $data['budget_status'] != null){
6946                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
6947            }
6948
6949            if(isset($data['client_type']) && $data['client_type'] != null){
6950                $where .= " AND ct.customer_type_id = {$data['client_type']}";
6951            }
6952
6953
6954            if(isset($data['segment_id']) && $data['segment_id'] != null){
6955                $where .= " AND q.segment_id = {$data['segment_id']}";
6956            }
6957
6958            $col = "1";
6959
6960            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
6961                if($data['data_to_display'] == 1){
6962                    $col = "1";
6963                }
6964
6965                if($data['data_to_display'] == 2){
6966                    $col = "q.amount";
6967                }
6968            }
6969
6970            $budgetTypes = TblBudgetTypes::orderByRaw("ISNULL(priority), priority ASC")->get();
6971            $cols = "";
6972            foreach ($budgetTypes as $item) {
6973                if($item->name == '' || $item->name == null){
6974                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} ELSE 0 END), 0) AS 'Otros'";
6975                }else{
6976                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN {$col} ELSE 0 END), 0) AS '{$item->name}'";
6977                }
6978            }
6979
6980            $budgetTypeGroups = TblBudgetTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
6981
6982            $colsGroups = ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} END), 0) AS Otros";
6983
6984            foreach ($budgetTypeGroups as $item) {
6985                $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
6986                $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}'";
6987                $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}'";
6988            }
6989
6990            $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";
6991
6992            $col = $colsGroups . $cols;
6993
6994            if(@$data['data_to_display'] == 3){
6995
6996                $cols = "";
6997                foreach ($budgetTypes as $item) {
6998                    if($item->name == '' || $item->name == null){
6999                        $cols .= ",COALESCE(
7000                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount ELSE 0 END) /
7001                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 ELSE 0 END) * 100 , 0
7002                                    ) AS 'Otros'";
7003                    }else{
7004                        $cols .= ",COALESCE(
7005                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN q.amount ELSE 0 END) /
7006                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN 1 ELSE 0 END), 0
7007                                    ) AS '{$item->name}'";
7008                    }
7009                }
7010
7011                $colsGroups = ",COALESCE(
7012                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount END)) /
7013                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 END))
7014                            , 0) Otros";
7015
7016                foreach ($budgetTypeGroups as $item) {
7017                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
7018                    $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}'";
7019                    $colsGroups .= ",COALESCE(
7020                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.amount END)) /
7021                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN 1 END))
7022                                    , 0) '{$budgetTypeGroupName}'";
7023                }
7024
7025                $colsGroups .= ",COALESCE(
7026                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.amount END)) /
7027                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END))
7028                                , 0) total";
7029
7030                $col = $colsGroups . $cols;
7031            }
7032
7033            if(@$data['data_to_display'] == 4){
7034
7035                $cols = "";
7036
7037                foreach ($budgetTypes as $item) {
7038
7039                    if($item->name == '' || $item->name == null){
7040                        $cols .= ",COALESCE(
7041                                        SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) /
7042                                        SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 ELSE 0 END) * 100 , 0
7043                                ) AS 'Otros'";
7044                    }else{
7045                        $cols .= ", COALESCE(
7046                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.acceptance_date IS NOT NULL THEN 1 END) /
7047                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.created_at IS NOT NULL THEN 1 END) * 100, 0
7048                                ) AS '{$item->name}'";
7049                    }
7050                }
7051
7052                $colsGroups = ",COALESCE(
7053                                    (SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 END)) /
7054                                    (SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 END)) * 100
7055                                    , 0) Otros";
7056
7057                foreach ($budgetTypeGroups as $item) {
7058                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
7059                    $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}'";
7060                    $colsGroups .= ",COALESCE(
7061                                        (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)) /
7062                                        (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
7063                                    , 0) '{$budgetTypeGroupName}'";
7064                }
7065
7066                $colsGroups .= ",COALESCE(
7067                                    (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)) /
7068                                    (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
7069                                    , 0) total";
7070
7071                $col = $colsGroups . $cols;
7072            }
7073
7074            $query  = "SELECT
7075                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
7076                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
7077                            LPAD(WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'week',
7078                            DATE_FORMAT(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY), '%W, %M %e') 'namedate',
7079                            GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.id END) groupConcatIds
7080                            {$col}
7081                        FROM
7082                            tbl_quotations q
7083                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
7084                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
7085                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
7086                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
7087                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
7088                        WHERE
7089                            q.{$field} IS NOT NULL
7090                            AND q.for_add != 1
7091                            AND q.budget_type_id IS NOT NULL
7092                            AND q.budget_type_id != 7
7093                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1                            
7094                            {$where}
7095                            {$whereYear}
7096                        GROUP BY
7097                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
7098                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
7099                            WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) WITH ROLLUP
7100                        ORDER BY
7101                            YEAR DESC,
7102                            MONTH ASC,
7103                            WEEK ASC,
7104                            DATE_FORMAT(q.{$field}, '%e') ASC";
7105            // return $query;
7106            $result = DB::select($query);
7107
7108            $query = "SELECT
7109                        btg.budget_type_group_id,
7110                        btg.name,
7111                        (
7112                            SELECT
7113                                GROUP_CONCAT(COALESCE(bt.name, '') ORDER BY ISNULL(bt.priority), bt.priority ASC SEPARATOR '|')
7114                            FROM
7115                                tbl_budget_types bt
7116                            WHERE
7117                                bt.budget_type_group_id = btg.budget_type_group_id
7118                        ) budget_types
7119                        FROM
7120                            tbl_budget_type_groups btg
7121                        ORDER BY
7122                            ISNULL(btg.priority),
7123                            btg.priority ASC";
7124
7125            $budgetTypeGroups = DB::select($query);
7126
7127            foreach ($budgetTypeGroups as $item) {
7128                $item->group_key_name = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
7129                $item->budget_types = explode("|", $item->budget_types);
7130            }
7131
7132            return response([
7133                'message' => 'OK',
7134                'data' => $result,
7135                'budgetTypeGroups' => $budgetTypeGroups
7136            ]);
7137
7138        } catch (\Exception $e) {
7139            /** @disregard P1014 */
7140            $e->exceptionCode = 'LIST_QUOTATION_ANALYTICS_BY_TYPES_OF_BUDGETS_CREATED_PER_WEEK_EXCEPTION'; 
7141            report($e);
7142            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7143        }
7144    }
7145
7146    public function preview_file($id){
7147        
7148        try {
7149
7150            $file = TblFiles::where("file_id", $id)->first();
7151            
7152            if (!$file) {
7153                return response()->json([
7154                    'message' => 'KO',
7155                    'error' => __('language.file_not_found')
7156                ], 404);
7157            }                                
7158                        
7159            if (!Storage::disk('s3')->exists("uploads/" . $file->filename)) {                
7160                return response()->json(['message' => 'File not found'], 404);
7161            }
7162            
7163            $url = Storage::disk('s3')->temporaryUrl(
7164                "uploads/" . $file->filename,
7165                now()->addMinutes(5)
7166            );
7167
7168            return response()->json([
7169                'filename' => $file->filename,
7170                'url' => $url,
7171                'uploaded_by' => $file->uploaded_by,
7172                'uploaded_at' => $file->uploaded_at
7173            ]);
7174
7175        } catch (\Exception $e) {
7176            /** @disregard P1014 */
7177            $e->exceptionCode = 'PREVIEW_FILE_EXCEPTION'; 
7178            report($e);
7179            return response()->json([
7180                'message' => 'KO',
7181                'error' => $e->getMessage()
7182            ], 500);
7183        }
7184    }
7185
7186    function get_past_added_quotation(Request $request){
7187
7188        try {
7189
7190            $data = $request->all();
7191            $keyword = addslashes($data['keyword']);
7192            $result = array();
7193
7194            if(isset($keyword) && !empty($keyword)){
7195                $array = explode(' ', $keyword);
7196
7197                $where = "";
7198
7199                $availableParameters = array('client', 'email');
7200
7201                $searchTextArray = explode(" ", $keyword);
7202
7203                $searchArray = array();
7204                $matchScoreArray = array();
7205                foreach ($availableParameters as $field) {
7206                    foreach ($searchTextArray as $word) {
7207                        array_push($searchArray, "({$field} LIKE '%{$word}%')");
7208                        array_push($matchScoreArray, "CASE WHEN {$field} LIKE '%{$word}%' THEN 1 ELSE 0 END");
7209                    }
7210                }
7211
7212                $searchArray = implode(" OR ", $searchArray);
7213                $matchScoreArray = implode(" + ", $matchScoreArray);
7214                $matchScoreCol = "({$matchScoreArray})";
7215                $where .= " AND ({$searchArray}";
7216
7217                $query = "SELECT
7218                            id,
7219                            client,
7220                            segment_id,
7221                            CONCAT(`client`, ' - ', email) `client_email`,
7222                            email,
7223                            phone_number,
7224                            customer_type_id,
7225                            {$matchScoreCol} match_score
7226                        FROM tbl_quotations
7227                        WHERE for_add = 0
7228                        AND email IS NOT NULL AND phone_number IS NOT NULL
7229                        {$where}
7230                        GROUP BY client, email
7231                        ORDER BY match_score DESC, client ASC
7232                        ";
7233
7234                $result = DB::select($query);
7235            }
7236
7237            return response(['message' => 'OK', 'data' => $result]);
7238
7239        } catch (\Exception $e) {
7240            /** @disregard P1014 */
7241            $e->exceptionCode = 'GET_PAST_ADDED_QUOTATION_EXCEPTION'; 
7242            report($e);
7243            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7244        }
7245    }
7246
7247    function send_acceptance_notification($quotationId, $companyId, $userId, $updatedBy){
7248
7249        $budget = TblQuotations::where('id', $quotationId)->first();
7250
7251        if($budget != null){
7252            $to = TblToAcceptanceNotifications::where('company_id', $companyId)->get();
7253            $cc = TblCcAcceptanceNotifications::where('company_id', $companyId)->get();
7254
7255            if(count($to) > 0 && count($cc) > 0){
7256
7257                $company = TblCompanies::where('company_id', $companyId)->first();
7258
7259                $quoteId = $budget->quote_id;
7260                $amount = $this->currency($budget->amount, 1);
7261
7262                $url = env('URL') . "orders/{$quotationId}?company_id={$companyId}";
7263                $href = "<a href='{$url}'>{$quoteId}</a>";
7264
7265                $imgpath = File::get('fireservicetitan.png');
7266                $base64 = "data:image/png;base64,".base64_encode($imgpath);
7267
7268                $body = __('language.send_acceptance_notification.body_hello');
7269                $body .= __('language.send_acceptance_notification.body_message');
7270
7271                $body = str_replace('{{client}}', $budget->client, $body);
7272                $body = str_replace('{{username}}', $updatedBy, $body);
7273                $body = str_replace('{{company}}', $company->name, $body);
7274                $body = str_replace('{{amount}}', $amount, $body);
7275                $body = str_replace('{{quote_id}}', $href, $body);
7276
7277                $body .= "<p>Fire Service Titan</p>";
7278                $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
7279
7280                $html = '<!DOCTYPE html>';
7281                $html .= '<html>';
7282                $html .= '<head>';
7283                $html .= '<meta charset="UTF-8">';
7284                $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
7285                $html .= '</head>';
7286                $html .= '<body>';
7287                $html .= $body;
7288                $html .= '</body>';
7289                $html .= '</html>';
7290
7291
7292                $subject = __('language.send_acceptance_notification.subject');
7293                $subject = str_replace('{{quote_id}}', $quoteId, $subject);
7294
7295                $email = new \SendGrid\Mail\Mail();
7296
7297                $user = TblUsers::where('id', $userId)->first();
7298
7299                if(env('SENDGRID_STAGING')){
7300                    $email->addTo($user->email);
7301                }else{
7302
7303                    $emails = array();
7304
7305                    foreach ($to as $item) {
7306                        if(!in_array($item->email, $emails)){
7307                            array_push($emails, $item->email);
7308                            $email->addTo($item->email);
7309                        }
7310                    }
7311
7312                    foreach ($cc as $item) {
7313                        if(!in_array($item->email, $emails)){
7314                            array_push($emails, $item->email);
7315                            $email->addCc($item->email);
7316                        }
7317                    }
7318
7319                    $email->addCc($user->email);
7320                    array_push($emails, $user->email);
7321
7322                    $ccUser = TblUsers::where('name', $budget->commercial)->first();
7323
7324                    if($ccUser){
7325                        if(!in_array($ccUser->email, $emails)){
7326                            $email->addCc($ccUser->email);
7327                        }
7328                    }
7329                }
7330
7331                $email->setFrom('fire@fire.es', 'Fire Service Titan');
7332                $email->setSubject($subject);
7333                $email->addContent("text/html", $html);
7334
7335                $email->addAttachment(
7336                    $imgpath,
7337                    "image/png",
7338                    "fireservicetitan.png",
7339                    "inline",
7340                    "fireservicetitan"
7341                );
7342
7343                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
7344
7345                $response = $sendgrid->send($email);
7346                if ($response->statusCode() == 202) {
7347
7348                    $comment = "Email de aprobación automática enviada al equipo de opearciones el " . date('Y-m-d H:i:s');
7349                    $budget->last_follow_up_comment = $budget->last_follow_up_comment . "\n" . $comment;
7350
7351                    TblQuotations::where('id', $quotationId)->update(
7352                        array(
7353                            'last_follow_up_comment' => $budget->last_follow_up_comment
7354                        )
7355                    );
7356
7357                    Log::channel('email_log')->info('ID:' . $quoteId . ' - ACCEPTANCE EMAIL NOTIFICATION SENT');
7358                } else {
7359                    $error = true;
7360                    Log::channel('email_log')->error('ID:' . $quoteId . ' - ' . $response->body());
7361                }
7362
7363            }
7364        }
7365    }
7366
7367    function get_total_quotations_by_budget_status(Request $request){
7368
7369        try {
7370
7371            $data = $request->all();
7372
7373            $companyId = addslashes($data['company_id']);
7374
7375            $where = "";
7376
7377            if($companyId != 0){
7378                $where = " AND a.company_id = {$companyId} ";
7379            }else{
7380                $where = " AND a.company_id IN ({$this->companyId}";
7381            }
7382
7383            $user = null;
7384
7385            if(isset($data['commercial'])){
7386                if($data['commercial'] != 'All'){
7387                    $user = TblUsers::where('name', $data['commercial'])->first();
7388                }
7389            }else{
7390                $user = TblUsers::where('id', $this->userId)->first();
7391            }
7392
7393            $totalPendingFollowUps = 0;
7394            $totalRequestAndVisit = 0;
7395            $totalError = 0;
7396            $totalG3WError = 0;
7397            $totalSendToClient = 0;
7398
7399            $d = false;
7400
7401            if($user != null){
7402                $where .= " AND a.commercial = '{$user->name}";
7403                $d = true;
7404            }
7405
7406            if($data['commercial'] == 'All'){
7407                $d = true;
7408            }
7409
7410            if($d){
7411                $query = "SELECT
7412                            COUNT(DISTINCT a.id) total
7413                        FROM
7414                            tbl_quotations a
7415                            LEFT JOIN (
7416                                SELECT
7417                                a.id,
7418                                SUBSTRING_INDEX(
7419                                    SUBSTRING_INDEX(a.email, ',', n.digit + 1),
7420                                    ',',
7421                                    -1
7422                                ) AS email_domain
7423                                FROM
7424                                tbl_quotations a
7425                                INNER JOIN (
7426                                    SELECT
7427                                    0 AS digit
7428                                    UNION ALL
7429                                    SELECT
7430                                    1
7431                                    UNION ALL
7432                                    SELECT
7433                                    2
7434                                    UNION ALL
7435                                    SELECT
7436                                    3
7437                                    UNION ALL
7438                                    SELECT
7439                                    4
7440                                    UNION ALL
7441                                    SELECT
7442                                    5
7443                                    UNION ALL
7444                                    SELECT
7445                                    6
7446                                    UNION ALL
7447                                    SELECT
7448                                    7
7449                                    UNION ALL
7450                                    SELECT
7451                                    8
7452                                    UNION ALL
7453                                    SELECT
7454                                    9
7455                                ) n ON LENGTH(
7456                                    REPLACE(a.email, ',', '')
7457                                ) <= LENGTH(a.email)- n.digit
7458                                GROUP BY a.id
7459                            ) temp ON a.id = temp.id
7460                            LEFT JOIN tbl_companies b
7461                                ON a.company_id = b.company_id
7462                        WHERE
7463                            a.last_follow_up_date < NOW()
7464                            AND a.budget_status_id IN (2)
7465                            AND a.email IS NOT NULL
7466                            AND a.email <> ''
7467                            AND NOT EXISTS (
7468                                SELECT
7469                                1
7470                                FROM
7471                                tbl_blocked_domains bd
7472                                WHERE
7473                                temp.email_domain LIKE CONCAT('%', bd.domain, '%')
7474                                AND bd.company_id = a.company_id
7475                            )
7476                            AND a.last_follow_up_date IS NOT NULL
7477                            AND a.reason_for_not_following_up_id IS NULL
7478                            AND a.last_follow_up_date > 0
7479                            AND a.total_sent < b.limit_reminder_emails
7480                            AND a.for_add = 0 {$where}";
7481
7482                    $result = DB::select($query);
7483
7484                    $totalPendingFollowUps = $result[0]->total;
7485
7486                    $query = "SELECT
7487                                COUNT(1) total
7488                            FROM
7489                                tbl_quotations a
7490                            WHERE
7491                                a.budget_status_id IN (6, 8, 12)
7492                                {$where}
7493                            ";
7494
7495                    $result = DB::select($query);
7496
7497                    $totalRequestAndVisit = $result[0]->total;
7498
7499                    $query = "SELECT
7500                                COUNT(1) total
7501                            FROM
7502                                tbl_quotations a
7503                            WHERE
7504                                a.x_status LIKE '%Error%'
7505                                {$where}
7506                            ";
7507
7508                    $result = DB::select($query);
7509
7510                    $totalError = $result[0]->total;
7511
7512                    $query = "SELECT
7513                                COUNT(1) total
7514                                FROM
7515                                    tbl_quotations a
7516                                WHERE
7517                                    a.g3w_warning = 1
7518                                    AND a.sync_import = 1
7519                                    {$where}
7520                                ";
7521
7522                    $result = DB::select($query);
7523
7524                    $totalG3WError = $result[0]->total;
7525
7526                    $query = "SELECT
7527                                COUNT(1) total
7528                                FROM
7529                                    tbl_quotations a
7530                                WHERE
7531                                    a.budget_status_id = (SELECT budget_status_id FROM tbl_budget_status WHERE name = 'Validado')
7532                                    AND a.total_sent = 0
7533                                    {$where}
7534                                ";
7535
7536                    $result = DB::select($query);
7537
7538                    $totalSendToClient = $result[0]->total;
7539            }
7540
7541            return response([
7542                'message' => 'OK',
7543                'userId' => ($user) ? $user->id : null,
7544                'totalPendingFollowUps' => $totalPendingFollowUps,
7545                'totalRequestAndVisit' => $totalRequestAndVisit,
7546                'totalError' => $totalError,
7547                'totalG3WError' => $totalG3WError,
7548                'totalSendToClient' => $totalSendToClient
7549            ]);
7550
7551
7552        } catch (\Exception $e) {
7553            /** @disregard P1014 */
7554            $e->exceptionCode = 'GET_TOTAL_QUPTATIONS_BY_BUDGET_STATUS_EXCEPTION'; 
7555            report($e);
7556            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7557        }
7558
7559    }
7560
7561    function sendgrid_webhook_receiver(Request $request){
7562
7563        try {
7564
7565            $data = $request->all();
7566
7567            $jsonBody = array();
7568            $order = array();
7569            $orderEmails = array();
7570
7571            Log::channel('email_log')->info('WEBHOOK: ' . json_encode($data));
7572
7573            $quoteId = null;
7574
7575            foreach ($data as $item) {
7576                $matches = explode(".", $item['sg_message_id']);
7577                $messageId = $matches[0];
7578
7579                Log::channel('email_log')->info('MESSAGE-ID: ' . $messageId);
7580
7581                $result = TblSendgridWebhook::where('x_message_id', $messageId)->first();
7582                $quoteId = $result->quotation_id;
7583                Log::channel('email_log')->info('SENDGRID-BODY: ' . json_encode($result));
7584
7585                if(empty($order)){
7586                    $order = TblQuotations::where('x_message_id', $messageId)->first();
7587                    $quoteId = $order->id;
7588                    // if(env('SENDGRID_STAGING')){
7589                    //     $user = TblUsers::where('name', $order->updated_by)->first();
7590
7591                    //     $orderEmails = array($user->email);
7592                    // }else{
7593                        $orderEmails = explode(",", $order->email);
7594                    // }
7595                }
7596
7597                // if(in_array($item['email'], $orderEmails)){
7598                    if($result->json_body == null){
7599                        array_push($jsonBody, $item);
7600                    }else{
7601                        $jsonBody = json_decode($result->json_body);
7602                        array_push($jsonBody, $item);
7603                    }
7604                // }
7605
7606                Log::channel('email_log')->info('JSON-BODY: ' . json_encode($jsonBody));
7607
7608                TblSendgridWebhook::where('x_message_id', $messageId)->update(
7609                    array(
7610                        'json_body' => json_encode($jsonBody),
7611                        'updated_at' => date('Y-m-d H:i:s')
7612                    )
7613                );
7614
7615                if($quoteId != null){
7616                    $this->get_files($quoteId);
7617                }
7618
7619                Cache::flush();
7620            }
7621
7622        } catch (\Exception $e) {
7623            /** @disregard P1014 */
7624            $e->exceptionCode = 'SENDGRID_WEBHOOK_RECEIVER_EXCEPTION'; 
7625            report($e);
7626            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7627        }
7628
7629    }
7630
7631    function isEmailValid($email) {
7632        // Regular expression pattern for email validation
7633        $pattern = '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/';
7634
7635        // Check if the email matches the pattern
7636        if (preg_match($pattern, $email)) {
7637            return true; // Valid email
7638        } else {
7639            return false; // Invalid email
7640        }
7641    }
7642
7643    function list_email_status($companyId){
7644
7645        try {
7646
7647            $companyId = addslashes($companyId);
7648
7649            $where = "";
7650            if($companyId != 0){
7651                $where = " company_id = {$companyId} ";
7652            }else{
7653                $where = " company_id IN ({$this->companyId})";
7654            }
7655
7656            $query = "SELECT DISTINCT x_status FROM tbl_quotations WHERE {$where} AND x_status IS NOT NULL";
7657            $result = DB::select($query);
7658
7659            return response([
7660                'message' => 'OK',
7661                'data' => $result,
7662            ]);
7663
7664
7665        } catch (\Exception $e) {
7666            /** @disregard P1014 */
7667            $e->exceptionCode = 'LIST_EMAIL_STATUS_EXCEPTION'; 
7668            report($e);
7669            return response(['message' => 'KO', 'error' => $e->getMessage()]);
7670        }
7671
7672    }
7673
7674    function list_quotation_analytics_commercial(Request $request){
7675
7676        try {
7677
7678            $data = $request->all();
7679            $companyId = addslashes($data['company_id']);
7680            $field = $data['field'];
7681
7682            $where = "";
7683            $whereYear = "";
7684            $dateLflArray = array();
7685            $companyIds = $this->companyIds;
7686            $whereQ = "";
7687
7688            $acc = "";
7689            if($field == 'acceptance_date'){
7690                $acc = " AND q.acceptance_date IS NOT NULL ";
7691                // $field = 'created_at';
7692
7693                if(@$data['data_to_display'] == 4){
7694                    $field = 'created_at';
7695                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7696                    $whereQ .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7697                }
7698            }else{
7699                $field = 'created_at';
7700                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7701                $whereQ .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
7702            }
7703
7704            if(isset($data['years']) && $data['years'] != null){
7705                $years = implode(',', $data['years']);
7706                if(count($data['years']) > 0){
7707                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
7708                }
7709            }
7710
7711            if($companyId != 0){
7712                $companyIds = array($companyId);
7713            }
7714
7715            foreach ($companyIds as $v) {
7716
7717                $lflWhere = " AND q.company_id = {$v} ";
7718
7719                $query = "SELECT
7720                            CONCAT(
7721                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
7722                                ' - ',
7723                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
7724                            ) AS date_like,
7725                            YEAR(q.{$field}) 'year',
7726                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
7727                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
7728                            {$v} 'company_id'
7729                        FROM
7730                            tbl_quotations q
7731                        WHERE
7732                            q.{$field} IS NOT NULL
7733                            AND q.for_add != 1
7734                            {$lflWhere}
7735                            {$whereYear}
7736                        GROUP BY YEAR(q.{$field})
7737                        ORDER BY YEAR(q.{$field}) DESC";
7738
7739                $dateLike = DB::select($query);
7740
7741                $dateLflArray[$v] = $dateLike;
7742            }
7743
7744            $isFy = true;
7745
7746            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
7747                $isFy = false;
7748                $ytdArray = array();
7749                $ytdAcceptanceArray = array();
7750                $lflCompanyIds = array();
7751                foreach ($dateLflArray as $k => $v) {
7752                    foreach ($dateLflArray[$k] as $item) {
7753                        $year = $item->year;
7754                        $now = date('m-d');
7755                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
7756                    }
7757
7758                    $ytdArray = implode(' OR ', $ytdArray);
7759                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
7760                    $ytdArray = array();
7761                }
7762
7763                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7764                $where .= " AND ({$lflCompanyIds}";
7765                $whereQ .= " AND ({$lflCompanyIds}";
7766            }
7767
7768            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
7769                $isFy = false;
7770                $lflArray = array();
7771                $ytdAcceptanceArray = array();
7772                $lflCompanyIds = array();
7773                foreach ($dateLflArray as $k => $v) {
7774                    foreach ($dateLflArray[$k] as $item) {
7775                        $year = $item->year;
7776                        $min_date_like = $item->min_date_like;
7777                        $max_date_like = $item->max_date_like;
7778                        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}')");
7779                    }
7780
7781                    $lflArray = implode(' OR ', $lflArray);
7782                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
7783                    $lflArray = array();
7784                }
7785
7786                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
7787                $where .= " AND ({$lflCompanyIds}";
7788                $whereQ .= " AND ({$lflCompanyIds}";
7789            }
7790
7791            if($isFy){
7792                if($companyId != 0){
7793                    $where .= " AND q.company_id = {$companyId} ";
7794                    $whereQ .= " AND q.company_id = {$companyId} ";
7795                }else{
7796                    $where .= " AND q.company_id IN ({$this->companyId})";
7797                    $whereQ .= " AND q.company_id IN ({$this->companyId})";
7798                }
7799            }
7800
7801            if(isset($data['source']) && $data['source'] != null){
7802                $where .= " AND s.name = '{$data['source']}'";
7803            }
7804
7805            if(isset($data['month']) && $data['month'] != null){
7806                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
7807            }
7808
7809            if(isset($data['week']) && $data['week'] != null){
7810                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
7811            }
7812
7813            if(isset($data['commercial']) && $data['commercial'] != null){
7814                $where .= " AND q.commercial = '{$data['commercial']}'";
7815            }
7816
7817            if(isset($data['created_by']) && $data['created_by'] != null){
7818                $where .= " AND q.created_by = '{$data['created_by']}'";
7819            }
7820
7821            if(isset($data['budget_type']) && $data['budget_type'] != null){
7822                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
7823            }
7824
7825            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
7826                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
7827            }
7828
7829            if(isset($data['budget_status']) && $data['budget_status'] != null){
7830                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
7831            }
7832
7833            if(isset($data['client_type']) && $data['client_type'] != null){
7834                $where .= " AND ct.customer_type_id = {$data['client_type']}";
7835            }
7836
7837            if(isset($data['segment_id']) && $data['segment_id'] != null){
7838                $where .= " AND q.segment_id = {$data['segment_id']}";
7839            }
7840
7841            $col = "1";
7842
7843            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
7844                if($data['data_to_display'] == 1){
7845                    $col = "1";
7846                }
7847
7848                if($data['data_to_display'] == 2){
7849                    $col = "q.amount";
7850                }
7851            }
7852
7853            $query = "SELECT
7854                        q.commercial 'name',
7855                        COUNT(q.commercial) totalCommercial
7856                    FROM tbl_quotations q
7857                    WHERE
7858                        q.for_add = 0
7859                        AND q.{$field} IS NOT NULL
7860                        {$whereQ}
7861                    GROUP BY q.commercial
7862                    HAVING COUNT(q.commercial) > 0
7863                    ORDER BY totalCommercial DESC";
7864
7865            $resultCommercials = DB::select($query);
7866
7867            $now = TblQuotations::whereIn('company_id', $this->companyIds)->orderBy($field, 'DESC')->pluck($field)->first();
7868            $weekNumber = date('W', strtotime($now));
7869            $thisWeek = date('Y-m-d', strtotime($now . " - " . (date('N', strtotime($now)) - 1) . " days"));
7870
7871            $query = "SELECT
7872                        q.commercial 'name',
7873                        COUNT(q.commercial) totalCommercial
7874                    FROM tbl_quotations q
7875                    WHERE
7876                        q.for_add = 0
7877                        AND q.{$field} IS NOT NULL
7878                        AND YEARWEEK(q.{$field}, 1) = YEARWEEK(NOW(), 1)
7879                        {$whereQ}
7880                    GROUP BY q.commercial
7881                    HAVING COUNT(q.commercial) > 0
7882                    ORDER BY totalCommercial DESC";
7883
7884            $resultCommercialsOrder = DB::select($query);
7885
7886            $namesToRemove = array();
7887
7888            foreach ($resultCommercialsOrder as $item) {
7889                $namesToRemove[$item->name] = true;
7890            }
7891
7892            $resultArray = [];
7893            foreach ($resultCommercials as $item) {
7894                if (!isset($namesToRemove[$item->name])) {
7895                    $resultArray[] = $item;
7896                }
7897            }
7898
7899            $resultCommercials = array_merge($resultCommercialsOrder, $resultArray);
7900
7901            $cols = "";
7902
7903            $colsGroupConcatIds = "";
7904
7905            foreach ($resultCommercials as $item) {
7906                $cols .= ",COALESCE(
7907                    SUM(
7908                        CASE WHEN q.commercial = '{$item->name}{$acc} THEN {$col} ELSE 0 END
7909                    ), 0
7910                ) '{$item->name}'";
7911
7912                $colsGroupConcatIds .= ",GROUP_CONCAT(CASE WHEN q.commercial = '{$item->name}{$acc} THEN q.id END) 'groupConcatIds-{$item->name}'";
7913            }
7914
7915            $cols .= ",COALESCE(
7916                SUM(
7917                    CASE WHEN q.commercial IS NOT NULL {$acc} THEN {$col} ELSE 0 END
7918                ), 0
7919            ) total";
7920
7921            if(@$data['data_to_display'] == 3){
7922
7923                $cols = "";
7924
7925                foreach ($resultCommercials as $item) {
7926                    $cols .= ",COALESCE(
7927                        (
7928                            SUM(CASE WHEN q.commercial = '{$item->name}{$acc} THEN q.amount END)
7929                        ) /
7930                        (
7931                            SUM(CASE WHEN q.commercial = '{$item->name}{$acc} THEN 1 END)
7932                        )
7933                    , 0) '{$item->name}'";
7934                }
7935
7936                $cols .= ",COALESCE(
7937                    (
7938                        SUM(CASE WHEN q.commercial IS NOT NULL {$acc} THEN q.amount END)
7939                    ) /
7940                    (
7941                        SUM(CASE WHEN q.commercial IS NOT NULL {$acc} THEN 1 END)
7942                    )
7943                , 0) total";
7944            }
7945
7946            if(@$data['data_to_display'] == 4){
7947
7948                $cols = "";
7949
7950                foreach ($resultCommercials as $item) {
7951                    $cols .= ",COALESCE(
7952                        (
7953                            SUM(CASE WHEN q.commercial = '{$item->name}' AND q.acceptance_date IS NOT NULL THEN 1 END)
7954                        ) /
7955                        (
7956                            SUM(CASE WHEN q.commercial = '{$item->name}' AND q.created_at IS NOT NULL THEN 1 END)
7957                        ) * 100
7958                    , 0) '{$item->name}'";
7959                }
7960
7961                $cols .= ",COALESCE(
7962                    (
7963                        SUM(CASE WHEN q.commercial IS NOT NULL AND q.acceptance_date IS NOT NULL THEN 1 END)
7964                    ) /
7965                    (
7966                        SUM(CASE WHEN q.commercial IS NOT NULL AND q.created_at IS NOT NULL THEN 1 END)
7967                    ) * 100
7968                , 0) total";
7969            }
7970
7971            $query  = "SELECT
7972                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
7973                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
7974                            LPAD(WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'week',
7975                            DATE_FORMAT(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY), '%W, %M %e') 'namedate',
7976                            GROUP_CONCAT(
7977                                CASE WHEN q.{$field} IS NOT NULL
7978                                THEN q.id END
7979                            ) AS groupConcatIds
7980                            {$colsGroupConcatIds}
7981                            {$cols}
7982                        FROM
7983                            tbl_quotations q
7984                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
7985                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
7986                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
7987                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
7988                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
7989                        WHERE
7990                            q.{$field} IS NOT NULL
7991                            AND q.for_add != 1
7992                            AND q.budget_type_id != 7
7993                            AND q.budget_type_id IS NOT NULL
7994                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
7995                            {$where}
7996                            {$whereYear}
7997                        GROUP BY
7998                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
7999                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
8000                            WEEK(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) WITH ROLLUP
8001                        ORDER BY
8002                            YEAR DESC,
8003                            MONTH ASC,
8004                            WEEK ASC,
8005                            DATE_FORMAT(q.{$field}, '%e') ASC";
8006
8007            $value = Cache::get(base64_encode($query));
8008
8009            if(!$value){
8010                $result = DB::select($query);
8011
8012                Cache::put(base64_encode($query), $result, 600);
8013            }else{
8014                $result = $value;
8015            }
8016
8017            return response([
8018                'message' => 'OK',
8019                'data' => $result,
8020                'commercials' => $resultCommercials
8021            ]);
8022
8023        } catch (\Exception $e) {
8024            /** @disregard P1014 */
8025            $e->exceptionCode = 'LIST_QUOTATION_ANALYTICS_COMMERCIAL_EXCEPTION'; 
8026            report($e);
8027            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8028        }
8029    }
8030
8031    function clear_open_data($companyId){
8032
8033        try {
8034
8035            $companyIds = array($companyId);
8036            if($companyId == 0){
8037                $companyIds = $this->companyIds;
8038            }
8039
8040            $user = TblUsers::where('id', $this->userId)->first();
8041
8042            if(count($companyIds) > 0){
8043
8044                foreach ($companyIds as $id) {
8045                    $startedAt = date('Y-m-d H:i:s');
8046                    $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')");
8047
8048                    TblOrdersUpdateLogs::create(
8049                        array(
8050                            'company_id' => $id,
8051                            'to_process' => 'Orders',
8052                            'status' => 'success',
8053                            'for_add_deleted_affected_rows' => $affectedRows,
8054                            'processed_by' => $user->name,
8055                            'started_at' => $startedAt,
8056                            'ended_at' => date('Y-m-d H:i:s')
8057                        )
8058                    );
8059                }
8060            }
8061
8062            return response([
8063                'message' => 'OK',
8064            ]);
8065
8066        } catch (\Exception $e) {
8067            /** @disregard P1014 */
8068            $e->exceptionCode = 'CLEAR_OPEN_DATA_EXCEPTION'; 
8069            report($e);
8070            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8071        }
8072
8073    }
8074
8075    function list_quotation_analytics_order_size(Request $request){
8076
8077        try {
8078
8079            $data = $request->all();
8080            $companyId = addslashes($data['company_id']);
8081            $field = $data['field'];
8082
8083            $where = "";
8084            $dateLflArray = array();
8085            $whereYear = "";
8086            $companyIds = $this->companyIds;
8087
8088            if($field == 'acceptance_date'){
8089                if(@$data['data_to_display'] == 4){
8090                    $field = 'created_at';
8091                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8092                }
8093            }else{
8094                $field = 'created_at';
8095                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8096            }
8097
8098            if(isset($data['years']) && $data['years'] != null){
8099                $years = implode(',', $data['years']);
8100                if(count($data['years']) > 0){
8101                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
8102                }
8103            }
8104
8105            if($companyId != 0){
8106                $companyIds = array($companyId);
8107            }
8108
8109            foreach ($companyIds as $v) {
8110
8111                $lflWhere = " AND q.company_id = {$v} ";
8112
8113                $query = "SELECT
8114                            CONCAT(
8115                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
8116                                ' - ',
8117                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
8118                            ) AS date_like,
8119                            YEAR(q.{$field}) 'year',
8120                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
8121                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
8122                            {$v} 'company_id'
8123                        FROM
8124                            tbl_quotations q
8125                        WHERE
8126                            q.{$field} IS NOT NULL
8127                            AND q.for_add != 1
8128                            {$lflWhere}
8129                            {$whereYear}
8130                        GROUP BY YEAR(q.{$field})
8131                        ORDER BY YEAR(q.{$field}) DESC";
8132
8133                $dateLike = DB::select($query);
8134
8135                $dateLflArray[$v] = $dateLike;
8136            }
8137
8138            $isFy = true;
8139
8140            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
8141                $isFy = false;
8142                $ytdArray = array();
8143                $ytdAcceptanceArray = array();
8144                $lflCompanyIds = array();
8145                foreach ($dateLflArray as $k => $v) {
8146                    foreach ($dateLflArray[$k] as $item) {
8147                        $year = $item->year;
8148                        $now = date('m-d');
8149                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
8150                    }
8151
8152                    $ytdArray = implode(' OR ', $ytdArray);
8153                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
8154                    $ytdArray = array();
8155                }
8156
8157                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8158                $where .= " AND ({$lflCompanyIds}";
8159            }
8160
8161            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
8162                $isFy = false;
8163                $lflArray = array();
8164                $ytdAcceptanceArray = array();
8165                $lflCompanyIds = array();
8166                foreach ($dateLflArray as $k => $v) {
8167                    foreach ($dateLflArray[$k] as $item) {
8168                        $year = $item->year;
8169                        $min_date_like = $item->min_date_like;
8170                        $max_date_like = $item->max_date_like;
8171                        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}')");
8172                    }
8173
8174                    $lflArray = implode(' OR ', $lflArray);
8175                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
8176                    $lflArray = array();
8177                }
8178
8179                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8180                $where .= " AND ({$lflCompanyIds}";
8181            }
8182
8183            if($isFy){
8184                if($companyId != 0){
8185                    $where .= " AND q.company_id = {$companyId} ";
8186                }else{
8187                    $where .= " AND q.company_id IN ({$this->companyId})";
8188                }
8189            }
8190
8191            if(isset($data['source']) && $data['source'] != null){
8192                $where .= " AND s.name = '{$data['source']}'";
8193            }
8194
8195            if(isset($data['source']) && $data['source'] != null){
8196                $where .= " AND s.name = '{$data['source']}'";
8197            }
8198
8199            if(isset($data['commercial']) && $data['commercial'] != null){
8200                $where .= " AND q.commercial = '{$data['commercial']}'";
8201            }
8202
8203            if(isset($data['created_by']) && $data['created_by'] != null){
8204                $where .= " AND q.created_by = '{$data['created_by']}'";
8205            }
8206
8207            if(isset($data['budget_type']) && $data['budget_type'] != null){
8208                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
8209            }
8210
8211            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
8212                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
8213            }
8214
8215            if(isset($data['budget_status']) && $data['budget_status'] != null){
8216                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
8217            }
8218
8219            if(isset($data['client_type']) && $data['client_type'] != null){
8220                $where .= " AND ct.customer_type_id = {$data['client_type']}";
8221            }
8222
8223            if(isset($data['segment_id']) && $data['segment_id'] != null){
8224                $where .= " AND q.segment_id = {$data['segment_id']}";
8225            }
8226
8227            $col = "q.one";
8228
8229            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
8230                if($data['data_to_display'] == 1){
8231                    $col = "q.one";
8232                }
8233
8234                if($data['data_to_display'] == 2){
8235                    $col = "q.amount";
8236                }
8237            }
8238
8239            if((isset($data['start_date']) && $data['start_date'] != null) && isset($data['end_date']) && $data['end_date'] != null){
8240                $where .= " AND q.{$field} BETWEEN '{$data['start_date']}' AND '{$data['end_date']}";
8241            }elseif((isset($data['start_date']) && $data['start_date'] == null || $data['start_date'] == "") && isset($data['end_date']) && $data['end_date'] != null){
8242                $where .= " AND q.{$field} = '{$data['end_date']}";
8243            }
8244
8245            $whereQ = $where;
8246
8247            $sortBy = array(
8248                0 => 'q.amount < 100',
8249                1 => 'q.amount BETWEEN 100 AND 500',
8250                2 => 'q.amount BETWEEN 500 AND 2000',
8251                3 => 'q.amount BETWEEN 2000 AND 10000',
8252                4 => 'q.amount BETWEEN 10000 AND 30000',
8253                5 => 'q.amount BETWEEN 30000 AND 100000',
8254                6 => 'q.amount BETWEEN 100000 AND 999999999999'
8255            );
8256
8257            $query = "SELECT
8258                        q.commercial 'name',
8259                        COUNT(q.commercial) totalCommercial
8260                    FROM tbl_quotations q
8261                    LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8262                    LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8263                    LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8264                    LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8265                    WHERE
8266                        q.for_add = 0
8267                        AND q.{$field} IS NOT NULL
8268                        AND q.for_add != 1
8269                        AND q.budget_type_id != 7
8270                        AND q.budget_type_id IS NOT NULL
8271                        {$whereQ}
8272                        {$whereYear}
8273                    GROUP BY q.commercial
8274                    HAVING COUNT(q.commercial) > 0
8275                    ORDER BY totalCommercial DESC";
8276
8277            $resultCommercials = DB::select($query);
8278
8279            if(isset($data['sort_by'])){
8280                if($data['sort_by'] != 7){
8281                    $s = $sortBy[$data['sort_by']];
8282                    $whereQ .= " AND {$s} ";
8283                }
8284            }
8285
8286            $num = "COUNT(1)";
8287
8288            if(@$data['data_to_display'] == 2){
8289                $num = "SUM(q.amount)";
8290            }
8291
8292            if(@$data['data_to_display'] == 3){
8293                $num = "SUM(q.amount) / COUNT(1)";
8294            }
8295
8296            if(@$data['data_to_display'] == 4){
8297                $num = "(SUM(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) / COUNT(q.created_at) * 100)";
8298            }
8299
8300            $query = "SELECT
8301                    q.commercial 'name',
8302                    COUNT(q.commercial) totalCommercial,
8303                    {$num} num
8304                FROM tbl_quotations q
8305                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8306                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8307                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8308                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8309                WHERE
8310                    q.for_add = 0
8311                    AND q.{$field} IS NOT NULL
8312                    AND q.for_add != 1
8313                    AND q.budget_type_id != 7
8314                    AND q.budget_type_id IS NOT NULL
8315                    {$whereQ}
8316                    {$whereYear}
8317                GROUP BY q.commercial
8318                HAVING COUNT(q.commercial) > 0
8319                ORDER BY num DESC";
8320
8321            $resultCommercialsOrder = DB::select($query);
8322
8323            foreach ($resultCommercialsOrder as $item) {
8324                $namesToRemove[$item->name] = true;
8325            }
8326
8327            $resultArray = [];
8328            foreach ($resultCommercials as $item) {
8329                if (!isset($namesToRemove[$item->name])) {
8330                    $resultArray[] = $item;
8331                }
8332            }
8333
8334            $resultCommercials = array_merge($resultCommercialsOrder, $resultArray);
8335
8336            $cols = "";
8337
8338            $colsGroupConcatIds = "";
8339
8340            foreach ($resultCommercials as $item) {
8341                $cols .= ",COALESCE(
8342                    SUM(
8343                        CASE WHEN q.commercial = '{$item->name}' THEN {$col} ELSE 0 END
8344                    ), 0
8345                ) '{$item->name}'";
8346
8347                $colsGroupConcatIds .= ",GROUP_CONCAT(CASE WHEN q.commercial = '{$item->name}' THEN q.id END) 'groupConcatIds-{$item->name}'";
8348            }
8349
8350            $cols .= ",COALESCE(
8351                SUM(
8352                    CASE WHEN q.commercial IS NOT NULL THEN {$col} ELSE 0 END
8353                ), 0
8354            ) total";
8355
8356            $range = "CASE
8357                        WHEN amount < 100 THEN '< 100€'
8358                        WHEN amount BETWEEN 100 AND 500 THEN '100€ - 500€'
8359                        WHEN amount BETWEEN 500 AND 2000 THEN '500€ - 2k€'
8360                        WHEN amount BETWEEN 2000 AND 10000 THEN '2k€ - 10k€'
8361                        WHEN amount BETWEEN 10000 AND 30000 THEN '10k€ - 30k€'
8362                        WHEN amount BETWEEN 30000 AND 100000 THEN '30k€ - 100k€'
8363                        WHEN amount BETWEEN 100000 AND 999999999999 THEN '> 100k€'
8364                    END AS amount_range";
8365
8366            if(@$data['data_to_display'] == 3){
8367
8368                $range = "CASE
8369                            WHEN SUM(amount) / COUNT(1) < 100 THEN '< 100€'
8370                            WHEN SUM(amount) / COUNT(1) BETWEEN 100 AND 500 THEN '100€ - 500€'
8371                            WHEN SUM(amount) / COUNT(1) BETWEEN 500 AND 2000 THEN '500€ - 2k€'
8372                            WHEN SUM(amount) / COUNT(1) BETWEEN 2000 AND 10000 THEN '2k€ - 10k€'
8373                            WHEN SUM(amount) / COUNT(1) BETWEEN 10000 AND 30000 THEN '10k€ - 30k€'
8374                            WHEN SUM(amount) / COUNT(1) BETWEEN 30000 AND 100000 THEN '30k€ - 100k€'
8375                            WHEN SUM(amount) / COUNT(1) BETWEEN 100000 AND 999999999999 THEN '> 100k€'
8376                        END AS amount_range";
8377
8378                $cols = "";
8379
8380                foreach ($resultCommercials as $item) {
8381                    $cols .= ",COALESCE(
8382                        (
8383                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.amount END)
8384                        ) /
8385                        (
8386                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.one END)
8387                        )
8388                    , 0) '{$item->name}'";
8389                }
8390
8391                $cols .= ",COALESCE(
8392                    (
8393                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.amount END)
8394                    ) /
8395                    (
8396                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.one END)
8397                    )
8398                , 0) total";
8399            }
8400
8401            if(@$data['data_to_display'] == 4){
8402
8403                $cols = "";
8404
8405                foreach ($resultCommercials as $item) {
8406                    $cols .= ",COALESCE(
8407                        (
8408                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.acceptanceDate END)
8409                        ) /
8410                        (
8411                            SUM(CASE WHEN q.commercial = '{$item->name}' THEN q.createdAt END)
8412                        ) * 100
8413                    , 0) '{$item->name}'";
8414                }
8415
8416                $cols .= ",COALESCE(
8417                    (
8418                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.acceptanceDate END)
8419                    ) /
8420                    (
8421                        SUM(CASE WHEN q.commercial IS NOT NULL THEN q.createdAt END)
8422                    ) * 100
8423                , 0) total";
8424            }
8425
8426            $query  = "WITH amount_ranges AS (
8427                            SELECT '< 100€' AS amount_range
8428                            UNION ALL SELECT '100€ - 500€'
8429                            UNION ALL SELECT '500€ - 2k€'
8430                            UNION ALL SELECT '2k€ - 10k€'
8431                            UNION ALL SELECT '10k€ - 30k€'
8432                            UNION ALL SELECT '30k€ - 100k€'
8433                            UNION ALL SELECT '> 100k€'
8434                        )
8435
8436                        SELECT
8437                            ar.amount_range,
8438                             GROUP_CONCAT(
8439                                q.id
8440                            ) AS groupConcatIds
8441                            {$colsGroupConcatIds}
8442                            {$cols}
8443                        FROM
8444                            amount_ranges ar
8445                        LEFT JOIN (
8446                            SELECT
8447                                commercial,
8448                                GROUP_CONCAT(
8449                                    CASE WHEN q.{$field} IS NOT NULL THEN id END
8450                                ) id,
8451                                amount AS amount,
8452                                COUNT(CASE WHEN q.created_at IS NOT NULL THEN 1 END) createdAt,
8453                                COUNT(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 END) acceptanceDate,
8454                                COUNT(1) AS one,
8455                                {$range}
8456                            FROM
8457                                tbl_quotations q
8458                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8459                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8460                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8461                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8462                            WHERE
8463                                q.{$field} IS NOT NULL
8464                                AND q.for_add = 0
8465                                AND q.for_add != 1
8466                                AND q.budget_type_id != 7
8467                                AND q.budget_type_id IS NOT NULL
8468                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
8469                                {$where}
8470                                {$whereYear}
8471                            GROUP BY
8472                                commercial,
8473                                id
8474                        ) AS q ON ar.amount_range = q.amount_range
8475                        GROUP BY
8476                            ar.amount_range WITH ROLLUP
8477                        ORDER BY
8478                            CASE
8479                                WHEN ar.amount_range = '< 100€' THEN 1
8480                                WHEN ar.amount_range = '100€ - 500€' THEN 2
8481                                WHEN ar.amount_range = '500€ - 2k€' THEN 3
8482                                WHEN ar.amount_range = '2k€ - 10k€' THEN 4
8483                                WHEN ar.amount_range = '10k€ - 30k€' THEN 5
8484                                WHEN ar.amount_range = '30k€ - 100k€' THEN 6
8485                                ELSE 7
8486                            END";
8487
8488            $value = Cache::get(base64_encode($query));
8489
8490            if(!$value){
8491                $result = DB::select($query);
8492
8493                Cache::put(base64_encode($query), $result, 600);
8494            }else{
8495                $result = $value;
8496            }
8497
8498            return response([
8499                'message' => 'OK',
8500                'data' => $result,
8501                'commercials' => $resultCommercials
8502            ]);
8503
8504        } catch (\Exception $e) {
8505            /** @disregard P1014 */
8506            $e->exceptionCode = 'LIST_QUOTATION_ANALYTICS_COMMERCIAL_EXCEPTION'; 
8507            report($e);
8508            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8509        }
8510
8511    }
8512
8513    function send_email_template_preview($emailTemplateId){
8514
8515        try {
8516
8517            $emailTemplateId = addslashes($emailTemplateId);
8518
8519            $emailTemplate = TblEmailConfiguration::where('id', $emailTemplateId)->first();
8520
8521            $user   = TblUsers::where('id', $this->userId)->first();
8522            $error  = false;
8523
8524            $toEmail = $user->email;
8525
8526            $availableParameters = [
8527                'quote_id',
8528                'company_id',
8529                'client',
8530                'client_type',
8531                'phone_number',
8532                'email',
8533                'issue_date',
8534                'request_date',
8535                'duration',
8536                'invoice_number',
8537                'type',
8538                'acceptance_date',
8539                'status',
8540                'source',
8541                'amount',
8542                'reason_for_not_following_up',
8543                'last_follow_up_date',
8544                'last_follow_up_comment',
8545                'reason_for_rejection_id',
8546                'reason_for_rejection',
8547                'commercial',
8548                'created_at',
8549                'created_by',
8550                'updated_at',
8551                'updated_by'
8552            ];
8553
8554            $dateParameters = [
8555                'issue_date',
8556                'request_date',
8557                'acceptance_date',
8558                'last_follow_up_date',
8559                'created_at',
8560                'updated_at',
8561            ];
8562
8563            if($this->locale == 'es'){
8564                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
8565            }
8566
8567            if($this->locale == 'es'){
8568                setlocale(LC_ALL, "es_ES", 'Spanish_Spain', 'Spanish');
8569            }
8570
8571            $body = $emailTemplate->html;
8572            $subject = $emailTemplate->subject;
8573
8574            preg_match_all('/{{(.*?)}}/', $body, $matches);
8575
8576            $parameters = $matches[1];
8577
8578            $result = TblQuotations::where('for_add', 0)->whereIn('company_id', $this->companyIds)->first();
8579
8580            foreach ($parameters as $parameter) {
8581
8582                if(in_array($parameter, $dateParameters)){
8583                    if($result->{$parameter}){
8584                        $result->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result->{$parameter})));
8585                    }
8586                }
8587
8588                if(in_array($parameter, $availableParameters)){
8589                    $body = str_replace('{{' . $parameter . '}}', $result->{$parameter}, $body);
8590                }
8591            }
8592
8593            preg_match_all('/{{(.*?)}}/', $subject, $matches);
8594
8595            $parameters = $matches[1];
8596
8597            foreach ($parameters as $parameter) {
8598
8599                if(in_array($parameter, $dateParameters)){
8600                    if($result->{$parameter}){
8601                        $result->{$parameter} = iconv('ISO-8859-2', 'UTF-8', strftime("%A, %B %d, %Y", strtotime($result->{$parameter})));
8602                    }
8603                }
8604
8605                if(in_array($parameter, $availableParameters)){
8606                    $subject = str_replace('{{' . $parameter . '}}', $result->{$parameter}, $subject);
8607                }
8608            }
8609
8610
8611            $email = new \SendGrid\Mail\Mail();
8612
8613            $templateFiles = TblEmailFiles::where('email_template_id', $emailTemplateId)->orderBy('order', 'asc')->get();
8614
8615            foreach ($templateFiles as $item) {
8616                $f = storage_path('app/public/uploads/' . $item->filename);
8617                $imgpath = file_get_contents($f);
8618                $mimeType = mime_content_type($f);
8619
8620                $email->addAttachment(
8621                    $imgpath,
8622                    $mimeType,
8623                    str_replace(' ', '', $item->original_name),
8624                    "inline",
8625                    str_replace(' ', '', $item->original_name),
8626                );
8627
8628                $body .= "<img src='cid:{$item->original_name}' style='height: 45px; padding-right: 6px' />";
8629            }
8630
8631            $html = '<!DOCTYPE html>';
8632            $html .= '<html>';
8633            $html .= '<head>';
8634            $html .= '<meta charset="UTF-8">';
8635            $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
8636            $html .= '</head>';
8637            $html .= '<body>';
8638            $html .= $body;
8639            $html .= '</body>';
8640            $html .= '</html>';
8641
8642            if($toEmail != null){
8643
8644                $companyEmail = null;
8645
8646                if($emailTemplate->from_id != null){
8647                    $companyEmail = TblCompanyEmails::where('id', $emailTemplate->from_id)->first();
8648                }else{
8649                    $companyEmail = TblCompanyEmails::where('is_active', 1)->where('verified', 1)->where('company_id', $result->company_id)->first();
8650                }
8651
8652                if(!$companyEmail){
8653                    return response(['message' => 'KO', 'error' => __('language.no_active_verified_sender')]);
8654                }
8655
8656                $email->setFrom($companyEmail->from_email, $companyEmail->from_name);
8657                $email->setSubject($subject);
8658                $email->addTo($toEmail);
8659                $email->addContent("text/html", $html);
8660
8661                $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
8662
8663                $response = $sendgrid->send($email);
8664                if ($response->statusCode() == 202) {
8665                    return response(['message' => 'OK']);
8666                }
8667            }
8668
8669            return response(['message' => 'KO']);
8670
8671        } catch (\Exception $e) {
8672            /** @disregard P1014 */
8673            $e->exceptionCode = 'SEND_EMAIL_TEMPLATE_EXCEPTION'; 
8674            report($e);
8675            return response(['message' => 'KO', 'error' => $e->getMessage()]);
8676        }
8677
8678    }
8679
8680    function list_quotation_analytics_by_types_of_budgets_company_per_week(Request $request){
8681
8682        try {
8683
8684            $data = $request->all();
8685            $companyId = addslashes($data['company_id']);
8686            $field = $data['field'];
8687
8688            $where = "";
8689            $whereYear = "";
8690            $dateLflArray = array();
8691            $companyIds = $this->companyIds;
8692
8693            $acc = "";
8694            if($field == 'acceptance_date'){
8695                $acc = " AND q.acceptance_date IS NOT NULL ";
8696                // $field = 'created_at';
8697
8698                if(@$data['data_to_display'] == 4){
8699                    $field = 'created_at';
8700                    $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8701                }
8702            }else{
8703                $field = 'created_at';
8704                $where .= " AND YEAR(q.created_at) = YEAR(q.issue_date)";
8705            }
8706
8707            if($companyId != 0){
8708                $companyIds = array($companyId);
8709            }
8710
8711            if(isset($data['years']) && $data['years'] != null){
8712                $years = implode(',', $data['years']);
8713                if(count($data['years']) > 0){
8714                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
8715                }
8716            }
8717
8718            foreach ($companyIds as $v) {
8719
8720                $lflWhere = " AND q.company_id = {$v} ";
8721
8722                $query = "SELECT
8723                            CONCAT(
8724                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
8725                                ' - ',
8726                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
8727                            ) AS date_like,
8728                            YEAR(q.{$field}) 'year',
8729                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
8730                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
8731                            {$v} 'company_id'
8732                        FROM
8733                            tbl_quotations q
8734                        WHERE
8735                            q.{$field} IS NOT NULL
8736                            AND q.for_add != 1
8737                            {$lflWhere}
8738                            {$whereYear}
8739                        GROUP BY YEAR(q.{$field})
8740                        ORDER BY YEAR(q.{$field}) DESC";
8741
8742                $dateLike = DB::select($query);
8743
8744                $dateLflArray[$v] = $dateLike;
8745            }
8746
8747            $isFy = true;
8748
8749            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
8750                $isFy = false;
8751                $ytdArray = array();
8752                $ytdAcceptanceArray = array();
8753                $lflCompanyIds = array();
8754                foreach ($dateLflArray as $k => $v) {
8755                    foreach ($dateLflArray[$k] as $item) {
8756                        $year = $item->year;
8757                        $now = date('m-d');
8758                        array_push($ytdArray, "DATE_FORMAT(q.{$field}, '%Y-%m-%d') BETWEEN '{$year}-01-01' AND '{$year}-{$now}'");
8759                    }
8760
8761                    $ytdArray = implode(' OR ', $ytdArray);
8762                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$ytdArray})");
8763                    $ytdArray = array();
8764                }
8765
8766                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8767                $where .= " AND ({$lflCompanyIds}";
8768            }
8769
8770            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
8771                $isFy = false;
8772                $lflArray = array();
8773                $ytdAcceptanceArray = array();
8774                $lflCompanyIds = array();
8775                foreach ($dateLflArray as $k => $v) {
8776                    foreach ($dateLflArray[$k] as $item) {
8777                        $year = $item->year;
8778                        $min_date_like = $item->min_date_like;
8779                        $max_date_like = $item->max_date_like;
8780                        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}')");
8781                    }
8782
8783                    $lflArray = implode(' OR ', $lflArray);
8784                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
8785                    $lflArray = array();
8786                }
8787
8788                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
8789                $where .= " AND ({$lflCompanyIds}";
8790            }
8791
8792            if($isFy){
8793                if($companyId != 0){
8794                    $where .= " AND q.company_id = {$companyId} ";
8795                }else{
8796                    $where .= " AND q.company_id IN ({$this->companyId})";
8797                }
8798            }
8799
8800            if(isset($data['source']) && $data['source'] != null){
8801                $where .= " AND s.name = '{$data['source']}'";
8802            }
8803
8804            if(isset($data['month']) && $data['month'] != null){
8805                $where .= " AND MONTH(q.{$field}) = '{$data['month']}'";
8806            }
8807
8808            if(isset($data['week']) && $data['week'] != null){
8809                $where .= " AND WEEK(q.{$field}) = '{$data['week']}'";
8810            }
8811
8812            if(isset($data['commercial']) && $data['commercial'] != null){
8813                $where .= " AND q.commercial = '{$data['commercial']}'";
8814            }
8815
8816            if(isset($data['created_by']) && $data['created_by'] != null){
8817                $where .= " AND q.created_by = '{$data['created_by']}'";
8818            }
8819
8820            if(isset($data['budget_type']) && $data['budget_type'] != null){
8821                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
8822            }
8823
8824            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
8825                $where .= " AND bt.budget_type_group_id = {$data['budget_type_group']}";
8826            }
8827
8828            if(isset($data['budget_status']) && $data['budget_status'] != null){
8829                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
8830            }
8831
8832            if(isset($data['client_type']) && $data['client_type'] != null){
8833                $where .= " AND ct.customer_type_id = {$data['client_type']}";
8834            }
8835
8836            if(isset($data['segment_id']) && $data['segment_id'] != null){
8837                $where .= " AND q.segment_id = {$data['segment_id']}";
8838            }
8839
8840            $col = "1";
8841
8842            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
8843                if($data['data_to_display'] == 1){
8844                    $col = "1";
8845                }
8846
8847                if($data['data_to_display'] == 2){
8848                    $col = "q.amount";
8849                }
8850            }
8851
8852            $budgetTypes = TblBudgetTypes::orderByRaw("ISNULL(priority), priority ASC")->get();
8853            $cols = "";
8854            foreach ($budgetTypes as $item) {
8855                if($item->name == '' || $item->name == null){
8856                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} ELSE 0 END), 0) AS 'Otros'";
8857                }else{
8858                    $cols .= ",COALESCE(SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN {$col} ELSE 0 END), 0) AS '{$item->name}'";
8859                }
8860            }
8861
8862            $budgetTypeGroups = TblBudgetTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
8863
8864            $colsGroups = ",COALESCE(SUM(CASE WHEN bt.name IS NULL {$acc} THEN {$col} END), 0) AS Otros";
8865
8866            foreach ($budgetTypeGroups as $item) {
8867                $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8868                $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}'";
8869                $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}'";
8870            }
8871
8872            $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";
8873
8874            $col = $colsGroups . $cols;
8875
8876            if(@$data['data_to_display'] == 3){
8877
8878                $cols = "";
8879                foreach ($budgetTypes as $item) {
8880                    if($item->name == '' || $item->name == null){
8881                        $cols .= ",COALESCE(
8882                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount ELSE 0 END) /
8883                                        SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 ELSE 0 END) * 100
8884                                    , 0) AS 'Otros'";
8885                    }else{
8886                        $cols .= ", COALESCE(
8887                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN q.amount ELSE 0 END) /
8888                                        SUM(CASE WHEN bt.name = '{$item->name}{$acc} THEN 1 ELSE 0 END)
8889                                    , 0) AS '{$item->name}'";
8890                    }
8891                }
8892
8893                $colsGroups = ",COALESCE(
8894                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN q.amount END)) /
8895                                (SUM(CASE WHEN bt.name IS NULL {$acc} THEN 1 END))
8896                            , 0) Otros";
8897
8898                foreach ($budgetTypeGroups as $item) {
8899                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8900                    $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}'";
8901                    $colsGroups .= ",COALESCE(
8902                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN q.amount END)) /
8903                                        (SUM(CASE WHEN (bt.budget_type_group_id = {$item->budget_type_group_id} OR bt.name IS NULL) {$acc} THEN 1 END))
8904                                    , 0) '{$budgetTypeGroupName}'";
8905                }
8906
8907                $colsGroups .= ",COALESCE(
8908                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.amount END)) /
8909                                    (SUM(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN 1 END))
8910                                , 0) total";
8911
8912                $col = $colsGroups . $cols;
8913            }
8914
8915            if(@$data['data_to_display'] == 4){
8916
8917                $cols = "";
8918
8919                foreach ($budgetTypes as $item) {
8920
8921                    if($item->name == '' || $item->name == null){
8922                        $cols .= ",COALESCE(
8923                                        SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 ELSE 0 END) /
8924                                        SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 ELSE 0 END) * 100
8925                                    , 0) AS 'Otros'";
8926                    }else{
8927                        $cols .= ", COALESCE(
8928                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.acceptance_date IS NOT NULL THEN 1 END) /
8929                                        SUM(CASE WHEN bt.name = '{$item->name}' AND q.created_at IS NOT NULL THEN 1 END) * 100
8930                                    , 0) AS '{$item->name}'";
8931                    }
8932                }
8933
8934                $colsGroups = ",COALESCE(
8935                                    (SUM(CASE WHEN bt.name IS NULL AND q.acceptance_date IS NOT NULL THEN 1 END)) /
8936                                    (SUM(CASE WHEN bt.name IS NULL AND q.created_at IS NOT NULL THEN 1 END)) * 100
8937                                , 0) Otros";
8938
8939                foreach ($budgetTypeGroups as $item) {
8940                    $budgetTypeGroupName = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
8941                    $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}'";
8942                    $colsGroups .= ",COALESCE(
8943                                        (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)) /
8944                                        (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
8945                                    , 0) '{$budgetTypeGroupName}'";
8946                }
8947
8948                $colsGroups .= ",COALESCE(
8949                                    (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)) /
8950                                    (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
8951                                    , 0) total";
8952
8953                $col = $colsGroups . $cols;
8954            }
8955
8956            $query  = "SELECT
8957                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)) AS 'year',
8958                            LPAD(MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)), 2, 0) AS 'month',
8959                            q.company_id,
8960                            c.name 'companyName',
8961                            GROUP_CONCAT(CASE WHEN (bt.budget_type_group_id IS NOT NULL OR bt.name IS NULL) {$acc} THEN q.id END) groupConcatIds
8962                            {$col}
8963                        FROM
8964                            tbl_quotations q
8965                            LEFT JOIN tbl_sources s ON s.source_id = q.source_id
8966                            LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
8967                            LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
8968                            LEFT JOIN tbl_budget_type_groups btg ON bt.budget_type_group_id = btg.budget_type_group_id
8969                            LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
8970                            LEFT JOIN tbl_companies c ON q.company_id = c.company_id
8971                        WHERE
8972                            q.{$field} IS NOT NULL
8973                            AND q.for_add != 1
8974                            AND q.budget_type_id != 7
8975                            AND q.budget_type_id IS NOT NULL
8976                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1                            
8977                            {$where}
8978                            {$whereYear}
8979                        GROUP BY
8980                            YEAR(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
8981                            MONTH(DATE_ADD(q.{$field}, INTERVAL - WEEKDAY(q.{$field}) DAY)),
8982                            q.company_id WITH ROLLUP
8983                        ORDER BY
8984                            YEAR DESC,
8985                            MONTH ASC,
8986                            q.company_id ASC,
8987                            DATE_FORMAT(q.{$field}, '%e') ASC";
8988
8989            $result = DB::select($query);
8990
8991            $query = "SELECT
8992                        btg.budget_type_group_id,
8993                        btg.name,
8994                        (
8995                            SELECT
8996                                GROUP_CONCAT(COALESCE(bt.name, '') ORDER BY ISNULL(bt.priority), bt.priority ASC SEPARATOR '|')
8997                            FROM
8998                                tbl_budget_types bt
8999                            WHERE
9000                                bt.budget_type_group_id = btg.budget_type_group_id
9001                        ) budget_types
9002                        FROM
9003                            tbl_budget_type_groups btg
9004                        ORDER BY
9005                            ISNULL(btg.priority),
9006                            btg.priority ASC";
9007
9008            $budgetTypeGroups = DB::select($query);
9009
9010            foreach ($budgetTypeGroups as $item) {
9011                $item->group_key_name = str_replace(" ", "", $item->name) . $item->budget_type_group_id;
9012                $item->budget_types = explode("|", $item->budget_types);
9013            }
9014
9015            return response([
9016                'message' => 'OK',
9017                'data' => $result,
9018                'budgetTypeGroups' => $budgetTypeGroups
9019            ]);
9020
9021        } catch (\Exception $e) {
9022            /** @disregard P1014 */
9023            $e->exceptionCode = 'LIST_QUOTATION_ANALYTICS_BY_TYPES_OF_BUDGETS_COMPANT_PER_WEEK_EXCEPTION'; 
9024            report($e);
9025            return response(['message' => 'KO', 'error' => $e->getMessage()]);
9026        }
9027    }
9028
9029    function request_permission_commercial(Request $request){
9030
9031        try {
9032
9033            $data = $request->all();
9034
9035            $id = addslashes($data['id']);
9036            $requestedBy = $data['requested_by'];
9037            $body = "";
9038
9039            $result = TblQuotations::where('id', $id)->first();
9040
9041            $subject = __('language.request_permission_commercial.subject');
9042            $subject = str_replace('{{quote_id}}', $result->quote_id, $subject);
9043            $subject = str_replace('{{username}}', $requestedBy, $subject);
9044
9045            $email = new \SendGrid\Mail\Mail();
9046
9047            $imgpath = File::get('fireservicetitan.png');
9048
9049            $email->addAttachment(
9050                $imgpath,
9051                "image/png",
9052                "fireservicetitan.png",
9053                "inline",
9054                "fireservicetitan"
9055            );
9056
9057            $url = env('URL') . "orders/{$id}?company_id={$result->company_id}";
9058            $href = "<a href='{$url}'>{$result->quote_id}</a>";
9059
9060            $user = TblUsers::where('name', $requestedBy)->first();
9061
9062            $urlClick = env('URL') . "update?confirm_request={$id}&requested_by={$user->id}&quote_id={$result->quote_id}";
9063            $company = TblCompanies::where('company_id', $result->company_id)->first();
9064
9065            $body .= __('language.request_permission_commercial.body_hello');
9066            $body .= __('language.request_permission_commercial.body_message');
9067
9068            $amount = $this->currency($result->amount, 1);
9069
9070            $body = str_replace('{{commercial}}', $result->commercial, $body);
9071            $body = str_replace('{{company}}', $company->name, $body);
9072            $body = str_replace('{{client}}', $result->client, $body);
9073            $body = str_replace('{{amount}}', $amount, $body);
9074            $body = str_replace('{{quote_id}}', $href, $body);
9075            $body = str_replace('{{click}}', $urlClick, $body);
9076            $body = str_replace('{{username}}', $requestedBy, $body);
9077
9078            $body .= "<p>Fire Service Titan</p>";
9079            $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
9080
9081            $html = '<!DOCTYPE html>';
9082            $html .= '<html>';
9083            $html .= '<head>';
9084            $html .= '<meta charset="UTF-8">';
9085            $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
9086            $html .= '</head>';
9087            $html .= '<body>';
9088            $html .= $body;
9089            $html .= '</body>';
9090            $html .= '</html>';
9091
9092            $user = TblUsers::where('id', $this->userId)->first();
9093
9094            if(env('SENDGRID_STAGING')){
9095                $email->addTo($user->email);
9096            }else{
9097                $email->addTo("luis.collar@fire.es");
9098
9099                $user = TblUsers::where('name', $result->created_by)->first();
9100                if($user && $user->email != "luis.collar@fire.es"){
9101                    $email->addTo($user->email);
9102                }
9103
9104                if($result->created_by != $result->commercial){
9105                    $user = TblUsers::where('name', $result->commercial)->first();
9106                    if($user->email != "luis.collar@fire.es"){
9107                        $email->addTo($user->email);
9108                    }
9109                }
9110            }
9111
9112            $email->setFrom("titan@fire.es");
9113            $email->setSubject($subject);
9114
9115            $email->addContent("text/html", $html);
9116
9117            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
9118
9119            $response = $sendgrid->send($email);
9120            if ($response->statusCode() == 202) {
9121                return response(['message' => 'OK']);
9122            }
9123
9124            return response(['message' => 'KO']);
9125
9126        } catch (\Exception $e) {
9127            /** @disregard P1014 */
9128            $e->exceptionCode = 'REQUEST_PERMISSION_EXCEPTION'; 
9129            report($e);
9130            return response(['message' => 'KO', 'error' => $e->getMessage()]);
9131        }
9132
9133    }
9134
9135    function confirm_update_commercial(Request $request){
9136
9137        try {
9138            sleep(3);
9139            $data = $request->all();
9140            $id = addslashes($data['id']);
9141            $userId = addslashes($data['requested_by']);
9142
9143            $user = TblUsers::where('id', $userId)->first();
9144
9145            if($user){
9146
9147                TblQuotations::where('id', $data['id'])->update(
9148                    array(
9149                        'commercial' => $user->name,
9150                        'updated_at' => date('Y-m-d H:i:s')
9151                    )
9152                );
9153
9154            }else{
9155                return response(['message' => 'KO', 'error' => 'invalid_user']);
9156            }
9157
9158            return response(['message' => 'OK']);
9159
9160        } catch (\Exception $e) {
9161            /** @disregard P1014 */
9162            $e->exceptionCode = 'CONFIRM_UPDATE_COMMERCIAL_EXCEPTION'; 
9163            report($e);
9164            return response(['message' => 'KO', 'error' => $e->getMessage()]);
9165        }
9166    }
9167
9168    function calculateEmailRequestSize(Mail $email){
9169
9170        $size = 0;
9171
9172        // Add size of 'from', 'to', 'subject', 'content'
9173        $from = $email->getFrom();
9174        $size += strlen(json_encode([
9175            'from' => $from->getEmail() . ' ' . $from->getName(),
9176            'subject' => $email->getSubject()
9177        ]));
9178
9179        // Add size of 'to' (recipients)
9180        $personalizations = $email->getPersonalization();
9181        foreach ($personalizations as $personalization) {
9182            foreach ($personalization->getTos() as $to) {
9183                $size += strlen($to->getEmail() . ' ' . $to->getName());
9184            }
9185        }
9186
9187        // Add size of content
9188        foreach ($email->getContents() as $content) {
9189            $size += strlen($content->getValue());
9190        }
9191
9192        // Add size of attachments (if any)
9193
9194        if($email->getAttachments() != null && $email->getAttachments() != ""){
9195            foreach ($email->getAttachments() as $attachment) {
9196                $size += strlen($attachment->getContent()); // Base64 encoded size
9197                $size += strlen($attachment->getFilename());
9198                $size += strlen($attachment->getType());
9199            }
9200        }
9201
9202        $sizeInMegabytes = $size / 1048576; // 1 MB = 1,048,576 bytes
9203
9204        return (int) ceil($sizeInMegabytes);
9205    }
9206
9207    public function list_quotation_analytics_commercial_productivity(Request $request){
9208        Log::info($request);    
9209
9210        // try {
9211
9212            $data = $request->all();
9213            $companyId = addslashes($data['company_id']);
9214
9215            $where = "";
9216            $whereYear = "";
9217            $whereVisit = "";
9218
9219            $dateLflArray = array();
9220            $companyIds = $this->companyIds;
9221
9222            if($companyId != 0){
9223                $companyIds = array($companyId);
9224            }
9225
9226            $field = "issue_date";
9227
9228            if(isset($data['years']) && $data['years'] != null){
9229                $years = implode(',', $data['years']);
9230                if(count($data['years']) > 0){
9231                    $whereYear = " AND YEAR(q.{$field}) IN ({$years})";
9232                }
9233            }
9234
9235            foreach ($companyIds as $v) {
9236
9237                $lflWhere = " AND q.company_id = {$v} ";
9238
9239                $query = "SELECT
9240                            CONCAT(
9241                                DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field}),
9242                                ' - ',
9243                                DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%c/%e/'), YEAR({$field})
9244                            ) AS date_like,
9245                            YEAR(q.{$field}) 'year',
9246                            DATE_FORMAT((SELECT MIN(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS min_date_like,
9247                            DATE_FORMAT((SELECT MAX(q.{$field}) FROM tbl_quotations q WHERE q.{$field} IS NOT NULL {$lflWhere}), '%m-%d') AS max_date_like,
9248                            {$v} 'company_id'
9249                        FROM
9250                            tbl_quotations q
9251                        WHERE
9252                            q.{$field} IS NOT NULL
9253                            AND q.for_add != 1
9254                            {$lflWhere}
9255                            {$whereYear}
9256                        GROUP BY YEAR(q.{$field})
9257                        ORDER BY YEAR(q.{$field}) DESC";
9258
9259                $dateLike = DB::select($query);
9260
9261                if(count($dateLike) > 0){
9262                    $dateLflArray[$v] = $dateLike;
9263                }
9264            }
9265
9266            $whereAcceptanceDate = "";
9267
9268            if(isset($data['source']) && $data['source'] != null){
9269                $where .= " AND s.name = '{$data['source']}'";
9270            }
9271
9272            if(isset($data['month']) && $data['month'] != null){
9273                $where .= " AND MONTH(q.created_at) = '{$data['month']}'";
9274            }
9275
9276            if(isset($data['week']) && $data['week'] != null){
9277                $where .= " AND WEEK(q.created_at) = '{$data['week']}'";
9278            }
9279
9280            if(isset($data['commercial']) && $data['commercial'] != null){
9281                $commercial = implode("','", $data['commercial']);
9282                if(count($data['commercial']) > 0){
9283                    $where .= " AND q.commercial IN ('{$commercial}') ";
9284                    $whereVisit .= " AND q.commercial IN ('{$commercial}') ";
9285                }
9286            }
9287
9288            if(isset($data['created_by']) && $data['created_by'] != null){
9289                $created_by = implode("','", $data['created_by']);
9290                if(count($data['created_by']) > 0){
9291                    $where .= " AND q.created_by IN ('{$created_by}')";
9292                }
9293            }
9294
9295            if(isset($data['budget_type']) && $data['budget_type'] != null){
9296                $where .= " AND bt.budget_type_id = {$data['budget_type']}";
9297            }
9298
9299            if(isset($data['budget_type_group']) && $data['budget_type_group'] != null){
9300                $budgetTypeGroupIds = implode(",", $data['budget_type_group']);
9301                if(count($data['budget_type_group']) > 0){
9302                    $where .= " AND bt.budget_type_group_id IN ({$budgetTypeGroupIds})";
9303                }
9304            }
9305
9306            if(isset($data['budget_status']) && $data['budget_status'] != null){
9307                $where .= " AND bs.budget_status_id = {$data['budget_status']}";
9308            }
9309
9310            if(isset($data['client_type']) && $data['client_type'] != null){
9311                $where .= " AND ct.customer_type_id = {$data['client_type']}";
9312            }
9313
9314            if(isset($data['segment_id']) && $data['segment_id'] != null){
9315                $where .= " AND q.segment_id = {$data['segment_id']}";
9316            }
9317
9318            if(isset($data['role_id']) && $data['role_id'] != null){
9319                $roleId = implode(",", $data['role_id']);
9320                if(count($data['role_id']) > 0){
9321                    $where .= " AND r.role_id IN ({$roleId})";
9322                    $whereVisit .= " AND r.role_id IN ({$roleId}";
9323                }
9324            }
9325
9326            $groupByFilter = 2;
9327            if(isset($data['group_by']) && $data['group_by'] != null){
9328                $groupByFilter = $data['group_by'];
9329            }
9330
9331            $groupBy = "1, 2, 3, q.commercial, budget_type";
9332
9333            if($groupByFilter == 1){
9334                $groupBy = "1, q.commercial, 2, 3, budget_type";
9335            }
9336
9337            if($groupByFilter == 3){
9338                $groupBy = "1, budget_type, q.commercial, 2, 3";
9339            }
9340
9341            $aggregatedBy = 1;
9342            $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', LPAD(q.week, 2, 0) AS 'week', ";
9343            $aggregatedByCalc = " / 4";
9344            if(isset($data['aggregated_by']) && $data['aggregated_by'] != null){
9345                $aggregatedBy = $data['aggregated_by'];
9346                if($data['aggregated_by'] == 1){
9347
9348                    $groupBy = "1, 2, 3, q.commercial, budget_type";
9349
9350                    if($groupByFilter == 1){
9351                        $groupBy = "1, q.commercial, 2, 3, budget_type";
9352                    }
9353
9354                    if($groupByFilter == 3){
9355                        $groupBy = "1, budget_type, q.commercial, 2, 3";
9356                    }
9357
9358                    $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', LPAD(q.week, 2, 0) AS 'week', ";
9359                }elseif($data['aggregated_by'] == 2){
9360                    $groupBy = "1, 2, q.commercial, budget_type";
9361
9362                    if($groupByFilter == 1){
9363                        $groupBy = "1, q.commercial, 2, budget_type";
9364                    }
9365
9366                    if($groupByFilter == 3){
9367                        $groupBy = "1, budget_type, q.commercial, 2";
9368                    }
9369
9370                    $aggregatedCol = "LPAD(q.month, 2, 0) AS 'month', NULL AS 'week',";
9371                    $aggregatedByCalc = "";
9372                }elseif($data['aggregated_by'] == 3){
9373                    $groupBy = "1, q.commercial, budget_type";
9374
9375                    if($groupByFilter == 3){
9376                        $groupBy = "1, budget_type, q.commercial";
9377                    }
9378
9379                    $aggregatedCol = "NULL AS 'month', NULL AS 'week',";
9380                    $aggregatedByCalc = " * 12";
9381                }
9382            }
9383
9384            $whereAcceptanceDate = $where;
9385            $whereCreatedAt = $where;
9386
9387            $isFy = true;
9388
9389            if($companyId != 0){
9390                $where .= " AND q.company_id = {$companyId} ";
9391                $whereCreatedAt .= " AND q.company_id = {$companyId} ";
9392                $whereAcceptanceDate .= " AND q.company_id = {$companyId} ";
9393                $whereVisit .= " AND q.company_id = {$companyId} ";
9394            }else{
9395                $where .= " AND q.company_id IN ({$this->companyId}";
9396                $whereCreatedAt .= " AND q.company_id IN ({$this->companyId}";
9397                $whereAcceptanceDate .= " AND q.company_id IN ({$this->companyId}";
9398                $whereVisit .= " AND q.company_id IN ({$this->companyId}";
9399            }
9400
9401            if(isset($data['campaign']) && $data['campaign'] != null){
9402                $campaign = implode("','", $data['campaign']);
9403                if(count($data['campaign']) > 0){
9404                    $whereVisit .= " AND q.campaign IN ('{$campaign}')";
9405                }
9406            }
9407
9408            if(isset($data['ytd']) && $data['ytd'] != null && $data['ytd'] == true){
9409                $isFy = false;
9410                $now = date('m-d');
9411
9412                $where .= " AND q.{$field} BETWEEN DATE_FORMAT(q.{$field}, '%Y-01-01') AND DATE_FORMAT(q.{$field}, '%Y-{$now}') ";
9413                $whereCreatedAt .= " AND q.created_at BETWEEN DATE_FORMAT(q.created_at, '%Y-01-01') AND DATE_FORMAT(q.created_at, '%Y-{$now}') ";
9414                $whereAcceptanceDate .= " AND q.acceptance_date BETWEEN DATE_FORMAT(q.acceptance_date, '%Y-01-01') AND DATE_FORMAT(q.acceptance_date, '%Y-{$now}') ";
9415                $whereVisit .= " AND q.visit_date BETWEEN DATE_FORMAT(q.visit_date, '%Y-01-01') AND DATE_FORMAT(q.visit_date, '%Y-{$now}') ";
9416            }
9417
9418            if(isset($data['lfl']) && $data['lfl'] != null && $data['lfl'] == true){
9419                $isFy = false;
9420                $lflArray = array();
9421                $ytdAcceptanceArray = array();
9422                $lflCompanyIds = array();
9423                $lflCompanyIdsAcc = array();
9424                foreach ($dateLflArray as $k => $v) {
9425                    foreach ($dateLflArray[$k] as $item) {
9426                        $year = $item->year;
9427                        $min_date_like = $item->min_date_like;
9428                        $max_date_like = $item->max_date_like;
9429                        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}')");
9430                        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}')");
9431                    }
9432
9433                    $lflArray = implode(' OR ', $lflArray);
9434                    array_push($lflCompanyIds, "q.company_id = {$k} AND ({$lflArray})");
9435                    $lflArray = array();
9436
9437                    $ytdAcceptanceArray = implode(' OR ', $ytdAcceptanceArray);
9438                    array_push($lflCompanyIdsAcc, "q.company_id = {$k} AND ({$ytdAcceptanceArray})");
9439                    $ytdAcceptanceArray = array();
9440                }
9441
9442                $lflCompanyIds = implode(' OR ', $lflCompanyIds);
9443                $where .= " AND ({$lflCompanyIds}";
9444
9445                $lflCompanyIdsAcc = implode(' OR ', $lflCompanyIdsAcc);
9446                $whereAcceptanceDate .= " AND ({$lflCompanyIdsAcc}";
9447            }
9448
9449            $orderBy = "CASE WHEN q.commercial IS NULL OR q.budget_type IS NULL THEN q.priority END DESC, q.priority ASC,";
9450
9451            if(isset($data['order_by'])){
9452                $col = $data['order_by']['column'];
9453                $sort = $data['order_by']['sort'];
9454
9455                if(!empty($sort) || $sort != null){
9456                    $orderBy = "CASE WHEN q.commercial IS NULL OR q.budget_type IS NULL THEN {$col} END DESC, {$col} {$sort},";
9457                }
9458            }
9459
9460
9461            $visitTypes = TblVisitTypeGroups::orderByRaw("ISNULL(priority), priority ASC")->get();
9462
9463            $visitCols = "";
9464            $visitMainTableCols = "";
9465            $visitSubMainTableCols = "";
9466            $visitSubTableCols = "";
9467            $visitMainCols = "";
9468
9469            $visitCall = array("Visita", "Llamada");
9470
9471            foreach ($visitCall as $value) {
9472                foreach ($visitTypes as $item) {
9473                    $visitTypeNames = $value . $item->visit_type_group_id;
9474                    $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}'";
9475                    $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}'";
9476                    $visitMainTableCols .= ",COALESCE(SUM(q.total{$visitTypeNames}), 0) AS 'total{$visitTypeNames}'";
9477                    $visitMainTableCols .= ",GROUP_CONCAT(q.groupConcatIds{$visitTypeNames})  AS 'groupConcatIds{$visitTypeNames}'";
9478                    $visitSubMainTableCols .= ",q.total{$visitTypeNames}";
9479                    $visitSubMainTableCols .= ",q.groupConcatIds{$visitTypeNames}";
9480                    $visitSubTableCols .= ",0 AS total{$visitTypeNames}";
9481                    $visitSubTableCols .= ",NULL AS groupConcatIds{$visitTypeNames}";
9482                    $visitMainCols .= ",COALESCE(SUM(q.total{$visitTypeNames}), 0) total{$visitTypeNames}";
9483                    $visitMainCols .= ",GROUP_CONCAT(q.groupConcatIds{$visitTypeNames}) groupConcatIds{$visitTypeNames}";
9484                }
9485            }
9486
9487
9488            $businessGoalsDefault = TblBusinessGoals::where('is_default', 1)->where('budget_type_group_id', 999999999)->first();
9489
9490            $businessGoalsDefault->issue_objective = $businessGoalsDefault->issue_objective ?? 1;
9491            $businessGoalsDefault->acceptance_objective = $businessGoalsDefault->acceptance_objective ?? 1;
9492            $businessGoalsDefault->new_objective = $businessGoalsDefault->new_objective ?? 1;
9493            $businessGoalsDefault->is_amount = $businessGoalsDefault->is_amount ?? 1;
9494
9495            $gO = "";
9496
9497            if($groupByFilter != 3){
9498                $gO = "ORDER BY
9499                        1 DESC,
9500                        2 ASC,
9501                        3 ASC,
9502                        q.commercial ASC,
9503                        {$orderBy}
9504                        DATE_FORMAT(q.namedate, '%e') ASC";
9505            }else{
9506                $gO = "ORDER BY
9507                        1 DESC,
9508                        2 ASC,
9509                        3 ASC,
9510                        budget_type ASC,
9511                        q.commercial ASC";
9512            }
9513
9514            $query = "WITH business_goal_objective_users AS (
9515                        SELECT
9516                            bg.user_id,
9517                            bg.issue_objective,
9518                            bg.acceptance_objective,
9519                            bg.new_objective,
9520                            bg.is_amount
9521                        FROM tbl_business_goals bg
9522                        WHERE bg.budget_type_group_id = 999999999
9523                    ), business_goal_objective_roles AS (
9524                        SELECT
9525                            bg.role_id,
9526                            bg.issue_objective,
9527                            bg.acceptance_objective,
9528                            bg.new_objective,
9529                            bg.is_amount
9530                        FROM tbl_business_goals bg
9531                        WHERE bg.budget_type_group_id = 999999999
9532                    )
9533
9534                    SELECT
9535                        q.year,
9536                        {$aggregatedCol}
9537                        q.namedate created_at,
9538                        q.commercial,
9539                        q.budget_type,
9540                        COALESCE(SUM(q.issue_date), 0) totalIssue,
9541                        COALESCE(SUM(q.created_at), 0) totalCreatedAt,
9542                        GROUP_CONCAT(q.groupConcatIds) groupConcatIds,
9543                        CASE
9544                            WHEN SUM(q.is_amountIssue) > 0 THEN
9545                                (SUM(q.revenueIssue) / NULLIF(SUM(q.issueObjective), 0)) * 100
9546                            ELSE
9547                                (SUM(q.issue_date) / NULLIF(SUM(q.issueObjective), 0)) * 100
9548                        END AS totalIssueObjective,
9549                        CASE
9550                            WHEN (CASE
9551                                WHEN SUM(q.is_amountIssue) > 0 THEN
9552                                    (SUM(q.revenueIssue) / NULLIF(SUM(q.issueObjective), 0)) * 100
9553                                ELSE
9554                                    (SUM(q.issue_date) / NULLIF(SUM(q.issueObjective), 0)) * 100
9555                            END) BETWEEN 1 AND 70 THEN 'text-danger'
9556                            WHEN (CASE
9557                                WHEN SUM(q.is_amountIssue) > 0 THEN
9558                                    (SUM(q.revenueIssue) / NULLIF(SUM(q.issueObjective), 0)) * 100
9559                                ELSE
9560                                    (SUM(q.issue_date) / NULLIF(SUM(q.issueObjective), 0)) * 100
9561                            END) BETWEEN 70 AND 90 THEN 'text-warning'
9562                        END textIssueColor,
9563                        SUM(q.revenueIssue) revenueIssue,
9564                        CASE
9565                            WHEN SUM(q.is_amountIssue) > 0 THEN
9566                                (SUM(q.revenueIssue) / NULLIF(SUM(q.issueObjectiveMonthly), 0)) * 100
9567                            ELSE
9568                                (SUM(q.issue_date) / NULLIF(SUM(q.issueObjectiveMonthly), 0)) * 100
9569                        END AS totalIssueObjectiveMonthly,
9570                        CASE
9571                            WHEN SUM(q.is_amountIssue) > 0 THEN
9572                                (SUM(q.revenueIssue) / NULLIF(SUM(q.issueObjectiveYearly), 0)) * 100
9573                            ELSE
9574                                (SUM(q.issue_date) / NULLIF(SUM(q.issueObjectiveYearly), 0)) * 100
9575                        END AS totalIssueObjectiveYearly,
9576                        COALESCE(SUM(q.acceptance_date), 0) totalAcceptance,
9577                        GROUP_CONCAT(q.groupConcatCreatedAtIds) groupConcatCreatedAtIds,
9578                        SUM(q.totalIssueLessThan5) AS totalIssueLessThan5,
9579                        GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) AS groupConcatIdsIssueLessThan5,
9580                        GROUP_CONCAT(q.groupConcatAcceptanceIds) groupConcatAcceptanceIds,
9581                        CASE
9582                            WHEN SUM(q.is_amountAcceptance) > 0 THEN
9583                                (SUM(q.revenueAcceptance) / NULLIF(SUM(q.acceptanceObjective), 0)) * 100
9584                            ELSE
9585                                (SUM(q.acceptance_date) / NULLIF(SUM(q.acceptanceObjective), 0)) * 100
9586                        END AS totalAcceptanceObjective,
9587                        CASE
9588                            WHEN SUM(q.is_amountAcceptance) > 0 THEN
9589                                (SUM(q.revenueAcceptance) / NULLIF(SUM(q.acceptanceObjectiveMonthly), 0)) * 100
9590                            ELSE
9591                                (SUM(q.acceptance_date) / NULLIF(SUM(q.acceptanceObjectiveMonthly), 0)) * 100
9592                        END AS totalAcceptanceObjectiveMonthly,
9593                        CASE
9594                            WHEN SUM(q.is_amountAcceptance) > 0 THEN
9595                                (SUM(q.revenueAcceptance) / NULLIF(SUM(q.acceptanceObjectiveYearly), 0)) * 100
9596                            ELSE
9597                                (SUM(q.acceptance_date) / NULLIF(SUM(q.acceptanceObjectiveYearly), 0)) * 100
9598                        END AS totalAcceptanceObjectiveYearly,
9599                        CASE
9600                            WHEN (CASE
9601                                WHEN SUM(q.is_amountAcceptance) > 0 THEN
9602                                    (SUM(q.revenueAcceptance) / NULLIF(SUM(q.acceptanceObjective), 0)) * 100
9603                                ELSE
9604                                    (SUM(q.acceptance_date) / NULLIF(SUM(q.acceptanceObjective), 0)) * 100
9605                            END) BETWEEN 1 AND 70 THEN 'text-danger'
9606                            WHEN (CASE
9607                                WHEN SUM(q.is_amountAcceptance) > 0 THEN
9608                                    (SUM(q.revenueAcceptance) / NULLIF(SUM(q.acceptanceObjective), 0)) * 100
9609                                ELSE
9610                                    (SUM(q.acceptance_date) / NULLIF(SUM(q.acceptanceObjective), 0)) * 100
9611                            END) BETWEEN 70 AND 90 THEN 'text-warning'
9612                        END textAcceptanceColor,
9613                        SUM(q.revenueAcceptance) revenueAcceptance,
9614                        COALESCE(SUM(q.totalRejected), 0) totalRejected,
9615                        GROUP_CONCAT(q.groupConcatRejectedIds) groupConcatRejectedIds,
9616                        SUM(q.revenueRejected) revenueRejected,
9617                        COALESCE(SUM(q.totalNew)) totalNew,
9618                        GROUP_CONCAT(q.groupConcatNewIds) groupConcatNewIds,
9619                        CASE
9620                            WHEN SUM(q.is_amountNew) > 0 THEN
9621                                (SUM(q.revenueNew) / NULLIF(SUM(q.newObjective), 0)) * 100
9622                            ELSE
9623                                (SUM(q.totalNew) / NULLIF(SUM(q.newObjective), 0)) * 100
9624                        END AS totalNewObjective,
9625                        CASE
9626                            WHEN SUM(q.is_amountNew) > 0 THEN
9627                                (SUM(q.revenueNew) / NULLIF(SUM(q.newObjectiveMonthly), 0)) * 100
9628                            ELSE
9629                                (SUM(q.totalNew) / NULLIF(SUM(q.newObjectiveMonthly), 0)) * 100
9630                        END AS totalNewObjectiveMonthly,
9631                        CASE
9632                            WHEN SUM(q.is_amountNew) > 0 THEN
9633                                (SUM(q.revenueNew) / NULLIF(SUM(q.newObjectiveYearly), 0)) * 100
9634                            ELSE
9635                                (SUM(q.totalNew) / NULLIF(SUM(q.newObjectiveYearly), 0)) * 100
9636                        END AS totalNewObjectiveYearly,
9637                        CASE
9638                            WHEN (CASE
9639                                WHEN SUM(q.is_amountNew) > 0 THEN
9640                                    (SUM(q.revenueNew) / NULLIF(SUM(q.newObjective), 0)) * 100
9641                                ELSE
9642                                    (SUM(q.totalNew) / NULLIF(SUM(q.newObjective), 0)) * 100
9643                            END) BETWEEN 1 AND 70 THEN 'text-danger'
9644                            WHEN (CASE
9645                                WHEN SUM(q.is_amountNew) > 0 THEN
9646                                    (SUM(q.revenueNew) / NULLIF(SUM(q.newObjective), 0)) * 100
9647                                ELSE
9648                                    (SUM(q.totalNew) / NULLIF(SUM(q.newObjective), 0)) * 100
9649                            END) BETWEEN 70 AND 90 THEN 'text-warning'
9650                        END textNewColor,
9651                        SUM(q.revenueNew) revenueNew,
9652                        COALESCE(SUM(q.totalVisit), 0) totalVisit,
9653                        GROUP_CONCAT(q.groupConcatVisitIds) groupConcatVisitIds,
9654                        COALESCE(SUM(q.totalCall), 0) totalCall,
9655                        GROUP_CONCAT(q.groupConcatCallIds) groupConcatCallIds,
9656                        SUM(q.is_amountIssue) AS is_amountIssue,
9657                        SUM(q.is_amountNew) AS is_amountNew,
9658                        SUM(q.is_amountAcceptance) AS is_amountAcceptance,
9659                        SUM(q.issueObjective) AS issueObjective,
9660                        SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9661                        SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9662                        SUM(q.newObjective) AS newObjective,
9663                        SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9664                        SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9665                        SUM(q.acceptanceObjective) AS acceptanceObjective,
9666                        SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9667                        SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9668                        {$visitMainCols}
9669                    FROM
9670                    (
9671                        SELECT
9672                            q.year,
9673                            q.month,
9674                            q.week,
9675                            q.namedate,
9676                            SUM(q.issue_date) AS issue_date,
9677                            q.acceptance_date,
9678                            q.created_at,
9679                            q.commercial,
9680                            q.budget_type,
9681                            GROUP_CONCAT(q.groupConcatIds) AS groupConcatIds,
9682                            CASE
9683                                WHEN q.is_amountIssue > 0 THEN
9684                                    SUM(q.revenueIssue / q.issueObjective) * 100
9685                                ELSE
9686                                    SUM(q.issue_date / q.issueObjective) * 100
9687                                END
9688                            AS totalIssueObjective,
9689                            CASE
9690                                WHEN q.is_amountIssue > 0 THEN
9691                                    SUM(q.revenueIssue / q.issueObjectiveMonthly) * 100
9692                                ELSE
9693                                    SUM(q.issue_date / q.issueObjectiveMonthly) * 100
9694                                END
9695                            AS totalIssueObjectiveMonthly,
9696                            CASE
9697                                WHEN q.is_amountIssue > 0 THEN
9698                                    SUM(q.revenueIssue / q.issueObjectiveYearly) * 100
9699                                ELSE
9700                                    SUM(q.issue_date / q.issueObjectiveYearly) * 100
9701                                END
9702                            AS totalIssueObjectiveYearly,
9703                            SUM(q.revenueIssue) revenueIssue,
9704                            GROUP_CONCAT(q.groupConcatCreatedAtIds) AS groupConcatCreatedAtIds,
9705                            SUM(q.totalIssueLessThan5) totalIssueLessThan5,
9706                            GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) groupConcatIdsIssueLessThan5,
9707                            GROUP_CONCAT(q.groupConcatAcceptanceIds) AS groupConcatAcceptanceIds,
9708                            SUM(q.acceptanceObjective) totalAcceptanceObjective,
9709                            SUM(q.acceptanceObjectiveMonthly) totalAcceptanceObjectiveMonthly,
9710                            SUM(q.acceptanceObjectiveYearly) totalAcceptanceObjectiveYearly,
9711                            q.revenueAcceptance,
9712                            SUM(q.totalRejected) AS totalRejected,
9713                            GROUP_CONCAT(q.groupConcatRejectedIds) AS groupConcatRejectedIds,
9714                            SUM(q.revenueRejected) revenueRejected,
9715                            SUM(q.totalNew) AS totalNew,
9716                            GROUP_CONCAT(q.groupConcatNewIds) AS groupConcatNewIds,
9717                            CASE
9718                                WHEN q.is_amountNew > 0 THEN
9719                                    SUM(q.revenueNew / q.newObjective) * 100
9720                                ELSE
9721                                    SUM(q.totalNew / q.newObjective) * 100
9722                                END
9723                            AS totalNewObjective,
9724                             CASE
9725                                WHEN q.is_amountNew > 0 THEN
9726                                    SUM(q.revenueNew / q.newObjectiveMonthly) * 100
9727                                ELSE
9728                                    SUM(q.totalNew / q.newObjectiveMonthly) * 100
9729                                END
9730                            AS totalNewObjectiveMonthly,
9731                             CASE
9732                                WHEN q.is_amountNew > 0 THEN
9733                                    SUM(q.revenueNew / q.newObjectiveYearly) * 100
9734                                ELSE
9735                                    SUM(q.totalNew / q.newObjectiveYearly) * 100
9736                                END
9737                            AS totalNewObjectiveYearly,
9738                            SUM(q.revenueNew) revenueNew,
9739                            q.totalVisit,
9740                            q.groupConcatVisitIds,
9741                            q.totalCall,
9742                            q.groupConcatCallIds,
9743                            q.priority,
9744                            SUM(q.is_amountIssue) AS is_amountIssue,
9745                            SUM(q.is_amountNew) AS is_amountNew,
9746                            SUM(q.is_amountAcceptance) AS is_amountAcceptance,
9747                            SUM(q.issueObjective) AS issueObjective,
9748                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9749                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9750                            SUM(q.newObjective) AS newObjective,
9751                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9752                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9753                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9754                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9755                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9756                            {$visitSubMainTableCols}
9757                        FROM (
9758                            SELECT
9759                                YEAR(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'year',
9760                                MONTH(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'month',
9761                                WEEK(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY)) 'week',
9762                                DATE_FORMAT(DATE_ADD(q.issue_date, INTERVAL - WEEKDAY(q.issue_date) DAY), '%W, %M %e') namedate,
9763                                COUNT(CASE WHEN q.issue_date IS NOT NULL THEN 1 END) issue_date,
9764                                0 acceptance_date,
9765                                0 created_at,
9766                                q.commercial,
9767                                btg.name budget_type,
9768                                GROUP_CONCAT(CASE WHEN q.issue_date IS NOT NULL THEN q.id END) AS groupConcatIds,
9769
9770                                SUM(CASE WHEN q.issue_date IS NOT NULL THEN q.amount END) AS revenueIssue,
9771                                NULL groupConcatCreatedAtIds,
9772                                0 totalIssueLessThan5,
9773                                NULL groupConcatIdsIssueLessThan5,
9774                                NULL groupConcatAcceptanceIds,
9775
9776                                0 revenueAcceptance,
9777                                COUNT(CASE WHEN bs.name = 'Rechazado' THEN 1 END) AS totalRejected,
9778                                GROUP_CONCAT(DISTINCT CASE WHEN bs.name = 'Rechazado' THEN q.id END) AS groupConcatRejectedIds,
9779                                COALESCE(SUM(CASE WHEN bs.name = 'Rechazado' THEN q.amount END), 0) AS revenueRejected,
9780                                COUNT(CASE WHEN ct.name = 'Nuevo' THEN 1 END) AS totalNew,
9781                                GROUP_CONCAT(DISTINCT CASE WHEN ct.name = 'Nuevo' THEN q.id END) AS groupConcatNewIds,
9782
9783                                COALESCE(SUM(CASE WHEN ct.name = 'Nuevo' THEN q.amount END), 0) revenueNew,
9784                                0 totalVisit,
9785                                NULL groupConcatVisitIds,
9786                                0 totalCall,
9787                                NULL groupConcatCallIds,
9788                                btg.priority,
9789                                CAST(
9790                                    CASE
9791                                        WHEN bg.issue_objective IS NOT NULL THEN bg.is_amount
9792                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.is_amount
9793                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.is_amount
9794                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.is_amount
9795                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.is_amount
9796                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9797                                    END
9798                                AS DOUBLE) AS is_amountIssue,
9799                                CAST(
9800                                    CASE
9801                                        WHEN bg.new_objective IS NOT NULL THEN bg.is_amount
9802                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.is_amount
9803                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.is_amount
9804                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.is_amount
9805                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.is_amount
9806                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->is_amount}
9807                                    END
9808                                AS DOUBLE) AS is_amountNew,
9809                                0 is_amountAcceptance,
9810                                CAST(
9811                                    CASE
9812                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9813                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9814                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9815                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9816                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9817                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9818                                    END {$aggregatedByCalc}
9819                                AS DOUBLE) AS issueObjective,
9820                                CAST(
9821                                    CASE
9822                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9823                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9824                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9825                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9826                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9827                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9828                                    END
9829                                AS DOUBLE) AS issueObjectiveMonthly,
9830                                CAST(
9831                                    CASE
9832                                        WHEN bg.issue_objective IS NOT NULL THEN bg.issue_objective
9833                                        WHEN bgou.issue_objective IS NOT NULL THEN bgou.issue_objective
9834                                        WHEN bg1.issue_objective IS NOT NULL THEN bg1.issue_objective
9835                                        WHEN bgor.issue_objective IS NOT NULL THEN bgor.issue_objective
9836                                        WHEN bgde.issue_objective IS NOT NULL THEN bgde.issue_objective
9837                                        WHEN bg.issue_objective IS NULL AND bg1.issue_objective IS NULL THEN {$businessGoalsDefault->issue_objective}
9838                                    END * 12
9839                                AS DOUBLE) AS issueObjectiveYearly,
9840                                CAST(
9841                                    CASE
9842                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9843                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9844                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9845                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9846                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9847                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9848                                    END {$aggregatedByCalc}
9849                                AS DOUBLE) AS newObjective,
9850                                CAST(
9851                                    CASE
9852                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9853                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9854                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9855                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9856                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9857                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9858                                    END
9859                                AS DOUBLE) AS newObjectiveMonthly,
9860                                CAST(
9861                                    CASE
9862                                        WHEN bg.new_objective IS NOT NULL THEN bg.new_objective
9863                                        WHEN bgou.new_objective IS NOT NULL THEN bgou.new_objective
9864                                        WHEN bg1.new_objective IS NOT NULL THEN bg1.new_objective
9865                                        WHEN bgor.new_objective IS NOT NULL THEN bgor.new_objective
9866                                        WHEN bgde.new_objective IS NOT NULL THEN bgde.new_objective
9867                                        WHEN bg.new_objective IS NULL AND bg1.new_objective IS NULL THEN {$businessGoalsDefault->new_objective}
9868                                    END * 12
9869                                AS DOUBLE) AS newObjectiveYearly,
9870                                0 acceptanceObjective,
9871                                0 acceptanceObjectiveMonthly,
9872                                0 acceptanceObjectiveYearly
9873                                {$visitSubTableCols}
9874                            FROM
9875                            tbl_quotations q
9876                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
9877                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
9878                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
9879                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
9880                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
9881                                LEFT JOIN tbl_users u ON q.commercial = u.name
9882                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
9883                                LEFT JOIN tbl_business_goals bg ON bg.budget_type_group_id = btg.budget_type_group_id AND bg.user_id = u.id
9884                                LEFT JOIN tbl_business_goals bg1 ON bg1.budget_type_group_id = btg.budget_type_group_id AND bg1.role_id = r.role_id
9885                                LEFT JOIN tbl_business_goals bgde ON bgde.budget_type_group_id = btg.budget_type_group_id AND bgde.is_default = 1
9886                                LEFT JOIN business_goal_objective_users bgou ON bgou.user_id = u.id
9887                                LEFT JOIN business_goal_objective_roles bgor ON bgor.role_id = r.role_id
9888                            WHERE
9889                                q.budget_type_id != 7
9890                                AND q.budget_type_id IS NOT NULL
9891                                AND q.for_add != 1
9892                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
9893                                AND bt.include = 1
9894                                AND (q.commercial IS NOT NULL AND q.commercial != '')
9895                                {$where}
9896                                {$whereYear}
9897                            GROUP BY
9898                                {$groupBy}
9899                        ) q
9900                        GROUP BY
9901                            {$groupBy} WITH ROLLUP
9902
9903                        UNION ALL
9904
9905                        SELECT
9906                            q.year,
9907                            q.month,
9908                            q.week,
9909                            q.namedate,
9910                            q.issue_date,
9911                            SUM(q.acceptance_date) AS acceptance_date,
9912                            q.created_at,
9913                            q.commercial,
9914                            q.budget_type,
9915                            q.groupConcatIds,
9916                            q.issueObjective totalIssueObjective,
9917                            q.issueObjectiveMonthly totalIssueObjectiveMonthly,
9918                            q.issueObjectiveYearly totalIssueObjectiveYearly,
9919                            q.revenueIssue,
9920                            q.groupConcatCreatedAtIds,
9921                            q.totalIssueLessThan5,
9922                            q.groupConcatIdsIssueLessThan5,
9923                            GROUP_CONCAT(q.groupConcatAcceptanceIds) AS groupConcatAcceptanceIds,
9924                            CASE
9925                                WHEN q.is_amountAcceptance > 0 THEN
9926                                    SUM(q.revenueAcceptance / q.acceptanceObjective) * 100
9927                                ELSE
9928                                    SUM(q.acceptance_date / q.acceptanceObjective) * 100
9929                                END
9930                            AS totalAcceptanceObjective,
9931                            CASE
9932                                WHEN q.is_amountAcceptance > 0 THEN
9933                                    SUM(q.revenueAcceptance / q.acceptanceObjectiveMonthly) * 100
9934                                ELSE
9935                                    SUM(q.acceptance_date / q.acceptanceObjectiveMonthly) * 100
9936                                END
9937                            AS totalAcceptanceObjectiveMonthly,
9938                            CASE
9939                                WHEN q.is_amountAcceptance > 0 THEN
9940                                    SUM(q.revenueAcceptance / q.acceptanceObjectiveYearly) * 100
9941                                ELSE
9942                                    SUM(q.acceptance_date / q.acceptanceObjectiveYearly) * 100
9943                                END
9944                            AS totalAcceptanceObjectiveYearly,
9945                            SUM(q.revenueAcceptance) revenueAcceptance,
9946                            q.totalRejected,
9947                            q.groupConcatRejectedIds,
9948                            q.revenueRejected,
9949                            q.totalNew,
9950                            q.groupConcatNewIds,
9951                            q.newObjective totalNewObjective,
9952                            q.newObjectiveMonthly totalNewObjectiveMonthly,
9953                            q.newObjectiveYearly totalNewObjectiveYearly,
9954                            q.revenueNew,
9955                            q.totalVisit,
9956                            q.groupConcatVisitIds,
9957                            q.totalCall,
9958                            q.groupConcatCallIds,
9959                            q.priority,
9960                            SUM(q.is_amountIssue) AS is_amountIssue,
9961                            q.is_amountNew,
9962                            q.is_amountAcceptance,
9963                            SUM(q.issueObjective) AS issueObjective,
9964                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
9965                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
9966                            SUM(q.newObjective) AS newObjective,
9967                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
9968                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
9969                            SUM(q.acceptanceObjective) AS acceptanceObjective,
9970                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
9971                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
9972                            {$visitSubMainTableCols}
9973                        FROM (
9974                            SELECT
9975                                YEAR(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'year',
9976                                MONTH(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'month',
9977                                WEEK(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY)) 'week',
9978                                DATE_FORMAT(DATE_ADD(q.acceptance_date, INTERVAL - WEEKDAY(q.acceptance_date) DAY), '%W, %M %e') namedate,
9979                                0 issue_date,
9980                                COUNT(CASE WHEN q.acceptance_date IS NOT NULL THEN 1 END) acceptance_date,
9981                                0 created_at,
9982                                q.commercial,
9983                                btg.name budget_type,
9984                                NULL groupConcatIds,
9985
9986                                0 revenueIssue,
9987                                NULL groupConcatCreatedAtIds,
9988                                0 totalIssueLessThan5,
9989                                NULL groupConcatIdsIssueLessThan5,
9990                                GROUP_CONCAT(CASE WHEN q.acceptance_date IS NOT NULL THEN q.id END) AS groupConcatAcceptanceIds,
9991
9992                                COALESCE(SUM(CASE WHEN q.acceptance_date IS NOT NULL THEN q.amount END), 0) AS revenueAcceptance,
9993                                0 totalRejected,
9994                                NULL groupConcatRejectedIds,
9995                                0 revenueRejected,
9996                                0 totalNew,
9997                                NULL groupConcatNewIds,
9998                                NULL totalNewObjective,
9999                                NULL totalNewObjectiveMonthly,
10000                                NULL totalNewObjectiveYearly,
10001                                0 revenueNew,
10002                                0 totalVisit,
10003                                NULL groupConcatVisitIds,
10004                                0 totalCall,
10005                                NULL groupConcatCallIds,
10006                                btg.priority,
10007                                0 is_amountIssue,
10008                                0 is_amountNew,
10009                                CAST(
10010                                    CASE
10011                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.is_amount
10012                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.is_amount
10013                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.is_amount
10014                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.is_amount
10015                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.is_amount
10016                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->is_amount}
10017                                    END
10018                                AS DOUBLE) AS is_amountAcceptance,
10019                                0 issueObjective,
10020                                0 issueObjectiveMonthly,
10021                                0 issueObjectiveYearly,
10022                                0 newObjective,
10023                                0 newObjectiveMonthly,
10024                                0 newObjectiveYearly,
10025                                CAST(
10026                                    CASE
10027                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
10028                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
10029                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
10030                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
10031                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
10032                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
10033                                    END {$aggregatedByCalc}
10034                                AS DOUBLE) AS acceptanceObjective,
10035                                CAST(
10036                                    CASE
10037                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
10038                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
10039                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
10040                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
10041                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
10042                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
10043                                    END
10044                                AS DOUBLE) AS acceptanceObjectiveMonthly,
10045                                CAST(
10046                                    CASE
10047                                        WHEN bg.acceptance_objective IS NOT NULL THEN bg.acceptance_objective
10048                                        WHEN bgou.acceptance_objective IS NOT NULL THEN bgou.acceptance_objective
10049                                        WHEN bg1.acceptance_objective IS NOT NULL THEN bg1.acceptance_objective
10050                                        WHEN bgor.acceptance_objective IS NOT NULL THEN bgor.acceptance_objective
10051                                        WHEN bgde.acceptance_objective IS NOT NULL THEN bgde.acceptance_objective
10052                                        WHEN bg.acceptance_objective IS NULL AND bg1.acceptance_objective IS NULL THEN {$businessGoalsDefault->acceptance_objective}
10053                                    END * 12
10054                                AS DOUBLE) AS acceptanceObjectiveYearly
10055                                {$visitSubTableCols}
10056                            FROM
10057                            tbl_quotations q
10058                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
10059                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
10060                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
10061                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
10062                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
10063                                LEFT JOIN tbl_users u ON q.commercial = u.name
10064                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
10065                                LEFT JOIN tbl_business_goals bg ON bg.budget_type_group_id = btg.budget_type_group_id AND bg.user_id = u.id
10066                                LEFT JOIN tbl_business_goals bg1 ON bg1.budget_type_group_id = btg.budget_type_group_id AND bg1.role_id = r.role_id
10067                                LEFT JOIN tbl_business_goals bgde ON bgde.budget_type_group_id = btg.budget_type_group_id AND bgde.is_default = 1
10068                                LEFT JOIN business_goal_objective_users bgou ON bgou.user_id = u.id
10069                                LEFT JOIN business_goal_objective_roles bgor ON bgor.role_id = r.role_id
10070                            WHERE
10071                                q.budget_type_id != 7
10072                                AND q.budget_type_id IS NOT NULL
10073                                AND q.for_add != 1
10074                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
10075                                AND bt.include = 1
10076                                AND (q.commercial IS NOT NULL AND q.commercial != '')
10077                                {$whereAcceptanceDate}
10078                                {$whereYear}
10079                            GROUP BY
10080                                {$groupBy}
10081                        ) q
10082                        GROUP BY
10083                            {$groupBy} WITH ROLLUP
10084
10085                        UNION ALL
10086
10087                        SELECT
10088                            q.year,
10089                            q.month,
10090                            q.week,
10091                            q.namedate,
10092                            q.issue_date,
10093                            q.acceptance_date,
10094                            SUM(q.created_at) AS created_at,
10095                            q.commercial,
10096                            q.budget_type,
10097                            q.groupConcatIds,
10098                            q.issueObjective totalIssueObjective,
10099                            q.issueObjectiveMonthly totalIssueObjectiveMonthly,
10100                            q.issueObjectiveYearly totalIssueObjectiveYearly,
10101                            q.revenueIssue,
10102                            GROUP_CONCAT(q.groupConcatCreatedAtIds) AS groupConcatCreatedAtIds,
10103                            SUM(q.totalIssueLessThan5) AS totalIssueLessThan5,
10104                            GROUP_CONCAT(q.groupConcatIdsIssueLessThan5) AS groupConcatIdsIssueLessThan5,
10105                            NULL groupConcatAcceptanceIds,
10106                            0 totalAcceptanceObjective,
10107                            0 totalAcceptanceObjectiveMonthly,
10108                            0 totalAcceptanceObjectiveYearly,
10109                            SUM(q.revenueAcceptance) revenueAcceptance,
10110                            q.totalRejected,
10111                            q.groupConcatRejectedIds,
10112                            q.revenueRejected,
10113                            q.totalNew,
10114                            q.groupConcatNewIds,
10115                            q.newObjective totalNewObjective,
10116                            q.newObjectiveMonthly totalNewObjectiveMonthly,
10117                            q.newObjectiveYearly totalNewObjectiveYearly,
10118                            q.revenueNew,
10119                            q.totalVisit,
10120                            q.groupConcatVisitIds,
10121                            q.totalCall,
10122                            q.groupConcatCallIds,
10123                            q.priority,
10124                            SUM(q.is_amountIssue) AS is_amountIssue,
10125                            q.is_amountNew,
10126                            q.is_amountAcceptance,
10127                            SUM(q.issueObjective) AS issueObjective,
10128                            SUM(q.issueObjectiveMonthly) AS issueObjectiveMonthly,
10129                            SUM(q.issueObjectiveYearly) AS issueObjectiveYearly,
10130                            SUM(q.newObjective) AS newObjective,
10131                            SUM(q.newObjectiveMonthly) AS newObjectiveMonthly,
10132                            SUM(q.newObjectiveYearly) AS newObjectiveYearly,
10133                            SUM(q.acceptanceObjective) AS acceptanceObjective,
10134                            SUM(q.acceptanceObjectiveMonthly) AS acceptanceObjectiveMonthly,
10135                            SUM(q.acceptanceObjectiveYearly) AS acceptanceObjectiveYearly
10136                            {$visitSubMainTableCols}
10137                        FROM (
10138                            SELECT
10139                                YEAR(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'year',
10140                                MONTH(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'month',
10141                                WEEK(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY)) 'week',
10142                                DATE_FORMAT(DATE_ADD(q.created_at, INTERVAL - WEEKDAY(q.created_at) DAY), '%W, %M %e') namedate,
10143                                0 issue_date,
10144                                0 acceptance_date,
10145                                COUNT(CASE WHEN q.created_at IS NOT NULL THEN 1 END) created_at,
10146                                q.commercial,
10147                                btg.name budget_type,
10148                                NULL groupConcatIds,
10149
10150                                0 revenueIssue,
10151                                GROUP_CONCAT(CASE WHEN q.created_at IS NOT NULL THEN q.id END) AS groupConcatCreatedAtIds,
10152                                COUNT(CASE WHEN ABS(DATEDIFF(q.created_at, q.issue_date)) < 5 THEN 1 END) AS totalIssueLessThan5,
10153                                GROUP_CONCAT(CASE WHEN ABS(DATEDIFF(q.created_at, q.issue_date)) < 5 THEN q.id END) AS groupConcatIdsIssueLessThan5,
10154                                NULL groupConcatAcceptanceIds,
10155
10156                                0 AS revenueAcceptance,
10157                                0 totalRejected,
10158                                NULL groupConcatRejectedIds,
10159                                0 revenueRejected,
10160                                0 totalNew,
10161                                NULL groupConcatNewIds,
10162                                NULL totalNewObjective,
10163                                NULL totalNewObjectiveMonthly,
10164                                NULL totalNewObjectiveYearly,
10165                                0 revenueNew,
10166                                0 totalVisit,
10167                                NULL groupConcatVisitIds,
10168                                0 totalCall,
10169                                NULL groupConcatCallIds,
10170                                btg.priority,
10171                                0 is_amountIssue,
10172                                0 is_amountNew,
10173                                0 is_amountAcceptance,
10174                                0 issueObjective,
10175                                0 issueObjectiveMonthly,
10176                                0 issueObjectiveYearly,
10177                                0 newObjective,
10178                                0 newObjectiveMonthly,
10179                                0 newObjectiveYearly,
10180                                0 acceptanceObjective,
10181                                0 acceptanceObjectiveMonthly,
10182                                0 acceptanceObjectiveYearly
10183                                {$visitSubTableCols}
10184                            FROM
10185                            tbl_quotations q
10186                                LEFT JOIN tbl_sources s ON s.source_id = q.source_id
10187                                LEFT JOIN tbl_budget_status bs ON bs.budget_status_id = q.budget_status_id
10188                                LEFT JOIN tbl_budget_types bt ON q.budget_type_id = bt.budget_type_id
10189                                LEFT JOIN tbl_budget_type_groups btg ON btg.budget_type_group_id = bt.budget_type_group_id
10190                                LEFT JOIN tbl_customer_types ct ON q.customer_type_id = ct.customer_type_id
10191                                LEFT JOIN tbl_users u ON q.commercial = u.name
10192                                LEFT JOIN tbl_roles r ON u.role_id = r.role_id
10193                            WHERE
10194                                q.budget_type_id != 7
10195                                AND q.budget_type_id IS NOT NULL
10196                                AND q.for_add != 1
10197                                AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
10198                                AND bt.include = 1
10199                                AND (q.commercial IS NOT NULL AND q.commercial != '')
10200                                {$whereCreatedAt}
10201                                {$whereYear}
10202                            GROUP BY
10203                                {$groupBy}
10204                        ) q
10205                        GROUP BY
10206                            {$groupBy} WITH ROLLUP
10207
10208                        UNION ALL
10209
10210                        SELECT
10211                            YEAR(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) YEAR,
10212                            MONTH(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) MONTH,
10213                            WEEK(DATE_ADD(q.visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY)) WEEK,
10214                            DATE_FORMAT(DATE_ADD(visit_date, INTERVAL - WEEKDAY(q.visit_date) DAY), '%W, %M %e') namedate,
10215                            0 issue_date,
10216                            0 acceptance_date,
10217                            0 created_at,
10218                            commercial,
10219                            NULL budget_type,
10220                            NULL groupConcatIds,
10221                            NULL totalIssueObjective,
10222                            NULL totalIssueObjectiveMonthly,
10223                            NULL totalIssueObjectiveYearly,
10224                            0 revenueIssue,
10225                            NULL groupConcatCreatedAtIds,
10226                            0 totalIssueLessThan5,
10227                            NULL groupConcatIdsIssueLessThan5,
10228                            NULL groupConcatAcceptanceIds,
10229                            NULL totalAcceptanceObjective,NULL totalAcceptanceObjectiveMonthly,
10230                            NULL totalAcceptanceObjectiveYearly,
10231                            0 revenueAcceptance,
10232                            0 totalRejected,
10233                            NULL groupConcatRejectedIds,
10234                            0 revenueRejected,
10235                            0 totalNew,
10236                            NULL groupConcatNewIds,
10237                            NULL totalNewObjective,NULL totalNewObjectiveMonthly,
10238                            NULL totalNewObjectiveYearly,
10239                            0 revenueNew,
10240                            COUNT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Visita' THEN 1 END) totalVisit,
10241                            GROUP_CONCAT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Visita' THEN q.id END) AS groupConcatVisitIds,
10242                            COUNT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Llamada' THEN 1 END) totalCall,
10243                            GROUP_CONCAT(CASE WHEN q.visit_date IS NOT NULL AND q.visit_call = 'Llamada' THEN q.id END) AS groupConcatCallIds,
10244                            0 priority,
10245                            0 is_amountIssue,
10246                            0 is_amountNew,
10247                            0 is_amountAcceptance,
10248                            0 issueObjective,
10249                            0 issueObjectiveMonthly,
10250                            0 issueObjectiveYearly,
10251                            0 newObjective,
10252                            0 newObjectiveMontly,
10253                            0 newObjectiveYearly,
10254                            0 acceptanceObjective,
10255                            0 acceptanceObjectiveMonthly,
10256                            0 acceptanceObjectiveYearly
10257                            {$visitCols}
10258                        FROM
10259                            tbl_pipelines q
10260                        LEFT JOIN tbl_users u ON q.commercial = u.name
10261                        LEFT JOIN tbl_roles r ON u.role_id = r.role_id
10262                        LEFT JOIN tbl_visit_types v ON q.visit_type_id = v.visit_type_id
10263                        WHERE q.visit_date IS NOT NULL
10264                            {$whereVisit}
10265                        GROUP BY
10266                            {$groupBy}
10267                             WITH ROLLUP
10268                    ) q
10269                    WHERE
10270                        q.year NOT IN (2021, 2022)
10271                    GROUP BY
10272                        {$groupBy}
10273                    {$gO}";
10274
10275                    Log::info($query);
10276
10277            $value = Cache::get(base64_encode($query));
10278
10279            if(!$value){
10280                $result = DB::select($query);
10281
10282                $structureData = new StructureData();
10283                $result = $structureData->parse($result, $groupByFilter, $aggregatedBy);
10284
10285                Cache::put(base64_encode($query), $result, 600);
10286            }else{
10287                $result = $value;
10288            }
10289
10290            return response([
10291                'message' => 'OK',
10292                'data' => $result
10293            ]);
10294
10295        // } catch (\Exception $e) {
10296        //     return response(['message' => 'KO', 'error' => $e->getMessage()]);
10297        // }
10298    }
10299
10300    function list_quotations_deleted($companyId){
10301
10302        try {
10303
10304            $companyId = addslashes($companyId);
10305            $where = "";
10306
10307            if($companyId != 0){
10308                $where = " a.company_id = {$companyId} ";
10309            }else{
10310                $where = " a.company_id IN ({$this->companyId})";
10311            }
10312
10313            $query = "SELECT
10314                        a.id,
10315                        a.quote_id,
10316                        a.company_id,
10317                        b.name company_name,
10318                        a.created_by,
10319                        a.updated_by,
10320                        a.updated_at,
10321                        a.for_add,
10322                        c.name reason,
10323                        a.reason_for_deletion
10324                    FROM tbl_quotations_deleted a
10325                    LEFT JOIN tbl_companies b
10326                        ON a.company_id = b.company_id
10327                    LEFT JOIN tbl_reasons c
10328                        ON a.reason_id = c.reason_id
10329                    WHERE {$where}
10330                    ORDER BY a.updated_at DESC";
10331
10332            $result = DB::select($query);
10333
10334            return response([
10335                'message' => 'OK',
10336                'data' => $result
10337            ]);
10338        } catch (\Exception $e) {
10339            /** @disregard P1014 */
10340            $e->exceptionCode = 'LIST_QUOTATIONS_DELETED_EXCEPTION'; 
10341            report($e);
10342            return response(['message' => 'KO', 'error' => $e->getMessage()]);
10343        }
10344    }
10345
10346    function delete_sengrid($id){
10347
10348        try {
10349
10350            $id = addslashes($id);
10351
10352            $order = TblQuotations::where('id', $id)->first();
10353
10354            if($order){
10355                if($order->x_message_id != null){
10356                    TblSendgridWebhook::where('quotation_id', $id)->where('x_message_id', $order->x_message_id)->delete();
10357
10358                    TblQuotations::where('id', $id)->update(
10359                        array(
10360                            'x_message_id' => null,
10361                            'x_status' => null
10362                        )
10363                    );
10364
10365                    Cache::flush();
10366                }
10367            }
10368
10369            return response([
10370                'message' => 'OK'
10371            ]);
10372
10373        } catch (\Exception $e) {
10374            /** @disregard P1014 */
10375            $e->exceptionCode = 'DELETE_SENDGRID_EXCEPTION'; 
10376            report($e);
10377            return response(['message' => 'KO', 'error' => $e->getMessage()]);
10378        }
10379    }
10380
10381    function download_productivity_commercial(Request $request){
10382
10383        try {
10384
10385            ini_set('max_execution_time', 123456);
10386
10387            $data = $request->all();
10388
10389            $result = $this->list_quotation_analytics_commercial_productivity($request);
10390            $result = $result->original['data'];
10391
10392            $spreadsheet = new Spreadsheet();
10393            $worksheet   = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, "Inputs");
10394            $spreadsheet->addSheet($worksheet, 0);
10395            $col         = range('A', 'Z');
10396
10397            for($i = 0; $i < 26; $i++){
10398                $worksheet->getColumnDimension($col[$i])->setAutoSize(true);
10399                if($i != 1){
10400                    $worksheet->getStyle($col[$i])
10401                        ->getAlignment()
10402                        ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
10403                }
10404            }
10405
10406            $l = 1;
10407            $worksheet->setCellValue('A' . $l, "Años");
10408
10409            if($data['group_by'] == 1){
10410                $worksheet->setCellValue('B' . $l, "Comercials");
10411                $worksheet->setCellValue('C' . $l, "Meses");
10412                $worksheet->setCellValue('D' . $l, "Semanas");
10413            }else{
10414                $worksheet->setCellValue('B' . $l, "Meses");
10415                $worksheet->setCellValue('C' . $l, "Semanas");
10416                $worksheet->setCellValue('D' . $l, "Comercials");
10417            }
10418
10419            $worksheet->setCellValue('E' . $l, "Categorías de presupuesto");
10420            $worksheet->setCellValue('F' . $l, "Presupuestos emitidos (#)");
10421            $worksheet->setCellValue('G' . $l, "Presupuestos emitidos (€)");
10422            $worksheet->setCellValue('H' . $l, "Presupuestos emitidos (Objetivo)");
10423            $worksheet->setCellValue('I' . $l, "Presupuestos aceptados (#)");
10424            $worksheet->setCellValue('J' . $l, "Presupuestos aceptados (€)");
10425            $worksheet->setCellValue('K' . $l, "Presupuestos aceptados (Objetivo)");
10426            $worksheet->setCellValue('L' . $l, "Presupuestos rechazados (#)");
10427            $worksheet->setCellValue('M' . $l, "Presupuestos rechazados (€)");
10428            $worksheet->setCellValue('N' . $l, "Presupuestos emitidos a nuevos clientes (#)");
10429            $worksheet->setCellValue('O' . $l, "Presupuestos emitidos a nuevos clientes (€)");
10430            $worksheet->setCellValue('P' . $l, "Presupuestos emitidos a nuevos clientes (Objetivo)");
10431            $worksheet->setCellValue('Q' . $l, "Venta (Llamada #)");
10432            $worksheet->setCellValue('R' . $l, "Venta (Visita #)");
10433            $worksheet->setCellValue('S' . $l, "Servicio (Llamada #)");
10434            $worksheet->setCellValue('T' . $l, "Servicio (Visita #)");
10435
10436            $l++;
10437
10438            foreach ($result as $item) {
10439
10440                $worksheet->setCellValue('A' . $l, $item['year']);
10441                $worksheet->setCellValue('F' . $l, $item['totalIssue']);
10442                $worksheet->setCellValue('G' . $l, $item['revenueIssue']);
10443                $worksheet->setCellValue('H' . $l, "-");
10444
10445                $worksheet->setCellValue('I' . $l, $item['totalAcceptance']);
10446                $worksheet->setCellValue('J' . $l, $item['revenueAcceptance']);
10447                $worksheet->setCellValue('K' . $l, "-");
10448
10449                $worksheet->setCellValue('L' . $l, $item['totalRejected']);
10450                $worksheet->setCellValue('M' . $l, $item['revenueRejected']);
10451
10452                $worksheet->setCellValue('N' . $l, $item['totalNew']);
10453                $worksheet->setCellValue('O' . $l, $item['revenueNew']);
10454                $worksheet->setCellValue('P' . $l, "-");
10455
10456                $worksheet->setCellValue('Q' . $l, $item['totalLlamada1']);
10457                $worksheet->setCellValue('R' . $l, $item['totalVisita1']);
10458
10459                $worksheet->setCellValue('S' . $l, $item['totalLlamada2']);
10460                $worksheet->setCellValue('T' . $l, $item['totalVisita2']);
10461
10462                $l++;
10463
10464                if($data['group_by'] == 1){
10465
10466                    if(count($item['commercials']) > 0){
10467
10468                        foreach ($item['commercials'] as $c) {
10469                            $worksheet->setCellValue('A' . $l, $item['year']);
10470
10471                            $worksheet->setCellValue('B' . $l, $c['commercial']);
10472                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10473                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10474                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10475
10476                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10477                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10478                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10479
10480                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10481                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10482
10483                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10484                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10485                            $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10486
10487                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10488                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10489
10490                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10491                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10492                            $l++;
10493
10494                            if(isset($c['budget_types']) && count($c['budget_types']) > 0){
10495                                foreach ($c['budget_types'] as $b) {
10496                                    $worksheet->setCellValue('A' . $l, $item['year']);
10497                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10498
10499                                    $worksheet->setCellValue('E' . $l, $b['name']);
10500                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10501                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10502                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10503
10504                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10505                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10506                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10507
10508                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10509                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10510
10511                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10512                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10513                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10514
10515                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10516                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10517
10518                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10519                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10520                                    $l++;
10521                                }
10522                            }
10523
10524                            if(isset($c['months']) && count($c['months']) > 0){
10525                                foreach ($c['months'] as $m) {
10526                                    $worksheet->setCellValue('A' . $l, $item['year']);
10527                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10528
10529                                    $worksheet->setCellValue('C' . $l, $m['month']);
10530                                    $worksheet->setCellValue('F' . $l, $m['totalIssue']);
10531                                    $worksheet->setCellValue('G' . $l, $m['revenueIssue']);
10532                                    $worksheet->setCellValue('H' . $l, $m['totalIssueObjectiveMonthly']);
10533
10534                                    $worksheet->setCellValue('I' . $l, $m['totalAcceptance']);
10535                                    $worksheet->setCellValue('J' . $l, $m['revenueAcceptance']);
10536                                    $worksheet->setCellValue('K' . $l, $m['totalAcceptanceObjectiveMonthly']);
10537
10538                                    $worksheet->setCellValue('L' . $l, $m['totalRejected']);
10539                                    $worksheet->setCellValue('M' . $l, $m['revenueRejected']);
10540
10541                                    $worksheet->setCellValue('N' . $l, $m['totalNew']);
10542                                    $worksheet->setCellValue('O' . $l, $m['revenueNew']);
10543                                    $worksheet->setCellValue('P' . $l, $m['totalNewObjectiveMonthly']);
10544
10545                                    $worksheet->setCellValue('Q' . $l, $m['totalLlamada1']);
10546                                    $worksheet->setCellValue('R' . $l, $m['totalVisita1']);
10547
10548                                    $worksheet->setCellValue('S' . $l, $m['totalLlamada2']);
10549                                    $worksheet->setCellValue('T' . $l, $m['totalVisita2']);
10550                                    $l++;
10551
10552                                    if(isset($m['weeks']) && count(@$m['weeks']) > 0 && count(@$m['weeks']) != 1){
10553                                        foreach ($m['weeks'] as $w) {
10554                                            $worksheet->setCellValue('A' . $l, $item['year']);
10555                                            $worksheet->setCellValue('B' . $l, $c['commercial']);
10556                                            $worksheet->setCellValue('C' . $l, $m['month']);
10557
10558                                            $worksheet->setCellValue('D' . $l, $w['created_at']);
10559                                            $worksheet->setCellValue('F' . $l, $w['totalIssue']);
10560                                            $worksheet->setCellValue('G' . $l, $w['revenueIssue']);
10561                                            $worksheet->setCellValue('H' . $l, $w['totalIssueObjective']);
10562
10563                                            $worksheet->setCellValue('I' . $l, $w['totalAcceptance']);
10564                                            $worksheet->setCellValue('J' . $l, $w['revenueAcceptance']);
10565                                            $worksheet->setCellValue('K' . $l, $w['totalAcceptanceObjective']);
10566
10567                                            $worksheet->setCellValue('L' . $l, $w['totalRejected']);
10568                                            $worksheet->setCellValue('M' . $l, $w['revenueRejected']);
10569
10570                                            $worksheet->setCellValue('N' . $l, $w['totalNew']);
10571                                            $worksheet->setCellValue('O' . $l, $w['revenueNew']);
10572                                            $worksheet->setCellValue('P' . $l, $w['totalNewObjective']);
10573
10574                                            $worksheet->setCellValue('Q' . $l, $w['totalLlamada1']);
10575                                            $worksheet->setCellValue('R' . $l, $w['totalVisita1']);
10576
10577                                            $worksheet->setCellValue('S' . $l, $w['totalLlamada2']);
10578                                            $worksheet->setCellValue('T' . $l, $w['totalVisita2']);
10579                                            $l++;
10580
10581                                            if(count($w['budget_types']) > 0){
10582                                                foreach ($w['budget_types'] as $b) {
10583                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10584                                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10585                                                    $worksheet->setCellValue('C' . $l, $m['month']);
10586
10587                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10588                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10589                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10590                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10591
10592                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10593                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10594                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10595
10596                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10597                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10598
10599                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10600                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10601                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10602
10603                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10604                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10605
10606                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10607                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10608                                                    $l++;
10609                                                }
10610                                            }
10611                                        }
10612                                    }elseif(isset($m['weeks']) && count(@$m['weeks']) == 1){
10613                                        foreach ($m['weeks'] as $w) {
10614                                            if(count($w['budget_types']) > 0){
10615                                                foreach ($w['budget_types'] as $b) {
10616                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10617                                                    $worksheet->setCellValue('B' . $l, $c['commercial']);
10618                                                    $worksheet->setCellValue('C' . $l, $m['month']);
10619
10620                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10621                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10622                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10623                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10624
10625                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10626                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10627                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10628
10629                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10630                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10631
10632                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10633                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10634                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10635
10636                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10637                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10638
10639                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10640                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10641                                                    $l++;
10642                                                }
10643                                            }
10644                                        }
10645
10646                                    }
10647                                }
10648                            }
10649                        }
10650                    }
10651                }else{
10652
10653                    if(isset($item['months']) && count($item['months']) > 0){
10654                        foreach ($item['months'] as $m) {
10655                            $worksheet->setCellValue('A' . $l, $item['year']);
10656                            $worksheet->setCellValue('B' . $l, $m['month']);
10657                            $worksheet->setCellValue('F' . $l, $m['totalIssue']);
10658                            $worksheet->setCellValue('G' . $l, $m['revenueIssue']);
10659                            $worksheet->setCellValue('H' . $l, "-");
10660
10661                            $worksheet->setCellValue('I' . $l, $m['totalAcceptance']);
10662                            $worksheet->setCellValue('J' . $l, $m['revenueAcceptance']);
10663                            $worksheet->setCellValue('K' . $l, "-");
10664
10665                            $worksheet->setCellValue('L' . $l, $m['totalRejected']);
10666                            $worksheet->setCellValue('M' . $l, $m['revenueRejected']);
10667
10668                            $worksheet->setCellValue('N' . $l, $m['totalNew']);
10669                            $worksheet->setCellValue('O' . $l, $m['revenueNew']);
10670                            $worksheet->setCellValue('P' . $l, "-");
10671
10672                            $worksheet->setCellValue('Q' . $l, $m['totalLlamada1']);
10673                            $worksheet->setCellValue('R' . $l, $m['totalVisita1']);
10674
10675                            $worksheet->setCellValue('S' . $l, $m['totalLlamada2']);
10676                            $worksheet->setCellValue('T' . $l, $m['totalVisita2']);
10677                            $l++;
10678
10679                            if(isset($m['weeks']) && count(@$m['weeks']) > 0){
10680                                foreach ($m['weeks'] as $w) {
10681                                    $worksheet->setCellValue('A' . $l, $item['year']);
10682                                    $worksheet->setCellValue('B' . $l, $m['month']);
10683
10684                                    $worksheet->setCellValue('C' . $l, $w['created_at']);
10685                                    $worksheet->setCellValue('F' . $l, $w['totalIssue']);
10686                                    $worksheet->setCellValue('G' . $l, $w['revenueIssue']);
10687                                    $worksheet->setCellValue('H' . $l, "-");
10688
10689                                    $worksheet->setCellValue('I' . $l, $w['totalAcceptance']);
10690                                    $worksheet->setCellValue('J' . $l, $w['revenueAcceptance']);
10691                                    $worksheet->setCellValue('K' . $l, "-");
10692
10693                                    $worksheet->setCellValue('L' . $l, $w['totalRejected']);
10694                                    $worksheet->setCellValue('M' . $l, $w['revenueRejected']);
10695
10696                                    $worksheet->setCellValue('N' . $l, $w['totalNew']);
10697                                    $worksheet->setCellValue('O' . $l, $w['revenueNew']);
10698                                    $worksheet->setCellValue('P' . $l, "-");
10699
10700                                    $worksheet->setCellValue('Q' . $l, $w['totalLlamada1']);
10701                                    $worksheet->setCellValue('R' . $l, $w['totalVisita1']);
10702
10703                                    $worksheet->setCellValue('S' . $l, $w['totalLlamada2']);
10704                                    $worksheet->setCellValue('T' . $l, $w['totalVisita2']);
10705                                    $l++;
10706
10707                                    if(count($w['commercials']) > 0){
10708                                        foreach ($w['commercials'] as $c) {
10709                                            $worksheet->setCellValue('A' . $l, $item['year']);
10710                                            $worksheet->setCellValue('B' . $l, $m['month']);
10711
10712                                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10713                                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10714                                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10715                                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjective']);
10716
10717                                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10718                                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10719                                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjective']);
10720
10721                                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10722                                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10723
10724                                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10725                                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10726                                            $worksheet->setCellValue('P' . $l, $c['totalNewObjective']);
10727
10728                                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10729                                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10730
10731                                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10732                                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10733                                            $l++;
10734
10735                                            if(count($c['budget_types']) > 0){
10736                                                foreach ($c['budget_types'] as $b) {
10737                                                    $worksheet->setCellValue('A' . $l, $item['year']);
10738                                                    $worksheet->setCellValue('B' . $l, $m['month']);
10739                                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10740
10741                                                    $worksheet->setCellValue('E' . $l, $b['name']);
10742                                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10743                                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10744                                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10745
10746                                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10747                                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10748                                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10749
10750                                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10751                                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10752
10753                                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10754                                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10755                                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10756
10757                                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10758                                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10759
10760                                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10761                                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10762                                                    $l++;
10763                                                }
10764                                            }
10765                                        }
10766                                    }
10767                                }
10768                            }
10769
10770                            if(count($m['commercials']) > 0){
10771                                foreach ($m['commercials'] as $c) {
10772                                    $worksheet->setCellValue('A' . $l, $item['year']);
10773                                    $worksheet->setCellValue('B' . $l, $m['month']);
10774
10775                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10776                                    $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10777                                    $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10778                                    $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10779
10780                                    $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10781                                    $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10782                                    $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10783
10784                                    $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10785                                    $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10786
10787                                    $worksheet->setCellValue('N' . $l, $c['totalNew']);
10788                                    $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10789                                    $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10790
10791                                    $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10792                                    $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10793
10794                                    $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10795                                    $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10796                                    $l++;
10797
10798                                    if(count($c['budget_types']) > 0){
10799                                        foreach ($c['budget_types'] as $b) {
10800                                            $worksheet->setCellValue('A' . $l, $item['year']);
10801                                            $worksheet->setCellValue('B' . $l, $m['month']);
10802                                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10803
10804                                            $worksheet->setCellValue('E' . $l, $b['name']);
10805                                            $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10806                                            $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10807                                            $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10808
10809                                            $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10810                                            $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10811                                            $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10812
10813                                            $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10814                                            $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10815
10816                                            $worksheet->setCellValue('N' . $l, $b['totalNew']);
10817                                            $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10818                                            $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10819
10820                                            $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10821                                            $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10822
10823                                            $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10824                                            $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10825                                            $l++;
10826                                        }
10827                                    }
10828                                }
10829                            }
10830                        }
10831                    }
10832
10833                    if(count($item['commercials']) > 0){
10834                        foreach ($item['commercials'] as $c) {
10835                            $worksheet->setCellValue('A' . $l, $item['year']);
10836
10837                            $worksheet->setCellValue('D' . $l, $c['commercial']);
10838                            $worksheet->setCellValue('F' . $l, $c['totalIssue']);
10839                            $worksheet->setCellValue('G' . $l, $c['revenueIssue']);
10840                            $worksheet->setCellValue('H' . $l, $c['totalIssueObjectiveYearly']);
10841
10842                            $worksheet->setCellValue('I' . $l, $c['totalAcceptance']);
10843                            $worksheet->setCellValue('J' . $l, $c['revenueAcceptance']);
10844                            $worksheet->setCellValue('K' . $l, $c['totalAcceptanceObjectiveYearly']);
10845
10846                            $worksheet->setCellValue('L' . $l, $c['totalRejected']);
10847                            $worksheet->setCellValue('M' . $l, $c['revenueRejected']);
10848
10849                            $worksheet->setCellValue('N' . $l, $c['totalNew']);
10850                            $worksheet->setCellValue('O' . $l, $c['revenueNew']);
10851                            $worksheet->setCellValue('P' . $l, $c['totalNewObjectiveYearly']);
10852
10853                            $worksheet->setCellValue('Q' . $l, $c['totalLlamada1']);
10854                            $worksheet->setCellValue('R' . $l, $c['totalVisita1']);
10855
10856                            $worksheet->setCellValue('S' . $l, $c['totalLlamada2']);
10857                            $worksheet->setCellValue('T' . $l, $c['totalVisita2']);
10858                            $l++;
10859
10860                            if(count($c['budget_types']) > 0){
10861                                foreach ($c['budget_types'] as $b) {
10862                                    $worksheet->setCellValue('A' . $l, $item['year']);
10863                                    $worksheet->setCellValue('D' . $l, $c['commercial']);
10864
10865                                    $worksheet->setCellValue('E' . $l, $b['name']);
10866                                    $worksheet->setCellValue('F' . $l, $b['totalIssue']);
10867                                    $worksheet->setCellValue('G' . $l, $b['revenueIssue']);
10868                                    $worksheet->setCellValue('H' . $l, $b['totalIssueObjective']);
10869
10870                                    $worksheet->setCellValue('I' . $l, $b['totalAcceptance']);
10871                                    $worksheet->setCellValue('J' . $l, $b['revenueAcceptance']);
10872                                    $worksheet->setCellValue('K' . $l, $b['totalAcceptanceObjective']);
10873
10874                                    $worksheet->setCellValue('L' . $l, $b['totalRejected']);
10875                                    $worksheet->setCellValue('M' . $l, $b['revenueRejected']);
10876
10877                                    $worksheet->setCellValue('N' . $l, $b['totalNew']);
10878                                    $worksheet->setCellValue('O' . $l, $b['revenueNew']);
10879                                    $worksheet->setCellValue('P' . $l, $b['totalNewObjective']);
10880
10881                                    $worksheet->setCellValue('Q' . $l, $b['totalLlamada1']);
10882                                    $worksheet->setCellValue('R' . $l, $b['totalVisita1']);
10883
10884                                    $worksheet->setCellValue('S' . $l, $b['totalLlamada2']);
10885                                    $worksheet->setCellValue('T' . $l, $b['totalVisita2']);
10886                                    $l++;
10887                                }
10888                            }
10889                        }
10890                    }
10891                }
10892
10893                $l++;
10894            }
10895
10896            if($data['group_by'] == 1){
10897                if($data['aggregated_by'] == 3){
10898                    $worksheet->removeColumn('C');
10899                    $worksheet->removeColumn('C');
10900                }elseif($data['aggregated_by'] == 2){
10901                    $worksheet->removeColumn('D');
10902                }
10903            }else{
10904                if($data['aggregated_by'] == 3){
10905                    $worksheet->removeColumn('B');
10906                    $worksheet->removeColumn('B');
10907                }elseif($data['aggregated_by'] == 2){
10908                    $worksheet->removeColumn('C');
10909                }
10910            }
10911
10912
10913
10914            $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
10915            ob_start();
10916            $writer->save('php://output');
10917            $file = ob_get_contents();
10918            ob_end_clean();
10919
10920            return response($file);
10921
10922        } catch (\Exception $e) {
10923            /** @disregard P1014 */
10924            $e->exceptionCode = 'DOWNLOAD_PRODUCTIVITY_COMMERCIAL_EXCEPTION'; 
10925            report($e);
10926            return response(['message' => 'KO', 'error' => $e->getMessage()]);
10927        }
10928
10929    }
10930
10931    function update_commercial_numbers($companyId)
10932    {
10933        $phpBinary = '/usr/bin/php';
10934
10935        $artisanPath = escapeshellarg(base_path('artisan'));
10936
10937        $command = sprintf(
10938            '%s %s update:commercial-numbers %s > /dev/null 2>&1 &',
10939            $phpBinary,
10940            $artisanPath,
10941            $companyId
10942        );
10943
10944        exec($command, $output, $returnVar);
10945    }
10946
10947    function list_quotation_analytics_by_service_type(Request $request){
10948
10949        try {
10950
10951            $data = $request->all();
10952            $companyId = addslashes($data['company_id']);
10953            $where  = "";
10954
10955            if($companyId != 0){
10956                $where .= " AND c.company_id = {$companyId} ";
10957            }else{
10958                $where .= " AND c.company_id IN ({$this->companyId}";
10959            }
10960
10961            $col = "1";
10962
10963            if(isset($data['data_to_display']) && $data['data_to_display'] != null){
10964                if($data['data_to_display'] == 1){
10965                    $col = "1";
10966                }
10967
10968                if($data['data_to_display'] == 2){
10969                    $col = "q.amount";
10970                }
10971            }
10972
10973            if(isset($data['approvals'])){
10974                $approvals = addslashes($data['approvals']);
10975
10976                if($approvals == 2){
10977                    $where .= " AND q.for_approval != 1 ";
10978                }
10979
10980                if($approvals == 3){
10981                    $where .= " AND q.for_approval > 0 ";
10982                }
10983
10984                if($approvals == 4){
10985                    $where .= " AND q.approved_by IS NOT NULL";
10986                }
10987
10988                if($approvals == 5){
10989                    $where .= " AND q.for_approval = 2 AND q.approved_by IS NULL";
10990                }
10991
10992                if($approvals == 6){
10993                    $where .= " AND q.approved_by IS NOT NULL AND q.approved_by_v2 IS NOT NULL";
10994                }
10995
10996                if($approvals == 7){
10997                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NOT NULL AND q.approved_by_v2 IS NULL";
10998                }
10999
11000                if($approvals == 8){
11001                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NULL AND q.approved_by_v2 IS NOT NULL";
11002                }
11003
11004                if($approvals == 9){
11005                    $where .= " AND q.for_approval = 3 AND q.approved_by IS NULL AND q.approved_by_v2 IS NULL";
11006                }
11007            }
11008
11009            if(isset($data['role_id']) && $data['role_id'] != null){
11010                $roleIds = implode(",", $data['role_id']);
11011                if(count($data['role_id']) > 0){
11012                    $where .= " AND u.role_id IN ({$roleIds}, 999999999)";
11013                }
11014            }
11015
11016            if(isset($data['client_type']) && $data['client_type'] != null){
11017                $where .= " AND q.customer_type_id = {$data['client_type']}";
11018            }
11019
11020            $weekDay = "- WEEKDAY(q.date)";
11021
11022            if(isset($data['start_of_the_week']) && $data['start_of_the_week'] != null){
11023                switch ($data['start_of_the_week']) {
11024                    case 0:
11025                        $weekDay = "- WEEKDAY(q.date)";
11026                        break;
11027                    case 1:
11028                        $weekDay = "(1 - WEEKDAY(q.date))";
11029                        break;
11030                    case 2:
11031                        $weekDay = "(2 - WEEKDAY(q.date))";
11032                        break;
11033                    case 3:
11034                        $weekDay = "(3 - WEEKDAY(q.date))";
11035                        break;
11036                    case 4:
11037                        $weekDay = "(4 - WEEKDAY(q.date))";
11038                        break;
11039                    default:
11040                        $weekDay = "- WEEKDAY(q.date)";
11041                        break;
11042                }
11043            }
11044
11045            $whereDates = "";
11046
11047            if((isset($data['start_date']) && $data['start_date'] != null) && (isset($data['end_date']) && $data['end_date'] != null)){
11048                $whereDates = " AND q.date BETWEEN '{$data['start_date']}' AND '{$data['end_date']}";
11049            }
11050
11051            $query = "SELECT
11052                        q.region,
11053                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) 'year',
11054                        LPAD(MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'month',
11055                        LPAD(WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'week',
11056                        DATE_FORMAT(DATE_ADD(q.date, INTERVAL {$weekDay} DAY), '%W, %M %e') namedate,
11057
11058                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' THEN q.id END) AS groupConcatIdsTotalEnviado,
11059                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END), 0) AS totalIssueEnviado,
11060
11061                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoEnviado,
11062                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoEnviado,
11063                        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,
11064
11065                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosEnviado,
11066                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosEnviado,
11067                        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,
11068
11069                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasEnviado,
11070                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasEnviado,
11071                        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,
11072
11073                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
11074                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
11075                        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,
11076
11077                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
11078                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
11079                        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,
11080
11081                        CASE
11082                            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
11083                            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)
11084                                / 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)
11085                        END AS weightedAverageMarginForTheCompanyEnviado,
11086                        CASE
11087                            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
11088                            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)
11089                                / 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)
11090                        END AS weightedAverageInvoiceEnviado,
11091
11092                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' THEN q.id END) AS groupConcatIdsTotalAceptado,
11093                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END), 0) AS totalIssueAceptado,
11094
11095                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoAceptado,
11096                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoAceptado,
11097                        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,
11098
11099                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosAceptado,
11100                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosAceptado,
11101                        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,
11102
11103                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasAceptado,
11104                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasAceptado,
11105                        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,
11106
11107                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosAceptado,
11108                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosAceptado,
11109                        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,
11110
11111                        CASE
11112                            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
11113                            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)
11114                                / 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)
11115                        END AS weightedAverageMarginForTheCompanyAceptado,
11116                        CASE
11117                            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
11118                            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)
11119                                / 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)
11120                        END AS weightedAverageInvoiceAceptado,
11121
11122                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN 1 END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalIssuePercentage,
11123                        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,
11124                        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,
11125                        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,
11126                        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,
11127
11128                        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,
11129                        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,
11130                        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,
11131                        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,
11132                        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
11133                    FROM
11134                    (
11135                        SELECT
11136                            c.region,
11137                            q.issue_date AS DATE,
11138                            'issue' AS date_type,
11139                            q.acceptance_date,
11140                            q.issue_date,
11141                            q.id,
11142                            q.margin_for_the_company,
11143                            CASE
11144                                WHEN bt.budget_type_group_id = 4
11145                                AND q.budget_margin_enabled > 0
11146                                AND q.budget_margin_enabled IS NOT NULL
11147                                AND q.margin_for_the_company <> 0
11148                            THEN q.margin_for_the_company * q.amount
11149                            END s1,
11150                            q.invoice_margin,
11151                            CASE
11152                                WHEN bt.budget_type_group_id = 4
11153                                AND q.budget_margin_enabled > 0
11154                                AND q.budget_margin_enabled IS NOT NULL
11155                                AND q.invoice_margin <> 0
11156                            THEN q.invoice_margin * q.amount
11157                            END s2,
11158                            q.budget_type_id,
11159                            q.budget_status_id,
11160                            q.amount,
11161                            bt.budget_type_group_id,
11162                            q.budget_margin_enabled
11163                        FROM
11164                            tbl_quotations q
11165                        JOIN tbl_companies c
11166                            ON c.company_id = q.company_id
11167                        LEFT JOIN tbl_budget_types bt
11168                            ON q.budget_type_id = bt.budget_type_id
11169                        LEFT JOIN tbl_users u
11170                            ON u.name = q.created_by
11171                        LEFT JOIN tbl_roles r
11172                            ON r.role_id = u.role_id
11173                        WHERE
11174                            q.issue_date IS NOT NULL
11175                            AND q.for_add != 1
11176                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
11177                            AND (q.commercial IS NOT NULL AND q.commercial != '')
11178                            AND q.budget_type_id != 7
11179                            AND q.budget_type_id IS NOT NULL
11180                            {$where}
11181
11182                        UNION ALL
11183
11184                        SELECT
11185                            c.region,
11186                            q.acceptance_date AS DATE,
11187                            'acceptance' AS date_type,
11188                            q.acceptance_date,
11189                            q.issue_date,
11190                            q.id,
11191                            q.margin_for_the_company,
11192                            CASE
11193                                WHEN bt.budget_type_group_id = 4
11194                                AND q.budget_margin_enabled > 0
11195                                AND q.budget_margin_enabled IS NOT NULL
11196                                AND q.margin_for_the_company > 0
11197                            THEN q.margin_for_the_company * q.amount
11198                            END s1,
11199                            q.invoice_margin,
11200                            CASE
11201                                WHEN bt.budget_type_group_id = 4
11202                                AND q.budget_margin_enabled <> 0
11203                                AND q.budget_margin_enabled IS NOT NULL
11204                                AND q.invoice_margin <> 0
11205                            THEN q.invoice_margin * q.amount
11206                            END s2,
11207                            q.budget_type_id,
11208                            q.budget_status_id,
11209                            q.amount,
11210                            bt.budget_type_group_id,
11211                            q.budget_margin_enabled
11212                        FROM
11213                            tbl_quotations q
11214                        JOIN tbl_companies c
11215                            ON c.company_id = q.company_id
11216                        LEFT JOIN tbl_budget_types bt
11217                            ON q.budget_type_id = bt.budget_type_id
11218                        LEFT JOIN tbl_users u
11219                            ON u.name = q.created_by
11220                        LEFT JOIN tbl_roles r
11221                            ON r.role_id = u.role_id
11222                        WHERE
11223                            q.acceptance_date IS NOT NULL
11224                            AND q.for_add != 1
11225                            AND q.budget_type_id IS NOT NULL
11226                            AND q.budget_type_id != 7
11227                            AND q.acceptance_date != '0000-00-00 00:00:00'
11228                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
11229                            {$where}
11230                    ) AS q
11231                    WHERE q.date != '0000-00-00 00:00:00' {$whereDates}
11232                    GROUP BY
11233                        q.region,
11234                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11235                        MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11236                        WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) WITH ROLLUP
11237                    ORDER BY
11238                        q.region IS NULL,
11239                        q.region,
11240                        CASE WHEN q.region IS NOT NULL
11241                            AND YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11242                            AND MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11243                            AND WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11244                        THEN 0
11245                        ELSE 1 END,
11246                    YEAR DESC,
11247                    MONTH ASC,
11248                    WEEK ASC";
11249
11250            $value = Cache::get(base64_encode($query));
11251
11252            if(!$value){
11253                $result = DB::select($query);
11254
11255                Cache::put(base64_encode($query), $result, 600);
11256            }else{
11257                $result = $value;
11258            }
11259
11260            $query = "SELECT
11261                        q.region,
11262                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) 'year',
11263                        LPAD(MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'month',
11264                        LPAD(WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)), 2, 0) 'week',
11265                        DATE_FORMAT(DATE_ADD(q.date, INTERVAL {$weekDay} DAY), '%W, %M %e') namedate,
11266
11267                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' THEN q.id END) AS groupConcatIdsTotalEnviado,
11268                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END), 0) AS totalIssueEnviado,
11269
11270                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoEnviado,
11271                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoEnviado,
11272                        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,
11273
11274                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosEnviado,
11275                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosEnviado,
11276                        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,
11277
11278                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasEnviado,
11279                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasEnviado,
11280                        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,
11281
11282                        GROUP_CONCAT(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosEnviado,
11283                        COALESCE(SUM(CASE WHEN q.date_type = 'issue' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosEnviado,
11284                        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,
11285
11286                        CASE
11287                            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
11288                            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)
11289                                / 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)
11290                        END AS weightedAverageMarginForTheCompanyEnviado,
11291                        CASE
11292                            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
11293                            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)
11294                                / 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)
11295                        END AS weightedAverageInvoiceEnviado,
11296
11297                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' THEN q.id END) AS groupConcatIdsTotalAceptado,
11298                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END), 0) AS totalIssueAceptado,
11299
11300                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN q.id END) AS groupConcatIdsMantenimientoAceptado,
11301                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 3 THEN {$col} END), 0) totalMantenimientoAceptado,
11302                        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,
11303
11304                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN q.id END) AS groupConcatIdsCorrectivosAceptado,
11305                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 5 THEN {$col} END), 0) totalCorrectivosAceptado,
11306                        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,
11307
11308                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN q.id END) AS groupConcatIdsObrasAceptado,
11309                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id = 4 THEN {$col} END), 0) totalObrasAceptado,
11310                        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,
11311
11312                        GROUP_CONCAT(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN q.id END) AS groupConcatIdsOtrosAceptado,
11313                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' AND q.budget_type_group_id IN (6, 7, 8) THEN {$col} END), 0) totalOtrosAceptado,
11314                        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,
11315
11316                        CASE
11317                            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
11318                            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)
11319                                / 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)
11320                        END AS weightedAverageMarginForTheCompanyAceptado,
11321                        CASE
11322                            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
11323                            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)
11324                                / 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)
11325                        END AS weightedAverageInvoiceAceptado,
11326
11327                        COALESCE(SUM(CASE WHEN q.date_type = 'acceptance' THEN {$col} END) / SUM(CASE WHEN q.date_type = 'issue' THEN {$col} END) * 100, 0) totalIssuePercentage,
11328                        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,
11329                        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,
11330                        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,
11331                        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,
11332
11333                        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,
11334                        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,
11335                        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,
11336                        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,
11337                        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
11338                    FROM
11339                    (
11340                        SELECT
11341                            'Total Grupo FIRE' region,
11342                            q.issue_date AS DATE,
11343                            'issue' AS date_type,
11344                            q.acceptance_date,
11345                            q.issue_date,
11346                            q.id,
11347                            q.margin_for_the_company,
11348                            CASE
11349                                WHEN bt.budget_type_group_id = 4
11350                                AND q.budget_margin_enabled > 0
11351                                AND q.budget_margin_enabled IS NOT NULL
11352                                AND q.margin_for_the_company <> 0
11353                            THEN q.margin_for_the_company * q.amount
11354                            END s1,
11355                            q.invoice_margin,
11356                            CASE
11357                                WHEN bt.budget_type_group_id = 4
11358                                AND q.budget_margin_enabled > 0
11359                                AND q.budget_margin_enabled IS NOT NULL
11360                                AND q.invoice_margin <> 0
11361                            THEN q.invoice_margin * q.amount
11362                            END s2,
11363                            q.budget_type_id,
11364                            q.budget_status_id,
11365                            q.amount,
11366                            bt.budget_type_group_id,
11367                            q.budget_margin_enabled
11368                        FROM
11369                            tbl_quotations q
11370                        JOIN tbl_companies c
11371                            ON c.company_id = q.company_id
11372                        LEFT JOIN tbl_budget_types bt
11373                            ON q.budget_type_id = bt.budget_type_id
11374                        LEFT JOIN tbl_users u
11375                            ON u.name = q.created_by
11376                        LEFT JOIN tbl_roles r
11377                            ON r.role_id = u.role_id
11378                        WHERE
11379                            q.issue_date IS NOT NULL
11380                            AND q.for_add != 1
11381                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
11382                            AND (q.commercial IS NOT NULL AND q.commercial != '')
11383                            AND q.budget_type_id != 7
11384                            AND q.budget_type_id IS NOT NULL
11385                            {$where}
11386
11387                        UNION ALL
11388
11389                        SELECT
11390                            'Total Grupo FIRE' region,
11391                            q.acceptance_date AS DATE,
11392                            'acceptance' AS date_type,
11393                            q.acceptance_date,
11394                            q.issue_date,
11395                            q.id,
11396                            q.margin_for_the_company,
11397                            CASE
11398                                WHEN bt.budget_type_group_id = 4
11399                                AND q.budget_margin_enabled > 0
11400                                AND q.budget_margin_enabled IS NOT NULL
11401                                AND q.margin_for_the_company <> 0
11402                            THEN q.margin_for_the_company * q.amount
11403                            END s1,
11404                            q.invoice_margin,
11405                            CASE
11406                                WHEN bt.budget_type_group_id = 4
11407                                AND q.budget_margin_enabled > 0
11408                                AND q.budget_margin_enabled IS NOT NULL
11409                                AND q.invoice_margin <> 0
11410                            THEN q.invoice_margin * q.amount
11411                            END s2,
11412                            q.budget_type_id,
11413                            q.budget_status_id,
11414                            q.amount,
11415                            bt.budget_type_group_id,
11416                            q.budget_margin_enabled
11417                        FROM
11418                            tbl_quotations q
11419                        JOIN tbl_companies c
11420                            ON c.company_id = q.company_id
11421                        LEFT JOIN tbl_budget_types bt
11422                            ON q.budget_type_id = bt.budget_type_id
11423                        LEFT JOIN tbl_users u
11424                            ON u.name = q.created_by
11425                        LEFT JOIN tbl_roles r
11426                            ON r.role_id = u.role_id
11427                        WHERE
11428                            q.acceptance_date IS NOT NULL
11429
11430                            AND q.for_add != 1
11431                            AND q.amount REGEXP '^[0-9]+\\.?[0-9]*$' = 1
11432                            AND (q.commercial IS NOT NULL AND q.commercial != '')
11433                            AND q.budget_type_id != 7
11434                            AND q.budget_type_id IS NOT NULL
11435                            {$where}
11436                    ) AS q
11437                    WHERE q.date != '0000-00-00 00:00:00' {$whereDates}
11438                    GROUP BY
11439                        q.region,
11440                        YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11441                        MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)),
11442                        WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) WITH ROLLUP
11443                    ORDER BY
11444                        q.region IS NULL,
11445                        q.region,
11446                        CASE WHEN q.region IS NOT NULL
11447                            AND YEAR(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11448                            AND MONTH(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11449                            AND WEEK(DATE_ADD(q.date, INTERVAL {$weekDay} DAY)) IS NULL
11450                        THEN 0
11451                        ELSE 1 END,
11452                    YEAR DESC,
11453                    MONTH ASC,
11454                    WEEK ASC";
11455
11456            $totalGroupValue = Cache::get(base64_encode($query));
11457
11458            if(!$totalGroupValue){
11459                $totalGroup = DB::select($query);
11460
11461                Cache::put(base64_encode($query), $totalGroup, 600);
11462            }else{
11463                $totalGroup = $totalGroupValue;
11464            }
11465
11466            array_pop($result);
11467            $merged = array_merge($result, $totalGroup);
11468
11469            return response([
11470                'message' => 'OK',
11471                'data' => $merged
11472            ]);
11473
11474        } catch (\Exception $e) {
11475            /** @disregard P1014 */
11476            $e->exceptionCode = 'LIST_QUOTATIONS_ANALYTICS_BY_SERVICE_TYPE_EXCEPTION'; 
11477            report($e);
11478            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11479        }
11480
11481    }
11482
11483    public function getIdsFromInternalQuoteIds($ids){
11484        $idsArray = array_filter(explode(',', $ids), 'is_numeric');
11485        return TblQuotations::whereIn("internal_quote_id", $idsArray)
11486            ->pluck("id")
11487            ->toArray();
11488    }
11489
11490    public function checkQuotationExistByInternalQuoteId(Request $request)
11491    {
11492        try{
11493            $idsString = $request->all()["ids"];
11494            $ids = explode(',',$idsString);
11495            $region = urldecode(@getallheaders()["Region"]);
11496            $company = TblCompanies::where("region", $region)->first();
11497
11498            if(!$company){
11499                Throw new \Exception("Region no encontrada");
11500            }
11501
11502            $companyId = $company->company_id;
11503
11504            $idsChecked = [];
11505
11506            foreach ($ids as $id){
11507                $quote = TblQuotations::where("internal_quote_id", $id)->where("company_id", $companyId)->first();
11508                if(
11509                    ($companyId === 18 || $companyId === 22)
11510                    && !$quote
11511                ){
11512                    $quote = TblQuotations::where("internal_quote_id", $id)->whereIn("company_id", [18,22])->first();
11513                }
11514                $idsChecked[$id] = $quote ? $quote->id : null;
11515            }
11516
11517            return response([
11518                'message' => 'OK',
11519                'data' => $idsChecked
11520            ]);
11521
11522        }catch (\Exception $e) {
11523            /** @disregard P1014 */
11524            $e->exceptionCode = 'CHECK_QUOTATION_EXIST_BY_INTERNAL_QUOTE_ID_EXCEPTION'; 
11525            report($e);
11526            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11527        }
11528
11529    }
11530
11531    public function addUpdateLog($id, $userId, $field, $oldData, $newData){
11532        $oldRegister = null;
11533        $newRegister = null;
11534
11535        if($field == "company_id"){
11536            $oldRegister = TblCompanies::where("company_id", $oldData)->first();
11537            $newRegister = TblCompanies::where("company_id", $newData)->first();
11538        }
11539
11540        if($field == "customer_type_id"){
11541            $oldRegister = TblCustomerTypes::where("customer_type_id", $oldData)->first();
11542            $newRegister = TblCustomerTypes::where("customer_type_id", $newData)->first();
11543        }
11544
11545        if($field == "segment_id"){
11546            $oldRegister = TblSegments::where("segment_id", $oldData)->first();
11547            $newRegister = TblSegments::where("segment_id", $newData)->first();
11548        }
11549
11550        if($field == "budget_type_id"){
11551            $oldRegister = TblBudgetTypes::where("budget_type_id", $oldData)->first();
11552            $newRegister = TblBudgetTypes::where("budget_type_id", $newData)->first();
11553        }
11554
11555        if($field == "budget_status_id"){
11556            $oldRegister = TblBudgetStatus::where("budget_status_id", $oldData)->first();
11557            $newRegister = TblBudgetStatus::where("budget_status_id", $newData)->first();
11558        }
11559
11560        if($field == "source_id"){
11561            $oldRegister = TblSources::where("source_id", $oldData)->first();
11562            $newRegister = TblSources::where("source_id", $newData)->first();
11563        }
11564
11565        $oldData = $oldRegister ? $oldRegister->name : 'N/A';
11566        $newData = $newRegister ? $newRegister->name : 'N/A';
11567
11568        if(is_numeric($userId)){
11569            $userName = TblUsers::where("id", $userId)->first()->name;
11570        } else {
11571            $userName = $userId;
11572        }
11573
11574        if($oldData !== $newData){
11575            TblQuotationsLog::create(
11576                array(
11577                    'quotation_id' => $id,
11578                    'user' => $userName,
11579                    'field' => $field,
11580                    'old_value' => $oldData,
11581                    'new_value' => $newData
11582                )
11583            );
11584        }
11585    }
11586
11587    public function setSolicitudDuplicity(Request $request){
11588        try{
11589            $type = $request->all()["type"];
11590            $quoteId = $request->all()["quoteId"];
11591            $companyId = $request->all()["companyId"];
11592
11593            $quote = TblQuotations::where("quote_id", $quoteId)->where("company_id", $companyId)->first();            
11594
11595            if(!$quote){
11596                throw new \Exception("Quote no encontrada");
11597            }
11598
11599            $newIdSolicitudDuplicityValue = null;
11600
11601            if($type === "reject"){
11602                $quote->budget_status_id = 20;
11603                $newIdSolicitudDuplicityValue = "R" . $quote->id_solicitud_duplicity;
11604            }
11605
11606            $this->addUpdateLog($quote->id, "System", "id_solicitud_duplicity", $quote->id_solicitud_duplicity, $newIdSolicitudDuplicityValue);
11607            
11608            $quote->id_solicitud_duplicity = $newIdSolicitudDuplicityValue;
11609
11610            $quote->save();
11611
11612            return response([
11613                'message' => 'OK',
11614                'data' => $quote
11615            ]);
11616
11617        }catch (\Exception $e) {
11618            /** @disregard P1014 */
11619            $e->exceptionCode = 'SET_SOLICITUD_DUPLICITY_EXCEPTION'; 
11620            report($e);
11621            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11622        }
11623    } 
11624
11625    public function getQuoteIdOfDuplicityById($id){
11626        try{
11627            $quote = TblQuotations::where("id", $id)->first();            
11628
11629            if(!$quote){
11630                throw new \Exception("Quote no encontrada");
11631            }
11632
11633            return response([
11634                'message' => 'OK',
11635                'data' => $quote
11636            ]);
11637
11638        }catch (\Exception $e) {
11639            /** @disregard P1014 */
11640            $e->exceptionCode = 'GET_QUOTE_ID_OF_DUPLICITY_BY_QUOTE_ID_EXCEPTION'; 
11641            report($e);
11642            return response(['message' => 'KO', 'error' => $e->getMessage()]);
11643        }
11644    }
11645}