#!/usr/bin/perl
# Zobrazí objednávku z databáze. Přístup by měli mít jen zaměstnanci obchodu.
# Copyright © 2008-2013 Dan Zeman <zeman@ufal.mff.cuni.cz>
# 14.2.2008: vytvořeno
# 16.2.2009: odkaz pro snadnou kontrolu organizace podle iča
# 16.2.2009: je možné poznamenat, že objednávka byla uzavřena (vyřízena)
# 17.3.2009: je možné odeslat úvodní mail, že zboží máme skladem
# 18.11.2009: upravený úvodní mail pro objednávky na Palubu
# 5.12.2009: lze upravovat v databázi údaj o tom, které zboží v dané objednávce nemáme
# 6.5.2012: dospěla sem přestavba, nyní se pracuje s databází "obchod" (ale "hry" mohou být potřeba kvůli detailům o zboží)
# 18.10.2014: nyní je možné objednat doručení přes Uloženku

use utf8;
use DBI;
# Přidat Danovy sdílené knihovny. Skript běžící pod uživatelem apache by je jinak nenašel.
use lib '/home/dan/lib';
use dzcgi;
use sitesql;
use dzsql;
use mail;
use dbobj;
use objmail;
use cas;
use ascii;
# Přinutit Perl, aby UTF8 vypisoval jako UTF8 a nevymýšlel pro mě "vhodné" osmibitové kódování.
binmode(STDOUT, ':utf8');



# Zapamatovat si, kdy jsme s generováním stránky začali, abychom na konci mohli
# zjistit, jak dlouho nám to trvalo.
$starttime = time();



# Používání absolutních URL místo relativních údajně zvyšuje šance, že prohlížeč nepoužije cache.
my $urlbase = 'http://hrejsi.cz/cgi/hry/vnitro';
# Poslat MIME záhlaví dokumentu.
print("Content-Type: text/html; charset=utf-8\n\n");
# Přečíst parametry.
dzcgi::cist_parametry(\%konfig);
#dzcgi::cist_formular_post(\%konfig);
if(exists($konfig{post}))
{
    dzcgi::cist_formular_post(\%konfig);
}
# Kontrola parametrů: Jestliže nebylo zadáno číslo objednávky, nesmí být zadána akce.
# Domyslíme si sice číslo poslední objednávky, tu pak ale chceme jen zobrazit, rozhodně s ní nechceme provádět žádné akce.
unless($konfig{cislo}>0)
{
    $konfig{akce} = '';
}
# 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">
    <meta http-equiv="Cache-Control" content="no-cache" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Expires" CONTENT="0" /><!-- 0 is illegal timestamp, which means "now" -->
    <meta name="robots" content="noindex">
    <meta name="robots" content="noarchive">
    <title>Objednávka $konfig{cislo}</title>
  </head>
  <body>
