#!/usr/bin/perl
# Umožňuje pořadatelům kontrolovat přihlášky před jejich importem do Accessu.
# Copyright © 2006-2011 Dan Zeman <zeman@ufal.mff.cuni.cz>
# Licence: GNU GPL

use utf8; # říct Perlu, že konstantní řetězce ve zdrojáku jsou v UTF
use DBI; # spolupráce se serverem MySQL
use lib '/s/w/lib/dan';
use lib '/s/w/lib/cgi/mso';
use lib '/s/w/lib/cgi/mso/vnitro';
use dancgi; # čtení parametrů z webu nebo z ARGV
use jazyky; # jazykové verze textů
use mso; # funkce pro generování stránek o olympiádě
binmode(STDOUT, ":utf8"); # říct Perlu, že UTF chceme i na výstupu

# Připojit se k databázi.
$databaze = mso::pripojit_se_k_databazi();

# Výchozí nastavení parametru. Muže být pořbito parametry z URL/ARGV.
mso::provest_vychozi_nastaveni_parametru(\%konfig, $databaze);
# Načíst parametry z URL.
dancgi::cist_parametry(\%konfig);
# Umožnit volat skript z příkazového řádku a předat parametry tam (např. perl prihlaseni.pl akce=caroly).
dancgi::rozebrat_parametry($ARGV[0], \%konfig);
if($konfig{jazyk} eq "")
{
    $konfig{jazyk} = "cs";
}
$jazyky::jazyk = $konfig{jazyk};



# Poslat MIME záhlaví dokumentu.
print("Content-Type: text/html; charset=utf-8\n\n");
# Poslat začátek stránky.
print <<EOF
<html>
  <head>
    <meta http-equiv="Content-Language" content="cs">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Přehled nových přihlášek</title>
  </head>
  <body>
  <h1>Přehled nových přihlášek</h1>
  <p>Následující tabulka obsahuje seznam osob automaticky uložených přihlašovacím formulářem.
     Pokud některá osoba odeslala několik přihlášek, objeví se v&nbsp;seznamu několikrát.
     U každé osoby může následovat jeden nebo několik záznamů nalezených v&nbsp;databázi,
     které se s&nbsp;osobou více či méně shodují.
     Zaškrtněte záznamy, které podle vás skutečně patří osobě, jež odeslala přihlášku.
     Potom stiskněte tlačítko <a href="#ulozit">Uložit</a> na konci stránky.
     Databáze na kub.cz si zapamatuje přihlášky, které jste přiřadili k&nbsp;nějakému záznamu,
     a zapamatuje si také ke kterému.
     Později budete moci takové přihlášky načíst do Accessu a trvale je přiřadit k&nbsp;dotyčné osobě.
     Pozor!
     Načtení přihlášek na akce nemá nic společného s&nbsp;údaji o osobě (jako je např. obec nebo e-mail).
     Pokud se tyto údaje v&nbsp;přihlášce liší od údajů uvedených u této osoby v&nbsp;databázi,
     a pokud se domníváte, že údaje z&nbsp;přihlášky jsou správné a údaje v&nbsp;databázi se mají opravit,
     musíte to udělat ručně.
     Mějte také na paměti, že zde porovnáváme přihlášky s&nbsp;databází <em>vyexportovanou</em>
     z&nbsp;Accessu na kub.cz.
     Pokud jste od posledního exportu prováděli v&nbsp;Accessu změny, toto porovnání nemusí být přesné.</p>
  <form action="prihlasky.pl" method=get>
EOF
;
# Získat z databáze přehled nových přihlášek.
# Načíst přihlášky, které ještě v Accessu nejsou, ale přihlašovací skript je uložil do MySQL.
my $prihlasky = mso::dotazat_se_databaze($databaze,
    'jmeno', 'prijmeni', 'obec', 'zeme', 'pohlavi', 'kategorie',
    'clenpaluba', 'clenscrabble', 'clendama', 'clendama2', 'clengo', 'clenothello', 'clenhadanka',
    'email', 'poznamka', 'cas_odeslani_access', 'vs', 'zaplaceno_dne', 'kod_osoby', 'osoby_auto ORDER BY zaplaceno_dne DESC, vs');
