Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
ArcadiaController
n/a
0 / 0
n/a
0 / 0
57
n/a
0 / 0
 outgoingMail
n/a
0 / 0
10
n/a
0 / 0
 checkShippingRequiredFields
n/a
0 / 0
4
n/a
0 / 0
 checkRequiredFields
n/a
0 / 0
21
n/a
0 / 0
 makeXml
n/a
0 / 0
22
n/a
0 / 0
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Controllers\Controller;
6use App\Http\Resources\StatusResource;
7use App\Mail\CourrierArcadiaError;
8use App\Models\Customer;
9use DOMDocument;
10use Illuminate\Http\Request;
11use Illuminate\Support\Facades\Log;
12use Illuminate\Support\Facades\Mail;
13use Illuminate\Support\Facades\Storage;
14use Illuminate\Support\Facades\Validator;
15
16/**
17 * @codeCoverageIgnore
18 */
19class ArcadiaController extends Controller
20{
21    /**
22     * @param Request $request
23     * @return StatusResource
24     */
25    public function outgoingMail(Request $request)
26    {
27        $validator = Validator::make($request->all(), [
28            'crm_id' => 'required',
29            'fields' => 'required|json',
30            'type' => 'required',
31            'shipping' => 'required_if:type,default|json'
32        ]);
33
34        if ($validator->fails()) {
35            return new StatusResource([
36                'status' => 'KO',
37                'code' => 201,
38                'message' => 'Error on required fields.',
39                'errors' => $validator->errors()
40            ]);
41        }
42
43        $brandId  = $request->brand_id;
44        $crmId    = $request->crm_id;
45        $fields   = json_decode($request->fields);
46        $type     = $request->type;
47        $shipping = $type === 'default' ? json_decode($request->shipping) : false;
48
49        $customer = Customer::where('id', $crmId)->first();
50        if (!$customer) {
51            return new StatusResource(['status' => 'KO', 'code' => 202, 'message' => 'User not found.']);
52        }
53
54        $CustomerInfo = $customer->infos()->where('brand_id', $brandId)->first();
55
56        if (!$CustomerInfo) {
57            return new StatusResource(['status' => 'KO', 'code' => 202, 'message' => 'User not found.']);
58        }
59
60        $check = $this->checkRequiredFields($fields, $type);
61        if ($check['status'] !== 'OK') {
62            return new StatusResource($check);
63        }
64
65        if ($type === 'default') {
66            $check = $this->checkShippingRequiredFields($shipping);
67            if ($check['status'] !== 'OK') {
68                return new StatusResource($check);
69            }
70        }
71
72        $xml = $this->makeXml($fields, $type, $customer, $CustomerInfo, $shipping);
73
74        try {
75            Storage::disk('arcadia')->put(date("Ymd_His") . microtime(true) . ".xml", $xml);
76            return new StatusResource(['status' => 'OK']);
77        } catch (\Exception $e) {
78            Log::critical("ARCADIA XML CREATION FAILED : " . $e->getMessage());
79            Mail::to(config('mail.MAIL_ADMIN'))->send(new CourrierArcadiaError(
80                "ARCADIA XML CREATION FAILED",
81                "Une erreur est survenue lors de la création du fichier XML : " . $e->getMessage(),
82                $xml ?: ''
83            ));
84            return new StatusResource(['status' => 'KO', 'code' => 204, 'message' => 'Arcadia XML Creation failed.']);
85        }
86    }
87
88    /**
89     * @param mixed $fields
90     * @return array
91     */
92    private function checkShippingRequiredFields($fields)
93    {
94        $test = [
95            'firstname',
96            'lastname',
97            'address',
98            'city',
99            'postcode'
100        ];
101
102        foreach ($test as $t) {
103            if (!array_key_exists($t, $fields)) {
104                $errors[] = ['field' => $t, 'error' => 'required'];
105            }
106        }
107
108        if (!empty($errors)) {
109            return ['status' => 'KO', 'code' => 203, 'message' => $errors];
110        }
111
112        return ['status' => 'OK'];
113    }
114
115    /**
116     *
117     * @param mixed $fields
118     * @param mixed $type
119     * @return array
120     */
121    // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh, Squiz.Commenting.FunctionComment.Missing
122    private function checkRequiredFields($fields, $type): array
123    {
124        $errors = [];
125
126        $key = array_search('operation', array_column($fields->root, 'fieldName'));
127        if ($key === false) {
128            $errors[] = ['field' => 'operation', 'error' => 'required'];
129        }
130
131        $key = array_search('support_code', array_column($fields->orderLine, 'fieldName'));
132        if ($key === false) {
133            $errors[] = ['field' => 'support_code', 'error' => 'required'];
134        }
135
136        $key = array_search('label_type_support', array_column($fields->orderLine, 'fieldName'));
137        if ($key === false) {
138            $errors[] = ['field' => 'label_type_support', 'error' => 'required'];
139        }
140
141        $key = array_search('order_date', array_column($fields->root, 'fieldName'));
142        if ($key === false) {
143            $errors[] = ['field' => 'order_date', 'error' => 'required'];
144        }
145
146        $regex = join('', [
147            '/^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|',
148            '((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))',
149            '|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]',
150            '|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/'
151        ]);
152        if (!preg_match($regex, $fields->root[$key]->fieldValue)) {
153            $errors[] = ['field' => 'order_date', 'error' => 'format must be DD/MM/YYYY'];
154        }
155
156        if ($type === 'default') {
157            $key = array_search('order_num', array_column($fields->root, 'fieldName'));
158            if ($key === false) {
159                $errors[] = ['field' => 'order_num', 'error' => 'required for default type'];
160            }
161
162            if (!is_numeric($fields->root[$key]->fieldValue) || strlen($fields->root[$key]->fieldValue) !== 9) {
163                $errors[] = ['field' => 'order_num', 'error' => 'format must be 9 numeric characters'];
164            }
165
166            $key = array_search('state_order_cb', array_column($fields->root, 'fieldName'));
167            if ($key === false) {
168                $errors[] = ['field' => 'state_order_cb', 'error' => 'required for default type'];
169            }
170
171            if ($fields->root[$key]->fieldValue !== 1 && $fields->root[$key]->fieldValue !== 'Null') {
172                $errors[] = ['field' => 'state_order_cb', 'error' => 'value must be 1 or Null (Yes Null not NULL)'];
173            }
174
175            $orderCB = $fields->root[$key]->fieldValue;
176
177            $key = array_search('state_order_check', array_column($fields->root, 'fieldName'));
178            if ($key === false) {
179                $errors[] = ['field' => 'state_order_check', 'error' => 'required for default type'];
180            }
181
182            if ($fields->root[$key]->fieldValue !== 1 && $fields->root[$key]->fieldValue !== 'Null') {
183                $errors[] = ['field' => 'state_order_check', 'error' => 'value must be 1 or Null (Yes Null not NULL)'];
184            }
185
186            $orderCheck = $fields->root[$key]->fieldValue;
187
188            if ($orderCB === $orderCheck) {
189                $errors[] = [
190                    'field' => 'state_order',
191                    'error' => 'state_order_cb and state_order_check values must be different'
192                ];
193            }
194
195            $key = array_search('package_unit_weight', array_column($fields->orderLine, 'fieldName'));
196            if ($key === false) {
197                $errors[] = ['field' => 'package_unit_weight', 'error' => 'required for default type'];
198            }
199        } elseif ($type === 'game') {
200            $key = array_search('code_unique', array_column($fields->orderLine, 'fieldName'));
201            if ($key === false) {
202                $errors[] = ['field' => 'code_unique', 'error' => 'required for game type'];
203            }
204        }//end if
205
206        if (!empty($errors)) {
207            return ['status' => 'KO', 'code' => 203, 'message' => $errors];
208        }
209
210        return ['status' => 'OK'];
211    }
212
213    /**
214     * @param mixed $fields
215     * @param mixed $type
216     * @param mixed $customer
217     * @param mixed $customerInfos
218     * @param mixed $shipping
219     * @return string|false
220     */
221    // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh, Squiz.Commenting.FunctionComment.Missing
222    private function makeXml($fields, $type, $customer, $customerInfos, $shipping)
223    {
224        $pivot = [
225            'order_num' => 'Num_Commande',
226            // Required if type = default - format 9 numeric characters.
227            'order_date' => 'Date_Commande',
228            // Required - format : DD/MM/YYYY .
229            'operation' => 'Operation',
230            // Required.
231            'support_code' => 'Code_Support',
232            // Required.
233            'label_type_support' => 'Libelle_Type_Support',
234            // Required.
235            'package_unit_weight' => 'Poids_Unitaire_Colis',
236            // Required if type = default.
237            'qty' => 'Quantite',
238            'code_on_pack' => 'Code_on_Pack',
239            'code_unique' => 'Code_Unique',
240            // Required if type = game.
241            // Required if type = default - format 1 ou Null (oui Null et pas NULL).
242            'state_order_cb' => 'Etat_Commande_CB',
243            // Required if type = default - format 1 ou Null (oui Null et pas NULL).
244            'state_order_check' => 'Etat_Commande_Cheque',
245
246        ];
247
248        $dom               = new DOMDocument('1.0', 'UTF-8');
249        $dom->formatOutput = true;
250
251        $root = $dom->createElement('export_arcadia');
252        $dom->appendChild($root);
253        $order = $root->appendChild($dom->createElement('Commande'));
254
255        $key = array_search('order_num', array_column($fields->root, 'fieldName'));
256        if ($key === false) {
257            $order->appendChild($dom->createElement('Num_Commande'));
258        } else {
259            $order->appendChild($dom->createElement('Num_Commande', $fields->root[$key]->fieldValue));
260        }
261
262        foreach ($fields->root as $value) {
263            // phpcs:ignore PSR2.ControlStructures.ControlStructureSpacing.SpacingAfterOpenBrace
264            if (
265                isset($pivot[$value->fieldName]) && $value->fieldName !== 'state_order_cb' &&
266                $value->fieldName !== 'state_order_check' && $value->fieldName !== 'order_num'
267            ) {
268                $order->appendChild($dom->createElement($pivot[$value->fieldName], $value->fieldValue));
269            }
270        }
271
272        if ($type === 'default') {
273            $key = array_search('state_order_cb', array_column($fields->root, 'fieldName'));
274            if ($key) {
275                $order->appendChild($dom->createElement('Etat_Commande_CB', $fields->root[$key]->fieldValue));
276            }
277
278            $key = array_search('state_order_check', array_column($fields->root, 'fieldName'));
279            if ($key) {
280                $order->appendChild($dom->createElement('Etat_Commande_Cheque', $fields->root[$key]->fieldValue));
281            }
282        }
283
284        $order->appendChild($dom->createElement('Email_conso'))
285        ->appendChild($dom->createCDATASection("$customer->email"));
286        $order->appendChild($dom->createElement('Civilite'));
287
288        if ($type === 'default') {
289            $order->appendChild($dom->createElement('Nom'))
290                ->appendChild($dom->createCDATASection("$shipping->lastname"));
291            $order->appendChild($dom->createElement('Prenom'))
292                ->appendChild($dom->createCDATASection("$shipping->firstname"));
293            $order->appendChild($dom->createElement('Adresse'))
294                ->appendChild($dom->createCDATASection("$shipping->address"));
295            $order->appendChild($dom->createElement('Adresse_Complementaire'));
296            $order->appendChild($dom->createElement('CP'))
297            ->appendChild($dom->createCDATASection("$shipping->postcode"));
298            $order->appendChild($dom->createElement('Ville'))->appendChild($dom->createCDATASection("$shipping->city"));
299            if (isset($shipping->phone) && !empty($shipping->phone)) {
300                $order->appendChild($dom->createElement('Telephone'))
301                    ->appendChild($dom->createCDATASection("$shipping->phone"));
302            } else {
303                $order->appendChild($dom->createElement('Telephone'));
304            }
305        } else {
306            $order->appendChild($dom->createElement('Nom'))
307                ->appendChild($dom->createCDATASection("$customerInfos->lastname"));
308            $order->appendChild($dom->createElement('Prenom'))
309                ->appendChild($dom->createCDATASection("$customerInfos->firstname"));
310            $order->appendChild($dom->createElement('Adresse'))
311                ->appendChild($dom->createCDATASection("$customerInfos->address"));
312            $order->appendChild($dom->createElement('Adresse_Complementaire'))
313                ->appendChild($dom->createCDATASection("$customerInfos->address2"));
314            $order->appendChild($dom->createElement('CP'))
315                ->appendChild($dom->createCDATASection("$customerInfos->postcode"));
316            $order->appendChild($dom->createElement('Ville'))
317                ->appendChild($dom->createCDATASection("$customerInfos->city"));
318            $order->appendChild($dom->createElement('Telephone'))
319                ->appendChild($dom->createCDATASection("$customerInfos->phone"));
320        }//end if
321
322        $orderLine = $order->appendChild($dom->createElement('Ligne_de_Commande'));
323
324        $key = array_search('qty', array_column($fields->orderLine, 'fieldName'));
325        if ($key === false) {
326            $orderLine->appendChild($dom->createElement('Quantite', '1'));
327        }
328
329        $key = array_search('package_unit_weight', array_column($fields->orderLine, 'fieldName'));
330        if ($key === false) {
331            $orderLine->appendChild($dom->createElement('Poids_Unitaire_Colis'));
332        }
333
334        foreach ($fields->orderLine as $value) {
335            // phpcs:ignore PSR2.ControlStructures.ControlStructureSpacing.SpacingAfterOpenBrace
336            if (
337                isset($pivot[$value->fieldName]) &&
338                $value->fieldName !== 'code_on_pack' &&
339                $value->fieldName !== 'code_unique'
340            ) {
341                $orderLine->appendChild($dom->createElement($pivot[$value->fieldName], $value->fieldValue));
342            }
343        }
344
345        if ($type === 'game') {
346            $key = array_search('code_on_pack', array_column($fields->orderLine, 'fieldName'));
347            if ($key) {
348                $orderLine->appendChild(
349                    $dom->createElement('Code_on_Pack')
350                )->appendChild($dom->createCDATASection($fields->orderLine[$key]->fieldValue));
351            }
352
353            $key = array_search('code_unique', array_column($fields->orderLine, 'fieldName'));
354            if ($key) {
355                $orderLine->appendChild(
356                    $dom->createElement('Code_Unique')
357                )->appendChild($dom->createCDATASection($fields->orderLine[$key]->fieldValue));
358            }
359        }
360
361        return $dom->saveXML();
362    }
363}