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