# Jestliže reagujeme na odeslání formuláře, zpracovat údaje.
if($konfig{zpracovat})
{
    zpracovat_udaje(\%konfig, $prihlasky);
}
# Vypsat přehled objednávek.
vypsat_prehled_prihlasek($prihlasky);
# Poslat konec stránky.
print <<EOF
  <input type=hidden name=zpracovat value="1">
  <a name="ulozit"><input type=submit name="ulozit" value="Uložit"></a>
  <p>Zpracované přihlášky (tj. takové, které už jste si načetli do Accessu) můžete odstranit
     z&nbsp;tohoto dočasného úložiště.
     Stisknutím následujícího tlačítka odstraníte ty přihlášky, které jsou nahoře zaškrtnuté.
     To znamená, že odstraníte příslušné záznamy z&nbsp;tabulky kub.cz/mso/osoby_auto
     a související záznamy z&nbsp;tabulky kub.cz/mso/prihlasky_auto.
     Záznamy z&nbsp;tabulky kub.cz/mso/osoby, které nahoře rovněž vidíte vedle zaškrtávátek,
     zůstanou nedotčeny, stejně jako záznamy z&nbsp;tabulky kub.cz/mso/prihlasky, tedy
     z&nbsp;trvalého úložiště přihlášek.</p>
  <a name="odstranit"><input type=submit name="odstranit" value="Odstranit zaškrtnuté"></a>
  </form>
  </body>
</html>
EOF
;



##############################################################################
# PODPROGRAMY
##############################################################################



