diff --git a/CREDITS b/CREDITS index 5a4ed79..41a8e13 100644 --- a/CREDITS +++ b/CREDITS @@ -1,5 +1,5 @@ #!/bin/cat -# $Id: CREDITS,v 1.167 2012/02/07 00:22:01 gilles Exp gilles $ +# $Id: CREDITS,v 1.168 2012/02/19 22:26:00 gilles Exp gilles $ If you want to make a donation to the author, Gilles LAMIRAL, use any of the following ways: @@ -30,7 +30,13 @@ I thank very much all of these people. I thank also very much all people who bought imapsync from the homepage but I don't cite them here. -? (Found no card in the packet may be lost since book is damaged, amazon and paper box for an international transported book ...) +Pierre GUILLAUME // e-Lixir +Fixed 2 bugs about [Gmail] folder names. +one is about $cache_dir and bsd_globs() that needs escaped characters. +Second is eval and --delete2foldersonly --delete2foldersbutnot that need +also good escaping. Thanks. + +? (Found no card in the packet; may be lost since book is damaged, amazon and paper box for an international transported book ...) Contributed by giving the book 87.18 "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp" diff --git a/ChangeLog b/ChangeLog index 117aeb9..4d88439 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,17 +1,32 @@ RCS file: RCS/imapsync,v Working file: imapsync -head: 1.484 +head: 1.487 branch: locks: strict - gilles: 1.484 + gilles: 1.487 access list: symbolic names: keyword substitution: kv -total revisions: 484; selected revisions: 484 +total revisions: 487; selected revisions: 487 description: ---------------------------- -revision 1.484 locked by: gilles; +revision 1.487 locked by: gilles; +date: 2012/02/29 05:29:21; author: gilles; state: Exp; lines: +7 -7 +Fixed a useless Perl warning. +---------------------------- +revision 1.486 +date: 2012/02/23 23:05:49; author: gilles; state: Exp; lines: +10 -10 +Removed "Memory/biggest message ratio" in final stats, useless now. +Fixed a warning about memory_consumption when the call fails. +---------------------------- +revision 1.485 +date: 2012/02/19 22:24:23; author: gilles; state: Exp; lines: +16 -12 +Applied Pierre GUILLAUME patch about + 1) $cache_dir and bsd_globs() that needs escaped characters. + 2) eval and --delete2foldersonly --delete2foldersbutnot that need also good escaping. Thanks Pierre. +---------------------------- +revision 1.484 date: 2012/02/07 00:19:33; author: gilles; state: Exp; lines: +8 -7 Just a comment about examine versus select on host1. ---------------------------- diff --git a/FAQ b/FAQ index a345516..c833e01 100644 --- a/FAQ +++ b/FAQ @@ -1,10 +1,12 @@ #!/bin/cat -# $Id: FAQ,v 1.102 2012/01/08 06:40:50 gilles Exp gilles $ +# $Id: FAQ,v 1.104 2012/02/20 18:23:29 gilles Exp gilles $ +------------------+ | FAQ for imapsync | +------------------+ +http://imapsync.lamiral.info/FAQ + Unix versus Windows syntax. A) \ versus ^ @@ -503,6 +505,19 @@ you have to enter imapsync ... --password1 "$%%&<>|^"^" +======================================================================= +Q. On Windows, some passwords begin with an equal = character. + Login fails. What can I do? + +R. Use twice equals == characters instead; For example, if =secret + is the password then use: + + imapsync ... --password1 ==secret + +or even + + imapsync ... --password1 "==secret" + ======================================================================= Q. With huge account (many messages) when it comes to reading the destination server it comes out this error: diff --git a/README b/README index a5f3deb..5e9564f 100644 --- a/README +++ b/README @@ -3,7 +3,7 @@ NAME Synchronise mailboxes between two imap servers. Good at IMAP migration. More than 44 different IMAP server softwares supported with success. - $Revision: 1.484 $ + $Revision: 1.487 $ SYNOPSIS To synchronise imap account "foo" on "imap.truc.org" to imap account @@ -444,5 +444,5 @@ SIMILAR SOFTWARES Feedback (good or bad) will often be welcome. - $Id: imapsync,v 1.484 2012/02/07 00:19:33 gilles Exp gilles $ + $Id: imapsync,v 1.487 2012/02/29 05:29:21 gilles Exp gilles $ diff --git a/VERSION b/VERSION index 003ada6..7f91fad 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.484 +1.487 diff --git a/VERSION_EXE b/VERSION_EXE index 003ada6..7f91fad 100644 --- a/VERSION_EXE +++ b/VERSION_EXE @@ -1 +1 @@ -1.484 +1.487 diff --git a/W/paypal_reply/memo b/W/paypal_reply/memo index 514c092..6b143bc 100644 --- a/W/paypal_reply/memo +++ b/W/paypal_reply/memo @@ -1,14 +1,14 @@ #!/bin/sh -# $Id: memo,v 1.5 2011/05/20 12:57:31 gilles Exp gilles $ +# $Id: memo,v 1.6 2012/02/24 12:23:38 gilles Exp gilles $ echo paypal_bilan_tests_invoice paypal_bilan_tests_invoice() { -# DID output no diff between paypal_bilan_1.43 and 1.?? +# DID output no diff between paypal_bilan_1.46 and 1.47 ( #set -x -/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.44 --bnc --debug --debug_invoice --first_in 147 --avoid_numbers '292 293 643 644 731 732 1093 1330 1331 1332 1333 1334' /g/paypal/paypal_201?_??_complet.csv \ +/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.46 --bnc --debug --debug_invoice --first_in 147 --avoid_numbers '292 293 643 644 731 732 1093 1330 1331 1332 1333 1334' /g/paypal/paypal_201?_??_complet.csv \ > /g/var/paypal_bilan/tests/paypal_invoice.out1 2>&1 /g/public_html/imapsync/W/paypal_reply/paypal_bilan --bnc --debug --debug_invoice --first_in 147 --avoid_numbers '292 293 643 644 731 732 1093 1330 1331 1332 1333 1334' /g/paypal/paypal_201?_??_complet.csv \ > /g/var/paypal_bilan/tests/paypal_invoice.out2 2>&1 diff --git a/W/paypal_reply/paypal_bilan b/W/paypal_reply/paypal_bilan index c2339a5..db7df17 100755 --- a/W/paypal_reply/paypal_bilan +++ b/W/paypal_reply/paypal_bilan @@ -1,6 +1,6 @@ #!/usr/bin/perl -# $Id: paypal_bilan,v 1.45 2012/01/30 03:12:55 gilles Exp gilles $ +# $Id: paypal_bilan,v 1.47 2012/02/24 12:22:05 gilles Exp gilles $ use strict; use warnings; @@ -27,6 +27,7 @@ my $total_eur_invoice = 0 ; my $nb_invoice = 0 ; my $nb_invoice_refund = 0 ; my $nb_invoice_suspended = 0 ; +my $nb_invoice_canceled = 0 ; my ( $tests, $testeur ) ; my $debug ; @@ -41,6 +42,7 @@ my $bnc = '' ; my $usdeur = 1.2981 ; my $invoices ; my %invoice_refund ; +my %invoice_canceled ; my %invoice_suspended ; my $write_invoices = 0 ; my $avoid_numbers ; @@ -148,6 +150,10 @@ foreach my $invoice ( @invoices_wanted ) { my $nb_invoice_sent = scalar( @invoice_sent ) ; @invoice_not_sent = sort { $a <=> $b } keys( %invoice_not_sent ) ; +my @invoice_canceled = sort { $a <=> $b } keys( %invoice_canceled ) ; +my @invoice_suspended = sort { $a <=> $b } keys( %invoice_suspended ) ; +my @invoice_refund = sort { $a <=> $b } keys( %invoice_refund ) ; + print "USD banque $total_usd_received\n" ; print "USD invoice $total_usd_invoice\n" ; my $total_eur_from_usd ; @@ -174,8 +180,9 @@ print "EUR total TVA $total_TVA_EUR\n" ; print "EUR total HT sup $total_HT_EUR_sup\n" ; print "EUR total TVA sup $total_TVA_EUR_sup\n" ; print "Nb invoice $nb_invoice ( from $first_invoice_paypal to $last_invoice )\n" ; -print "Nb invoice refund $nb_invoice_refund\n" ; -print "Nb invoice suspended $nb_invoice_suspended\n" ; +print "Nb invoice canceled $nb_invoice_canceled @invoice_canceled\n" ; +print "Nb invoice suspended $nb_invoice_suspended @invoice_suspended\n" ; +print "Nb invoice refund $nb_invoice_refund @invoice_refund\n" ; print "Nb invoice sent $nb_invoice_sent\n" ; print "Have to send invoices @invoice_not_sent\n" if ( @invoice_not_sent ) ; @@ -420,7 +427,6 @@ sub compute_line { and 'EUR' eq $Devise and 'Remboursé' eq $Etat ) { - #$invoice = $first_invoice + $nb_invoice ; $invoice = next_invoice( ) ; $nb_invoice++ ; $nb_invoice_refund++; @@ -429,12 +435,24 @@ sub compute_line { $print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ; } + if ( + 'Paiement sur site marchand reçu' eq $Type + and 'EUR' eq $Devise + and 'Annulé' eq $Etat + ) { + $invoice = next_invoice( ) ; + $nb_invoice++ ; + $nb_invoice_canceled++; + $invoice_canceled{ $invoice }++ ; + + $print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ; + } + if ( 'Paiement sur site marchand reçu' eq $Type and 'EUR' eq $Devise and 'Suspendu' eq $Etat ) { - #$invoice = $first_invoice + $nb_invoice ; $invoice = next_invoice( ) ; $nb_invoice++ ; $nb_invoice_suspended++; @@ -448,7 +466,6 @@ sub compute_line { and 'EUR' eq $Devise and 'Non compensé' eq $Etat ) { - #$invoice = $first_invoice + $nb_invoice ; $invoice = next_invoice( ) ; $nb_invoice++ ; $print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ; diff --git a/W/paypal_reply/paypal_bilan_1.46 b/W/paypal_reply/paypal_bilan_1.46 new file mode 100755 index 0000000..efe7251 --- /dev/null +++ b/W/paypal_reply/paypal_bilan_1.46 @@ -0,0 +1,1123 @@ +#!/usr/bin/perl + +# $Id: paypal_bilan,v 1.46 2012/02/24 11:53:06 gilles Exp gilles $ + +use strict; +use warnings; +use Getopt::Long; +use Text::CSV_XS ; +use IO::Handle ; +use Data::Dumper ; +use Unicode::MapUTF8 qw(to_utf8 from_utf8 utf8_supported_charset); +use Test::More 'no_plan' ; + +die unless (utf8_supported_charset('ISO-8859-1')); + +my $total_usd_received = 0 ; +my $total_usd_invoice = 0 ; +my $total_HT_EUR_exo = 0 ; +my $total_HT_EUR_ass = 0 ; +my $total_TVA_EUR = 0 ; + +my $total_HT_EUR_sup = 0 ; +my $total_TVA_EUR_sup = 0 ; + +my $total_eur_received = 0 ; +my $total_eur_invoice = 0 ; +my $nb_invoice = 0 ; +my $nb_invoice_refund = 0 ; +my $nb_invoice_suspended = 0 ; + +my ( $tests, $testeur ) ; +my $debug ; +my $debug_csv ; +my $debug_dev ; +my $debug_invoice ; +my $debug_invoice_utf8 ; + +my $first_invoice = 1 ; +my $print_details = '' ; +my $bnc = '' ; +my $usdeur = 1.2981 ; +my $invoices ; +my %invoice_refund ; +my %invoice_suspended ; +my $write_invoices = 0 ; +my $avoid_numbers ; + +my $dir_invoices = '/g/var/paypal_invoices' ; + +my $option_ret = GetOptions ( + 'tests' => \$tests, + 'debug' => \$debug, + 'debug_csv' => \$debug_csv, + 'debug_dev' => \$debug_dev, + 'debug_invoice' => \$debug_invoice, + 'debug_invoice_utf8' => \$debug_invoice_utf8, + + 'first_invoice=i' => \$first_invoice, + 'print_details|details' => \$print_details, + 'bnc' => \$bnc, + 'usdeur=f' => \$usdeur, + 'invoices=s' => \$invoices, + 'write_invoices!' => \$write_invoices, + 'avoid_numbers=s' => \$avoid_numbers, +); + +$testeur = Test::More->builder ; +$testeur->no_ending(1) ; + +if ( $tests ) { + $testeur->no_ending( 0 ) ; + exit( tests( ) ) ; +} + + +my @files = @ARGV ; +my %action_of_invoice ; + +my %invoice_paypal ; +#$invoice_paypal{ $first_invoice } = 1 ; + +my @invoices_wanted = split( /\s+/, $invoices ) if $invoices ; + +my @avoid_numbers = split( /\s+/, $avoid_numbers ) if $avoid_numbers ; +my %avoid_numbers ; +@avoid_numbers{ @avoid_numbers } = ( ) if @avoid_numbers ; + +#print "@invoices\n" ; + +foreach my $file ( @files ) { + + my @actions = parse_file( $file ) ; + + foreach my $action (@actions) { + my %action = %$action ; + #print $action->{ Nom }, "\n" ; + my( $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat, + $Devise, $Montant, $Numero_davis_de_reception, $Solde, + $Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe, $Titre_de_l_objet ) + = @action{ ( 'Date', 'Heure', 'Fuseau horaire', 'Nom', 'Type', 'Etat', + 'Devise', 'Montant', "Numéro d'avis de réception", 'Solde', + 'Pays', 'Nom Option 1', 'Valeur Option 1', 'Hors taxe', "Titre de l'objet") } ; + #print "$Nom\n" ; + ( $Etat ) = @action{ ( 'Etat', ) } || @action{ ( 'État' ) } ; + my $invoice = 'NONE' ; + $Montant = $action->{ Net } if not defined $Montant; + compute_line($action, $invoice, $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat, + $Devise, $Montant, $Numero_davis_de_reception, $Solde, + $Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe, $Titre_de_l_objet ) ; + + # index by invoice number + $action_of_invoice{ $action->{ 'invoice' } } = $action ; + } + delete $action_of_invoice{ 'NONE' } ; +} + +my $last_invoice ; +my @invoice_paypal = sort { $a <=> $b } keys %invoice_paypal ; +$last_invoice = $invoice_paypal[-1] || 0 ; +my $first_invoice_paypal = $invoice_paypal[0] || 0 ; + +@invoices_wanted = ( $first_invoice .. $last_invoice ) if ( ! @invoices_wanted ) ; + +my @invoice_sent ; +my %invoice_sent ; +my @invoice_not_sent ; +my %invoice_not_sent ; + +foreach my $invoice ( @invoices_wanted ) { + + my $action = $action_of_invoice{ $invoice } ; + next if ! $action ; + my $email_address = $action->{ "De l'adresse email" } ; + + my $invoice_sent = invoice_sent( $dir_invoices, $invoice, $email_address ) ; + #print "$invoice $invoice_sent\n" ; + + if ( $invoice_sent ) { + $invoice_sent{ $invoice }++ ; + #build_invoice( $invoice ) ; + }else{ + $invoice_not_sent{ $invoice }++ ; + build_invoice( $invoice ) ; + } +} + +@invoice_sent = sort { $a <=> $b } keys( %invoice_sent ) ; +my $nb_invoice_sent = scalar( @invoice_sent ) ; +@invoice_not_sent = sort { $a <=> $b } keys( %invoice_not_sent ) ; + +print "USD banque $total_usd_received\n" ; +print "USD invoice $total_usd_invoice\n" ; +my $total_eur_from_usd ; +$total_eur_from_usd = sprintf('%2.2f', $total_usd_invoice / $usdeur ) ; # au 30 nov 2010 http://fr.finance.yahoo.com/devises/convertisseur/#from=EUR;to=USD;amt=1 +print "EUR from USD $total_eur_from_usd\n" ; +print "EUR banque $total_eur_received\n" ; +print "EUR invoice $total_eur_invoice\n" ; + +my $total_eur = $total_eur_from_usd + $total_eur_invoice ; + +$total_HT_EUR_exo = sprintf('%2.2f', $total_HT_EUR_exo) ; +$total_HT_EUR_ass = sprintf('%2.2f', $total_HT_EUR_ass) ; +$total_TVA_EUR = sprintf('%2.2f', $total_TVA_EUR) ; + +$total_HT_EUR_sup = sprintf('%2.2f', $total_HT_EUR_sup) ; +$total_TVA_EUR_sup = sprintf('%2.2f', $total_TVA_EUR_sup) ; + +$total_eur = sprintf('%2.2f', $total_eur) ; + +print "EUR total $total_eur\n" ; +print "EUR total HT exo $total_HT_EUR_exo\n" ; +print "EUR total HT assuj $total_HT_EUR_ass\n" ; +print "EUR total TVA $total_TVA_EUR\n" ; +print "EUR total HT sup $total_HT_EUR_sup\n" ; +print "EUR total TVA sup $total_TVA_EUR_sup\n" ; +print "Nb invoice $nb_invoice ( from $first_invoice_paypal to $last_invoice )\n" ; +print "Nb invoice refund $nb_invoice_refund\n" ; +print "Nb invoice suspended $nb_invoice_suspended\n" ; +print "Nb invoice sent $nb_invoice_sent\n" ; +print "Have to send invoices @invoice_not_sent\n" if ( @invoice_not_sent ) ; + +my $total_eur2 = $total_HT_EUR_exo + $total_HT_EUR_ass + $total_TVA_EUR + $total_HT_EUR_sup + $total_TVA_EUR_sup ; +print "$total_eur != $total_eur2 = $total_HT_EUR_exo + $total_HT_EUR_ass + $total_TVA_EUR + $total_HT_EUR_sup + $total_TVA_EUR_sup\n" +if ( $total_eur != $total_eur2 ) ; + +sub parse_one_line_io { + my $csv = shift ; + my $io = shift ; + + my $line = $csv->getline($io) ; + + return if ( $csv->eof( ) ) ; + if ( not defined( $line ) ) { + my($cde, $str, $pos) = $csv->error_diag () ; + print "[$cde] [$str] [$pos]\n" ; + + } + return( $line ) ; +} + +sub hash_and_count_dupplicate { + my @columns = @_ ; + my %columns ; + + #@columns_def{ @columns_def } = ( ) ; + foreach my $col ( @columns ) { + $columns{ $col } += 1 ; + } + $debug_csv and print "Nb columns: ", scalar( keys %columns ), " ", scalar( @columns ), "\n" ; + # debug how many time a title is defined + foreach my $col (1 .. scalar( @columns )) { + $debug_csv and print "$col | ", + deci_to_AA( $col ) , " | ", + $columns{ $columns[ $col - 1 ] }, " | ", + $columns[ $col - 1 ], "\n" ; + } + + # exit in case two columns have the same name + die "Erreur : doublons dans les titres\n" if ( scalar( keys %columns ) != scalar( @columns ) ) ; + + return( %columns ) ; +} + +sub deci_to_AA { + my $deci = shift ; + my $AA = ''; + + while ( $deci > 0 ) { + my $quot = int( ( $deci - 1 ) / 26 ) ; + my $rest = $deci - 1 - ( 26 * $quot ) ; + my $char = chr ( ord('A') + $rest ) ; + $AA = $char . $AA ; + $deci = $quot ; + } + #print "col=$AA\n" ; + return( $AA ) ; +} + +sub remove_first_blank { + my $string = shift ; + + $string =~ s/^ +// ; + return( $string ) ; + +} + +sub parse_file { + my $file = shift ; + + open my $io, "<", $file or die "$file: $!" ; + + my $csv = Text::CSV_XS->new( { + sep_char => ',', + binary => 1, + keep_meta_info => 1, + eol => $/, + } ) ; + + my $line_1 = parse_one_line_io( $csv, $io ) ; + die if ( not defined $line_1 ) ; # first line must have no problem + + my @columns_def_orig = @$line_1 ; + my @columns_def = map { remove_first_blank( $_ ) } @columns_def_orig ; + $debug_csv and print "columns_def = ", map( { "[$_]" } @columns_def ), "\n"; + + my %columns_def = hash_and_count_dupplicate( @columns_def ) ; + my $nb_columns_def = scalar @columns_def ; + + my $line_counter = 2 ; + my @actions ; + while ( 1 ) { + $debug_csv and print "ligne $line_counter ", $csv->eof( ), "\n" ; + my $line = parse_one_line_io( $csv, $io ) ; + last if ( $csv->eof( ) ) ; + if ( not defined $line ) { + print "Erreur ligne $line_counter : ", $csv->error_diag, "\n\n"; + ++$line_counter ; + next ; + } + my @columns = @$line ; + + if ( $nb_columns_def != scalar @columns ) { + print "Erreur ligne $line_counter : nombre de colonnes = ", scalar @columns, " != $nb_columns_def\n" ; + ++$line_counter ; + next ; + } + my %columns ; + @columns{ @columns_def } = @columns ; + $columns{ 'file_csv' } = $file ; + $columns{ 'line_number' } = $line_counter ; + $csv->combine( @columns ) ; + my $line_csv = $csv->string(); + $columns{ 'line_csv' } = $line_csv ; + $debug_csv and print map( { "[$_] = [" . $columns{$_} . "]\n" } + @columns_def, 'line_number', 'line_csv', 'file_csv' ), + "\n"; + ++$line_counter ; + push( @actions, \%columns ) ; + } + close( $io ); + return( reverse @actions ) ; +} + +sub next_invoice { + my @current_numbers = sort { $a <=> $b } ( $first_invoice - 1, keys( %invoice_paypal ) ) ; + my $last_invoice = $current_numbers[ -1 ] || 0 ; + + #keys( %avoid_numbers ), + my $next_invoice = $last_invoice + 1 ; + while ( exists( $avoid_numbers{ $next_invoice } ) ) { $next_invoice++ ; } + $invoice_paypal{ $next_invoice } = 1 ; + #print "AAA [@current_numbers] [$last_invoice] [$next_invoice]\n" ; + + return( $next_invoice ) ; +} + +sub keyval { + my %hash = @_ ; + return( join( " ", map( { "$_ => " . $hash{ $_ } } keys %hash ) ) . "\n" ) ; +} + + +sub tests_next_invoice { + ok( 1 == next_invoice( ), 'next_invoice: 1' ) ; + ok( 2 == next_invoice( ), 'next_invoice: 2' ) ; + @avoid_numbers{ (3, 4, 6, 8 ) } = ( ) ; + ok( 5 == next_invoice( ), 'next_invoice: 7' ) ; + ok( 7 == next_invoice( ), 'next_invoice: 8' ) ; + ok( 9 == next_invoice( ), 'next_invoice: 9' ) ; + %invoice_paypal = () ; + $first_invoice = 7 ; + ok( 7 == next_invoice( ), 'next_invoice: 7' ) ; +} + + +sub tests { + tests_next_invoice( ) ; + #tests_half( ) ; + tests_cut( ) ; +} + +sub compute_line { + my( $action, $invoice, $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat, + $Devise, $Montant, $Numero_davis_de_reception, $Solde, + $Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe_paypal, $Titre_de_l_objet ) = @_ ; + + $debug and print( "-" x 60, "\n", + "[$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] ", + "[$Devise] [$Hors_taxe_paypal] [$Montant] [$Numero_davis_de_reception] [$Solde]\n", + "[$Pays] [$Nom_Option_1] [$Valeur_Option_1] [$Titre_de_l_objet]\n" ) ; + + $Montant =~ s/[^0-9-,.]//g ; + $Montant =~ s/,/./g ; + #$debug and print "MM[$Montant]\n" ; + $Hors_taxe_paypal =~ s/,/./g ; + + my $MontantEUR; + my( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR ) ; + my( $montant_HT_EUR_sup, $montant_TVA_EUR_sup ) ; + + if ( $bnc ) { + $MontantEUR = $Montant ; + $MontantEUR = sprintf( "%.4f", $Montant/$usdeur ) if ($Devise eq 'USD') ; + print( "\n", "=" x 60, "\n" ) ; + print( "[$Date] [$Nom] [$Type] [$Etat] [$Devise] [$Hors_taxe_paypal] [$Montant] [EUR $MontantEUR]\n", + "[$Pays] [$Nom_Option_1] [$Valeur_Option_1] [$Titre_de_l_objet]\n" ) ; + } + + if ( + 'Paiement sur site marchand reçu' eq $Type + and 'USD' eq $Devise + and ( 'Terminé' eq $Etat or 'Compensé' eq $Etat ) + ) { + $Montant =~tr/,/./; + #print "$Montant\n" ; + my $Montant2_usd; + $Montant2_usd = $Hors_taxe_paypal ; + $total_usd_received += $Montant ; + $total_usd_invoice += $Montant2_usd ; + ( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR, $montant_HT_EUR_sup, $montant_TVA_EUR_sup ) + = tva_line( $Devise, $Montant2_usd, $Pays, $Nom_Option_1, $Valeur_Option_1, $Titre_de_l_objet ) ; + $total_HT_EUR_exo += $montant_HT_EUR_exo ; + $total_HT_EUR_ass += $montant_HT_EUR_ass ; + $total_TVA_EUR += $montant_TVA_EUR ; + #$invoice = $first_invoice + $nb_invoice ; + $invoice = next_invoice( ) ; + $nb_invoice++ ; + $print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ; + + } + + if ( + 'Paiement sur site marchand reçu' eq $Type + and 'EUR' eq $Devise + and ( 'Terminé' eq $Etat or 'Compensé' eq $Etat ) + ) { + $Montant =~tr/,/./; + #print "$Montant\n" ; + my $Montant2_eur; + $Montant2_eur = $Hors_taxe_paypal ; + $total_eur_received += $Montant ; + $total_eur_invoice += $Montant2_eur ; + ( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR, $montant_HT_EUR_sup, $montant_TVA_EUR_sup ) + = tva_line( $Devise, $Montant2_eur, $Pays, $Nom_Option_1, $Valeur_Option_1, $Titre_de_l_objet ) ; + $total_HT_EUR_exo += $montant_HT_EUR_exo ; + $total_HT_EUR_ass += $montant_HT_EUR_ass ; + $total_TVA_EUR += $montant_TVA_EUR ; + $total_HT_EUR_sup += $montant_HT_EUR_sup ; + $total_TVA_EUR_sup += $montant_TVA_EUR_sup ; + + + #$invoice = $first_invoice + $nb_invoice ; + $invoice = next_invoice( ) ; + $nb_invoice++ ; + $print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ; + } + + if ( + 'Paiement sur site marchand reçu' eq $Type + and 'EUR' eq $Devise + and 'Remboursé' eq $Etat + ) { + #$invoice = $first_invoice + $nb_invoice ; + $invoice = next_invoice( ) ; + $nb_invoice++ ; + $nb_invoice_refund++; + $invoice_refund{ $invoice }++ ; + + $print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ; + } + + if ( + 'Paiement sur site marchand reçu' eq $Type + and 'EUR' eq $Devise + and 'Suspendu' eq $Etat + ) { + #$invoice = $first_invoice + $nb_invoice ; + $invoice = next_invoice( ) ; + $nb_invoice++ ; + $nb_invoice_suspended++; + $invoice_suspended{ $invoice }++ ; + + $print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ; + } + + if ( + 'Paiement sur site marchand reçu' eq $Type + and 'EUR' eq $Devise + and 'Non compensé' eq $Etat + ) { + #$invoice = $first_invoice + $nb_invoice ; + $invoice = next_invoice( ) ; + $nb_invoice++ ; + $print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ; + } + + $action->{ 'invoice' } = $invoice ; + if ( $bnc ) { + my $FR_flag = '' ; + $FR_flag = ' FR' if $Pays eq 'France' ; + my $IND_flag = '' ; + $IND_flag = ' IND' if ('imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 ) ; + print "FE $invoice$FR_flag$IND_flag\n" ; + print "FE $invoice$FR_flag$IND_flag imapsync $Nom\n" ; + printf( "%.2f [EUR %.2f]\n", $Montant, $MontantEUR ) ; + } +} + +sub build_invoice { + my $invoice = shift ; + + return if ! $invoice ; + + my $action = $action_of_invoice{ $invoice } ; + my $refund = '' ; + $refund = 'REFUND ' if $invoice_refund{ $invoice } ; + my %action = %$action if $action ; + #print Data::Dumper->Dump( [$action] ) ; + + my( $Date, $Heure, $Nom, $Type, $Etat, $Devise, $Hors_taxe, $Commission, $Net, + $De_l_adresse_email, $A_l_adresse_email, $N_de_transaction, $Titre_de_l_objet, + $TVA, $Nom_Option_1, $Valeur_Option_1, $N_de_transaction_de_reference, + $Adresse_1, $Adresse_2_district_quartier, $Ville, + $Etat_Province, $Code_postal, $Pays, $line_number, $line_csv, $file_csv ) + = @action{ ( 'Date', 'Heure', 'Nom', 'Type', 'Etat', 'Devise', 'Hors taxe', 'Commission', 'Net', + "De l'adresse email", "A l'adresse email", 'N° de transaction', "Titre de l'objet", + 'TVA', 'Nom Option 1', 'Valeur Option 1', 'Nº de transaction de référence', + 'Adresse 1', 'Adresse 2/district/quartier', 'Ville', + 'Etat/Province/Région/Comté/Territoire/Préfecture/République', 'Code postal', 'Pays', 'line_number', 'line_csv', 'file_csv' ) } ; + + my( $Etat_Province1 ) = @action{ ( 'Etat/Province/Région/Comté/Territoire/Préfecture/République' ) } ; + my( $Etat_Province2 ) = @action{ ( 'État/Province/Région/Comté/Territoire/Préfecture/République' ) } ; + + $Etat_Province = @action{ ( 'Etat/Province/Région/Comté/Territoire/Préfecture/République' ) } + || @action{ ( 'État/Province/Région/Comté/Territoire/Préfecture/République' ) } + || '' ; + + #print "$Hors_taxe $Devise\n" ; + my $Hors_taxe_num = $Hors_taxe ; + $Hors_taxe_num =~ s{,}{.} ; + if ($Hors_taxe_num > 100) { + print "invoice $invoice $Hors_taxe_num > 100\n" ; + #return() ; + } + + my ( $email_message_header, $email_message_body ) + = build_email_message( $Date, $Nom, $De_l_adresse_email, $invoice, $Titre_de_l_objet ) ; + if ( $write_invoices and ! invoice_sent( $dir_invoices, $invoice, $De_l_adresse_email ) ) { + write_email_message( $dir_invoices, $invoice, + $email_message_header, $email_message_body, + $De_l_adresse_email) ; + write_csv_info( $dir_invoices, $invoice, $file_csv, $line_number, $line_csv ) ; + } + + + + #print "==== $invoice $refund=================================================" ; + #print $email_message ; + + my( + $clientAdrA, + $clientAdrB, + $clientAdrC, + $clientAdrD, + $clientAdrE, + $clientAdrF, + ) + = build_address( + $Nom, + $Adresse_1, + $Adresse_2_district_quartier, + $Ville, + $Code_postal, + $Etat_Province, + $Pays, + ) ; + + foreach my $str ( + $De_l_adresse_email, + $Nom, + $clientAdrA, + $clientAdrB, + $clientAdrC, + $clientAdrD, + $clientAdrE, + $clientAdrF, + ) { + $str =~ s{#}{\\#}g ; + $str =~ s{_}{\\_}g ; + $str =~ s{&}{\\&}g ; + } + + my ( $clientTypeEN, $clientTypeFR ) = client_type( $Nom_Option_1, $Valeur_Option_1 ) ; + + my $quantity = '1' ; + + my ( + $descriptionFR, + $descriptionEN, + $usageFR, + $usageEN, + ) + = description_stuff( $Titre_de_l_objet, $clientTypeEN ) ; + + my ( + $priceHT, + $tvaFR, + $tvaEN, + $priceTVA, + $priceTTC, + $messageTVAFR, + $messageTVAEN, + $priceTTCusd + ) + = tva_stuff( $clientTypeEN, $Pays, $Hors_taxe, $Devise, $Titre_de_l_objet ) ; + + my $object_type = object_type( $Titre_de_l_objet ) ; + + my ( $urlSrc, $urlExe ) = download_urls( $Date, $object_type ) ; + #print "ZZZ $object_type ( $urlSrc, $urlExe )\n" ; + + my ( $Nom1 ) = cut( $Nom, 42 ) ; + my $tex_variables = qq{ +%% Begin input from paypal_bilan +\\providecommand{\\invoiceNumber}{$invoice} +\\providecommand{\\clientName}{$Nom1} +\\providecommand{\\clientEmail}{$De_l_adresse_email} +\\providecommand{\\clientAdrA}{$clientAdrA} +\\providecommand{\\clientAdrB}{$clientAdrB} +\\providecommand{\\clientAdrC}{$clientAdrC} +\\providecommand{\\clientAdrD}{$clientAdrD} +\\providecommand{\\clientAdrE}{$clientAdrE} +\\providecommand{\\clientAdrF}{$clientAdrF} +\\providecommand{\\invoiceDate}{$Date} +\\providecommand{\\invoiceHour}{$Heure} + +\\providecommand{\\descriptionFR}{$descriptionFR} +\\providecommand{\\descriptionEN}{$descriptionEN} +\\providecommand{\\usageFR}{$usageFR} +\\providecommand{\\usageEN}{$usageEN} +\\providecommand{\\quantity}{$quantity} + +\\providecommand{\\priceHT}{$priceHT} +\\providecommand{\\tvaFR}{$tvaFR} +\\providecommand{\\tvaEN}{$tvaEN} +\\providecommand{\\priceTVA}{$priceTVA} +\\providecommand{\\priceTTC}{$priceTTC} +\\providecommand{\\priceTTCusd}{$priceTTCusd} +\\providecommand{\\messageTVAFR}{$messageTVAFR} +\\providecommand{\\messageTVAEN}{$messageTVAEN} +\\providecommand{\\urlSrc}{\\url{$urlSrc}} +\\providecommand{\\urlExe}{\\url{$urlExe}} +%% End input from paypal_bilan +} ; + + my $tex_variables_utf8 = to_utf8( { -string => $tex_variables, -charset => 'ISO-8859-1' } ) ; + + print $tex_variables_utf8 if $debug_invoice_utf8 ; + print $tex_variables if $debug_invoice ; + + #print "$invoice ", invoice_sent( $dir_invoices, $invoice, $De_l_adresse_email ), "\n" ; + if ( $write_invoices and ! invoice_sent( $dir_invoices, $invoice, $De_l_adresse_email ) ) { + write_tex_variables_file( $dir_invoices, $invoice, $Date, $tex_variables_utf8 ) ; + } + +} + +sub description_stuff { + my ( $object, $clientTypeEN ) = @_ ; + + my $object_type = object_type( $object ) ; + + my ( $descriptionFR, $descriptionEN ) ; + if ( 'software' eq $object_type ) { + $descriptionFR = 'Logiciel imapsync. Tous droits cédés.' ; + $descriptionEN = '(Imapsync software. All rights conceded.)' ; + } + + my ( $usageFR, $usageEN ) ; + if ( 'professional' eq $clientTypeEN + and 'software' eq $object_type ) { + $usageFR = 'Usage à titre professionnel.' ; + $usageEN = '(professional usage.)' ; + } + + if ( 'individual' eq $clientTypeEN + and 'software' eq $object_type ) { + $usageFR = 'Usage à titre individuel.' ; + $usageEN = '(individual usage.)' ; + } + + if ( 'support' eq $object_type ) { + $descriptionFR = 'Support sur le logiciel imapsync.' ; + $descriptionEN = '(Imapsync support.)' ; + $usageFR = '' ; + $usageEN = '' ; + } + return( $descriptionFR, $descriptionEN, $usageFR, $usageEN ) ; +} + + + +sub object_type { + my $object = shift ; + + if ( 'imapsync' eq $object + or 'imapsync.exe' eq $object + or 'imapsync source' eq $object + or 'imapsync source code' eq $object + ) { + return( 'software' ) ; + }elsif ( 'imapsync support' eq $object ) { + return( 'support' ) ; + } +} + +sub build_email_message { + + my ( $date, $name, $email, $invoice, $objet ) = @_ ; + + my $object_type = object_type( $objet ) ; + + my $message_header_software = qq{X-imapsync: invoice $invoice for imapsync software +From: Gilles LAMIRAL +Bcc: gilles\@lamiral.info +Subject: [imapsync invoice] $invoice ($date) for imapsync software +Disposition-Notification-To: Gilles LAMIRAL +} ; + + my $message_header_support = qq{X-imapsync: invoice $invoice for imapsync support +From: Gilles LAMIRAL +Bcc: gilles\@lamiral.info +Subject: [imapsync invoice] $invoice ($date) for imapsync support +Disposition-Notification-To: Gilles LAMIRAL +} ; + + my $message_body_software = qq{ +Hello $name, + +First of all, I'm sorry for the delay in getting back to you. + +You'll find in the attachment the invoice of imapsync +software you bought and paid (dd/mm/yyyy $date). +The invoice file is named facture_imapsync-${invoice}.pdf +This invoice is in PDF format, ready to be print. + +Should you need a hardcopy of this invoice, +I'll send it to you upon request by regular mail. + +As the law requires, this numeric invoice PDF file +is signed with my private gpg key. + +The resulting gpg signature is in the file named +facture_imapsync-${invoice}.pdf.asc +you will also find in the attachment. + +You can check I (Gilles LAMIRAL) really did generate +this invoice with the following command line: + + gpg --verify facture_imapsync-${invoice}.pdf.asc facture_imapsync-${invoice}.pdf + +or any other gpg graphical tool. + +Once more, thank you for buying and using imapsync. + +Any feedback is welcome. + + +-- +Best Regards, 09 51 84 42 42 +Gilles Lamiral. France, Baulon (35580) 06 20 79 76 06 +} ; + + + my $message_body_support = qq{ +Hello $name, + +First of all, I'm sorry for the delay in getting back to you. + +You'll find in the attachment the invoice of imapsync +support you bought and paid (dd/mm/yyyy $date). +The invoice file is named facture_imapsync-${invoice}.pdf +This invoice is in PDF format, ready to be print. + +Should you need a hardcopy of this invoice, +I'll send it to you upon request by regular mail. + +As the law requires, this numeric invoice PDF file +is signed with my private gpg key. + +The resulting gpg signature is in the file named +facture_imapsync-${invoice}.pdf.asc +you will also find in the attachment. + +You can check I (Gilles LAMIRAL) really did generate +this invoice with the following command line: + + gpg --verify facture_imapsync-${invoice}.pdf.asc facture_imapsync-${invoice}.pdf + +or any other gpg graphical tool. + +Once more, thank you for buying imapsync support. + +Any feedback is welcome. + +-- +Best Regards, 09 51 84 42 42 +Gilles Lamiral. France, Baulon (35580) 06 20 79 76 06 +} ; + + + + + my $message_body_blabla = qq{ +Here is the fingerprint of my public key +pub 1024D/FDA2B3DC 2002-05-08 + Key fingerprint = 7906 F53D 0D62 0C67 304A 4CF0 6928 869B FDA2 B3DC +uid Gilles LAMIRAL +sub 1024g/A2C4CB42 2002-05-08 + +Of course the verification doesn't prove anything until +all the following conditions are met: +- you met me, +- I agree that the fingerprint above is really mine +- I prove I'm Gilles LAMIRAL with an official paper. + +Normally we won't have to verify anything unless +I disagree with this invoice and the payment +you made for imapsync. +} ; + + my ( $message_header, $message_body ) ; + if ( 'support' eq $object_type ) { + $message_header = $message_header_support ; + $message_body = $message_body_support ; + }elsif ( 'software' eq $object_type ) { + $message_header = $message_header_software ; + $message_body = $message_body_software ; + } + return( $message_header, $message_body ) ; + +} + +sub write_csv_info { + + my( $dir_invoices, $invoice, $file_csv, $line_number, $line_csv ) = @_ ; + + open( CSVINFO, "> $dir_invoices/$invoice/csv_info.txt") or die ; + print CSVINFO join( "\n", $file_csv, $line_number, $line_csv ) ; + close( CSVINFO ) ; + +} + +sub invoice_sent { + + my ( $dir_invoices, $invoice, $email_address ) = @_ ; + + return( 1 ) if ( -f "$dir_invoices/$invoice/SENT_TO_$email_address" ) ; + return( 0 ) ; + +} + +sub write_email_message { + my ( $dir_invoices, $invoice, $message_header, $message_body, $email_address ) = @_ ; + + my $message_body_utf8 = to_utf8({ -string => $message_body, -charset => 'ISO-8859-1' }); + + mkdir( "$dir_invoices/$invoice" ) or die if ! -d "$dir_invoices/$invoice" ; + + open( HEADER, "> $dir_invoices/$invoice/facture_message_header.txt") or die ; + print HEADER $message_header ; + close( HEADER ) ; + + open( BODY, "> $dir_invoices/$invoice/facture_message_body.txt") or die ; + print BODY $message_body_utf8 ; + close( BODY ) ; + + open( ADDRESS, "> $dir_invoices/$invoice/email_address.txt") or die ; + print ADDRESS "$email_address\n" ; + close( ADDRESS ) ; +} + + +sub write_tex_variables_file { + my ( $dir_invoices, $invoice, $date_jjSmmSaaaa, $tex_variables_utf8 ) = @_ ; + + mkdir( "$dir_invoices/$invoice" ) or die if ! -d "$dir_invoices/$invoice" ; + open( FILE, "> $dir_invoices/$invoice/imapsync_var.tex") or die ; + print FILE $tex_variables_utf8 ; + close( FILE ) ; + + if ( ! -f "$dir_invoices/$invoice/imapsync_var_manual.tex" ) { + open( FILE, "> $dir_invoices/$invoice/imapsync_var_manual.tex") or die ; + print FILE "%% $0 created file +%% Can be used to override imapsync_var.tex definitions\n" ; + print FILE $tex_variables_utf8 ; + close( FILE ) ; + } + +} + +sub download_urls { + my $date_jjSmmSaaaa = shift ; + my $object_type = shift ; + + my $date_aaaa_mm_jj = date_aaaa_mm_jj( $date_jjSmmSaaaa ) ; + #print "$date_aaaa_mm_jj $date_jjSmmSaaaa $object_type\n" ; + my ( $urlSrc, $urlExe ) ; + + if ('2011_05_01' le $date_aaaa_mm_jj + and 'software' eq $object_type ) { + $urlSrc = 'http://ks.lamiral.info/imapsync/paypal_return.shtml' ; + $urlExe = '' ; + return( $urlSrc, $urlExe ) ; + } + + if ('2011_05_01' le $date_aaaa_mm_jj + and 'support' eq $object_type ) { + $urlSrc = 'http://ks.lamiral.info/imapsync/paypal_return_support.shtml' ; + $urlExe = '' ; + return( $urlSrc, $urlExe ) ; + } + + if ('2011_03_24' le $date_aaaa_mm_jj) { + $urlSrc = 'http://www.linux-france.org/prj/imapsync/paypal_return.shtml' ; + $urlExe = '' ; + return( $urlSrc, $urlExe ) ; + } + if ('2011_02_21' le $date_aaaa_mm_jj) { + $urlSrc = 'http://www.linux-france.org/depot/2011_02_21/OUMbo7/' ; + $urlExe = 'http://www.linux-france.org/depot/2011_02_21/rHSVNs/' ; + return( $urlSrc, $urlExe ) ; + } + if ('2011_01_18' le $date_aaaa_mm_jj) { + $urlSrc = 'http://www.linux-france.org/depot/2011_01_18/zPRRNt/' ; + $urlExe = 'http://www.linux-france.org/depot/2011_01_18/FO1QzG/' ; + return( $urlSrc, $urlExe ) ; + } + if ('2011_01_18' le $date_aaaa_mm_jj) { + $urlSrc = 'http://www.linux-france.org/depot/2010_11_28/SiNdlZ/' ; + $urlExe = 'http://www.linux-france.org/depot/2010_11_28/R3ZAyr/' ; + return( $urlSrc, $urlExe ) ; + } + $urlSrc = 'http://www.linux-france.org/depot/2010_11_08/X2PWMe/' ; + $urlExe = 'http://www.linux-france.org/depot/2010_11_08/ZZ7zSc/' ; + return( $urlSrc, $urlExe ) ; +} + +sub date_aaaa_mm_jj { + my $date_jjSmmSaaaa = shift ; + + if ( $date_jjSmmSaaaa =~ m{(\d\d)/(\d\d)/(\d\d\d\d)} ) { + my( $jj, $mm, $aaaa ) = ( $1, $2, $3 ) ; + return( join( '_', $aaaa, $mm, $jj ) ) ; + }else{ + return( '9999_12_31' ) ; + } +} + + +sub tva_line { + my( $Devise, $Montant2, $Pays, $Nom_Option_1, $Valeur_Option_1, $Titre_de_l_objet ) = @_ ; + my( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR ) = ( 0, 0, 0 ) ; + + my( $montant_HT_EUR_sup, $montant_TVA_EUR_sup ) = ( 0, 0 ) ; + + $Montant2 = $Montant2/$usdeur if 'USD' eq $Devise ; + + if ( 'imapsync' eq $Titre_de_l_objet + or 'imapsync.exe' eq $Titre_de_l_objet + or 'imapsync source' eq $Titre_de_l_objet + or 'imapsync source code' eq $Titre_de_l_objet + + ) { + if ( + ( 'imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 ) + or + ( 'France' eq $Pays ) + ) { + $montant_HT_EUR_ass = $Montant2 / 1.196 ; + $montant_TVA_EUR = $Montant2 / 1.196 * 0.196 ; + $debug_dev and print "$Montant2 $Pays $Valeur_Option_1\n" ; + }else{ + $montant_HT_EUR_exo = $Montant2 ; + } + } + + if ( 'imapsync support' eq $Titre_de_l_objet ) { + #print "ZZZZ $Titre_de_l_objet $Montant2\n" ; + $montant_HT_EUR_sup = $Montant2 / 1.196 ; + $montant_TVA_EUR_sup = $Montant2 / 1.196 * 0.196 ; + } + + + return( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR, $montant_HT_EUR_sup, $montant_TVA_EUR_sup ) ; +} + + + +sub tva_stuff { + my( $clientTypeEN, $Pays, $Hors_taxe, $Devise, $Titre_de_l_objet ) = @_ ; + + my $priceTTCusd = '' ; + $Hors_taxe =~ s{,}{.} ; + + if ( $Devise eq 'USD' ) { + $priceTTCusd = "(usd $Hors_taxe)" ; + $Hors_taxe = ( $Hors_taxe/$usdeur ) ; + } + + my ( + $priceHT, + $tvaFR, + $tvaEN, + $priceTVA, + $priceTTC, + $messageTVAFR, + $messageTVAEN, + ) ; + + if ( ( 'individual' eq $clientTypeEN) + or + ( 'France' eq $Pays ) + or + ( 'imapsync support' eq $Titre_de_l_objet ) + ) { + $priceHT = sprintf('%2.2f', $Hors_taxe/1.196) ; + $tvaFR = '19,60\%'; + $tvaEN = ''; + $priceTVA = sprintf('%2.2f', $Hors_taxe/1.196*0.196) ; + $priceTTC = sprintf('%2.2f', $Hors_taxe) ; + $messageTVAFR = ''; + $messageTVAEN = ''; + }else{ + $priceHT = sprintf('%2.2f', $Hors_taxe) ; + $tvaFR = 'néant'; + $tvaEN = '(none)'; + $priceTVA = 0 ; + $priceTTC = $priceHT; + $messageTVAFR = 'Exonération de TVA, article 259 B-1 du Code Général des Impôts'; + $messageTVAEN = '(VAT tax-exempt, article 259 B-1 French General Tax Code)'; + } + foreach my $price ( $priceHT, $priceTVA, $priceTTC, $priceTTCusd ) { + #print "[$price]\n" ; + $price =~ s{\.}{, } ; + } + return( + $priceHT, + $tvaFR, + $tvaEN, + $priceTVA, + $priceTTC, + $messageTVAFR, + $messageTVAEN, + $priceTTCusd + ) ; +} + +sub client_type { + my ( $Nom_Option_1, $Valeur_Option_1 ) = @_ ; + + my ( $clientTypeEN, $clientTypeFR ) = ( 'professional', 'professionnel' ) ; + + if ('imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 ) { + $clientTypeEN = 'individual' ; + $clientTypeFR = 'individuel' ; + }elsif ('imapsync usage' eq $Nom_Option_1 and 'professional' eq $Valeur_Option_1 ) { + $clientTypeEN = 'professional' ; + $clientTypeFR = 'professionnel' ; + } + return( $clientTypeEN, $clientTypeFR ) ; +} + +sub build_address { + my( + $Nom, + $Adresse_1, + $Adresse_2_district_quartier, + $Ville, + $Code_postal, + $Etat_Province, + $Pays, + ) = @_ ; + + my $addr = " +=========================================================== +Nom $Nom +Adresse_1 $Adresse_1 +Adresse_2_district_quartier $Adresse_2_district_quartier +Ville Code_postal $Ville $Code_postal +Etat_Province $Etat_Province +Pays $Pays +" ; + #print $addr ; + + my @address ; + $Nom = '' if ( $Nom =~ m/^\s+$/ ) ; + my( $Nom1, $Nom2 ) = cut( $Nom, 42 ) ; + push( @address, $Nom1 ) if $Nom1 ; + #push( @address, $Nom2 ) if $Nom2 ; + push( @address, $Adresse_1 ) if $Adresse_1 ; + push( @address, $Adresse_2_district_quartier ) if $Adresse_2_district_quartier ; + push( @address, "$Ville $Code_postal" ) if ( $Ville or $Code_postal ); + push( @address, $Etat_Province ) if $Etat_Province ; + push( @address, $Pays, ) if $Pays ; + + + my $clientAdrA = shift( @address ) || '' ; + my $clientAdrB = shift( @address ) || '' ; + my $clientAdrC = shift( @address ) || '' ; + my $clientAdrD = shift( @address ) || '' ; + my $clientAdrE = shift( @address ) || '' ; + my $clientAdrF = shift( @address ) || '' ; + +$addr = " +[$clientAdrA] +[$clientAdrB] +[$clientAdrC] +[$clientAdrD] +[$clientAdrE] +[$clientAdrF] +"; + #print $addr ; + + return( + $clientAdrA, + $clientAdrB, + $clientAdrC, + $clientAdrD, + $clientAdrE, + $clientAdrF, + ) ; +} + + +sub half { + my $string = shift ; + my $half = int( lenght( $string ) / 2 ) ; + # TO BE DONE + +} + +sub tests_half { + my( $aa, $bb ) = half( 'aa bb' ) ; + ok( 'aa' eq $aa, 'half: aa' ) ; + ok( 'bb' eq $bb, 'half: bb' ) ; +} + +sub cut { + my $string = shift ; + my $offset = shift ; + + return( $string, '' ) if length( $string ) < $offset ; + my $first = substr( $string, 0, $offset ) ; + my $last = substr( $string, $offset ) ; + return( $first, $last ) ; +} + +sub tests_cut { + my( $aa, $bb ) = cut("123456789", 4 ) ; + ok( '1234' eq $aa, 'cut 123456789 4 => first 1234' ) ; + ok( '56789' eq $bb, 'cut 123456789 4 => last 56789' ) ; +} diff --git a/W/paypal_reply/paypal_build_invoices b/W/paypal_reply/paypal_build_invoices index 7d17cc5..53dba5e 100755 --- a/W/paypal_reply/paypal_build_invoices +++ b/W/paypal_reply/paypal_build_invoices @@ -1,6 +1,6 @@ #!/bin/sh -# $Id: paypal_build_invoices,v 1.24 2012/01/28 02:19:43 gilles Exp gilles $ +# $Id: paypal_build_invoices,v 1.26 2012/02/24 12:32:56 gilles Exp gilles $ # usage: sh paypal_build_invoices /g/var/paypal_invoices/???? @@ -23,6 +23,7 @@ set -x #/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 1185 /g/paypal/paypal_2011_11_complet.csv #/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 1263 /g/paypal/paypal_2011_12_complet.csv /g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 1335 /g/paypal/paypal_2012_01_complet.csv +/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 1417 /g/paypal/paypal_2012_02_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 147 /g/paypal/paypal_2010_11_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 214 /g/paypal/paypal_2010_12_complet.csv @@ -38,6 +39,7 @@ set -x : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 1185 /g/paypal/paypal_2011_11_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 1263 /g/paypal/paypal_2011_12_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 1335 /g/paypal/paypal_2012_01_complet.csv +: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 1417 /g/paypal/paypal_2012_02_complet.csv set +x # La totale diff --git a/imapsync b/imapsync index e390dfc..ed22fd2 100755 --- a/imapsync +++ b/imapsync @@ -20,7 +20,7 @@ Synchronise mailboxes between two imap servers. Good at IMAP migration. More than 44 different IMAP server softwares supported with success. -$Revision: 1.484 $ +$Revision: 1.487 $ =head1 SYNOPSIS @@ -519,7 +519,7 @@ Entries for imapsync: Feedback (good or bad) will often be welcome. -$Id: imapsync,v 1.484 2012/02/07 00:19:33 gilles Exp gilles $ +$Id: imapsync,v 1.487 2012/02/29 05:29:21 gilles Exp gilles $ =cut @@ -636,7 +636,7 @@ my( # global variables initialisation -$rcs = '$Id: imapsync,v 1.484 2012/02/07 00:19:33 gilles Exp gilles $ '; +$rcs = '$Id: imapsync,v 1.487 2012/02/29 05:29:21 gilles Exp gilles $ '; $total_bytes_transferred = 0; $total_bytes_skipped = 0; @@ -1377,7 +1377,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) { my $h2_msg = $cache_1_2_ref->{ $h1_msg } ; $debugcache and print "cache messages update flags $h1_msg->$h2_msg\n"; sync_flags( $h1_fold, $h1_msg, $h2_fold, $h2_msg, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) ; - my $h1_size = $h1_fir_ref->{ $h1_msg }->{ 'RFC822.SIZE' } ; + my $h1_size = $h1_fir_ref->{ $h1_msg }->{ 'RFC822.SIZE' } || 0 ; $total_bytes_skipped += $h1_size; $nb_msg_skipped += 1; } @@ -1399,7 +1399,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) { unless($dry) { $imap2->expunge() }; } -$debug and print "Time: ", timenext(), " s\n"; + $debug and print "Time: ", timenext(), " s\n"; } sub total_bytes_max_reached { @@ -1868,8 +1868,8 @@ sub banner_imapsync { my @argv_copy = @_; my $banner_imapsync = join("", '$RCSfile: imapsync,v $ ', - '$Revision: 1.484 $ ', - '$Date: 2012/02/07 00:19:33 $ ', + '$Revision: 1.487 $ ', + '$Date: 2012/02/29 05:29:21 $ ', "\n",localhost_info(), "\n", "Command line used:\n", "$0 ", command_line_nopassword(@argv_copy), "\n", @@ -2874,14 +2874,18 @@ sub tests_cache_map { } -sub get_cache { +sub get_cache { $debugcache and print "Entering get_cache\n"; my ( $cache_dir, $h1_msgs_ref, $h2_msgs_ref, $h1_msgs_all_hash_ref, $h2_msgs_all_hash_ref ) = @_; -d $cache_dir or return( undef ); # exit if cache directory doesn't exist - $debugcache and print "cache_dir: $cache_dir\n"; + $debugcache and print "cache_dir : $cache_dir\n"; - $cache_dir =~ s{\\}{\\\\}g; + #$cache_dir =~ s{\\}{\\\\}g; + $cache_dir =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\\])/\\$1/g ; + + $debugcache and print "cache_dir fix: $cache_dir\n"; + my @cache_files = bsd_glob( "$cache_dir/*" ) ; #$debugcache and print "cache_files: [@cache_files]\n"; @@ -3312,7 +3316,7 @@ sub stats { my $timestart_str = localtime( $timestart ) ; my $timeend_str = localtime( $timeend ) ; - my $memory_consumption = memory_consumption(); + my $memory_consumption = memory_consumption( ) || 0 ; my $memory_ratio = ($max_msg_size_in_bytes) ? sprintf('%.1f', $memory_consumption / $max_msg_size_in_bytes) : "NA"; @@ -3345,7 +3349,7 @@ sub stats { print "Reconnections to host2 : $host2_reconnect_count\n"; printf ("Memory consumption : %.1f MB\n", $memory_consumption / 1024 / 1024); print "Biggest message : $max_msg_size_in_bytes bytes\n"; - print "Memory/biggest message ratio : $memory_ratio\n"; +# print "Memory/biggest message ratio : $memory_ratio\n"; print "Detected $nb_errors errors\n\n"; print $warn_release, "\n"; @@ -3670,7 +3674,7 @@ sub check_last_release { } sub imapsync_version { - my $rcs = '$Id: imapsync,v 1.484 2012/02/07 00:19:33 gilles Exp gilles $ '; + my $rcs = '$Id: imapsync,v 1.487 2012/02/29 05:29:21 gilles Exp gilles $ '; $rcs =~ m/,v (\d+\.\d+)/; my $VERSION = ($1) ? $1: "UNKNOWN"; return($VERSION); @@ -3973,7 +3977,7 @@ EOF sub memory_consumption { # memory consumed by imapsync until now in bytes - return((memory_consumption_of_pids())[0]); + return( ( memory_consumption_of_pids( ) )[0] ); } sub memory_consumption_of_pids { @@ -4253,16 +4257,16 @@ sub list_folders_in_2_not_in_1 { return( reverse @h2_folders_not_in_1 ); } -sub delete_folders_in_2_not_in_1 { +sub delete_folders_in_2_not_in_1 { my $dry_message = ''; $dry_message = "\t(not really since --dry mode)" if $dry; foreach my $folder (@h2_folders_not_in_1) { - if ( defined($delete2foldersonly) and eval("\$folder !~ $delete2foldersonly" ) ) { + if ( defined( $delete2foldersonly ) and eval( "\$folder !~ \$delete2foldersonly" ) ) { print "Not deleting $folder because of --delete2foldersonly $delete2foldersonly\n"; next; } - if ( defined($delete2foldersbutnot) and eval("\$folder =~ $delete2foldersbutnot" ) ) { + if ( defined( $delete2foldersbutnot ) and eval( "\$folder =~ \$delete2foldersbutnot" ) ) { print "Not deleting $folder because of --delete2foldersbutnot $delete2foldersbutnot\n"; next; } diff --git a/index.shtml b/index.shtml index 2768f25..193615c 100644 --- a/index.shtml +++ b/index.shtml @@ -5,7 +5,7 @@ Imapsync: an IMAP migration tool ( release <!--#exec cmd="cat VERSION"--> ) - + @@ -168,7 +168,7 @@ See file.txt example for batch massive migrat

