Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
1.67% covered (danger)
1.67%
2 / 120
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
SendEmailInvoiceNewCreditDays
1.67% covered (danger)
1.67%
2 / 120
20.00% covered (danger)
20.00%
1 / 5
1199.77
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 handle
0.00% covered (danger)
0.00%
0 / 70
0.00% covered (danger)
0.00%
0 / 1
812
 send_email
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
6
 isEmailValid
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 detectDelimiter
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace App\Console\Commands;
4
5use App\Models\TblCustomerChangeComms;
6use App\Services\GestionaService;
7use Illuminate\Console\Command;
8use Illuminate\Support\Facades\File;
9use Illuminate\Support\Facades\Log;
10
11class SendEmailInvoiceNewCreditDays extends Command
12{
13    /**
14     * The name and signature of the console command.
15     *
16     * @var string
17     */
18    protected $signature = 'send:invoice-new-credit-days {invoiceDate?}';
19
20    /**
21     * The console command description.
22     *
23     * @var string
24     */
25    protected $description = 'Send email invoice new credit days';
26
27    protected $gestionaService;
28
29    /**
30     * Create a new command instance.
31     *
32     * @return void
33     */
34    public function __construct(GestionaService $gestionaService)
35    {
36        parent::__construct();
37        $this->gestionaService = $gestionaService;
38    }
39
40    /**
41     * Execute the console command.
42     *
43     * @return int
44     */
45    public function handle()
46    {
47        try {
48
49            $invoiceDate = $this->argument('invoiceDate') ?? null;
50
51            if ($invoiceDate != null) {
52                $d = \DateTime::createFromFormat('Y-m-d', $invoiceDate);
53
54                if (! $d || $d->format('Y-m-d') !== $invoiceDate) {
55                    throw new \InvalidArgumentException('Invalid date format. Expected Y-m-d.');
56                }
57            } else {
58                $invoiceDate = date('Y-m-d', strtotime('-1 day'));
59            }
60            $logo = File::get(public_path('fireservicetitan.png'));
61
62            $regions = [
63                'Catalunya',
64                'Madrid',
65                'Andalucía',
66                'Baleares',
67                'Comunidad Valenciana',
68            ];
69
70            foreach ($regions as $region) {
71                $yesterdayInvoices = $this->gestionaService->request('get', 'factura/vence/'.$invoiceDate, $region, []);
72
73                if (! empty($yesterdayInvoices) && ! empty($yesterdayInvoices['facturas'])) {
74
75                    for ($i = 0; $i < count($yesterdayInvoices['facturas']); $i++) {
76
77                        $email = new \SendGrid\Mail\Mail;
78
79                        $invoiceId = $yesterdayInvoices['facturas'][$i]['ID'];
80                        $dataInvoice = $this->gestionaService->request('get', 'factura/'.$invoiceId, $region, []);
81
82                        if (! empty($dataInvoice) && ! empty($dataInvoice['factura'])) {
83
84                            if (isset($dataInvoice['factura']['cod_cliente'])) {
85
86                                $clientCode = $dataInvoice['factura']['cod_cliente'];
87                                $result = TblCustomerChangeComms::where('client_code', $clientCode)->where('email_sent_at', null)->first();
88
89                                if ($result != null) {
90
91                                    $clientInvoiceResponse = $this->gestionaService->request('get', 'cliente/'.$result->client_code, $result->region, []);
92
93                                    if (! empty($clientInvoiceResponse) && ! empty($clientInvoiceResponse['cliente'])) {
94                                        $addTo = [];
95                                        $toEmail = [];
96
97                                        if (config('services.sendgrid.staging')) {
98                                            $toEmail = ['christian@ibventur.es'];
99                                        } else {
100
101                                            if (isset($clientInvoiceResponse['cliente']['email_facturacion'])) {
102                                                $toEmail = $clientInvoiceResponse['cliente']['email_facturacion'];
103                                            }
104
105                                            if (isset($clientInvoiceResponse['cliente']['email'])) {
106                                                $toEmail = $clientInvoiceResponse['cliente']['email'];
107                                            }
108
109                                        }
110
111                                        if (! empty($toEmail)) {
112                                            $delimiter = $this->detectDelimiter($toEmail);
113                                            $toEmail = explode($delimiter, $toEmail);
114                                            $toEmail = array_map('trim', $toEmail);
115
116                                            $invalidEmailCount = 0;
117
118                                            foreach ($toEmail as $clientEmail) {
119                                                $isValid = $this->isEmailValid($clientEmail);
120                                                if ($isValid) {
121                                                    if (! in_array($clientEmail, $addTo)) {
122                                                        array_push($addTo, $clientEmail);
123                                                        $email->addTo($clientEmail);
124                                                    }
125                                                } else {
126                                                    $invalidEmailCount++;
127                                                    Log::channel('cron_send_email_invoice_new_credit_days')->error("[$result->client_code]: Invalid email address $clientEmail");
128                                                }
129                                            }
130
131                                            if ($invalidEmailCount != count($toEmail)) {
132                                                $this->send_email($result->id, $result->client_code, $result->client_name, $result->credit_days, $logo, $addTo, $email);
133                                            }
134                                        }
135
136                                        if(!empty($toEmail)){
137                                            $delimiter = $this->detectDelimiter($toEmail);
138                                            $toEmail = explode($delimiter, $toEmail);
139                                            $toEmail = array_map('trim', $toEmail); 
140
141                                            $invalidEmailCount = 0;
142                                            
143                                            foreach ($toEmail as $clientEmail) {
144                                                $isValid = $this->isEmailValid($clientEmail);
145                                                if ($isValid) {                                                    
146                                                    if (! in_array($clientEmail, $addTo)) {
147                                                        array_push($addTo, $clientEmail);
148                                                        $email->addTo($clientEmail);
149                                                    }
150                                                } else {
151                                                    $invalidEmailCount++;
152                                                    Log::channel('cron_send_email_invoice_new_credit_days')->error("[$result->client_code]: Invalid email address $clientEmail");
153                                                }
154                                            }
155
156                                            if ($invalidEmailCount != count($toEmail)) {
157                                                $this->send_email($result->id, $result->client_code, $result->client_name, $result->credit_days, $logo, $addTo, $email);
158                                            }
159                                        }                                        
160                                    }
161                                }
162                            }
163                        }
164                    }
165                }
166            }
167
168        } catch (\Exception $e) {
169            Log::channel('cron_send_email_invoice_new_credit_days')->error($e->getMessage());
170
171            return 1;
172        }
173
174        return 0;
175    }
176
177    public function send_email($id, $clientCode, $clientName, $creditDays, $logo, $addTo, $email)
178    {
179
180        $body = "<p>Estimado {$clientName},</p></br>";
181        $body .= "<p>Le informamos de que, como parte de un proceso de revisión y mejora de nuestros procedimientos administrativos y de facturación, a partir del 01/03/2026 el plazo de vencimiento de las facturas emitidas a su nombre pasará a ser de {$creditDays} días, en sustitución del plazo actual.</p></br>";
182        $body .= '<p>Esta modificación tiene como objetivo homogeneizar y optimizar la gestión administrativa, sin que suponga ningún otro cambio al servicio que le ofrecemos habitualmente.</p></br>';
183        $body .= '<p>Muchas gracias.</p></br>';
184        $body .= '<p>Fire Service Titan</p>';
185        $body .= "<img src='cid:fireservicetitan' style='height: 45px;' />";
186
187        $html = '<!DOCTYPE html>';
188        $html .= '<html>';
189        $html .= '<head>';
190        $html .= '<meta charset="UTF-8">';
191        $html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
192        $html .= '</head>';
193        $html .= '<body>';
194        $html .= $body;
195        $html .= '</body>';
196        $html .= '</html>';
197
198        $email->setFrom('fire@fire.es', 'Fire Service Titan');
199        $email->setSubject('Condiciones comerciales Grupo Fire');
200        $email->addContent('text/html', $html);
201        $email->addCc('xavier.lopez@fire.es');
202
203        $email->addAttachment(
204            $logo,
205            'image/png',
206            'fireservicetitan.png',
207            'inline',
208            'fireservicetitan'
209        );
210
211        $sendgrid = new \SendGrid(config('services.sendgrid.api_key'));
212        $response = $sendgrid->send($email);
213
214        if ($response->statusCode() == 202) {
215            $addTo = json_encode($addTo);
216            TblCustomerChangeComms::where('id', $id)
217                ->update([
218                    'email_sent_at' => date('Y-m-d H:i:s'),
219                ]
220                );
221            Log::channel('cron_send_email_invoice_new_credit_days')->info("[SENT-OK] ID:$clientCode - $addTo");
222        } else {
223            $error = $response->body();
224            Log::channel('cron_send_email_invoice_new_credit_days')->error("[ERROR-SG] ID:$clientCode - $addTo - $error");
225        }
226    }
227
228    public function isEmailValid($email)
229    {
230        $pattern = '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/';
231
232        if (preg_match($pattern, $email)) {
233            return true;
234        } else {
235            return false;
236        }
237    }
238
239    public function detectDelimiter($string)
240    {
241        $delimiters = [',', ';', '|'];
242        $counts = [];
243
244        foreach ($delimiters as $delimiter) {
245            $counts[$delimiter] = substr_count($string, $delimiter);
246        }
247
248        return array_search(max($counts), $counts);
249    }
250}