File Coverage

blib/lib/Business/Shipping/MRW.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Business::Shipping::MRW;
2              
3             =doc
4             MRW : Modulo SAGEC
5             =cut
6              
7 1     1   14687 use 5.006;
  1         2  
  1         45  
8 1     1   4 use strict;
  1         1  
  1         28  
9 1     1   4 use warnings;
  1         4  
  1         30  
10              
11 1     1   580 use Data::Dumper;
  1         7310  
  1         70  
12 1     1   211 use Mojo::UserAgent;
  0            
  0            
13             use Time::HiRes 'gettimeofday';
14             use POSIX 'strftime';
15             use JSON::XS;
16             use MIME::Base64;
17             use XML::Simple;
18              
19             use feature 'say';
20              
21             =head1 VERSION
22              
23             Version 0.02
24              
25             =cut
26            
27             our $VERSION = '0.02';
28              
29             =head1 SYNOPSIS
30              
31             use Business::Shipping::MRW;
32              
33             my $MRW = Business::Shipping::MRW->new();
34              
35             my $Info = $E->TransmEnvio('envio.json');
36              
37             my $PDF = $E->EtiquetaEnvio($Info->{NumeroEnvio});
38              
39              
40             =head1 EXPORT
41              
42             A list of functions that can be exported. You can delete this section
43             if you don't export anything, such as for a purely object-oriented module.
44              
45             =head1 SUBROUTINES/METHODS
46              
47             =head2 new
48            
49             =cut
50             sub new {
51             my $class = shift;
52             my $file = shift;
53             my $self;
54              
55             my $config = OpenJSON($file);
56            
57             map { $self->{mrw}->{$_} = $config->{$_} } keys %{ $config };
58              
59             $self->{errors} = [];
60            
61             $self = bless $self, $class;
62              
63             return $self;
64             }
65              
66             =head2
67              
68             =cut
69             sub Error {
70             my $self = shift;
71             my $msg = shift;
72            
73             push @{$self->{errors}} , $msg;
74             }
75              
76             sub Errors {
77             my $self = shift;
78              
79             print Dumper $self->{errors};
80             }
81            
82             =head2
83             Open JSON File
84             =cut
85             sub OpenJSON {
86             my $file = shift;
87            
88             local $/;
89             open( my $fh, '<', $file );
90            
91             my $json_text = <$fh>;
92             my $perl_scalar = decode_json( $json_text );
93              
94             return $perl_scalar;
95             }
96              
97             =head2
98             Formato: FFFFFAAAAAAYYYYMMDDhhmmssnnn (length:28)
99             =cut
100             sub NumeroSolicitud {
101             my $self = shift;
102              
103             my ($t, $nsec) = gettimeofday;
104             $nsec = substr($nsec,3);
105              
106             my @t = localtime $t;
107             my $fecha = strftime "%Y%m%d%H%M%S", localtime $t;
108            
109             my $str = qq{$self->{mrw}->{CodigoFranquicia}$self->{mrw}->{CodigoAbonado}$fecha$nsec};
110              
111             return $str;
112             }
113              
114             =head2
115             Codigos de servicio
116             =cut
117             sub CodigoServicio {
118             my $self = shift;
119             my $tipo = shift;
120             my $ret;
121            
122             my $codes = {
123             '0005' => 'Urgente hoy',
124             '0010' => 'Promociones',
125             '0100' => 'Urgente 12',
126             '0110' => 'Urgente 14',
127             '0120' => 'Urgente 22',
128             '0200' => 'Urgente 19',
129             '0205' => 'Urgente 19 Expedicion',
130             '0210' => 'Urgente 19 Mas 40 Kilos',
131             '0220' => '48 Horas Portugal',
132             '0230' => 'Bag 19',
133             '0235' => 'Bag 14',
134             '0300' => 'Economico',
135             '0310' => 'Economico Mas 40 Kilos',
136             '0350' => 'Economico Interinsular',
137             '0400' => 'Express Documentos',
138             '0450' => 'Express 2 Kilos',
139             '0480' => 'Caja Express 3 Kilos',
140             '0490' => 'Documentos 14',
141             '0800' => 'Ecommerce',
142             '0810' => 'Ecommerce Canje',
143             };
144              
145             map { $ret = $_ if $codes->{$_} eq $tipo } keys %{$codes};
146            
147             unless ( $ret ) {
148             $self->Error("CodigoServicio no valido : $tipo , fijado 0200");
149             return '0200';
150             }
151            
152             return $ret;
153             }
154              
155             =head2
156             AuthInfo Header
157             =cut
158             sub AuthInfo {
159             my $self = shift;
160             my $str;
161              
162             $str = '
163            
164             '.$self->{mrw}->{CodigoFranquicia}.'
165             '.$self->{mrw}->{CodigoAbonado}.'
166            
167             '.$self->{mrw}->{UserName}.'
168             '.$self->{mrw}->{Password}.'
169            
170             ';
171            
172             return $str;
173             }
174              
175             =head2
176             Metodo que se usa para la Transmision del envio
177              
178             Hasta implementar WSDL real no esta chapuza usar GenMethods para regenerar struct
179              
180             Opcional: 'DatosRecogida'
181             =cut
182             sub TransmEnvio {
183             my $self = shift;
184             my $Envio = shift;
185              
186             $Envio = OpenJSON($Envio);
187            
188             my $Fecha = strftime "%d/%m/%Y", localtime;
189              
190             ## TransmEnvioRequest
191             my $Req = {
192             'DatosEntrega' => {
193             'Telefono' => $Envio->{DatosEntrega}->{Telefono},
194             'Nif' => $Envio->{DatosEntrega}->{Nif},
195             'Nombre' => $Envio->{DatosEntrega}->{Nombre},
196             'Observaciones' => $Envio->{DatosEntrega}->{Observaciones},
197             'Contacto' => $Envio->{DatosEntrega}->{Contacto},
198             'ALaAtencionDe' => $Envio->{DatosEntrega}->{ALaAtencionDe},
199             'Direccion' => {
200             CodigoTipoVia => '',
201             Via => $Envio->{DatosEntrega}->{Direccion}->{Via},
202             Numero => $Envio->{DatosEntrega}->{Direccion}->{Numero},
203             Resto => '',
204             CodigoPostal => $Envio->{DatosEntrega}->{Direccion}->{CodigoPostal},
205             Poblacion => $Envio->{DatosEntrega}->{Direccion}->{Poblacion},
206             },
207             },
208             'DatosServicio' => {
209             'SeguroOpcional' => '',
210             'Notificaciones' => {
211             CanalNotificacion => $Envio->{DatosServicio}->{Notificaciones}->{CanalNotificacion},
212             TipoNotificacion => $Envio->{DatosServicio}->{Notificaciones}->{TipoNotificacion},
213             MailSMS => $Envio->{DatosServicio}->{Notificaciones}->{MailSMS},
214             },
215             'Frecuencia' => '',
216             'Entrega830' => 'N',
217             'ConfirmacionInmediata' => '',
218             'DescripcionServicio' => '',
219             'NumeroPuentes' => '',
220             'EntregaPartirDe' => '',
221             'Retorno' => 'N',
222             'Bultos' => $Envio->{DatosServicio}->{Bultos},
223             'TipoMercancia' => '',
224             'Reembolso' => $Envio->{DatosServicio}->{Reembolso},
225             'ImporteReembolso' => $Envio->{DatosServicio}->{ImporteReembolso},
226             'Fecha' => $Fecha,
227             'ValorEstadisticoEuros' => '',
228             'TramoHorario' => '',
229             'EntregaSabado' => $Envio->{DatosServicio}->{EntregaSabado},
230             'NumeroAlbaran' => '',
231             'Peso' => $Envio->{DatosServicio}->{Peso},
232             'NumeroBultos' => $Envio->{DatosServicio}->{NumeroBultos},
233             'CodigoPromocion' => '',
234             'Mascara_Campos' => '',
235             'Mascara_Tipos' => '',
236             'ValorDeclarado' => '',
237             'Referencia' => $Envio->{DatosServicio}->{Referencia},
238             'ServicioEspecial' => '',
239             'CodigoMoneda' => '',
240             'NumeroSobre' => '',
241             'EnFranquicia' => 'N',
242             'ValorEstadistico' => '',
243             'Asistente' => '',
244             'Gestion' => '',
245             'CodigoServicio' => $self->CodigoServicio( $Envio->{DatosServicio}->{CodigoServicio} ),
246             'PortesDebidos' => '',
247             },
248             };
249              
250             return $self->WS($self->MakeStruct($Req));
251             }
252              
253             =head2
254             Genera la estructura para el call
255             =cut
256             sub GetMethods {
257             my $S = XMLin(shift);
258              
259             for my $K ( keys %{$S->{request}} ) {
260             print "'$K' => {\n";
261             for my $E ( keys %{$S->{request}{$K}} ) {
262             print "\t'$E' => '',\n";
263             }
264             print "}\n";
265             }
266            
267             }
268              
269             =head2
270              
271             =cut
272             sub MakeStruct {
273             my $self = shift;
274             my $S = shift;
275             my $str = '';
276              
277             for my $K ( keys %{$S} ) {
278             $str .= "\n";
279             for my $E ( keys %{$S->{$K}} ) {
280              
281             if ( $E eq 'Bultos' ) {
282             $str .= $self->MakeBultos($S->{$K}->{Bultos});
283             } elsif ( ref $S->{$K}->{$E} eq 'HASH' ) {
284             $str .= $self->ForData($E,$S->{$K}->{$E});
285             } else {
286             $str .= "\t".$S->{$K}->{$E}."\n";
287             }
288            
289             }
290             $str .= "\n";
291             }
292              
293             $str .= '';
294            
295             return $str;
296             }
297              
298             sub ForData {
299             my $self = shift;
300             my $E = shift;
301             my $s = shift;
302            
303             my $string = "\t\n";
304            
305             for my $E ( keys %{$s} ) {
306             $string .= "\t\t".$s->{$E}."\n";
307             }
308              
309             $string .= "\t\n";
310            
311             return $string;
312             }
313            
314             sub WS {
315             my $self = shift;
316             my $struct = shift;
317            
318             my $message = '';
319              
320             $message .= $self->AuthInfo();
321             $message .= $struct;
322              
323             my $XML = $self->Post($message);
324              
325             my $Info;
326            
327             for my $K ( keys %{$XML->{'soap:Body'}->{'TransmEnvioResponse'}->{'TransmEnvioResult'}} ) {
328             $Info->{$K} = $XML->{'soap:Body'}->{'TransmEnvioResponse'}->{'TransmEnvioResult'}->{$K};
329             }
330            
331             $Info->{UrlPanel} = qq{$self->{mrw}->{Panel}?Franq=$self->{mrw}->{CodigoFranquicia}&Ab=$self->{mrw}->{CodigoAbonado}&Dep=&Pwd=$self->{mrw}->{Password}&Usr=$self->{mrw}->{UserName}&NumEnv=$Info->{NumeroEnvio}};
332              
333             $self->Error($Info->{Mensaje}) if $Info->{Mensaje};
334            
335             return $Info;
336             }
337              
338             sub Post {
339             my $self = shift;
340             my $msg = shift;
341              
342             my $ua = Mojo::UserAgent->new;
343              
344             my $XML = XMLin( $ua->post( $self->{mrw}->{WSDL} => {'Content-Type' => 'text/xml' } => $msg )->res->body );
345              
346             return $XML;
347             }
348              
349             sub MakeBultos {
350             my $self = shift;
351             my $Bultos = shift;
352            
353             my @map = qw(Alto Largo Ancho Dimension Referencia Peso);
354            
355             my $string = "\n";
356            
357             for my $B ( keys %{$Bultos} ) {
358             $string .= "\n";
359            
360             for my $K ( keys %{$Bultos->{$B}} ) {
361             $string .= "\t".$Bultos->{$B}->{$K}."\n";
362             }
363              
364             $string .= "\n";
365             }
366            
367             $string .= "\n";
368              
369             return $string;
370             }
371              
372             sub EtiquetaEnvio {
373             my $self = shift;
374             my $envio = shift;
375              
376             my $string = '';
377              
378             $string .= $self->AuthInfo();
379              
380             $string .= '
381            
382            
383             '.$envio.'
384            
385            
386            
387             0
388             1100
389             650
390            
391            
392            
393             ';
394              
395             my $XML = $self->Post($string);
396              
397             $self->SavePDF($envio,$XML->{'soap:Body'}->{GetEtiquetaEnvioResponse}->{GetEtiquetaEnvioResult}->{EtiquetaFile});
398              
399             return $XML;
400             }
401              
402             =head2
403             Guarda el PDF en la ruta definida
404             =cut
405             sub SavePDF {
406             my $self = shift;
407             my $Envio = shift;
408             my $PDF = shift;
409              
410             my $File = $self->{mrw}->{RutaPDF}.$Envio.'.pdf';
411              
412             say $File;
413            
414             open F,">$File";
415             print F decode_base64($PDF);
416             close F;
417             }
418              
419             =head1 AUTHOR
420              
421             Harun Delgado, C<< >>
422              
423             =head1 BUGS
424              
425             Please report any bugs or feature requests to C, or through
426             the web interface at L. I will be notified, and then you'll
427             automatically be notified of progress on your bug as I make changes.
428              
429             =head1 SUPPORT
430              
431             You can find documentation for this module with the perldoc command.
432              
433             perldoc Business::Shipping::MRW
434              
435             You can also look for information at:
436              
437             =over 4
438              
439             =item * RT: CPAN's request tracker (report bugs here)
440              
441             L
442              
443             =item * AnnoCPAN: Annotated CPAN documentation
444              
445             L
446              
447             =item * CPAN Ratings
448              
449             L
450              
451             =item * Search CPAN
452              
453             L
454              
455             =back
456              
457              
458             =head1 ACKNOWLEDGEMENTS
459              
460              
461             =head1 LICENSE AND COPYRIGHT
462              
463             Copyright 2015 Harun Delgado.
464              
465             This program is free software; you can redistribute it and/or modify it
466             under the terms of the the Artistic License (2.0). You may obtain a
467             copy of the full license at:
468              
469             L
470              
471             Any use, modification, and distribution of the Standard or Modified
472             Versions is governed by this Artistic License. By using, modifying or
473             distributing the Package, you accept this license. Do not use, modify,
474             or distribute the Package, if you do not accept this license.
475              
476             If your Modified Version has been derived from a Modified Version made
477             by someone other than you, you are nevertheless required to ensure that
478             your Modified Version complies with the requirements of this license.
479              
480             This license does not grant you the right to use any trademark, service
481             mark, tradename, or logo of the Copyright Holder.
482              
483             This license includes the non-exclusive, worldwide, free-of-charge
484             patent license to make, have made, use, offer to sell, sell, import and
485             otherwise transfer the Package with respect to any patent claims
486             licensable by the Copyright Holder that are necessarily infringed by the
487             Package. If you institute patent litigation (including a cross-claim or
488             counterclaim) against any party alleging that the Package constitutes
489             direct or contributory patent infringement, then this Artistic License
490             to you shall terminate on the date that such litigation is filed.
491              
492             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
493             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
494             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
495             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
496             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
497             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
498             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
499             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
500              
501             =cut
502              
503             1; # End of Business::Shipping::MRW