Buy imapsync source code

-

Buy latest imapsync Perl source code for 30 EUR +

Buy latest imapsync Perl source code for 42 EUR

@@ -178,7 +178,7 @@ See file.txt example for batch massive migrat

-30 EUR is equal to around 40 USD, no problem to pay in USD (or any currency) with paypal: +42 EUR is equal to around 54 USD, no problem to pay in USD (or any currency) with paypal:

@@ -233,7 +233,7 @@ name="submit" alt="PayPal - The safer, easier way to pay online!"/>

Struggle free from source code and Perl installation by
-buying the latest win32 standalone imapsync.exe for 30 EUR +buying the latest win32 standalone imapsync.exe for 42 EUR

@@ -244,7 +244,7 @@ buying the latest win32 standalone imapsync.exe for 30 EUR

-30 EUR is equal to around 40 USD, no problem to pay in USD (or any currency) with paypal: +42 EUR is equal to around 54 USD, no problem to pay in USD (or any currency) with paypal:

@@ -476,10 +476,12 @@ Prices are given par mailbox and may be outdated (december 2011).


@@ -508,7 +510,7 @@ alt="Viewable With Any Browser" /> This document last modified on -($Id: index.shtml,v 1.109 2012/02/07 10:54:11 gilles Exp gilles $) +($Id: index.shtml,v 1.112 2012/02/20 18:23:06 gilles Exp gilles $)

