Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
7.14% covered (danger)
7.14%
10 / 140
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
IfexController
7.14% covered (danger)
7.14%
10 / 140
20.00% covered (danger)
20.00%
1 / 5
610.68
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 request
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
132
 syncQuotations
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
30
 createQuotation
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 1
30
 updateQuotation
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\TblIfexLastUpdate;
6use App\Models\TblQuotations;
7use App\Services\PresupuestosService;
8use Carbon\Carbon;
9use Illuminate\Support\Facades\Log;
10use Mockery\Exception;
11use App\Exceptions\AppException;
12
13
14class IfexController extends Controller
15{
16    protected $statusNormalize;
17
18    public function __construct(protected PresupuestosService $presupuestosService)
19    {
20        $this->statusNormalize = [
21            'Oportunidad' => 1, // Oportunidad => Nuevo
22            'Pendiente' => 11, // Pendiente => Listo para enviar
23            'Pendiente Cliente' => 2, // Pendiente Cliente => Enviado
24            'Aceptado' => 3, // Aceptado => Aceptado
25            'En ejecución' => 12, // En ejecución => En proceso
26            'Rechazado' => 4, // Rechazado => Rechazado
27            'Anulado' => 5, // Anulado => Anulado
28            'Finalizado' => 3, // Finalizado => Aceptado
29        ];
30
31    }
32
33    protected function request($method, $endpoint, array $data = [])
34    {
35        try {
36            // $this->getCredentials($region);
37
38            /*if (!$this->apiUrl) {
39                throw new \Exception('API URL is not defined.');
40            }
41
42            if (!$this->accessToken) {
43                $this->auth($region);
44            }*/
45            $apiUrl = env('IFEX_API_URL', '');
46
47            $url = "{$apiUrl}{$endpoint}";
48            $curl = curl_init();
49
50            curl_setopt_array($curl, [
51                CURLOPT_URL => $url,
52                CURLOPT_RETURNTRANSFER => true,
53                CURLOPT_CUSTOMREQUEST => strtoupper((string) $method),
54                CURLOPT_HTTPHEADER => [
55                    'x-api-key: ' . env('IFEX_API_KEY', ''),
56                ],
57            ]);
58
59            if (in_array(strtoupper((string) $method), ['POST', 'PUT', 'PATCH']) && !empty($data)) {
60                if (!is_array($data)) {
61                    throw new \Exception('The $data parameter must be an array.');
62                }
63                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
64            }
65
66            $response = curl_exec($curl);
67
68            if (curl_errno($curl)) {
69                throw new \Exception('cURL error: '.curl_error($curl));
70            }
71
72            $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
73            curl_close($curl);
74
75            /*if ($httpCode === 401) {
76                $this->auth($region);
77                return $this->request($method, $endpoint, $region, $data);
78            }*/
79
80            if ($httpCode < 200 || $httpCode >= 300) {
81                Log::channel('ifex')->error('API Response Error: '.$response);
82
83                $errorResponse = json_decode($response, true);
84                $errorMessage = is_array($errorResponse) && isset($errorResponse['message'])
85                    ? $errorResponse['message']
86                    : 'Request error: '.$response;
87
88                throw new \Exception($errorMessage);
89            }
90
91            $responseData = json_decode($response, true);
92
93            if (json_last_error() !== JSON_ERROR_NONE) {
94                throw new \Exception('Invalid JSON response: '.$response);
95            }
96
97            return $responseData;
98        } catch (\Exception $e) {
99            Log::channel('g3w')->error('Error in request: '.$e->getMessage());
100            throw $e;
101        }
102    }
103
104    public function syncQuotations()
105    {
106        try {
107            $today = Carbon::now()->format('Y-m-d');
108            $requestDate = "presupuestos/creados-editados?fechainicio={$today}&fechafin={$today}";
109
110            $quotationsToSync = json_decode(json_encode($this->request('GET', $requestDate)));
111
112            foreach ($quotationsToSync as $quotation) {
113                if (TblQuotations::where('internal_quote_id', $quotation->codigo)->exists()) {
114                    $this->updateQuotation($quotation);
115                } else {
116                    $this->createQuotation($quotation);
117                }
118
119            }
120
121            TblIfexLastUpdate::where("id", 1)->first()->update(
122                [
123                    "last_date" => Carbon::now()->format('Y-m-d H:i:s')
124                ]
125            );
126
127            return ['success' => true, 'quotations' => $quotationsToSync];
128        }catch (\Exception $e){
129            report(AppException::fromException($e, 'SYNC_QUOTATIONS_IFEX_EXCEPTION'));
130            Log::channel('ifex')->error('Error updating quotations: ' . $e->getMessage(), [
131                'exception' => $e
132            ]);
133
134            return response()->json([
135                'success' => false,
136                'message' => 'Failed to update ifex quotations',
137                'error' => $e->getMessage(),
138                'error_code' => $e->exceptionCode ?: 500,
139            ], 500);
140        }
141    }
142
143    public function createQuotation($quotation): void{
144        //instalaciones 6 25O
145        //correctivos 3 25C
146        //mantenimiento 1 25P
147        $type = null;
148        if (str_contains((string) $quotation->codigo, "25O")) {
149            $type = 6;
150        }
151
152        if (str_contains((string) $quotation->codigo, "25C")) {
153            $type = 3;
154        }
155
156        if (str_contains((string) $quotation->codigo, "25P")) {
157            $type = 1;
158        }
159        if (str_contains((string) $quotation->codigo, "G25")) {
160            return;
161        }
162
163        $generateNumber = $this->presupuestosService->generateQuoteId(30);
164
165        $g3wNewId = $generateNumber['id'];
166        $newQuoteId = $generateNumber['number'];
167
168        $ifexArray = [
169            'internal_quote_id' => $quotation->codigo,
170            'quote_id' => $newQuoteId,
171            'company_id' => 30,
172            'customer_type_id' => 2,
173            'segment_id' => null,
174            'budget_type_id' => $type,
175            'budget_status_id' => $this->statusNormalize[$quotation->estado],
176            'source_id' => 55,
177            'client' => $quotation->clienteNombre ?? null,
178            'phone_number' => $quotation->clienteTelefono ?? null,
179            'email' => $quotation->clienteMail ?? null,
180            'issue_date' => $quotation->fecha ?? null,
181            'request_date' => $quotation->fechaAlta ?? null,
182            'acceptance_date' => $quotation->fechaAceptacion ?? null,
183            'amount' => $quotation->baseImponible ?? null,
184            'last_follow_up_date' => null,
185            'commercial' => 'Ifex',
186            'created_at' => $quotation->fecha ?? null,
187            'created_by' => 'Ifex',
188            'has_attachment' => 0,
189            'cost_of_labor' => 0,
190            'total_cost_of_job' => 0,
191            'invoice_margin' => 0,
192            'margin_for_the_company' => 0,
193            'revenue_per_date_per_worked' => 0,
194            'gross_margin' => 100,
195            'labor_percentage' => 0,
196            'sync_import' => 1,
197            'box_work_g3w' => null,
198            'for_add' => 0,
199            'for_approval' => 0,
200            'reason_for_not_following_up_id' => 2
201        ];
202
203        TblQuotations::where('id', $g3wNewId)->update($ifexArray);
204    }
205
206    public function updateQuotation($quotation): void{
207        $fstQuotation = TblQuotations::where("internal_quote_id", $quotation->codigo)->first();
208
209        // instalaciones 6 25O
210        // correctivos 3 25C
211        // mantenimiento 1 25P
212        $type = null;
213        if (str_contains((string) $quotation->codigo, "25O")) {
214            $type = 6;
215        }
216
217        if (str_contains((string) $quotation->codigo, "25C")) {
218            $type = 3;
219        }
220
221        if (str_contains((string) $quotation->codigo, "25P")) {
222            $type = 1;
223        }
224        if (str_contains((string) $quotation->codigo, "G25")) {
225            return;
226        }
227
228        $ifexArray = [
229            'internal_quote_id' => $quotation->codigo,
230            'budget_type_id' => $type,
231            'budget_status_id' => $this->statusNormalize[$quotation->estado],
232            'client' => $quotation->clienteNombre ?? null,
233            'phone_number' => $quotation->clienteTelefono ?? null,
234            'email' => $quotation->clienteMail ?? null,
235            'issue_date' => $quotation->fecha ?? null,
236            'request_date' => $quotation->fechaAlta ?? null,
237            'acceptance_date' => $quotation->fechaAceptacion ?? null,
238            'amount' => $quotation->baseImponible ?? null,
239            'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
240            'updated_by' => "Ifex"
241        ];
242
243        $fstQuotation->update($ifexArray);
244
245    }
246}