EOF
;
# Ladění: vypsat parametry CGI.
if(0)
{
    print("<p>Za účelem ladění následuje výpis všech parametrů, které skript dostal.</p>\n");
    print("<table>\n");
    foreach my $klic (sort(keys(%konfig)))
    {
        print("<tr><td>$klic</td><td> = $konfig{$klic}</td></tr>\n");
    }
    print("</table>\n");
    print("<hr/>\n");
}
# Připojit se k databázím.
# $databaze ... obsahuje objednávky
# $hdb ... obsahuje katalog a ceník her
# $odb ... obsahuje katalog a ceník ostatního zboží
$databaze = sitesql::connect('obchod');
$hdb = sitesql::connect('hry');
$odb = $databaze;
# Načíst katalog zboží. Zejména potřebujeme ke kódům zboží názvy zboží.
$katalog = dbobj::nacist_katalog($hdb, $odb);
# Vytáhnout z databáze údaje o objednávce. Buď známe číslo objednávky, nebo chceme poslední objednávku.
$objednavka = dbobj::zjistit_objednavku($databaze, $katalog, $konfig{cislo});
# Pokud jsme dostali požadavek na změnu stavu objednávky, splnit ho.
akce($konfig{akce}, $objednavka);
# Akcí se mohly změnit údaje o objednávce v databázi, např. její stav.
# Správně by nám sice funkce akce() měla tyto změny zohlednit rovnou v hashi %{$objednavka}, na který jsme jí dali odkaz,
# ale raději na to nebudeme spoléhat a načteme objednávku z databáze znova předtím, než ji zobrazíme uživateli.
$objednavka = dbobj::zjistit_objednavku($databaze, $katalog, $konfig{cislo});
# Vypsat přehled objednávek.
vypsat_objednavku($objednavka);
# Zjistit, jak dlouho nám to trvalo, a vypsat to na konec stránky.
my $hlaseni = cas::sestavit_hlaseni_o_trvani_programu($starttime);
print("  <div align=right><address>$hlaseni</address></div>\n");
# Poslat konec stránky.
print <<EOF
  </body>
  <head>
    <!-- Tohle se doporučuje zopakovat na konci dokumentu, protože pro Internet Explorer může být
         na začátku příliš brzo, aby se vůbec zabýval cachí (dosud načtená část stránky mu ještě
         nezaplnila dost velkou část bufferu. -->
    <meta http-equiv="pragma" content="no-cache" />
  </head>
</html>
EOF
;



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



#-----------------------------------------------------------------------------
# Vygeneruje HTML s přehledem objednaného zboží.
#-----------------------------------------------------------------------------
sub sestavit_seznam_objednaneho_zbozi
{
    my $objednavka = shift;
    my $html;
    $html .= "<p><b>Objednané zboží:</b></p>\n";
    $html .= "<table>\n";
    $html .= "  <tr>\n";
    $html .= "    <th valign=top align=left>Hra</th>\n";
    $html .= "    <th valign=top align=left>Položka</th>\n";
    $html .= "    <th valign=top align=left>Počet</th>\n";
    $html .= "    <th valign=top align=left>Jednotková cena</th>\n";
    $html .= "    <th valign=top align=left>Cena</th>\n";
    $html .= "  </tr>\n";
    my $objzbozi = $objednavka->{zbozi};
    foreach my $polozka (@{$objzbozi})
    {
        $html .= "  <tr>\n";
        $html .= "    <td valign=top align=left><a href=\"../prodej.pl?odd=hry&amp;pohled=hra&amp;hra=$polozka->{kod_hry}\">$polozka->{nazev_hry}</a></td>\n";
        $html .= "    <td valign=top align=left>";
        if($polozka->{kod_zbozi} eq '')
        {
            $html .= "<font color=red>Varování: V&nbsp;databázi nám chybí kód objednaného zboží!</font>";
        }
        else
        {
            $html .= $polozka->{nazev};
        }
        $html .= "</td>\n";
        $html .= "    <td valign=top align=right>$polozka->{pocet}&nbsp;×&nbsp;</td>\n";
        $html .= "    <td valign=top align=right>$polozka->{jednotkova_cena}&nbsp;Kč&nbsp;=&nbsp;</td>\n";
        $html .= "    <td valign=top align=right>$polozka->{cena_celkem}&nbsp;Kč</td>\n";
        $html .= "  </tr>\n";
    }
    $html .= "  <tr><td valign=top align=left colspan=3><i>mezisoučet</i></td><td></td><td valign=top align=right>$objednavka->{mezisoucet}&nbsp;Kč</td></tr>\n";
    $html .= "  <tr><td valign=top align=left colspan=3><i>poštovné</i></td><td></td><td valign=top align=right>$objednavka->{postovne}&nbsp;Kč</td></tr>\n";
    $html .= "  <tr><td valign=top align=left colspan=3><i>množstevní sleva</i></td><td></td><td valign=top align=right>$objednavka->{mnozstevni_sleva}&nbsp;Kč</td></tr>\n";
    $html .= "  <tr><td valign=top align=left colspan=3><i><b>celkem</b></i></td><td></td><td valign=top align=right><b>$objednavka->{celkem}&nbsp;Kč</b></td></tr>\n";
    $html .= "</table>\n";
    return $html;
}



#-----------------------------------------------------------------------------
# Vygeneruje HTML s historií stavů objednávky.
#-----------------------------------------------------------------------------
sub sestavit_historii_stavu
{
    my $objednavka = shift;
    my $html;
    # Zjistit aktuální stav objednávky.
    my $stav = 'objednáno';
    my $objstavy = $objednavka->{stavy};
    if(scalar(@{$objstavy}))
    {
        $stav = $objstavy->[0]{novy_stav};
    }
    $html .= "      <p><b>Stav: $dbobj::stavy{$stav}</b></p>\n";
    # Sestavit historii změn stavů objednávky.
    push(@{$objstavy}, {'cas_zmeny' => $objednavka->{cas}, 'novy_stav' => 'objednáno'});
    $html .= "      <ul>\n";
    foreach my $zmena (@{$objstavy})
    {
        my $cas = $zmena->{cas_zmeny};
        $cas =~ m/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/;
        my $formdatum = sprintf("%d.%d.%d", $3, $2, $1);
        my $formcas = sprintf("%d:%02d:%02d", $4, $5, $6);
        $html .= "        <li>$formdatum $formcas $zmena->{novy_stav}</li>\n";
    }
    $html .= "      </ul>\n";
    return $html;
}



#-----------------------------------------------------------------------------
# Vygeneruje HTML s údaji o odeslané zásilce.
#-----------------------------------------------------------------------------
sub sestavit_udaje_o_zasilce
{
    my $objednavka = shift;
    my $html;
    if($objednavka->{datum_odeslani} ne '')
    {
        $html .= "<p><b>Odeslaná zásilka:</b></p>\n";
        my $pilne = $objednavka->{pilne} ? ' (PILNĚ)' : '';
        $html .= "      <p>Odesláno: $objednavka->{datum_odeslani}$pilne<br/>\n";
        my $url_sledovani = '';
        if($objednavka->{odber} eq 'ulozenka')
        {
            if($objednavka->{ulozenka_branches} =~ m/^dpd/)
            {
                $url_sledovani = "https://tracking.dpd.de/cgi-bin/delistrack?lang=cs&pknr=$objednavka->{podaci_cislo}";
            }
            else
            {
                $url_sledovani = "https://tracking.ulozenka.cz/$objednavka->{podaci_cislo}";
            }
        }
        elsif($objednavka->{odber} eq 'intime')
        {
            $url_sledovani = "http://www.intime.cz/track_and_trace";
        }
        elsif($objednavka->{odber} eq 'dpd')
        {
            $url_sledovani = "https://tracking.dpd.de/cgi-bin/delistrack?lang=cs&pknr=$objednavka->{podaci_cislo}";
        }
        else # posta, posta_na_postu
        {
            $url_sledovani = "http://www.ceskaposta.cz/cz/nastroje/sledovani-zasilky.php?barcode=$objednavka->{podaci_cislo}&locale=CZ&send.x=51&send.y=6&go=ok";
        }
        $html .= "         Podací číslo: <a href=\"$url_sledovani\">$objednavka->{podaci_cislo}</a><br/>\n";
        $html .= "         Hmotnost: $objednavka->{hmotnost}&nbsp;kg<br/>\n";
        $html .= "         Námi zaplacené poštovné: $objednavka->{zaplacene_postovne}&nbsp;Kč</p>\n";
    }
    return $html;
}



#-----------------------------------------------------------------------------
# Vygeneruje HTML s údaji o požadovaném způsobu placení a dodání apod.
#-----------------------------------------------------------------------------
sub sestavit_kontaktni_udaje
{
    my $objednavka = shift;
    my $html;
    my $skype = $objednavka->{telefon};
    $skype =~ s/[-\s\/\.]//g;
    if($skype !~ m/^\+/)
    {
        $skype = "+420".$skype;
    }
    $html .= "<p><b>Kontakty:</b><br>\n";
    $html .= "   E-mail: <a href=\"mailto:$objednavka->{email}\">$objednavka->{email}</a><br>\n";
    $html .= "   Telefon: <a href=\"skype:$skype\">$objednavka->{telefon}</a></p>\n";
    $html .= "<p><b>Dodací adresa:</b><br>\n";
    $html .= "   $objednavka->{cele_jmeno}<br/>\n";
    $html .= "   $objednavka->{ulice_a_dum}<br/>\n";
    $html .= "   $objednavka->{psc} $objednavka->{obec}</p>\n";
    if($objednavka->{odber} eq 'ulozenka')
    {
        $html .= "<p><b>Pobočka Uloženky:</b><br/>\n";
        $html .= "   <a href=\"$objednavka->{ulozenka_branches_link}\">$objednavka->{ulozenka_branches_name}</a></p>\n";
    }
    elsif($objednavka->{odber} eq 'intime')
    {
        $html .= "<p><b>Poštomat:</b><br/>\n";
        $html .= "   <a href=\"$objednavka->{ulozenka_branches_link}\">$objednavka->{ulozenka_branches_name}</a></p>\n";
    }
    elsif($objednavka->{odber} eq 'posta_na_postu')
    {
        $html .= "<p><b>Pobočka České pošty:</b><br/>\n";
        $html .= "   <a href=\"$objednavka->{ulozenka_branches_link}\">$objednavka->{ulozenka_branches_name}</a></p>\n";
    }
    if($objednavka->{varsymbol}>0)
    {
        $html .= "<p><b>Variabilní symbol:</b><br/>\n";
        $html .= "   $objednavka->{varsymbol}</p>\n";
    }
    return $html;
}



#-----------------------------------------------------------------------------
# Vygeneruje HTML s údaji o požadovaném způsobu dodání nebo odběru zboží.
#-----------------------------------------------------------------------------
sub sestavit_udaje_o_dodani
{
    my $objednavka = shift;
    my $html;
    $html .= "      <td>\n";
    if($objednavka->{odber} eq 'jenstejn')
    {
        $html .= "        <img src=\"/obr/obchod/jenstejn.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        JENŠTEJN\n";
    }
    elsif($objednavka->{odber} eq 'cm')
    {
        $html .= "        <img src=\"/obr/obchod/cerny_most.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        ČERNÝ MOST\n";
    }
    elsif($objednavka->{odber} eq 'paluba')
    {
        $html .= "        <img src=\"/obr/obchod/paluba.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        PALUBA\n";
    }
    elsif($objednavka->{odber} eq 'ulozenka')
    {
        $html .= "        <img src=\"/obr/obchod/ulozenka.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        ULOŽENKA\n";
    }
    elsif($objednavka->{odber} eq 'intime')
    {
        $html .= "        <img src=\"/obr/obchod/postomat.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        POŠTOMAT\n";
    }
    elsif($objednavka->{odber} eq 'posta_na_postu')
    {
        $html .= "        <img src=\"/obr/obchod/posta_na_postu.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        ZBOŽÍ POŠTOU BALÍK NA POŠTU\n";
    }
    elsif($objednavka->{odber} eq 'posta_do_ruky')
    {
        $html .= "        <img src=\"/obr/obchod/posta.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        ZBOŽÍ POŠTOU BALÍK DO RUKY\n";
    }
    elsif($objednavka->{odber} eq 'dpd')
    {
        $html .= "        <img src=\"/obr/obchod/dpd.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        ZBOŽÍ DPD NA ADRESU\n";
    }
    else
    {
        $html .= "        <img src=\"/obr/obchod/posta.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        ZBOŽÍ POŠTOU\n";
    }
    $html .= "      </td>\n";
    return $html;
}



#-----------------------------------------------------------------------------
# Vygeneruje HTML s údaji o požadovaném způsobu placení zboží.
#-----------------------------------------------------------------------------
sub sestavit_udaje_o_placeni
{
    my $objednavka = shift;
    my $html;
    $html .= "      <td>\n";
    if($objednavka->{platba} eq 'hotově')
    {
        if($objednavka->{odber} =~ m/^(paluba|cm|jenstejn)$/)
        {
            $html .= "        <img src=\"/obr/obchod/hotovost.png\">\n";
            $html .= "      </td>\n";
            $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
            $html .= "        PENÍZE HOTOVĚ\n";
        }
        else
        {
            if($objednavka->{odber} eq 'ulozenka')
            {
                $html .= "        <img src=\"/obr/obchod/ulozenka.png\">\n";
            }
            elsif($objednavka->{odber} eq 'intime')
            {
                $html .= "        <img src=\"/obr/obchod/postomat.png\">\n";
            }
            elsif($objednavka->{odber} eq 'dpd')
            {
                $html .= "        <img src=\"/obr/obchod/dpd.png\">\n";
            }
            else
            {
                $html .= "        <img src=\"/obr/obchod/posta.png\">\n";
            }
            $html .= "      </td>\n";
            $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
            $html .= "        PENÍZE DOBÍRKOU\n";
        }
    }
    else
    {
        $html .= "        <img src=\"/obr/obchod/prevod.png\">\n";
        $html .= "      </td>\n";
        $html .= "      <td style='font-size:x-large;font-weight:bold'>\n";
        $html .= "        PENÍZE PŘEVODEM\n";
    }
    $html .= "      </td>\n";
    return $html;
}



#-----------------------------------------------------------------------------
# Vygeneruje text, který si Klárka přes schránku zkopíruje do Corelu, aby
# mohla vytisknout fakturu, složenku, podací lístek a štítky na balík.
#-----------------------------------------------------------------------------
sub sestavit_text_pro_corel
{
    my $objednavka = shift;
    my $html;
    $html .= "      <h2>Corel</h2>\n";
    $html .= "      <pre>\n";
    $html .= "$objednavka->{email}\n";
    $html .= "$objednavka->{telefon}\n";
    $html .= "Poznámka 2: $objednavka->{poznamka2}\n" if($objednavka->{poznamka2});
    $html .= "Poznámka 1: $objednavka->{poznamka}\n" if($objednavka->{poznamka});
    $html .= "\n";
    # Dodací adresa.
    $html .= "$objednavka->{cele_jmeno}\n";
    $html .= "$objednavka->{ulice_a_dum}\n";
    $html .= "$objednavka->{psc} $objednavka->{obec}\n";
    $html .= "\n";
    # Na složenku.
    if($objednavka->{ico})
    {
        $html .= "IČO: $objednavka->{ico}\n";
    }
    # Způsob dopravy a případně pobočka Uloženky.
    $html .= "$objednavka->{odber}\n";
    if($objednavka->{odber} eq 'ulozenka')
    {
        $html .= "Uloženka: $objednavka->{ulozenka_branches_name}\n";
    }
    elsif($objednavka->{odber} eq 'intime')
    {
        $html .= "Poštomat: $objednavka->{ulozenka_branches_name}\n";
    }
    elsif($objednavka->{odber} eq 'posta_na_postu')
    {
        $html .= "Pošta: $objednavka->{ulozenka_branches_name}\n";
    }
    # Placení.
    $html .= "$objednavka->{varsymbol}\n";
    if($objednavka->{platba} eq 'hotově')
    {
        if($objednavka->{odber} =~ m/^(paluba|cm|jenstejn)$/)
        {
            $html .= "HOTOVĚ\n";
        }
        else
        {
            $html .= "DOBÍRKOU\n";
        }
    }
    else
    {
        $html .= "PŘEVODEM\n";
    }
    $html .= "\n";
    # Datum zdanitelného plnění odpovídá přepnutí do stavu "máme" nebo "zaplaťte".
    my $objstavy = $objednavka->{stavy};
    foreach my $zmena (@{$objstavy})
    {
        if($zmena->{novy_stav} =~ m/^(zaplaťte|máme)$/)
        {
            my $cas = $zmena->{cas_zmeny};
            $cas =~ m/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/;
            my $formdatum = sprintf("%d.%d.%d", $3, $2, $1);
            $html .= "$formdatum\n\n";
            last;
        }
    }
    # Cena číslem a slovy.
    $html .= "Cena: $objednavka->{celkem}\n";
    $html .= zjistit_cislo_slovy($objednavka->{celkem})."Kč\n\n";
    my $objzbozi = $objednavka->{zbozi};
    foreach my $polozka (@{$objzbozi})
    {
        $html .= "$polozka->{nazev}\n";
    }
    $html .= "\n";
    foreach my $polozka (@{$objzbozi})
    {
        $html .= "\t$polozka->{pocet}\t";
        $html .= "$polozka->{jednotkova_cena}&nbsp;Kč\t";
        $html .= "$polozka->{cena_celkem}&nbsp;Kč\n";
    }
    $html .= "mezisoučet $objednavka->{mezisoucet}&nbsp;Kč\n" if(scalar(@{$objzbozi})>1);
    $html .= "poštovné $objednavka->{postovne}&nbsp;Kč\n";
    $html .= "množstevní sleva $objednavka->{mnozstevni_sleva}&nbsp;Kč\n" if($objednavka->{mnozstevni_sleva});
    $html .= "celkem $objednavka->{celkem}&nbsp;Kč\n";
    $html .= "      </pre>\n";
    return $html;
}



#-----------------------------------------------------------------------------
# Vypíše číslo slovy.
#-----------------------------------------------------------------------------
sub zjistit_cislo_slovy
{
    my $n = shift;
    return $n if($n>=10000); # větší čísla zatím nejsou implementována
    my $slovo;
    my @cislice = split(//, $n);
    my $c = pop(@cislice);
    my @jedenactky = qw(deset jedenáct dvanáct třináct čtrnáct patnáct šestnáct sedmnáct osmnáct devatenáct);
    my @jednotky = qw(nula jedna dvě tři čtyři pět šest sedm osm devět);
    if($cislice[-1]==1)
    {
        $slovo = $jedenactky[$c];
    }
    elsif($c>0)
    {
        $slovo = $jednotky[$c];
    }
    $c = pop(@cislice);
    my @desitky = qw(nula deset dvacet třicet čtyřicet padesát šedesát sedmdesát osmdesát devadesát);
    if($c>1)
    {
        $slovo = $desitky[$c].$slovo;
    }
    $c = pop(@cislice);
    my @stovky = qw(nula jednosto dvěstě třista čtyřista pětset šestset sedmset osmset devětset);
    if($c>0)
    {
        $slovo = $stovky[$c].$slovo;
    }
    $c = pop(@cislice);
    my @tisice = qw(nula jedentisíc dvatisíce třitisíce čtyřitisíce pěttisíc šesttisíc sedmtisíc osmtisíc devěttisíc);
    if($c>0)
    {
        $slovo = $tisice[$c].$slovo;
    }
    $slovo =~ s/^(.)/\u$1/;
    return $slovo;
}



#-----------------------------------------------------------------------------
# Vypíše údaje o objednávce.
#-----------------------------------------------------------------------------
sub vypsat_objednavku
{
    my $objednavka = shift;
    my $cislo_objednavky = $objednavka->{cas};
    my $cas = $objednavka->{cas};
    # V záhlaví nabídnout odkaz zpět na seznam nevyřízených objednávek.
    my @odkazy;
    my $filtr = $objednavka->{odber} eq 'paluba' ? '?filtr=paluba' : '';
    push(@odkazy, "<a href=\"$urlbase/objednavky.pl$filtr\">Zpět na seznam</a>");
    if($konfig{akce})
    {
        # Jestliže jsme se sem dostali postem z formuláře, umožnit přechod do obyčejného zobrazení objednávky,
        # které se dá obnovit bez opakovaného odeslání formuláře.
        push(@odkazy, "<a href=\"$urlbase/objednavka.pl?cislo=$objednavka->{cas}\">Skrýt zprávu o akci $konfig{akce}</a>");
    }
    my $odkazy = join(' | ', @odkazy);
    print("<p>$odkazy</p>\n");
    $objednavka->{cele_jmeno} = "$objednavka->{jmeno} $objednavka->{prijmeni}";
    $objednavka->{cele_jmeno} =~ s/^\s+//;
    $objednavka->{cele_jmeno} =~ s/\s+/&nbsp;/g;
    $objednavka->{cele_jmeno} =~ s/\s+$//;
    print("<h1>$objednavka->{cele_jmeno} ($konfig{cislo})</h1>\n");
    # Vedle sebe vypsat seznam objednaného zboží, historii stavů objednávky a (pokud jsou k dispozici) údaje o námi odeslané zásilce.
    print("<table border=1>\n");
    print("  <tr>\n");
    print("    <td valign=top>\n");
    print(sestavit_seznam_objednaneho_zbozi($objednavka));
    print("    </td>\n");
    print("    <td valign=top>\n");
    print(sestavit_historii_stavu($objednavka));
    print("    </td>\n");
    my $zasilka = sestavit_udaje_o_zasilce($objednavka);
    if($zasilka)
    {
        print("    <td valign=top>\n");
        print($zasilka);
        print("    </td>\n");
    }
    print("  </tr>\n");
    print("</table>\n");
    # Umožnit změnu stavu objednávky.
    print(formular_akce($objednavka));
    # Vypsat údaje o objednávce.
    print("<table>\n");
    print("<tr>\n");
    print("<td valign=top>\n");
    print(sestavit_kontaktni_udaje($objednavka));
    print("</td>\n");
    print("<td valign=top>\n");
    print("  <table>\n");
    print("    <tr>\n");
    print(sestavit_udaje_o_dodani($objednavka));
    print("      <td rowspan='3'>\n");
    if($konfig{akce} eq 'Upravit poznámku')
    {
        print("        <p>Poznámka obchod:</p>\n");
        print("        <form action='objednavka.pl'>\n");
        print("          <input type=hidden name=cislo value='$objednavka->{cas}' />\n");
        print("          <textarea name=poznamka_obchod rows='10' cols='60'>$objednavka->{poznamka_obchod}</textarea><br/>\n");
        print("          <input type=submit name=akce value='Uložit poznámku' />\n");
        print("        </form>\n");
    }
    else
    {
        print("        <p>Poznámka obchod:</p>\n");
        print("        <pre>$objednavka->{poznamka_obchod}</pre>\n");
        print("        <form action='objednavka.pl'>\n");
        print("          <input type=hidden name=cislo value='$objednavka->{cas}' />\n");
        print("          <input type=submit name=akce value='Upravit poznámku' />\n");
        print("        </form>\n");
    }
    print("      </td>\n");
    print("    </tr>\n");
    print("    <tr>\n");
    print(sestavit_udaje_o_placeni($objednavka));
    print("    </tr>\n");
    print("    <tr><td></td><td style='font-size:x-large;font-weight:bold'>$objednavka->{celkem}&nbsp;Kč</td></tr>\n");
    my $dulezite;
    $dulezite .= ' SMS' if($objednavka->{sms});
    $dulezite .= ' '.uc($objednavka->{rychlost}) if($objednavka->{rychlost});
    if($dulezite)
    {
        print("    <tr><td></td><td style='font-size:x-large;font-weight:bold'>$dulezite</td></tr>\n");
    }
    print("  </table>\n");
    print("  <p>Kontrola: $objednavka->{odber} $objednavka->{ulozenka_branches} $objednavka->{platba}<br/>\n");
    print("     Poznámka: $objednavka->{poznamka}<br/>\n");
    print("     Poznámka 2: $objednavka->{poznamka2}<br/>\n");
    print("     Sleva pro dětské organizace: $objednavka->{sleva_org_deti}<br/>\n");
    print("     Slevový kód: $objednavka->{slevkod}</p>\n");
    if($objednavka->{ico})
    {
        my $url = 'http://wwwinfo.mfcr.cz/cgi-bin/ares/ares_es.cgi?jazyk=cz&obch_jm=&ico='.$objednavka->{ico}.'&cestina=cestina&obec=&k_fu=&maxpoc=200&ulice=&cis_or=&cis_po=&setrid=ZADNE&pr_for=&okec=&okec_h=&xml=1&filtr=0&nace=&nace_h=';
        print("  <p>IČO: <a href=\"$url\">$objednavka->{ico}</a></p>\n");
    }
    print("</td>\n");
    print("</tr>\n");
    print("</table>\n");
    print("<h2>CSV pro Uloženku</h2>\n<pre>", dbobj::sestavit_csv_pro_ulozenku($objednavka, $header), "</pre>\n");
    print(sestavit_text_pro_corel($objednavka));
}



#-----------------------------------------------------------------------------
# Vygeneruje formulář s tlačítky pro akce, které lze s objednávkou provést.
#-----------------------------------------------------------------------------
sub formular_akce
{
    my $objednavka = shift;
    # Sestavit seznam ovládacích prvků (tlačítek). Některá tlačítka jsou povolená jen v některých stavech.
    my @prvky;
    my $chyba;
    my $disabled;
    push(@prvky, "<input type=hidden name=cislo value=\"$objednavka->{cas}\" />");
    # Tlačítko Máme připraví mail pro zákazníka, že zboží máme skladem a brzy mu ho odešleme (resp. dali jsme mu ho na Palubě do rezervací).
    proverit_pozadavek_na_zmenu_stavu($objednavka->{cas}, 'máme', \$chyba, \$disabled);
    push(@prvky, "<input type=submit name=akce value=\"Máme\"$disabled />");
    # Tlačítko Nemáme otevře formulář, ve kterém lze poznamenat, které zboží nám chybí k pokrytí objednávky.
    # Potom připraví mail pro zákazníka, že část zboží nemáme skladem.
    proverit_pozadavek_na_zmenu_stavu($objednavka->{cas}, 'nemáme', \$chyba, \$disabled);
    push(@prvky, "<input type=submit name=akce value=\"Nemáme\"$disabled />");
    # Tlačítko Peníze přišly připraví mail pro zákazníka, že jeho platba předem dorazila a že mu zboží brzy odešleme.
    proverit_pozadavek_na_zmenu_stavu($objednavka->{cas}, 'zaplaceno', \$chyba, \$disabled);
    push(@prvky, "<input type=submit name=akce value=\"Peníze přišly\"$disabled />");
    # Tlačítko Odeslali jsme připraví mail pro zákazníka, že jsme zboží odeslali, kdy asi dorazí a kde se dá zásilka sledovat.
    proverit_pozadavek_na_zmenu_stavu($objednavka->{cas}, 'odesláno', \$chyba, \$disabled);
    push(@prvky, "<input type=submit name=akce value=\"Odeslali jsme\"$disabled />");
    # Tlačítko Mail připraví libovolný jiný mail pro zákazníka, aniž by současně změnilo stav objednávky.
    push(@prvky, "<input type=submit name=akce value=\"Mail\" />");
    # Tlačítko Uzavřít označí objednávku za vyřízenou (zákazník už zboží obdržel, nám přišly peníze z dobírky apod.) Neposílá mail.
    push(@prvky, "<input type=submit name=akce value=\"Uzavřít\" />");
    # Seznam stavů pro nízkoúrovňové tlačítko Změnit stav.
    my $vyber_stavu = "  <select name=stav>\n";
    $vyber_stavu .= join('', map {"    <option value=\"$_\">$_</option>\n"} (@dbobj::poradi_stavu));
    $vyber_stavu .= "  </select>\n";
    # Vygenerovat formulář s tlačítky popsanými výše.
    my $html;
    $html .= "<form method=get action=\"objednavka.pl\">\n";
    $html .= "  <p>".join("\n  ", @prvky)."</p>\n";
    $html .= "  <p>Chcete-li pouze změnit stav objednávky bez odeslání odpovídajícího mailu zákazníkovi (protože jste ho poslali ručně jindy), můžete to udělat zde: \n";
    $html .= $vyber_stavu;
    $html .= "  <input type=submit name=akce value=\"Změnit stav\" /></p>\n";
    $html .= "</form>\n";
    return $html;
}



#-----------------------------------------------------------------------------
# Podle parametru "akce" rozhodne, zda reagujeme na stisk nějakého tlačítka a
# co se má provést.
#-----------------------------------------------------------------------------
sub akce
{
    my $akce = shift;
    my $objednavka = shift;
    # Připravit mail pro zákazníka, že zboží máme a brzy ho odešleme.
    if($akce eq 'Máme')
    {
        if($objednavka->{odber} eq 'paluba' && $objednavka->{platba} eq 'hotově')
        {
            pripravit_mail($objednavka, 'máme');
        }
        else
        {
            formular_variabilni_symbol($objednavka);
        }
    }
    # Připravit mail pro zákazníka, že (část) zboží nemáme a kdy očekáváme, že ho budeme mít.
    elsif($akce eq 'Nemáme')
    {
        # V tomto případě ještě neměníme stav zpracování objednávky, ale můžeme označit, které zboží nám chybí na skladě.
        formular_kontrola_skladu($objednavka);
    }
    # Uložit informace o zboží, které není na skladě a připravit mail pro zákazníka, že něco chybí a kdy to bude.
    elsif($akce eq 'Uložit sklad')
    {
        ulozit_sklad($objednavka);
        pripravit_mail($objednavka, 'nemáme');
    }
    # Připravit mail pro zákazníka, že peníze poslané předem přišly a zboží je připraveno k vyzvednutí na Palubě.
    elsif($akce eq 'Peníze přišly')
    {
        pripravit_mail($objednavka, 'zaplaceno');
    }
    # Uložit informace o zásilce odeslané poštou.
    elsif($akce eq 'Odeslali jsme')
    {
        formular_odeslano_postou($objednavka);
    }
    # Uložit informace o zásilce do databáze a připravit mail pro zákazníka, že jsme zboží odeslali.
    elsif($akce eq 'Uložit údaje o zásilce')
    {
        ulozit_udaje_o_zasilce($objednavka);
        pripravit_mail($objednavka, 'odesláno');
    }
    # Uložit variabilní symbol do databáze a připravit mail pro zákazníka, že zboží máme a brzy ho odešleme.
    elsif($akce eq 'Uložit variabilní symbol')
    {
        ulozit_variabilni_symbol($objednavka);
        pripravit_mail($objednavka, 'máme');
    }
    # Připravit libovolný jiný mail pro zákazníka, který není spojen se změnou stavu.
    elsif($akce eq 'Mail')
    {
        pripravit_mail($objednavka);
    }
    # Odeslat informační mail sestavený v některém z předcházejících kroků.
    elsif($akce eq 'Odeslat')
    {
        odeslat($objednavka);
    }
    # Přepnout objednávku do stavu uzavřeno, aniž bychom tím řekli, zda byla vyřízena, nebo zrušena.
    elsif($akce eq 'Uzavřít')
    {
        zmenit_stav_objednavky($objednavka->{cas}, 'uzavřeno');
    }
    # Přepnout objednávku do libovolného stavu, aniž bychom současně odeslali mail zákazníkovi.
    # Hodí se pro nestandardní případy, kdy jsme mail s dotyčnou informací poslali zákazníkovi ručně.
    elsif($akce eq 'Změnit stav')
    {
        zmenit_stav_objednavky($objednavka->{cas}, $konfig{stav}, 1);
    }
    # Uložit do databáze poznámku, kterou jsme k objednávce připsali.
    elsif($akce eq 'Uložit poznámku')
    {
        ulozit_poznamku($objednavka, $konfig{poznamka_obchod});
    }
}



#-----------------------------------------------------------------------------
# Projde objednané zboží a porovná ho s databází skladových zásob. Ke každé
# hře připíše, zda ji máme, případně, že ji máme jinde (např. v Jenštejně,
# když zákazník požaduje vyzvednutí na Palubě). POZOR! Při odeslání objednávky
# se stav zásob objednané hry sníží o jedničku (pokud jsme tedy alespoň jeden
# kus v evidenci měli), takže současný stav databáze vlastně vůbec nevypovídá
# o tom, zda pro tohoto zákazníka hru máme. Aby tohle mohlo fungovat, je třeba
# nejdříve změnit databázi a odesílání objednávky tak, aby se při ukládání
# objednávky do databáze taky zaznamenalo, které položky máme na skladě.
#-----------------------------------------------------------------------------
sub zjistit_co_je_na_sklade
{
    ###!!! viz komentář výše
}



#-----------------------------------------------------------------------------
# Zobrazí formulář, kde může uživatel zaškrtnout, které hry jsou na skladě.
#-----------------------------------------------------------------------------
sub formular_kontrola_skladu
{
    my $objednavka = shift;
    my $cislo_objednavky = $objednavka->{cas};
    my $objzbozi = $objednavka->{zbozi};
    print("<h1>Kontrola skladových zásob</h1>\n");
    print("<p>Vyplňte počty zboží, které vám k&nbsp;uspokojení objednávky <b>chybí.</b>\n");
    print("   (A to včetně zboží, které sice máme, ale jinde, než potřebujete, tj. např.\n");
    print("   zákazník chce zboží připravit na Palubě, ale my ho máme jen v&nbsp;Jenštejně.)</p>\n");
    # Odeslání formuláře mimo jiné způsobí odeslání e-mailu, proto je důležité,
    # aby metoda byla POST a ne GET. U metody POST totiž Firefox varuje uživatele,
    # když se pokouší tentýž formulář odeslat opakovaně.
    print("<form method=post action=\"objednavka.pl?post\">\n");
    print("<input type=hidden name=cislo value=\"$objednavka->{cas}\"/>");
    print("<table>\n");
    print("  <tr>\n");
    print("    <th valign=top align=left>Hra</th>\n");
    print("    <th valign=top align=left>Položka</th>\n");
    print("    <th valign=top align=left>Počet</th>\n");
    print("    <th valign=top align=left>Jednotková cena</th>\n");
    print("    <th valign=top align=left>Cena</th>\n");
    print("    <th valign=top align=left>Chybí</th>\n");
    print("  </tr>\n");
    foreach my $polozka (@{$objzbozi})
    {
        print("  <tr>\n");
        print("    <td valign=top align=left><a href=\"../prodej.pl?hra=$polozka->{kod_hry}\">$polozka->{nazev_hry}</a></td>\n");
        print("    <td valign=top align=left>");
        if($polozka->{kod_zbozi} eq "")
        {
            print("<font color=red>Varování: V&nbsp;databázi nám chybí kód objednaného zboží!</font>");
        }
        else
        {
            print($polozka->{nazev});
        }
        print("</td>\n");
        print("    <td valign=top align=right>$polozka->{pocet}&nbsp;×&nbsp;</td>\n");
        print("    <td valign=top align=right>$polozka->{jednotkova_cena}&nbsp;Kč&nbsp;=&nbsp;</td>\n");
        print("    <td valign=top align=right>$polozka->{cena_celkem}&nbsp;Kč</td>\n");
        print("    <td valign=top align=left><i> ... chybí\n");
        print("      <input type=text size=\"3\" name=\"chybi$polozka->{kod_zbozi}\" value=\"$polozka->{chybi}\"/> kusů</i>\n");
        print("    </td>\n");
        print("  </tr>\n");
    }
    print("  <tr><td valign=top align=left colspan=3><i>mezisoučet</i></td><td></td><td valign=top align=right>$objednavka->{mezisoucet}&nbsp;Kč</td></tr>\n");
    print("  <tr><td valign=top align=left colspan=3><i>poštovné</i></td><td></td><td valign=top align=right>$objednavka->{postovne}&nbsp;Kč</td></tr>\n");
    print("  <tr><td valign=top align=left colspan=3><i>množstevní sleva</i></td><td></td><td valign=top align=right>$objednavka->{mnozstevni_sleva}&nbsp;Kč</td></tr>\n");
    print("  <tr><td valign=top align=left colspan=3><i><b>celkem</b></i></td><td></td><td valign=top align=right><b>$objednavka->{celkem}&nbsp;Kč</b></td></tr>\n");
    print("</table>\n");
    print("<p>Tlačítko <i>Uložit sklad</i> způsobí, že se odešle mail o chybějícím zboží Kláře\n");
    print("   a že se seznam chybějícího zboží uloží do databáze.\n");
    print("   Zákazníkovi se v&nbsp;tuto chvíli ještě žádný mail nepošle.</p>\n");
    print("<input type=submit name=akce value=\"Uložit sklad\"/>");
    print("</form>\n");
    print("<hr/>\n");
}



#-----------------------------------------------------------------------------
# Zobrazí formulář, kde může uživatel vyplnit údaje o odeslání zboží. Po
# odeslání formuláře se údaje uloží do databáze, ale zatím se nic neodešle
# zákazníkovi. Mail pro zákazníka se pouze připraví a zobrazí v dalším
# formuláři.
#-----------------------------------------------------------------------------
sub formular_odeslano_postou
{
    my $objednavka = shift;
    my $cislo_objednavky = $objednavka->{cas};
    my $objzbozi = $objednavka->{zbozi};
    print("<h1>Údaje o zásilce předané dopravci</h1>\n");
    print("<form method=post action=\"objednavka.pl?post\">\n");
    print("<input type=hidden name=cislo value=\"$objednavka->{cas}\"/>\n");
    print("<table>\n");
    my $datum = cas::ted()->{datum};
    print("<tr><td>Zásilka odeslána dne:</td><td><input type=text name='datum' value='$datum' /></td></tr>\n");
    print("<tr><td>Podací číslo:</td><td><input type=text name='podacicislo' /></td></tr>\n");
    print("<tr><td colspan=\"2\"><input type=checkbox name='pilne' /> pilně</td></tr>\n");
    print("<tr><td>Hmotnost v&nbsp;kg:</td><td><input type=text name='hmotnost' /></td></tr>\n");
    print("<tr><td>Zaplacené poštovné:</td><td><input type=text name='postovne' /></td></tr>\n");
    print("</table>\n");
    print("<p>Tlačítko <i>Uložit údaje o zásilce</i> způsobí, že se výše uvedené údaje uloží k&nbsp;objednávce do databáze\n");
    print("   a zobrazí se další formulář s&nbsp;konceptem mailu pro zákazníka.\n");
    print("   Zákazníkovi se v&nbsp;tuto chvíli ještě žádný mail nepošle a stav objednávky se nezmění.</p>\n");
    print("<input type=submit name=akce value=\"Uložit údaje o zásilce\"/>");
    print("</form>\n");
    print("<hr/>\n");
}



#-----------------------------------------------------------------------------
# Zobrazí formulář, kde může uživatel přiřadit objednávce variabilní symbol.
# Zobrazuje se po stisknutí tlačítka "Máme". Variabilní symbol dostanou
# všechny objednávky placené převodem nebo posílané poštou na dobírku.
# První dvě číslice odpovídají posledním dvěma číslicím aktuálního roku.
# Třetí číslice se liší podle druhu objednávky:
#   1 ... dobírka
#   3 ... převodem a poštou
#   5 ... převodem a Paluba
# Následují ještě 3 číslice, které udávají pořadové číslo objednávky.
# Ve formuláři bude předvyplněn další volný variabilní symbol. Uživatel ho
# může změnit (asi pouze zvýšit, jinak by hrozilo, že se do databáze dostanou
# duplicitní symboly), pokud mezitím přidělil nějaké symboly mimo systém.
# Pokud byla objednávka rozdělena a dostala 2 variabilní symboly, nižší symbol
# může uživatel připsat do poznámky k objednávce.
#-----------------------------------------------------------------------------
sub formular_variabilni_symbol
{
    my $objednavka = shift;
    my $cislo_objednavky = $objednavka->{cas};
    my $objzbozi = $objednavka->{zbozi};
    print("<h1>Přiřaďte objednávce variabilní symbol</h1>\n");
    # Zjistit další volný variabilní symbol.
    # Zjistit poslední dvojčíslí aktuálního roku.
    my $rok = cas::ted()->{rok};
    $rok = substr($rok, length($rok)-2, 2);
    # Podle druhu objednávky přidat třetí číslici.
    my $trojcisli = $rok . ($objednavka->{platba} eq 'převodem' ? ($objednavka->{odber} eq 'paluba' ? 5 : 3) : 1);
    # Najít v databázi nejvyšší dosud použitý variabilní symbol daného typu.
    my $minvs = $trojcisli.'000';
    my $maxvs = $trojcisli.'999';
    my $filtr = "(varsymbol >= $minvs) AND (varsymbol <= $maxvs)";
    my $pouzite_symboly = dzsql::dotaz($databaze, 'varsymbol', "objednavky WHERE $filtr ORDER BY varsymbol DESC");
    my $dalsi_vs;
    if(scalar(@{$pouzite_symboly}))
    {
        $dalsi_vs = $pouzite_symboly->[0]{varsymbol}+1;
    }
    else
    {
        # V rámci daného roku a druhu budeme číslovat od jedničky, ne od nuly.
        $dalsi_vs = $minvs+1;
    }
    # Zobrazit formulář s jedním okénkem.
    print("<form method=post action=\"objednavka.pl?post\">\n");
    print("<input type=hidden name=cislo value=\"$objednavka->{cas}\"/>\n");
    print("<table>\n");
    print("<tr><td>Variabilní symbol: </td><td><input type=text name='varsymbol' value='$dalsi_vs' /></td></tr>\n");
    print("</table>\n");
    print("<p>Předvyplněný symbol $dalsi_vs je podle databáze nejnižší dosud volný symbol pro daný rok a druh objednávky.\n");
    print("   Pokud jste tento symbol přidělili mimo systém a databáze o tom neví, můžete symbol změnit na vyšší.\n");
    print("   Pokud jste objednávku rozdělili a chcete jí přiřadit několik variabilních symbolů, uveďte sem nejvyšší symbol\n");
    print("   a ostatní si uložte v&nbsp;poznámce k&nbsp;objednávce.\n");
    print("   POZOR! Nikdo už nebude kontrolovat, zda jste omylem nezměnili symbol na nižší (již použitý) nebo dokonce na symbol určený pro jiný druh objednávky!</p>\n");
    print("<p>Tlačítko <i>Uložit variabilní symbol</i> způsobí, že se výše uvedené údaje uloží k&nbsp;objednávce do databáze\n");
    print("   a zobrazí se další formulář s&nbsp;konceptem mailu pro zákazníka.\n");
    print("   Zákazníkovi se v&nbsp;tuto chvíli ještě žádný mail nepošle a stav objednávky se nezmění.</p>\n");
    print("<input type=submit name=akce value=\"Uložit variabilní symbol\"/>");
    print("</form>\n");
    print("<hr/>\n");
}



#-----------------------------------------------------------------------------
# Reaguje na tlačítko Uložit sklad. Uloží do databáze nový stav skladových
# zásob k dané objednávce a případně pošle zprávu o novém stavu Kláře.
#-----------------------------------------------------------------------------
sub ulozit_sklad
{
    my $objednavka = shift;
    # Zjistit parametry akce: kolik kusů kterého zboží na skladě chybí.
    my %chybi;
    foreach my $parametr (keys(%konfig))
    {
        if($parametr =~ m/^chybi(\d+)$/)
        {
            my $kod_zbozi = $1;
            my $pocet = $konfig{$parametr};
            $chybi{$kod_zbozi} = $pocet;
        }
    }
    print("<p>Teď se zapsalo do databáze k&nbsp;objednávce, kolik kterého zboží chybí k&nbsp;uspokojení objednávky.\n");
    print("   Totéž se ještě poslalo Kláře e-mailem, aby mohla zboží doobjednat nebo přesunout mezi Jenštejnem a Palubou.\n");
    print("   Zákazníkovi se ještě žádná zpráva neposlala, to až tlačítkem Nemáme.\n");
    print("<ul>\n");
    my $zprava_klare;
    foreach my $polozka (@{$objednavka->{zbozi}})
    {
        my $drive = $polozka->{chybi} eq '' ? 0 : $polozka->{chybi};
        my $nyni = $chybi{$polozka->{kod_zbozi}};
        # Zajistit, aby nová položka byla nezáporné celé číslo.
        $nyni = ($nyni =~ m/^(\d+)/) ? $1 : 0;
        # Zajistit, aby počet chybějících kusů nebyl větší než počet objednaných kusů.
        my $chybove_hlaseni;
        if($nyni>$polozka->{pocet})
        {
            $chybove_hlaseni = "<font color=red>Varování: Nemůže chybět více kusů, než kolik je objednáno. $nyni opraveno na $polozka->{pocet}.</font><br/>\n";
            $nyni = $polozka->{pocet};
        }
        # Ohlásit změnu, kterou provedeme.
        my $li = "<li>$chybove_hlaseni$polozka->{kod_zbozi} $polozka->{nazev_hry}: objednáno $polozka->{pocet}, dříve chybělo $drive, nyní chybí $nyni</li>\n";
        print($li);
        $zprava_klare .= $li;
        # Uložit nový počet chybějících kusů do databáze.
        if($nyni!=$polozka->{chybi})
        {
            $polozka->{cas} = $objednavka->{cas};
            $polozka->{chybi} = $nyni;
        }
        dzsql::update($databaze, 'objzbozi', $polozka, ['chybi'], ['cas', 'kod_zbozi'], []);
    }
    print("</ul>\n");
    if($zprava_klare)
    {
        my %mail =
        (
            'From'    => 'obchod@hrejsi.cz',
            'To'      => 'danzeman11@gmail.com',
            'Cc'      => 'obchod@hrejsi.cz',
            'Subject' => "Obchod: Chybejici zbozi ($objednavka->{odber})",
            'text'    => $zprava_klare
        );
        mail::odeslat(%mail);
    }
}



#-----------------------------------------------------------------------------
# Reaguje na tlačítko Uložit údaje o zásilce. Uloží do databáze datum odeslání
# a podací číslo pošty. Nezajímá ho, zda už v databázi tyto údaje byly
# vyplněné a jak.
#-----------------------------------------------------------------------------
sub ulozit_udaje_o_zasilce
{
    my $objednavka = shift;
    # Zkontrolovat údaje.
    my @ndvm = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    if($konfig{datum} !~ m/^(\d+)\.(\d+)\.(\d+)$/ || $2<1 || $2>12 || $1<1 || $1>$ndvm[$2-1] || $3<2000 || $3>2100)
    {
        print("<p style='color:red'>Varování: chybně vyplněné datum '$konfig{datum}'. Očekáváme formát <i>d.m.rrrr</i>.</p>\n");
    }
    if($konfig{podacicislo} =~ m/^\s*$/)
    {
        print("<p style='color:red'>Varování: chybí podací číslo.</p>\n");
    }
    # Očekáváme, že uživatel vyplňuje desetinné číslo česky, tj. s desetinnou čárkou, ale hned po kontrole ji převedeme na desetinnou tečku.
    $konfig{hmotnost} =~ s/\./,/;
    if($konfig{hmotnost} !~ m/^\d+(,\d+)?$/)
    {
        print("<p style='color:red'>Varování: chybně vyplněná hmotnost zásilky '$konfig{hmotnost}'. Očekáváme nezáporné číslo, může být desetinné.</p>\n");
    }
    $konfig{hmotnost} =~ s/,/\./;
    if($konfig{postovne} =~ m/^\s*$/)
    {
        print("<p style='color:red'>Varování: chybí údaj o zaplaceném poštovném.</p>\n");
    }
    # Současně uložit údaje do našeho hashe o objednávce.
    # Bude se nám to hodit později při přípravě mailu pro zákazníka.
    $objednavka->{datum_odeslani} = $konfig{datum};
    $objednavka->{podaci_cislo} = $konfig{podacicislo};
    $objednavka->{pilne} = $konfig{pilne} ? 1 : 0;
    $objednavka->{hmotnost} = $konfig{hmotnost} ? $konfig{hmotnost} : 0;
    $objednavka->{zaplacene_postovne} = $konfig{postovne} ? $konfig{postovne} : 0;
    my @nazvy_update = ('datum_odeslani', 'podaci_cislo', 'pilne', 'hmotnost', 'zaplacene_postovne');
    my @nazvy_where = ('cas');
    my @nazvy_ciselnych_poli = ('pilne', 'hmotnost', 'zaplacene_postovne');
    dzsql::update($databaze, 'objednavky', $objednavka, \@nazvy_update, \@nazvy_where, \@nazvy_ciselnych_poli);
}



#-----------------------------------------------------------------------------
# Reaguje na tlačítko Uložit variabilní symbol. Uloží do databáze variabilní
# symbol, který byl objednávce přiřazen uživatelem. Nezajímá ho, zda je
# zvolený symbol konzistentní s daným druhem objednávky a zda už tento symbol
# nebyl v databázi přiřazen jiné objednávce.
#-----------------------------------------------------------------------------
sub ulozit_variabilni_symbol
{
    my $objednavka = shift;
    # Zkontrolovat údaje.
    if($konfig{varsymbol} !~ m/^\d+$/)
    {
        print("<p style='color:red'>Varování: chybně vyplněný variabilní symbol '$konfig{varsymbol}'. Očekáváme pouze číslice.</p>\n");
    }
    # Současně uložit údaje do našeho hashe o objednávce.
    # Bude se nám to hodit později při přípravě mailu pro zákazníka.
    $objednavka->{varsymbol} = $konfig{varsymbol};
    my @nazvy_update = ('varsymbol');
    my @nazvy_where = ('cas');
    my @nazvy_ciselnych_poli = ('varsymbol');
    dzsql::update($databaze, 'objednavky', $objednavka, \@nazvy_update, \@nazvy_where, \@nazvy_ciselnych_poli);
}



#-----------------------------------------------------------------------------
# Uloží do databáze poznámku, kterou jsme k objednávce připsali.
#-----------------------------------------------------------------------------
sub ulozit_poznamku
{
    my $objednavka = shift;
    my $poznamka = shift;
    # Současně uložit údaje do našeho hashe o objednávce.
    $objednavka->{poznamka_obchod} = $poznamka;
    # Uložit změněná pole z hashe do databáze.
    my @nazvy_update = ('poznamka_obchod');
    my @nazvy_where = ('cas');
    my @nazvy_ciselnych_poli = ();
    dzsql::update($databaze, 'objednavky', $objednavka, \@nazvy_update, \@nazvy_where, \@nazvy_ciselnych_poli);
}



#-----------------------------------------------------------------------------
# Ověří, zda je zamýšlená změna stavu přípustná. Zejména má zabránit tomu,
# abychom témuž zákazníkovi opakovaně odeslali stejný mail a mátli ho.
#-----------------------------------------------------------------------------
sub proverit_pozadavek_na_zmenu_stavu
{
    my $cislo_objednavky = shift;
    my $novy_stav = shift;
    # Chceme, aby se funkce dala snadno použít v podmínkách, proto vrací pouze 0 nebo 1.
    # Případné chybové hlášení zapíše do úložiště, na nějž dostane odkaz.
    my $refchyba = shift;
    my $uloziste;
    if(ref($refchyba) ne 'SCALAR')
    {
        $refchyba = \$uloziste;
    }
    ${$refchyba} = '';
    # Obdobně volitelně rovnou nastavíme parametr disabled pro tlačítko webového formuláře.
    my $refdisabled = shift;
    my $uloziste_disabled;
    if(ref($refdisabled) ne 'SCALAR')
    {
        $refdisabled = \$uloziste_disabled;
    }
    ${$refdisabled} = '';
    ###!!!
    # 28.11.2014: Klárka chce, aby měla vždy dovoleno přejít do libovolného stavu.
    # Tuhle funkci neruším, volá se na několika různých místech, ale bude nyní bez přemýšlení vracet 1.
    return 1;
    ###!!!
    my $stary_stav = dbobj::zjistit_stav_objednavky($databaze, $cislo_objednavky);
    # Typicky se do každého stavu dá dostat jen z jednoho konkrétního předcházejícího stavu.
    if($novy_stav =~ m/^(máme|zaplaťte)$/ && $stary_stav !~ m/^(objednáno|nemáme)$/)
    {
        ${$refchyba} = "Chyba: do stavu '$novy_stav' lze přejít pouze ze stavu 'objednáno', ale současný stav objednávky $cislo_objednavky je '$stary_stav'.";
    }
    elsif($novy_stav eq 'zaplaceno' && $stary_stav ne 'zaplaťte')
    {
        ${$refchyba} = "Chyba: do stavu '$novy_stav' lze přejít pouze ze stavu 'zaplaťte', ale současný stav objednávky $cislo_objednavky je '$stary_stav'.";
    }
    # Vrátit výsledek.
    if(${$refchyba})
    {
        ${$refdisabled} = " disabled error=\"${$refchyba}\"";
        return 0;
    }
    else
    {
        return 1;
    }
}



#-----------------------------------------------------------------------------
# Změní stav objednávky.
#-----------------------------------------------------------------------------
sub zmenit_stav_objednavky
{
    my $cislo_objednavky = shift;
    my $novy_stav = shift;
    my $nomail = shift; # došlo ke změně stavu bez odeslání mailu zákazníkovi?
    my $vysledek = dbobj::zmenit_stav_objednavky($databaze, $cislo_objednavky, $novy_stav, $nomail);
    if(!$vysledek)
    {
        print("<!-- zmenit_stav_objednavky() -->\n");
        print("<p><font color=red>$dbobj::chyba</font></p>\n");
        return 0;
    }
    return 1;
}



#-----------------------------------------------------------------------------
# Připraví koncept dopisu pro zákazníka.
#-----------------------------------------------------------------------------
sub pripravit_mail
{
    my $objednavka = shift;
    my $cislo_objednavky = $objednavka->{cas};
    my $novy_stav = shift;
    # Jestliže je $novy_stav prázdný, znamená to, že chceme pouze poslat mail bez změny stavu.
    if($novy_stav)
    {
        # Jestliže jsme stiskli tlačítko "Máme", chceme obvykle do stavu "máme" (a pošleme).
        # Pokud se ale bude platit předem, chceme místo toho do stavu "zaplaťte".
        if($novy_stav eq 'máme' && $objednavka->{platba} eq 'převodem')
        {
            $novy_stav = 'zaplaťte';
        }
        # Jestliže jsme stiskli tlačítko "Peníze přišly", chceme obvykle do stavu "zaplaceno".
        # Pokud jsme ale byli ve stavu "vytištěno před zaplacením", chceme do stavu "vytištěno".
        elsif($novy_stav eq 'zaplaceno' && dbobj::zjistit_stav_objednavky($databaze, $cislo_objednavky) eq 'vytištěno před zaplacením')
        {
            $novy_stav = 'vytištěno';
        }
        # Jestliže se chystáme přejít do nepovoleného stavu, ani nenabízet formulář na odeslání mailu.
        my $chyba;
        unless(proverit_pozadavek_na_zmenu_stavu($cislo_objednavky, $novy_stav, \$chyba))
        {
            print("<p><font color=red>$chyba</font></p>\n");
            return;
        }
    }
    # Připravit rekapitulaci objednaného zboží.
    my $rekapitulace;
    if($novy_stav eq 'nemáme')
    {
        $rekapitulace = ktere_zbozi_mame($objednavka);
    }
    else
    {
        $rekapitulace = objmail::prehled_zbozi($objednavka);
    }
    # Připravit formulář se vzorem mailu. Uživatel bude moci mail upravit a odeslat.
    my $vzor_mailu = objmail::vzor_mailu($novy_stav, $objednavka, $rekapitulace);
    # Předmět zprávy musí obsahovat jméno zákazníka.
    # Může obsahovat moje číslo objednávky, ale nejsem si vlastně jist, jestli je to k něčemu dobré.
    my $druheslovo = $objednavka->{odber} eq 'paluba' ? 'odber Paluba' : 'her';
    my $predmet = "Re: Objednavka $druheslovo: ".ascii::ascii($objednavka->{jmeno}.' '.$objednavka->{prijmeni}); # ." ($cislo_objednavky)";
    $predmet =~ s/"//g;
    print <<EOF
<form method=post action="objednavka.pl?post">
  <input type="hidden" name="cislo" value="$cislo_objednavky" />
  <input type="hidden" name="stav" value="$novy_stav" />
  <input type="hidden" name="predmet" value="$predmet" />
  <table>
    <tr><td>Odesílatel:</td><td>obchod\@hrejsi.cz</td></tr>
    <tr><td>Adresát:</td><td>$objednavka->{email}</td></tr>
    <tr><td>Kopie:</td><td>obchod\@hrejsi.cz</td></tr>
    <tr><td>Předmět:</td><td>$predmet</td></tr>
    <tr><td colspan="2">
      <textarea name="text_mailu" cols="80" rows="25" tabindex="1" accesskey=",">$vzor_mailu</textarea>
    </td></tr>
    <tr><td colspan="2"><input type=submit name=akce value="Odeslat" /><br/>
        Stisknutím tohoto tlačítka se odešle mail zákazníkovi a současně se v&nbsp;databázi změní stav objednávky.</td></tr>
  </table>
</form>
EOF
        ;
}



#-----------------------------------------------------------------------------
# Pro účely dopisu zákazníkovi připraví seznam zboží, které máme a které
# nemáme.
#-----------------------------------------------------------------------------
sub ktere_zbozi_mame
{
    my $objednavka = shift;
    my $text;
    foreach my $polozka (@{$objednavka->{zbozi}})
    {
        my $mame;
        if($polozka->{chybi}==0)
        {
            $mame = "MÁME";
        }
        elsif($polozka->{chybi}>=$polozka->{pocet})
        {
            $mame = "NEMÁME";
        }
        else
        {
            $mame = "CHYBÍ NÁM $polozka->{chybi} KS";
        }
        $text .= sprintf("%2d × %s: %s\n", $polozka->{pocet}, $polozka->{nazev}, $mame);
    }
    return $text;
}



#-----------------------------------------------------------------------------
# Reaguje na tlačítko Odeslat. Odešle mail zákazníkovi a provede související
# změnu stavu objednávky.
#-----------------------------------------------------------------------------
sub odeslat
{
    my $objednavka = shift;
    # Jestliže se chystáme přejít do nepovoleného stavu, nedovolit odeslání mailu.
    # Prázdný stav je povolen, znamená, že se má odeslat mail beze změny stavu.
    my $chyba;
    my $uspech = $konfig{stav} eq '' || proverit_pozadavek_na_zmenu_stavu($konfig{cislo}, $konfig{stav}, \$chyba);
    if(!$uspech)
    {
        print("<p><font color=red>$chyba</font></p>\n");
    }
    else
    {
        # Některé druhy mailů vyžadují před odesláním úpravu.
        # Jestliže uživatel zapomněl úpravu provést, nic neodesílat!
        if($konfig{stav} eq 'zaplaťte' && $konfig{text_mailu} =~ m/variabilní\ssymbol\sVS/)
        {
            print("<p><font color=red>Chyba: Asi jste nenahradili 'VSVSVSVSVS' skutečným variabilním symbolem. Mail nebyl odeslán a stav objednávky nebyl změněn.</font></p>\n");
        }
        else
        {
            # Z bezpečnostních důvodů si nepředávám adresu zákazníka v parametrech CGI, ale znova si ji zjistím z databáze.
            objmail::odeslat_mail($konfig{cislo}, $objednavka->{email}, $konfig{predmet}, $konfig{text_mailu});
            zmenit_stav_objednavky($konfig{cislo}, $konfig{stav}) if($konfig{stav});
            print("<p>Zákazníkovi byl odeslán mail.</p>\n");
            print("<pre style='background-color:yellow'>$konfig{text_mailu}</pre>\n");
        }
    }
}