diff --git a/test2.bat b/test2.bat index 8557d39..203a20c 100755 --- a/test2.bat +++ b/test2.bat @@ -1,5 +1,5 @@ -REM $Id: test2.bat,v 1.7 2012/01/08 06:39:12 gilles Exp gilles $ +REM $Id: test2.bat,v 1.8 2012/02/25 14:42:23 gilles Exp gilles $ cd C:\msys\1.0\home\Admin\imapsync REM perl ./imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --delete2 --expunge2 --folder INBOX @@ -26,3 +26,6 @@ REM --host2 imap.side2.org --user2 %%I --password2 %%J REM imapsync --host1 p --user1 tata --passfile1 secret.tata ^ REM --host2 p --user2 dollar --password2 "$%%&<>|^"^" --justlogin +imapsync --host1 p --user1 tata --passfile1 secret.tata ^ + --host2 p --user2 equal --password2 "==lalala" --justlogin --debugimap2 + diff --git a/tests.sh b/tests.sh index 96d9bb1..571de74 100644 --- a/tests.sh +++ b/tests.sh @@ -1,6 +1,6 @@ #!/bin/sh -# $Id: tests.sh,v 1.191 2012/02/07 09:27:17 gilles Exp gilles $ +# $Id: tests.sh,v 1.192 2012/02/25 14:41:47 gilles Exp gilles $ # Example 1: # CMD_PERL='perl -I./Mail-IMAPClient-3.25/lib' sh -x tests.sh @@ -1969,6 +1969,17 @@ ll_justlogin_dollar_char() { --justlogin } +ll_justlogin_equal_char() { + $CMD_PERL ./imapsync \ + --host1 $HOST1 --user1 tata \ + --passfile1 ../../var/pass/secret.tata \ + --host2 $HOST2 --user2 equal \ + --passfile2 ../../var/pass/secret.equal \ + --justlogin --debugimap2 +} + + + ll_usecache() { if can_send; then