Passed
Pull Request — master (#16)
by Carlos C
02:51
created

QuickFinkok::customerSignAndSendContracts()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 11
c 1
b 0
f 0
nc 2
nop 5
dl 0
loc 20
ccs 12
cts 12
cp 1
crap 3
rs 9.9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpCfdi\Finkok;
6
7
use DateTimeImmutable;
8
use PhpCfdi\Credentials\Credential;
9
use PhpCfdi\Finkok\Definitions\CancelAnswer;
10
use PhpCfdi\Finkok\Definitions\ReceiptType;
11
use PhpCfdi\Finkok\Definitions\RfcRole;
12
use PhpCfdi\Finkok\Definitions\SignedDocumentFormat;
13
use PhpCfdi\Finkok\Services\Cancel;
14
use PhpCfdi\Finkok\Services\Manifest;
15
use PhpCfdi\Finkok\Services\Registration;
16
use PhpCfdi\Finkok\Services\Retentions;
17
use PhpCfdi\Finkok\Services\Stamping;
18
use PhpCfdi\Finkok\Services\Utilities;
19
20
class QuickFinkok
21
{
22
    /** @var FinkokSettings */
23
    private $settings;
24
25 26
    public function __construct(FinkokSettings $factory)
26
    {
27 26
        $this->settings = $factory;
28 26
    }
29
30
    /**
31
     * Obtiene la configuración de conexión con la que será consumida la API de Finkok
32
     *
33
     * @return FinkokSettings
34
     */
35 26
    public function settings(): FinkokSettings
36
    {
37 26
        return $this->settings;
38
    }
39
40
    /**
41
     * Este método se encarga de realizar el timbrado de XML
42
     *
43
     * @param string $preCfdi
44
     * @return Stamping\StampingResult
45
     * @see https://wiki.finkok.com/doku.php?id=stamp
46
     */
47 1
    public function stamp(string $preCfdi): Stamping\StampingResult
48
    {
49 1
        $command = new Stamping\StampingCommand($preCfdi);
50 1
        $service = new Stamping\StampService($this->settings());
51 1
        return $service->stamp($command);
52
    }
53
54
    /**
55
     * Este método se encarga de realizar el timbrado de XML, una vez que se timbra el XML se guarda en una cola de
56
     * espera para ser enviado en el mejor momento a los servicios del SAT, por lo que el servicio de timbrado es
57
     * mucho mas rápido, y es de uso recomendado en timbrado de alto numero de timbres por segundo.
58
     *
59
     * Nota: El CFDI generado puede no estar disponible en los servidores del SAT hasta varios minutos después
60
     *
61
     * @param string $preCfdi
62
     * @return Stamping\StampingResult
63
     * @see https://wiki.finkok.com/doku.php?id=metodo_quick_stamp
64
     */
65 1
    public function quickStamp(string $preCfdi): Stamping\StampingResult
66
    {
67 1
        $command = new Stamping\StampingCommand($preCfdi);
68 1
        $service = new Stamping\QuickStampService($this->settings());
69 1
        return $service->quickstamp($command);
70
    }
71
72
    /**
73
     * Este método regresa la información de un XML ya timbrado previamente y que por algún motivo no se pudo recuperar
74
     * en la primera petición que se realizó, con este método se puede recuperar el UUID y el XML timbrado
75
     *
76
     * @param string $preCfdi
77
     * @return Stamping\StampingResult
78
     * @see https://wiki.finkok.com/doku.php?id=stamped
79
     */
80 1
    public function stamped(string $preCfdi): Stamping\StampingResult
81
    {
82 1
        $command = new Stamping\StampingCommand($preCfdi);
83 1
        $service = new Stamping\StampedService($this->settings());
84 1
        return $service->stamped($command);
85
    }
86
87
    /**
88
     * Obtiene el XML de un UUID timbrado en Finkok de tipo CFDI 3.3
89
     * solo es posible recuperar los timbrados en los últimos 3 meses.
90
     *
91
     * @param string $uuid
92
     * @param string $rfc
93
     * @return Utilities\DownloadXmlResult
94
     * @see https://wiki.finkok.com/doku.php?id=get_xml
95
     */
96 1
    public function cfdiDownload(string $uuid, string $rfc): Utilities\DownloadXmlResult
97
    {
98 1
        $command = new Utilities\DownloadXmlCommand($uuid, $rfc, 'I');
99 1
        $service = new Utilities\DownloadXmlService($this->settings());
100 1
        return $service->downloadXml($command);
101
    }
102
103
    /**
104
     * Este método se usa para consultar el estatus de una factura que se quedo pendiente de enviar al SAT debido a una
105
     * falla en el sistema del SAT o bien que se envió a través del método Quick_Stamp
106
     *
107
     * @param string $uuid
108
     * @return Stamping\QueryPendingResult
109
     * @see https://wiki.finkok.com/doku.php?id=query_pending
110
     */
111 1
    public function stampQueryPending(string $uuid): Stamping\QueryPendingResult
112
    {
113 1
        $command = new Stamping\QueryPendingCommand($uuid);
114 1
        $service = new Stamping\QueryPendingService($this->settings());
115 1
        return $service->queryPending($command);
116
    }
117
118
    /**
119
     * Este método es el encargado de cancelar uno o varios CFDIs emitidos por medio de los web services de Finkok
120
     * Durante el proceso no se envía ningún CSD a Finkok y la solicitud firmada es creada usando los datos del CSD
121
     *
122
     * @param Credential $credential
123
     * @param string $uuid
124
     * @return Cancel\CancelSignatureResult
125
     * @see https://wiki.finkok.com/doku.php?id=cancelsigned_method
126
     * @see https://wiki.finkok.com/doku.php?id=cancel_method
127
     */
128 1
    public function cancel(Credential $credential, string $uuid): Cancel\CancelSignatureResult
129
    {
130 1
        $signer = new Helpers\CancelSigner([$uuid]);
131 1
        $signedRequest = $signer->sign($credential);
132 1
        $command = new Cancel\CancelSignatureCommand($signedRequest);
133 1
        $service = new Cancel\CancelSignatureService($this->settings());
134 1
        return $service->cancelSignature($command);
135
    }
136
137
    /**
138
     * Consulta el estatus del CFDI emitido con Finkok y la forma posible de cancelación a partir de todos sus datos.
139
     * También se puede consultar en modo producción utilizando la librería `phpcfdi/sat-estado-cfdi`
140
     *
141
     * @param string $rfcIssuer
142
     * @param string $rfcRecipient
143
     * @param string $uuid
144
     * @param string $total
145
     * @return Cancel\GetSatStatusResult
146
     * @see https://wiki.finkok.com/doku.php?id=get_sat_status
147
     * @see https://github.com/phpcfdi/sat-estado-cfdi
148
     */
149 1
    public function satStatus(
150
        string $rfcIssuer,
151
        string $rfcRecipient,
152
        string $uuid,
153
        string $total
154
    ): Cancel\GetSatStatusResult {
155 1
        $command = new Cancel\GetSatStatusCommand($rfcIssuer, $rfcRecipient, $uuid, $total);
156 1
        $service = new Cancel\GetSatStatusService($this->settings());
157 1
        return $service->query($command);
158
    }
159
160
    /**
161
     * Consulta el estatus del CFDI emitido por Finkok y la forma posible de cancelación a partir del XML de un CFDI
162
     *
163
     * @param string $xmlCfdi
164
     * @return Cancel\GetSatStatusResult
165
     * @see https://wiki.finkok.com/doku.php?id=get_sat_status
166
     */
167 1
    public function satStatusXml(string $xmlCfdi): Cancel\GetSatStatusResult
168
    {
169 1
        $extractor = Helpers\GetSatStatusExtractor::fromXmlString($xmlCfdi);
170 1
        $command = $extractor->buildCommand();
171 1
        $service = new Cancel\GetSatStatusService($this->settings());
172 1
        return $service->query($command);
173
    }
174
175
    /**
176
     * Obtiene una lista de los UUIDs relacionados de un UUID
177
     *
178
     * @param Credential $credential
179
     * @param string $uuid
180
     * @param RfcRole|null $role si es NULL entonces se usa el rol de emisor
181
     * @return Cancel\GetRelatedSignatureResult
182
     * @see https://wiki.finkok.com/doku.php?id=get_related_signature
183
     * @see https://wiki.finkok.com/doku.php?id=get_related
184
     */
185 1
    public function obtainRelated(
186
        Credential $credential,
187
        string $uuid,
188
        RfcRole $role = null
189
    ): Cancel\GetRelatedSignatureResult {
190 1
        $signer = new Helpers\GetRelatedSigner($uuid, $role);
191 1
        $signedRequest = $signer->sign($credential);
192 1
        $command = new Cancel\GetRelatedSignatureCommand($signedRequest);
193 1
        $service = new Cancel\GetRelatedSignatureService($this->settings());
194 1
        return $service->getRelatedSignature($command);
195
    }
196
197
    /**
198
     * Consulta las solicitudes de cancelación tiene pendientes un receptor
199
     * Durante el proceso no se envía ningún CSD a Finkok y la solicitud firmada es creada usando los datos del CSD
200
     *
201
     * @param string $rfc
202
     * @return Cancel\GetPendingResult
203
     * @see https://wiki.finkok.com/doku.php?id=get_pending
204
     */
205 1
    public function obtainPendingToCancel(string $rfc): Cancel\GetPendingResult
206
    {
207 1
        $command = new Cancel\GetPendingCommand($rfc);
208 1
        $service = new Cancel\GetPendingService($this->settings());
209 1
        return $service->obtainPending($command);
210
    }
211
212
    /**
213
     * Permite al receptor de una factura Aceptar o Rechazar una determinada cancelación que tenga pendiente
214
     * Durante el proceso no se envía ningún CSD a Finkok y la solicitud firmada es creada usando los datos del CSD
215
     *
216
     * @param Credential $credential
217
     * @param string $uuid
218
     * @param CancelAnswer $answer
219
     * @return Cancel\AcceptRejectSignatureResult
220
     * @see https://wiki.finkok.com/doku.php?id=accept_reject_signature
221
     * @see https://wiki.finkok.com/doku.php?id=accept_reject
222
     */
223 1
    public function answerAcceptRejectCancellation(
224
        Credential $credential,
225
        string $uuid,
226
        CancelAnswer $answer
227
    ): Cancel\AcceptRejectSignatureResult {
228 1
        $signer = new Helpers\AcceptRejectSigner($uuid, $answer);
229 1
        $signedRequest = $signer->sign($credential);
230 1
        $command = new Cancel\AcceptRejectSignatureCommand($signedRequest);
231 1
        $service = new Cancel\AcceptRejectSignatureService($this->settings());
232 1
        return $service->acceptRejectSignature($command);
233
    }
234
235
    /**
236
     * Obtiene el acuse de recepción de la solicitud de cancelación
237
     *
238
     * @param string $rfcIssuer
239
     * @param string $uuid
240
     * @return Cancel\GetReceiptResult
241
     * @see https://wiki.finkok.com/doku.php?id=get_receipt
242
     */
243 1
    public function obtainCancelRequestReceipt(string $rfcIssuer, string $uuid): Cancel\GetReceiptResult
244
    {
245 1
        $command = new Cancel\GetReceiptCommand($rfcIssuer, $uuid, ReceiptType::cancellation());
246 1
        $service = new Cancel\GetReceiptService($this->settings());
247 1
        return $service->download($command);
248
    }
249
250
    /**
251
     * Obtener la fecha exacta de los servidores de timbrado para realizar el XML del CFDI
252
     *
253
     * @param string $postalCode Si está vacío se utiliza el horario de America/Mexico_City
254
     * @return Utilities\DatetimeResult
255
     * @see https://wiki.finkok.com/doku.php?id=datetime
256
     */
257 1
    public function serversDateTime(string $postalCode = ''): Utilities\DatetimeResult
258
    {
259 1
        $command = new Utilities\DatetimeCommand($postalCode);
260 1
        $service = new Utilities\DatetimeService($this->settings());
261 1
        return $service->datetime($command);
262
    }
263
264
    /**
265
     * Reporte de los UUID timbrados con fecha, de un RFC entre un periodo de tiempo determinado
266
     *
267
     * @param string $rfc
268
     * @param DateTimeImmutable $since
269
     * @param DateTimeImmutable $until
270
     * @return Utilities\ReportUuidResult
271
     * @see https://wiki.finkok.com/doku.php?id=report_uuid
272
     */
273 1
    public function reportUuids(
274
        string $rfc,
275
        DateTimeImmutable $since,
276
        DateTimeImmutable $until
277
    ): Utilities\ReportUuidResult {
278 1
        $command = new Utilities\ReportUuidCommand($rfc, 'I', $since, $until);
279 1
        $service = new Utilities\ReportUuidService($this->settings());
280 1
        return $service->reportUuid($command);
281
    }
282
283
    /**
284
     * Reporte de los créditos añadidos de un RFC
285
     *
286
     * @param string $rfc
287
     * @return Utilities\ReportCreditResult
288
     * @see https://wiki.finkok.com/doku.php?id=report_uuid
289
     */
290 1
    public function reportCredits(string $rfc): Utilities\ReportCreditResult
291
    {
292 1
        $command = new Utilities\ReportCreditCommand($rfc);
293 1
        $service = new Utilities\ReportCreditService($this->settings());
294 1
        return $service->reportCredit($command);
295
    }
296
297
    /**
298
     * Reporte de los créditos añadidos de un RFC
299
     *
300
     * @param string $rfc
301
     * @param int $startYear
302
     * @param int $startMonth
303
     * @param int $endYear
304
     * @param int $endMonth
305
     * @return Utilities\ReportTotalResult
306
     * @see https://wiki.finkok.com/doku.php?id=report_uuid
307
     */
308 1
    public function reportTotals(
309
        string $rfc,
310
        int $startYear,
311
        int $startMonth,
312
        int $endYear = 0,
313
        int $endMonth = 0
314
    ): Utilities\ReportTotalResult {
315 1
        $command = new Utilities\ReportTotalCommand($rfc, 'I', $startYear, $startMonth, $endYear, $endMonth);
316 1
        $service = new Utilities\ReportTotalService($this->settings());
317 1
        return $service->reportTotal($command);
318
    }
319
320
    /**
321
     * Agrega un cliente que va a timbrar bajo la cuenta de un socio de negocios de Finkok
322
     *
323
     * @param string $rfc
324
     * @param Registration\CustomerType|null $type Si es NULL entonces se utiliza OnDemand
325
     * @return Registration\AddResult
326
     * @see https://wiki.finkok.com/doku.php?id=add
327
     */
328 1
    public function customersAdd(string $rfc, ?Registration\CustomerType $type = null): Registration\AddResult
329
    {
330 1
        $command = new Registration\AddCommand($rfc, $type);
331 1
        $service = new Registration\AddService($this->settings());
332 1
        return $service->add($command);
333
    }
334
335
    /**
336
     * Edita el estatus de un cliente (suspender o activar)
337
     *
338
     * @param string $rfc
339
     * @param Registration\CustomerStatus $status
340
     * @return Registration\EditResult
341
     * @see https://wiki.finkok.com/doku.php?id=edit
342
     */
343 1
    public function customersEdit(string $rfc, Registration\CustomerStatus $status): Registration\EditResult
344
    {
345 1
        $command = new Registration\EditCommand($rfc, $status);
346 1
        $service = new Registration\EditService($this->settings());
347 1
        return $service->edit($command);
348
    }
349
350
    /**
351
     * Edita el tipo de un cliente (prepago/Prepaid o ilimitado/Ondemand)
352
     *
353
     * @param string $rfc
354
     * @param Registration\CustomerType $type
355
     * @return Registration\SwitchResult
356
     * @see https://wiki.finkok.com/doku.php?id=switch
357
     */
358 1
    public function customersSwitch(string $rfc, Registration\CustomerType $type): Registration\SwitchResult
359
    {
360 1
        $command = new Registration\SwitchCommand($rfc, $type);
361 1
        $service = new Registration\SwitchService($this->settings());
362 1
        return $service->switch($command);
363
    }
364
365
    /**
366
     * Obtiene un listado de clientes registrados, o solo uno si se especifica el RFC
367
     *
368
     * @param string $filterByRfc
369
     * @return Registration\ObtainResult
370
     * @see https://wiki.finkok.com/doku.php?id=get
371
     */
372 1
    public function customersObtain(string $filterByRfc = ''): Registration\ObtainResult
373
    {
374 1
        $command = new Registration\ObtainCommand($filterByRfc);
375 1
        $service = new Registration\ObtainService($this->settings());
376 1
        return $service->obtain($command);
377
    }
378
379
    /**
380
     * Asignar créditos un cliente que va a timbrar
381
     * Si el crédito es un valor positivo y el cliente está como OnDemand se cambiará a PrePaid con los créditos
382
     * Si el crédito es un valor positivo y el cliente está como PrePaid sumarán los créditos a los actuales
383
     * Si el crédito es -1 el cliente se pondrá como OnDemand
384
     *
385
     * @param string $rfc
386
     * @param int $credits
387
     * @return Registration\AssignResult
388
     * @see https://wiki.finkok.com/doku.php?id=assign
389
     */
390 1
    public function customersAssign(string $rfc, int $credits): Registration\AssignResult
391
    {
392 1
        $command = new Registration\AssignCommand($rfc, $credits);
393 1
        $service = new Registration\AssignService($this->settings());
394 1
        return $service->assign($command);
395
    }
396
397
    /**
398
     * Obtiene los textos del manifiesto de FINKOK (Aviso de Privacidad y Contrato de Servicio)
399
     *
400
     * @param string $rfc
401
     * @param string $name
402
     * @param string $address
403
     * @param string $email
404
     * @return Manifest\GetContractsResult
405
     * @see https://wiki.finkok.com/doku.php?id=get_contracts
406
     */
407 1
    public function customerGetContracts(
408
        string $rfc,
409
        string $name,
410
        string $address,
411
        string $email
412
    ): Manifest\GetContractsResult {
413 1
        $command = new Manifest\GetContractsCommand($rfc, $name, $address, $email);
414 1
        $service = new Manifest\GetContractsService($this->settings());
415 1
        return $service->obtainContracts($command);
416
    }
417
418
    /**
419
     * Envía el aviso de privacidad y contratos firmados
420
     *
421
     * @param string $snid
422
     * @param string $signedPrivacy
423
     * @param string $signedContract
424
     * @return Manifest\SignContractsResult
425
     * @see https://wiki.finkok.com/doku.php?id=firmar
426
     */
427 1
    public function customerSendContracts(
428
        string $snid,
429
        string $signedPrivacy,
430
        string $signedContract
431
    ): Manifest\SignContractsResult {
432 1
        $command = new Manifest\SignContractsCommand($snid, $signedPrivacy, $signedContract);
433 1
        $service = new Manifest\SignContractsService($this->settings());
434 1
        return $service->sendSignedContracts($command);
435
    }
436
437
    /**
438
     * Obtiene los documentos legales (aviso de privacidad y contrato), los firma con la FIEL y envía
439
     *
440
     * @param Credential $fiel
441
     * @param string $snid
442
     * @param string $address
443
     * @param string $email
444
     * @param DateTimeImmutable|null $signedOn Si es NULL se utiliza la fecha y hora del sistema
445
     * @return Manifest\SignContractsResult
446
     */
447 2
    public function customerSignAndSendContracts(
448
        Credential $fiel,
449
        string $snid,
450
        string $address,
451
        string $email,
452
        ?DateTimeImmutable $signedOn = null
453
    ): Manifest\SignContractsResult {
454 2
        $rfc = $fiel->rfc();
455 2
        $name = $fiel->legalName();
456 2
        $signedOn = $signedOn ?? new DateTimeImmutable();
457 2
        $documents = $this->customerGetContracts($rfc, $name, $address, $email);
458 2
        if (! $documents->success()) {
459 1
            return Manifest\SignContractsResult::createFromData(
460 1
                false,
461 1
                sprintf('Unable to get contracts: %s', $documents->error() ?: '(no error)')
462
            );
463
        }
464 1
        $privacy = (new Helpers\DocumentSigner($rfc, $signedOn, $documents->privacy()))->signUsingCredential($fiel);
465 1
        $contract = (new Helpers\DocumentSigner($rfc, $signedOn, $documents->contract()))->signUsingCredential($fiel);
466 1
        return $this->customerSendContracts($snid, $privacy, $contract);
467
    }
468
469
    /**
470
     * Obtiene los documentos legales (aviso de privacidad y contrato) previamente firmados con el SNID y RFC
471
     *
472
     * @param string $snid
473
     * @param string $rfc
474
     * @param SignedDocumentFormat|null $format
475
     * @return Manifest\GetSignedContractsResult
476
     */
477
    public function customerGetSignedContracts(
478
        string $snid,
479
        string $rfc,
480
        SignedDocumentFormat $format = null
481
    ): Manifest\GetSignedContractsResult {
482
        $format = $format ?? SignedDocumentFormat::xml();
483
        $command = new Manifest\GetSignedContractsCommand($snid, $rfc, $format);
484
        $service = new Manifest\GetSignedContractsService($this->settings());
485
        return $service->getSignedContracts($command);
486
    }
487
488 1
    public function retentionStamp(string $xml): Retentions\StampResult
489
    {
490 1
        $command = new Retentions\StampCommand($xml);
491 1
        $service = new Retentions\StampService($this->settings());
492 1
        return $service->stamp($command);
493
    }
494
495
    /**
496
     * Obtiene el XML de un UUID timbrado en Finkok de tipo CFDI de retenciones e información de pagos
497
     * solo es posible recuperar los timbrados en los últimos 3 meses.
498
     *
499
     * @param string $uuid
500
     * @param string $rfc
501
     * @return Utilities\DownloadXmlResult
502
     * @see https://wiki.finkok.com/doku.php?id=get_xml
503
     */
504 1
    public function retentionDownload(string $uuid, string $rfc): Utilities\DownloadXmlResult
505
    {
506 1
        $command = new Utilities\DownloadXmlCommand($uuid, $rfc, 'R');
507 1
        $service = new Utilities\DownloadXmlService($this->settings());
508 1
        return $service->downloadXml($command);
509
    }
510
511
    /**
512
     * Este método regresa la información de un XML de retenciones e información de pagos ya timbrado previamente y
513
     * que por algún motivo no se pudo recuperar en la primera petición que se realizó,
514
     * con este método se puede recuperar el UUID y el XML timbrado
515
     *
516
     * Nota: el método no está documentado en Finkok
517
     *
518
     * @param string $preCfdi
519
     * @return Retentions\StampedResult
520
     * @see https://wiki.finkok.com/doku.php?id=retentions
521
     */
522 1
    public function retentionStamped(string $preCfdi): Retentions\StampedResult
523
    {
524 1
        $command = new Retentions\StampedCommand($preCfdi);
525 1
        $service = new Retentions\StampedService($this->settings());
526 1
        return $service->stamped($command);
527
    }
528
529
    /**
530
     * Este método es el encargado de cancelar un CFDIs de retenciones emitido por medio de los web services de Finkok
531
     * Durante el proceso no se envía ningún CSD a Finkok y la solicitud firmada es creada usando los datos del CSD
532
     *
533
     * @param Credential $credential
534
     * @param string $uuid
535
     * @return Retentions\CancelSignatureResult
536
     * @see https://wiki.finkok.com/doku.php?id=cancel_signature_method_retentions
537
     * @see https://wiki.finkok.com/doku.php?id=cancel_method_retentions
538
     */
539
    public function retentionCancel(Credential $credential, string $uuid): Retentions\CancelSignatureResult
540
    {
541
        $signer = new Helpers\CancelSigner([$uuid]);
542
        $signedRequest = $signer->signRetention($credential);
543
        $command = new Retentions\CancelSignatureCommand($signedRequest);
544
        $service = new Retentions\CancelSignatureService($this->settings());
545
        return $service->cancelSignature($command);
546
    }
547
}
548