#-----------------------------------------------------------------------------
# Vypíše přehled přihlášek.
#-----------------------------------------------------------------------------
sub vypsat_prehled_prihlasek
{
    my $prihlasky = shift;
    # Vypsat přihlášky seřazené vzestupně podle okamžiku přihlášení (seřazené jsme je už dostali z databáze).
    my $irstart = 0; # číslo řádku, kterým začneme (ty před ním přeskočíme)
    my $nrmax = 50; # maximální počet řádků, které zobrazíme
    $irstart = $konfig{irstart} if(defined($konfig{irstart}) && $konfig{irstart} =~ m/^[0-9]+$/);
    $nrmax = $konfig{nrmax} if(defined($konfig{nrmax}) && $konfig{nrmax} =~ m/^[1-9][0-9]*$/);
    printf("  <p>Zobrazuji nejvýše $nrmax řádků počínaje řádkem č. %d.</p>\n", $irstart+1);
    print("  <table border=\"0\">\n");
    my $i_radek = 0;
    my $preruseno = 0;
    foreach my $p (@{$prihlasky})
    {
        # Příliš dlouhý webový formulář může být moc velké sousto pro Firefox na Klářině notebooku.
        # Pokud je přihlášek moc, zobrazit jen začátek seznamu, po jeho zpracování se objeví zbytek.
        if($i_radek < $irstart)
        {
            $i_radek++;
            next;
        }
        if($i_radek >= $irstart+$nrmax)
        {
            $preruseno = 1;
            last;
        }
        my $tdatr = ++$i_radek % 2 ? " bgcolor=#D5D5D5" : " bgcolor=#E5E5E5";
        $tdatr .= " valign=top";
        print("    <tr>\n");
        print("      <td$tdatr><input type=checkbox name=\"$p->{vs}\" value=\"novy\"></td>\n");
        print("      <td$tdatr align=right>nový</td>\n");
        my $formdatum;
        my $formcas;
        if($p->{cas_odeslani_access} =~ m/(\d+)\.(\d+)\.(\d+)(?:\s+(\d+):(\d+):(\d+))?/)
        {
            $formdatum = sprintf("%d.%d.%d", $1, $2, $3);
            $formcas = sprintf("%d:%02d:%02d", $4, $5, $6);
        }
        else
        {
            $formdatum = $p->{cas_odeslani_access};
        }
        print("      <td$tdatr align=right>$formdatum</td>\n");
        print("      <td$tdatr align=right>$formcas</td>\n");
        my $cele_jmeno = "$p->{jmeno} $p->{prijmeni}";
        $cele_jmeno =~ s/^\s+//;
        $cele_jmeno =~ s/\s+/&nbsp;/g;
        $cele_jmeno =~ s/\s+$//;
        print("      <td$tdatr>$cele_jmeno</td>\n");
        print("      <td$tdatr>$p->{obec}</td>\n");
        print("      <td$tdatr>$p->{zeme}</td>\n");
        print("      <td$tdatr>$p->{email}</td>\n");
        print("      <td$tdatr>$p->{pohlavi}</td>\n");
        print("      <td$tdatr>$p->{kategorie}</td>\n");
        # Údaje o členství v organizacích seskupit do jedné buňky.
        my @clenstvi = map
        {
            if($_ eq "clenpaluba") { $_ = "Paluba" }
            elsif($_ eq "clenscrabble") { $_ = "ČAS" }
            elsif($_ eq "clendama") { $_ = "ČFD" }
            elsif($_ eq "clendama2") { $_ = "ČUD" }
            elsif($_ eq "clengo") { $_ = "ČAGo" }
            elsif($_ eq "clenothello") { $_ = "ČFO" }
            elsif($_ eq "clenhadanka") { $_ = "SČHaK" }
        }
        (grep{m/^clen/ && $p->{$_}}(keys(%{$p})));
        my $clenstvi;
        if(scalar(@clenstvi))
        {
            $clenstvi = "Člen ".join(", ", @clenstvi);
        }
        print("      <td$tdatr>$clenstvi</td>\n");
        print("      <td$tdatr>$p->{poznamka}</td>\n");
        print("      <td$tdatr>$p->{vs}</td>\n");
        print("      <td$tdatr>$p->{zaplaceno_dne}</td>\n");
        print("    </tr>\n");
        # Pokusit se tuto osobu najít v tabulce osob.
        my $nalezy = mso::najit_osobu($p, $databaze);
        foreach my $nalez (@{$nalezy})
        {
            print("    <tr>\n");
            my $checked = $p->{kod_osoby}==$nalez->{kod} ? " checked=\"1\"" : "";
            print("      <td$tdatr align=right><input type=checkbox name=\"$p->{vs}\" value=\"$nalez->{kod}\"$checked></td>\n");
            print("      <td$tdatr align=right>$nalez->{kod}</td>\n");
            print("      <td$tdatr></td>\n");
            print("      <td$tdatr></td>\n");
            $cele_jmeno = "$nalez->{jmeno} $nalez->{prijmeni}";
            $cele_jmeno =~ s/^\s+//;
            $cele_jmeno =~ s/\s+/&nbsp;/g;
            $cele_jmeno =~ s/\s+$//;
            print("      <td$tdatr>$cele_jmeno</td>\n");
            print("      <td$tdatr>$nalez->{obec}</td>\n");
            print("      <td$tdatr>$nalez->{zeme}</td>\n");
            print("      <td$tdatr>$nalez->{e_mail}</td>\n");
            print("      <td$tdatr>$nalez->{pohlavi}</td>\n");
            print("      <td$tdatr>$nalez->{kategorie}</td>\n");
            # Údaje o členství v organizacích seskupit do jedné buňky.
            my @clenstvi = map
            {
                if($_ eq "clen_paluba") { $_ = "Paluba" }
                elsif($_ eq "clen_scrabble") { $_ = "ČAS" }
                elsif($_ eq "clen_dama") { $_ = "ČFD" }
                elsif($_ eq "clen_dama2") { $_ = "ČUD" }
                elsif($_ eq "clen_go") { $_ = "ČAGo" }
                elsif($_ eq "clen_othello") { $_ = "ČFO" }
                elsif($_ eq "clen_hadanka") { $_ = "SČHaK" }
            }
            (grep{m/^clen_/ && $nalez->{$_}}(keys(%{$nalez})));
            my $clenstvi;
            if(scalar(@clenstvi))
            {
                $clenstvi = "Člen ".join(", ", @clenstvi);
            }
            print("      <td$tdatr>$clenstvi</td>\n");
            print("    </tr>\n");
        }
    }
    print("  </table>\n");
    if($preruseno)
    {
        print("<p><font color=red><b>Upozornění:</b> Nezpracovaných přihlášek bylo příliš mnoho. Abychom nespotřebovali všechny zdroje na vašem počítači, zobrazili jsme pouze začátek seznamu. Nedivte se proto, že až tyto přihlášky zpracujete, objeví se tu další!</font></p>\n");
    }
    my $irpredch = $irstart-$nrmax; $irpredch = 0 if($irpredch<0);
    my $predchozi = $irpredch<$irstart ? "<a href=\"prihlasky.pl?irstart=$irpredch&amp;nrmax=$nrmax\">Předchozí</a>" : 'Předchozí';
    my $irnasled = $irstart+$nrmax;
    my $nasledujici = $preruseno ? "<a href=\"prihlasky.pl?irstart=".($irstart+$nrmax)."&amp;nrmax=$nrmax\">Následující</a>" : 'Následující';
    print("<p>&lt;&lt;&lt; $predchozi | $nasledujici &gt;&gt;&gt;</p>\n");
}



#------------------------------------------------------------------------------
# Zpracuje údaje z vyplněného formuláře a uloží je do databáze.
#------------------------------------------------------------------------------
sub zpracovat_udaje
{
    my $konfig = shift; # odkaz na hash
    my $prihlasky = shift; # odkaz na pole hashů
    # Buď chceme uložit zobrazení variabilních symbolů na kódy osob, nebo chceme
    # záznamy, na kterých je toto zobrazení definováno, odstranit.
    if($konfig->{odstranit})
    {
        for(my $i = 0; $i<=$#{$prihlasky}; $i++)
        {
            my $p = $prihlasky->[$i];
            if($konfig->{$p->{vs}})
            {
                # Nejdříve odstranit související záznamy z tabulky prihlasky_auto.
                my $sql = "DELETE FROM prihlasky_auto WHERE datum_prihlasky = '$p->{cas_odeslani_access}';";
                $databaze->prepare($sql)->execute();
                # Odstranit hlavní záznam z tabulky osoby_auto.
                $sql = "DELETE FROM osoby_auto WHERE cas_odeslani_access = '$p->{cas_odeslani_access}' LIMIT 1;";
                $databaze->prepare($sql)->execute();
                # Odstranit záznam z paměti, aby se později nezobrazil.
                splice(@{$prihlasky}, $i--, 1);
            }
        }
    }
    else
    {
        # Ke každé přihlášce uložit kód osoby odpovídající jejímu variabilnímu symbolu.
        # Pokud jejímu variabilnímu symbolu žádný kód osoby neodpovídá, uložit nulu.
        foreach my $p (@{$prihlasky})
        {
            if($konfig->{$p->{vs}} eq "nový")
            {
                # Budeme chtít do databáze zkopírovat informace o osobě a posléze i její přihlášky.
                $p->{kod_osoby} = -1;
            }
            elsif($konfig->{$p->{vs}})
            {
                # K příslušnému kódu osoby do databáze budeme kopírovat pouze přihlášky.
                $p->{kod_osoby} = $konfig->{$p->{vs}};
            }
            else
            {
                # Zatím nebudeme chtít dělat nic.
                $p->{kod_osoby} = 0;
            }
            # Uložit přiřazení kódů osob variabilním symbolům do databáze.
            my $sql = "UPDATE osoby_auto SET kod_osoby = $p->{kod_osoby} WHERE vs = $p->{vs} LIMIT 1;";
            $databaze->prepare($sql)->execute();
        }
    }
}
