File Coverage

blib/lib/oEdtk/Outmngr.pm
Criterion Covered Total %
statement 43 580 7.4
branch 0 190 0.0
condition 0 76 0.0
subroutine 15 35 42.8
pod 0 12 0.0
total 58 893 6.4


line stmt bran cond sub pod time code
1             package oEdtk::Outmngr;
2            
3 1     1   5 use strict;
  1         2  
  1         40  
4 1     1   6 use warnings;
  1         2  
  1         31  
5            
6 1     1   423 use File::Basename;
  1         3  
  1         69  
7 1     1   5 use Sys::Hostname;
  1         2  
  1         260  
8 1     1   5 use Text::CSV;
  1         2  
  1         11  
9 1     1   23 use Date::Calc qw(Today Gmtime Week_of_Year Add_Delta_Days);
  1         2  
  1         1017  
10 1     1   7 use List::Util qw(max sum);
  1         1  
  1         498  
11 1     1   11 use oEdtk::Config qw(config_read);
  1         2  
  1         41  
12 1     1   5 use oEdtk::DBAdmin qw(db_connect db_backup_agent create_table_INDEX @INDEX_COLS);
  1         2  
  1         928  
13 1     1   5 use POSIX qw(strftime);
  1         2  
  1         9  
14 1     1   416 use DBI;
  1         2  
  1         41  
15             # use Sys::Hostname;
16            
17 1     1   425 use Exporter;
  1         2  
  1         7244  
18             our $VERSION = 0.8024; # release number : Y.YSSS -> Year, Sequence
19             our @ISA = qw(Exporter);
20             our @EXPORT_OK = qw(
21             omgr_check_acquit
22             omgr_check_doclibs
23             omgr_check_seqlot_ref
24             omgr_depot_poste
25             omgr_export
26             omgr_import
27             omgr_lot_pending
28             omgr_purge_fs
29             omgr_stats
30             omgr_stats_referent
31             omgr_track_folds
32             omgr_track_report
33             );
34            
35             # Le lot par défaut.
36 1     1   8 use constant DEFLOT => 'DEF';
  1         2  
  1         80  
37 1     1   4 use constant DEFFIL => 'DEF';
  1         3  
  1         14153  
38            
39             # Description des traitements que l'on applique à nos lots de documents, avec
40             # la liste des champs mis à jour à chaque étape.
41             #
42             # 1. On insère chaque ligne de l'index dans la table $cfg->{'EDTK_DBI_OUTMNGR'} en renseignant
43             # un certain nombre de champs supplémentaires, en utilisant les informations
44             # tirées des tables EDTK_REFIDDOC et EDTK_SUPPORTS.
45             # ED_PORTADR, ED_CATDOC, ED_REFIMP, ED_TYPED, ED_FORMATP, ED_PGORIEN,
46             # ED_FORMDEF, ED_PAGEDEF, ED_FORMS, ED_NUMPGPLI
47             #
48             # 2. Une fois que toutes les lignes ont été insérées, on peut désormais faire
49             # des calculs supplémentaires et enrichir à nouveau nos entrées.
50             # ED_NBPGPLI, ED_NBPGDOC, ED_MODEDI
51             #
52             # 3. On peut maintenant sélectionner un lot pour nos documents. On essaye
53             # chacun des lots séquentiellement, dans l'ordre de priorité défini dans la
54             # table EDTK_LOTS. Si le lot matche des entrées, on assigne ces entrées au
55             # lot correspondant.
56             # ED_IDLOT
57             #
58             # 4. Une fois qu'un lot a été assigné, on en déduit un manufacturier via la
59             # table EDTK_LOTS. En fonction de ce manufacturier, on sélectionne une liste
60             # de filières de production possibles, dans l'ordre de priorité défini dans la
61             # table EDTK_FILIERES. Comme pour l'étape 3, on essaye de matcher nos entrées
62             # avec chacune de ces filières, en fonction de leurs contraintes.
63             # ED_IDFILIERE
64             #
65             # 5. La filière de production ayant été déterminée, on sait si l'on va imprimer
66             # en recto-verso ou juste en recto; on peut donc calculer de nouveaux champs
67             # supplémentaires.
68             # ED_PDSPLI, ED_NBFPLI
69             #
70             # 6. On peut finalement exporter nos entrées pour créer nos lots finaux à envoyer
71             # au manufacturier. Pour cela, on sélectionne les couples (idlot,idfilière)
72             # uniques dans notre table $cfg->{'EDTK_DBI_OUTMNGR'}, et pour chacun de ces couples, on essaye
73             # de satisfaire les contraintes en nombre de plis/pages minimum et maximum. Si
74             # c'est possible, on assigne un numéro de lot d'envoi unique aux documents.
75             # ED_SEQLOT
76            
77             # READ AND PROCESS AN INDEX FILE, STORING IT IN THE DATABASE, WHILE COMPUTING SOME VALUES.
78             sub omgr_import($$$) {
79 0     0 0   my ($app, $in, $corp) = @_;
80            
81             # Retrieve the database connection parameters.
82 0           my $cfg = config_read('EDTK_DB');
83            
84 0           my $pdbh= db_connect($cfg, 'EDTK_DBI_PARAM');
85 0           my $dbh = db_connect($cfg, 'EDTK_DBI_DSN', { AutoCommit => 0, RaiseError => 1 });
86            
87             # Create the $cfg->{'EDTK_DBI_OUTMNGR'} table if we're using SQLite.
88 0 0         if ($dbh->{'Driver'}->{'Name'} eq 'SQLite') {
89 0           create_table_INDEX($dbh, $cfg->{'EDTK_DBI_OUTMNGR'});
90             }
91            
92 0           eval {
93 0           my ($idldoc, $numencs, $encpds) = _omgr_insert($dbh, $pdbh, $app, $in, $corp);
94 0           _omgr_lot($dbh, $pdbh, $idldoc);
95 0           _omgr_filiere($dbh, $pdbh, $app, $idldoc, $numencs, $encpds);
96 0           $dbh->commit;
97             };
98 0 0         if ($@) {
99 0           warn "ERROR: $@\n";
100 0           eval { $dbh->rollback };
  0            
101 0           die "ERROR: rollback done before dying in omgr_import\n";
102             }
103            
104 0           $dbh->disconnect;
105 0           $pdbh->disconnect;
106             }
107            
108            
109             sub omgr_track_folds ($;$){
110             # EDIT LIST AND STATUS FROM START TO END
111             # LISTE DES LOTS PRODUITS JUSQU'A LA MISE SOUS PLIS
112 0     0 0   my $dbh = shift;
113 0           my $cfg = config_read('EDTK_DB', 'EDTK_STATS');
114 0   0       my $nb_j_historique = shift || $cfg->{'EDTK_STATS_DAYS_FROM'} || 10;
115 0           warn "INFO : omgr_track_folds for last $nb_j_historique days\n";
116 0           my ($sql);
117            
118             # REQUETE POUR LE MAIL SUIVI METIER
119             ###########################################################################
120             # SELECT A.ED_REFIDDOC, COUNT (DISTINCT A.ED_IDLDOC||TO_CHAR(A.ED_SEQDOC,'FM0000000')) AS NB_DOCS,
121             # A.ED_DTEDTION, COUNT (DISTINCT A.ED_SEQLOT||TO_CHAR(A.ED_IDPLI,'FM0000000')) AS NB_PLIS,
122             # B.ED_DTPOST, B.ED_DTPOST2, COUNT (DISTINCT A.ED_SEQLOT) AS NB_LOTS,
123             # NVL(B.ED_STATUS, NVL(A.ED_STATUS, 'PENDING...')) AS STATUS
124             # FROM EDTK_INDEX A, EDTK_ACQ B
125             # WHERE A.ED_SEQLOT=B.ED_SEQLOT (+)
126             # AND (A.ED_DTEDTION IS NULL OR A.ED_DTEDTION > TO_CHAR(SYSDATE-20, 'IYYYMMDD'))
127             # GROUP BY C.ED_MAIL_REFERENT, A.ED_REFIDDOC, A.ED_DTEDTION, B.ED_DTPOST, B.ED_DTPOST2, B.ED_STATUS, A.ED_STATUS
128             # ORDER BY C.ED_MAIL_REFERENT, A.ED_REFIDDOC;
129            
130             # SELECT A.ED_REFIDDOC, COUNT (DISTINCT A.ED_IDLDOC||TO_CHAR(A.ED_SEQDOC,'FM0000000')) AS NB_DOCS,
131             # A.ED_DTEDTION, COUNT (DISTINCT A.ED_SEQLOT||TO_CHAR(A.ED_IDPLI,'FM0000000')) AS NB_PLIS,
132             # B.ED_DTPOST, B.ED_DTPOST2, COUNT (DISTINCT A.ED_SEQLOT) AS NB_LOTS,
133             # NVL(B.ED_STATUS, NVL(A.ED_STATUS, 'PENDING...')) AS STATUS,
134             # C.ED_MAIL_REFERENT
135             # FROM EDTK_INDEX A, EDTK_ACQ B, EDTK_REFIDDOC C
136             # WHERE A.ED_SEQLOT=B.ED_SEQLOT (+)
137             # AND A.ED_REFIDDOC=C.ED_REFIDDOC
138             # AND (A.ED_DTEDTION IS NULL OR A.ED_DTEDTION > TO_CHAR(SYSDATE-20, 'IYYYMMDD'))
139             # GROUP BY C.ED_MAIL_REFERENT, A.ED_REFIDDOC, A.ED_DTEDTION, B.ED_DTPOST, B.ED_DTPOST2, B.ED_STATUS, A.ED_STATUS
140             # ORDER BY C.ED_MAIL_REFERENT, A.ED_REFIDDOC, A.ED_DTEDTION;
141            
142            
143 0           $sql = "SELECT A.ED_CORP, A.ED_REFIDDOC,"
144             . " NVL(B.ED_STATUS, NVL(A.ED_STATUS, 'PENDING...')) AS STATUS,"
145             . " COUNT (DISTINCT A.ED_IDLDOC||TO_CHAR(A.ED_SEQDOC,'FM0000000')) AS NB_DOCS,"
146             . " A.ED_DTEDTION, "
147             . " COUNT (DISTINCT A.ED_SEQLOT) AS NB_LOTS,"
148             . " COUNT (DISTINCT A.ED_SEQLOT||TO_CHAR(A.ED_IDPLI,'FM0000000')) AS NB_PLIS,"
149             . " B.ED_DTPOST, B.ED_DTPOST2, "
150             . " C.ED_MAIL_REFERENT AS REFERENT"
151             . " FROM " . $cfg->{'EDTK_STATS_OUTMNGR'} . " A, EDTK_ACQ B, EDTK_REFIDDOC C"
152             . " WHERE A.ED_SEQLOT=B.ED_SEQLOT (+)"
153             . " AND A.ED_REFIDDOC=C.ED_REFIDDOC"
154             . " AND (A.ED_DTEDTION IS NULL OR A.ED_DTEDTION > TO_CHAR(SYSDATE-?, 'IYYYMMDD'))"
155             . " GROUP BY C.ED_MAIL_REFERENT, A.ED_CORP, A.ED_REFIDDOC, A.ED_DTEDTION, B.ED_DTPOST, B.ED_DTPOST2, B.ED_STATUS, A.ED_STATUS"
156             . " ORDER BY C.ED_MAIL_REFERENT, A.ED_CORP, A.ED_REFIDDOC, STATUS, A.ED_DTEDTION";
157            
158 0           my $sth = $dbh->prepare($sql);
159 0           $sth->execute($nb_j_historique);
160            
161 0           my $rows = $sth->fetchall_arrayref();
162            
163 0           my $fmt = "%10s %-20s %-10s %7s %9s %7s %7s %8s %8s";
164 0           my @head= ("CORP", "REFIDDOC", "STATUS", "NB_DOCS", "DTEDITION", "NB_LOTS", "NB_PLIS", "DTPOST", "DTPOST2");
165 0           _filled_rows($rows);
166            
167 0           @$rows = (\$fmt, \@head, @$rows);
168 0           return $rows;
169             }
170            
171            
172             sub omgr_track_report {
173 0     0 0   my $dbh = shift;
174 0           my $cfg = config_read('EDTK_DB', 'EDTK_STATS');
175            
176 0           my ($sql);
177             #select A.ED_REFIDDOC,
178             # (CASE A.ED_MODEDI WHEN 'R' THEN 2 ELSE 1 END * SUM(A.ED_NBFPLI)) AS NB_FACES,
179             # COUNT (DISTINCT A.ED_SEQLOT||TO_CHAR(A.ED_IDPLI,'FM0000000')) AS NB_PLIS_SENT,
180             # B.ED_STATUS, B.ED_LOTNAME, A.ED_SEQLOT, C.ED_IDMANUFACT,
181             # B.ED_NBFACES AS NB_FACES_MANUFACT, B.ED_NBPLIS AS NB_PLIS_MANUFACT, B.ED_DTPOST
182             # FROM EDTK_INDEX A, EDTK_ACQ B, EDTK_LOTS C
183             # WHERE A.ED_SEQLOT = B.ED_SEQLOT AND B.ED_STATUS != 'SENT' AND A.ED_IDLOT = C.ED_IDLOT (+)
184             # GROUP BY C.ED_IDMANUFACT, A.ED_REFIDDOC, A.ED_SEQLOT, A.ED_MODEDI, B.ED_STATUS, B.ED_DTPOST, B.ED_LOTNAME, B.ED_NBFACES, B.ED_NBPLIS;
185 0           $sql = "SELECT A.ED_REFIDDOC, "
186             . " (CASE A.ED_MODEDI WHEN 'R' THEN 2 ELSE 1 END * SUM(A.ED_NBFPLI)) AS NB_FACES, "
187             . " COUNT (DISTINCT A.ED_SEQLOT||TO_CHAR(A.ED_IDPLI,'FM0000000')) AS NB_PLIS, "
188             . " B.ED_STATUS, B.ED_LOTNAME, A.ED_SEQLOT, C.ED_IDMANUFACT, "
189             . " B.ED_NBFACES AS NB_FACES_MANUFACT, B.ED_NBPLIS AS NB_PLIS_MANUFACT, B.ED_DTPOST "
190             . "FROM " . $cfg->{'EDTK_STATS_OUTMNGR'} . " A, EDTK_ACQ B, EDTK_LOTS C "
191             . "WHERE A.ED_SEQLOT = B.ED_SEQLOT AND B.ED_STATUS != 'SENT' AND A.ED_IDLOT = C.ED_IDLOT (+) "
192             . "GROUP BY C.ED_IDMANUFACT, A.ED_REFIDDOC, A.ED_SEQLOT, A.ED_MODEDI, B.ED_STATUS, B.ED_DTPOST, B.ED_LOTNAME, B.ED_NBFACES, B.ED_NBPLIS ";
193            
194 0           my $sth = $dbh->prepare($sql);
195 0           $sth->execute();
196            
197 0           my $rows = $sth->fetchall_arrayref();
198            
199 0           my $fmt = "%15s %6s %6s %7s %16s %7s %16s %14s %14s %8s ";
200 0           my @head= ("REFIDDOC", "FACES", "PLIS", "STATUS", "LOTNAME", "SEQLOT", "MANUFACTURER", "MANUFACT_FACES", "MANUFACT_PLIS", "DTPOST");
201 0           _filled_rows($rows);
202            
203             # return @tlist;
204 0           @$rows = (\$fmt, \@head, @$rows);
205 0           return $rows;
206             }
207            
208            
209             sub omgr_track_no_omgr(){
210             # select B.ed_refiddoc, count (DISTINCT A.ED_SOURCE) as NBREQUEST, A.ED_message
211             # from edtk_tracking A, edtk_refiddoc B, edtk_index C
212             # where B.ed_refiddoc = A.ed_app
213             # AND A.ED_JOB_EVT = 'J'
214             # and B.ed_massmail = 'C'
215             # and A.ED_SNGL_ID = C.ED_IDLDOC (+)
216             # and C.ED_dtedtion is null
217             # and (A.ed_sngl_id like '202%')
218             # group by B.ed_refiddoc, A.ED_message
219             # order by B.ed_refiddoc, A.ED_message
220             # ;
221            
222             1;
223             }
224            
225            
226             sub omgr_check_acquit($;$){
227 0     0 0   my $dbh = shift;
228 0           my $cfg = config_read('EDTK_DB', 'EDTK_STATS');
229 0   0       my $nb_j_historique = shift || $cfg->{'EDTK_STATS_DAYS_FROM'} || 100;
230            
231             # a partir de la base d'acquittement check :
232             # 1 - vérifier le nb de pages par seqlot
233             # 2 - vérifier le nb de plis par seqlot
234             # 3 - renseigner le statut dans acq
235             # 4 - renseigner la date de check
236            
237             #SELECT A.ED_SEQLOT,
238             # COUNT (DISTINCT A.ED_SEQLOT||TO_CHAR(A.ED_IDPLI,'FM0000000')) AS NB_PLIS, B.ED_NBPLIS,
239             # FROM EDTK_INDEX A, EDTK_ACQ B
240             # WHERE A.ED_SEQLOT=B.ED_SEQLOT
241             # AND ((B.ED_DTCHECK IS NULL OR B.ED_DTPRINT > TO_CHAR(SYSDATE-20, 'IYYYMMDD')) OR (B.ED_STATUS IS NULL OR B.ED_STATUS != 'SENT'))
242             # GROUP BY A.ED_SEQLOT, A.ED_MODEDI, B.ED_NBPLIS;
243 0           my ($sql, $num);
244 0           $sql = "SELECT A.ED_SEQLOT, "
245             . " COUNT (DISTINCT A.ED_SEQLOT||TO_CHAR(A.ED_IDPLI,'FM0000000')) AS NB_PLIS, B.ED_NBPLIS"
246             # cf $sqlnbfpli
247             # . ", (CASE A.ED_MODEDI WHEN 'R' THEN 2 ELSE 1 END * SUM(A.ED_NBFPLI)) AS NB_FACES, B.ED_NBFACES"
248             . " FROM " . $cfg->{'EDTK_STATS_OUTMNGR'} . " A, EDTK_ACQ B"
249             . " WHERE A.ED_SEQLOT=B.ED_SEQLOT"
250             . " AND ((B.ED_DTCHECK IS NULL OR B.ED_DTPRINT > TO_CHAR(SYSDATE-?, 'IYYYMMDD')) OR (B.ED_STATUS IS NULL OR B.ED_STATUS != 'SENT'))"
251             . " GROUP BY A.ED_SEQLOT, A.ED_MODEDI, B.ED_NBPLIS"
252             ;
253 0           my $sth = $dbh->prepare($sql);
254 0           $sth->execute($nb_j_historique);
255            
256 0           while (my $seqlot = $sth->fetchrow_hashref()) {
257             # # ON MET À JOUR CHACUN DES SEQLOTS
258 0           $sql = "UPDATE EDTK_ACQ "
259             . " SET ED_DTCHECK = TO_CHAR(SYSDATE, 'IYYYMMDD'), ED_STATUS = "
260             . " CASE "
261             . " WHEN ED_NBPLIS = ? THEN "
262             . " CASE WHEN (ED_DTPOST IS NOT NULL) THEN 'SENT' "
263             . " ELSE 'GOOD' "
264             . " END "
265             . " ELSE 'LACK' "
266             . " END "
267             . " WHERE ED_SEQLOT = ? ";
268 0           $num += $dbh->do($sql, undef, $seqlot->{'NB_PLIS'}, $seqlot->{'ED_SEQLOT'});
269             }
270 0           return $num;
271             }
272            
273            
274             sub _omgr_insert($$$$$) {
275             # - INJECTION DES DONNÉES PAGE/PAGE DE L'INDEX COMPO EN BASE DE DONNÉES
276             # - COMPLÉTION DE L'INDEX AVEC LES INFOS DES TABLES DE PARAMÉTRAGE REFIDDOC ET SUPPORTS
277             # - CALCULS DES QUANTITÉS PAGES/SUPPORTS
278             # REVOIR LA GESTION DES ENCARTS XXXXXXXXXX
279 0     0     my ($dbh, $pdbh, $app, $in, $corp) = @_;
280 0           my $cfg = config_read('EDTK_DB');
281            
282            
283             ################################################################################
284             # POUR GÉRER DYNAMIQUEMENT L'INDEX, LES OPÉRATIONS DE LECTURE CI-DESSOUS DEVRAIENT
285             # soit intégrer la boucle de lecture de l'index, soit être remplacée par des liens
286             ################################################################################
287             #
288             # Récupération des paramètres de l'application documentaire.
289 0           my $doc = $pdbh->selectrow_hashref("SELECT * FROM EDTK_REFIDDOC WHERE ED_REFIDDOC = ? " .
290             "AND (ED_CORP = ? OR ED_CORP = '%')", undef, $app, $corp);
291 0 0         die ("ERROR: die in _omgr_insert, message is " . $pdbh->errstr . "\n") if $pdbh->err;
292 0 0         if (!defined($doc)) {
293 0           die "ERROR: Could not find document \"$app\" in EDTK_REFIDDOC\n";
294             }
295            
296             # Récupération du support pour la première page et les suivantes.
297 0           my $p1 = $pdbh->selectrow_hashref('SELECT * FROM EDTK_SUPPORTS WHERE ED_REFIMP = ?',
298             undef, $doc->{'ED_REFIMP_P1'});
299 0 0         die ("ERROR: die in _omgr_insert, message is " . $pdbh->errstr . "\n") if $pdbh->err;
300 0 0         if (!defined($p1)) {
301 0           die "ERROR: Could not find support \"$doc->{'ED_REFIMP_P1'}\" in EDTK_SUPPORTS\n";
302             }
303            
304 0           my $ps = $pdbh->selectrow_hashref('SELECT * FROM EDTK_SUPPORTS WHERE ED_REFIMP = ?',
305             undef, $doc->{'ED_REFIMP_PS'});
306 0 0         die ("ERROR: die in _omgr_insert, message is " . $pdbh->errstr . "\n") if $pdbh->err;
307 0 0         if (!defined($ps)) {
308 0           die "ERROR: Could not find support \"$doc->{'ED_REFIMP_PS'}\" in EDTK_SUPPORTS\n";
309             }
310            
311             # Récupération de la liste des encarts à joindre pour ce document,
312             # et en déduire le poids supplémentaire à ajouter à chaque pli
313 0   0       my @encrefs = split(/,/, $doc->{'ED_REFIMP_REFIDDOC'} || "");
314 0           my $now = strftime("%Y%m%d", localtime());
315 0 0         my $sth = $pdbh->prepare('SELECT * FROM EDTK_SUPPORTS WHERE ED_REFIMP = ?')
316             or die ("ERROR: die in _omgr_insert, message is " . $pdbh->errstr);
317 0           my $encpds = 0;
318 0           my @needed = ();
319            
320 0           foreach my $encref (@encrefs) {
321             # L'ERREUR EST ICI : ON DEVRAIT AJOUTER DES LIGNES D'INDEX PAR ENCART AVEC TYPIMP = E dupliqué pour chaque encart à partir de la dernière ligne du document xxxxxx
322 0 0         my $enc = $pdbh->selectrow_hashref($sth, undef, $encref) or die ("ERROR: in omgr for encref $encref " . $pdbh->errstr . "\n");
323             #warn "DEBUG: looking for encart ".$enc->{'ED_REFIMP'}." for $now\n";
324 0 0 0       if (defined($enc->{'ED_DEBVALID'}) && length($enc->{'ED_DEBVALID'}) > 0 && $enc->{'ED_DEBVALID'} ne '99999999') {
      0        
325 0 0         next if $now < $enc->{'ED_DEBVALID'};
326             }
327 0 0 0       if (defined($enc->{'ED_FINVALID'}) && length($enc->{'ED_FINVALID'}) > 0) {
328 0 0         next if $now > $enc->{'ED_FINVALID'};
329             }
330 0           $encpds += $enc->{'ED_POIDSUNIT'};
331 0           push(@needed, $encref);
332             }
333 0   0       my $listerefenc = join(', ', @needed) || "none"; # xxx réfléchir impact mise sous pli, en dur ou paramétrable dans table supports ?
334             #warn "DEBUG: selected listerefenc => $listerefenc\n";
335             # POUR GÉRER DYNAMIQUEMENT L'INDEX, LES OPÉRATIONS DE LECTURE CI-DESSUS DEVRAIENT
336             # soit intégrer la boucle de lecture de l'index, soit être remplacée par des liens
337             ################################################################################
338            
339            
340            
341             # LOOP THROUGH THE INDEX FILE, GATHERING ENTRIES AND COUNTING THE NUMBER OF PAGES, ETC...
342 0           my $numpgpli = 0;
343 0           my $seqpgdoc = 0;
344 0           my $idldoc = undef;
345 0 0         open(my $fh, '<', $in) or die "ERROR: Cannot open index file \"$in\": $!\n";
346 0           my $prevseq = -1;
347 0           my $count = 0;
348            
349 0           my $csv = Text::CSV->new({ binary => 1, sep_char => ';' });
350 0           while (<$fh>) {
351             # PARSE THE CSV DATA AND EXTRACT ALL THE FIELDS.
352             # THE NEXT THREE LINES ARE NEEDED FOR THE COMPUSET CASE.
353             # THIS IS WHY WE USE TEXT::CSV::PARSE() AND TEXT::CSV::FIELDS()
354             # INSTEAD OF JUST TEXT::CSV::GETLINE().
355 0           s/^<50>//;
356 0           s/<53>.*$//;
357 0           s/\s*<[^>]*>\s*/;/g;
358            
359 0           $csv->parse($_);
360 0           my @data = $csv->fields();
361            
362             # Truncate the CP field if necessary.
363             # Si le CP est supérieur à 10 caractères, il est tronqué à 10 en prenant les 4 premiers suivi des 6 derniers
364 0 0         if (length($data[4]) > 10) {
365 0           warn "INFO : \"$data[4]\" truncated to 10 characters\n";
366 0           $data[4] = substr($data[4], 0, 4) . substr($data[4], -6);
367             }
368            
369             # Truncate the name of city field if necessary.
370 0 0         if (length($data[5]) > 30) {
371 0           warn "INFO : \"$data[5]\" truncated to 30 characters\n";
372 0           $data[5] =~ s/^(.{30}).*$/$1/;
373             }
374             # Truncate the name field if necessary.
375 0 0         if (length($data[7]) > 38) {
376 0           warn "INFO : \"$data[7]\" truncated to 38 characters\n";
377 0           $data[7] =~ s/^(.{38}).*$/$1/;
378             }
379            
380 0           my $first = $prevseq != $data[3]; # Is this the first page?
381 0 0         $idldoc = $data[1] unless defined $idldoc;
382            
383             # XXX Ces deux valeurs sont identiques pour le moment car on a qu'un document
384             # par pli, mais ce ne sera pas le cas une fois que le regroupement sera implémenté.
385 0 0         if ($first) {
386 0           $numpgpli = 1;
387 0           $seqpgdoc = 1;
388             } else {
389 0           $numpgpli++;
390 0           $seqpgdoc++;
391             }
392            
393 0 0 0       my $entry = {
    0          
394             ED_REFIDDOC => $data[0],
395             ED_IDLDOC => $idldoc,
396             ED_IDSEQPG => $data[2],
397             ED_SEQDOC => $data[3],
398             ED_CPDEST => $data[4],
399             ED_VILLDEST => $data[5],
400             ED_IDDEST => $data[6],
401             ED_NOMDEST => $data[7],
402             ED_IDEMET => $data[8],
403             ED_DTEDTION => $data[9],
404             ED_TYPPROD => $data[10],
405             ED_PORTADR => $doc->{'ED_PORTADR'}, # vérifier qu'on peut le gérer comme ED_TYPPROD
406             ED_ADRLN1 => $data[12],
407             ED_CLEGED1 => $data[13],
408             ED_ADRLN2 => $data[14],
409             ED_CLEGED2 => $data[15],
410             ED_ADRLN3 => $data[16],
411             ED_CLEGED3 => $data[17],
412             ED_ADRLN4 => $data[18],
413             ED_CLEGED4 => $data[19],
414             ED_ADRLN5 => $data[20],
415             ED_CORP => $data[21],
416             ED_DOCLIB => $data[22],
417             ED_REFIMP => $data[23],
418             ED_ADRLN6 => $data[24],
419             ED_SOURCE => $data[25],
420             ED_OWNER => $data[26],
421             ED_HOST => $data[27],
422             ED_IDIDX => $data[28],
423             ED_CATDOC => $data[29] || $doc->{'ED_CATDOC'},
424             ED_CODRUPT => $data[30],
425             ED_SEQPGDOC => $seqpgdoc,
426             ED_POIDSUNIT => $first ? $p1->{'ED_POIDSUNIT'} : $ps->{'ED_POIDSUNIT'},
427             ED_NBENC => scalar @needed, # ceci est un hack incompatible avec le regroupement de plis
428             ED_ENCPDS => $encpds, # ceci est un hack incompatible avec le regroupement de plis
429             ED_BAC_INSERT => $first ? $p1->{'ED_BAC_INSERT'} : $ps->{'ED_BAC_INSERT'},
430             ED_TYPED => $doc->{'ED_TYPED'},
431             ED_MODEDI => $doc->{'ED_MODEDI'},
432             ED_FORMATP => $doc->{'ED_FORMATP'},
433             ED_PGORIEN => $doc->{'ED_PGORIEN'},
434             # ED_FORMDEF => $doc->{'ED_FORMDEF'},
435             # ED_PAGEDEF => $doc->{'ED_PAGEDEF'},
436             # ED_FORMS => $doc->{'ED_FORMS'},
437             #ED_IDPLI =>
438             ED_NBDOCPLI => 1, # XXX Sera différent de 1 quand on fera du regroupement
439             ED_NUMPGPLI => $numpgpli,
440             ED_LISTEREFENC => $listerefenc,
441             ED_TYPOBJ => 'I' # XXX Il nous manque des données pour ce champ
442             };
443            
444             # On ne remplit le champ pré-imprimé que s'il n'est pas renseigné dans l'index.
445 0 0         if (length($entry->{'ED_REFIMP'}) == 0) {
446 0 0         $entry->{'ED_REFIMP'} = $first ? $doc->{'ED_REFIMP_P1'} : $doc->{'ED_REFIMP_PS'};
447             }
448            
449 0           my @cols = keys(%$entry);
450 0           my $sql = "INSERT INTO " . $cfg->{'EDTK_DBI_OUTMNGR'} . " (" . join(',', @cols) .
451             ") VALUES (" . join(',', ('?') x @cols) . ")";
452 0           my $sth = $dbh->prepare_cached($sql);
453             # warn "INFO : insert Query = $sql\n";
454             # warn "INFO : insert values = ". dump (%$entry) . "\n"; # bug d'insertion de certaines valeurs dans Postgres
455            
456 0           eval {
457 0           $sth->execute(values(%$entry));
458             };
459 0 0         if ($@) {
460 0           warn "ERROR: $@\n";
461 0           eval { $dbh->rollback };
  0            
462 0           die "ERROR: rollback done before dying in omgr_insert\n";
463             }
464            
465 0           $prevseq = $entry->{'ED_SEQDOC'};
466 0           $count++;
467             }
468 0           close($fh);
469            
470             # Mise à jour de ED_NBPGDOC.
471 0           my $sql = 'UPDATE ' . $cfg->{'EDTK_DBI_OUTMNGR'} . ' i SET ED_NBPGDOC = '
472             . '(SELECT COUNT(*) FROM ' . $cfg->{'EDTK_DBI_OUTMNGR'}
473             . ' WHERE ED_IDLDOC = ? AND ED_SEQDOC = i.ED_SEQDOC) WHERE ED_IDLDOC = ?';
474 0           $dbh->do($sql, undef, $idldoc, $idldoc);
475            
476             # Initialisation de ED_NBPGPLI à ED_NBPGDOC; sera différent si on fait du regroupement.
477 0           $sql = 'UPDATE ' . $cfg->{'EDTK_DBI_OUTMNGR'} . ' i SET ED_NBPGPLI = ED_NBPGDOC ' .
478             'WHERE ED_IDLDOC = ?';
479 0           $dbh->do($sql, undef, $idldoc);
480            
481             # Maintenant que l'on a calculé ED_NBPGPLI on peut mettre ED_MODEDI à jour.
482 0           $sql = "UPDATE " . $cfg->{'EDTK_DBI_OUTMNGR'} . " SET " .
483             "ED_MODEDI = " .
484             "CASE ED_MODEDI WHEN 'S' THEN 'R' ELSE CASE ED_NBPGPLI WHEN 1 THEN 'R' ELSE 'V' END END " .
485             "WHERE ED_IDLDOC = ?";
486 0           $dbh->do($sql, undef, $idldoc);
487 0           warn "INFO : Imported $count pages\n";
488 0           return ($idldoc, scalar @needed, $encpds);
489             }
490            
491            
492             sub _omgr_lot($$$) {
493             # RAPPROCHEMENT ENTRE DOCUMENTS DE L'INDEX ET TABLE DES LOTS => AFFECTATION DU LOT
494 0     0     my ($dbh, $pdbh, $idldoc) = @_;
495 0           my $cfg = config_read('EDTK_DB');
496            
497             # Sélection des lots appropriés.
498 0           my $sql = 'SELECT ED_IDLOT, ED_REFIDDOC, ED_CPDEST, ED_FILTER, ED_GROUPBY, ED_IDMANUFACT, ED_IDGPLOT ' .
499             'FROM EDTK_LOTS ORDER BY ED_PRIORITE';
500 0           my $sth = $pdbh->prepare($sql);
501 0           $sth->execute();
502 0           while (my $lot = $sth->fetchrow_hashref()) {
503             # On essaye de matcher des documents avec ce lot.
504 0           $sql = 'UPDATE ' . $cfg->{'EDTK_DBI_OUTMNGR'} . ' SET ED_IDLOT = ? ' ;
505            
506             #XXX AJOUTER GESTION DES REFENC / LOT : AJOUT ED_REFENC À ED_LISTREFENC
507             # if (defined $lot->{'ED_REFENC'}) {
508             # ajouter ED_REFENC à ED_LISTREFENC
509             # }
510            
511 0           my $where = ' WHERE ED_IDLOT IS NULL AND ED_IDLDOC = ? ';
512 0 0         if ($lot->{'ED_REFIDDOC'}=~/\%/) {
513 0           $where .= " AND ED_REFIDDOC LIKE ? ";
514             } else {
515 0           $where .= " AND ED_REFIDDOC = ? ";
516             }
517 0           my @values=($lot->{'ED_IDLOT'}, $idldoc, $lot->{'ED_REFIDDOC'});
518            
519 0 0         if (defined $lot->{'ED_CPDEST'}) {
520 0           $where .= " AND ED_CPDEST LIKE ? ";
521 0           push (@values, $lot->{'ED_CPDEST'});
522             }
523 0 0 0       if (defined $lot->{'ED_FILTER'} and $lot->{'ED_FILTER'}=~/\=/) {
524 0           $where .= " AND " . $lot->{'ED_FILTER'};
525             }
526            
527 0           my $num = $dbh->do($sql . $where, undef, @values);
528            
529 0 0         if ($num > 0) {
530 0           warn "INFO : Assigned $num pages to lot \"$lot->{'ED_IDLOT'}\"\n";
531             }
532             }
533            
534             # On assigne les entrées restantes au lot par défaut.
535 0           my $num = $dbh->do("UPDATE " . $cfg->{'EDTK_DBI_OUTMNGR'} . " SET ED_IDLOT = ? " .
536             "WHERE ED_IDLDOC = ? AND ED_IDLOT IS NULL", undef, DEFLOT, $idldoc);
537 0 0         if ($num > 0) {
538 0           warn "INFO : Assigned $num remaining pages to default lot \"" . DEFLOT . "\"\n";
539             }
540             }
541            
542            
543             sub _get_next_filiere ($$){
544 0     0     my ($pdbh, $filiere) = @_;
545            
546             # Récupération des paramètres d'assignation de la filiere.
547 0 0         my ($ed_priorite, $ed_idmanufact, $ed_typed, $ed_modedi, $ed_idgplot, $ed_nbbacprn)
548             = $pdbh->selectrow_array('select ED_PRIORITE, ED_IDMANUFACT, ED_TYPED, ED_MODEDI, ED_IDGPLOT, ED_NBBACPRN from EDTK_FILIERES where ED_IDFILIERE =? ',
549             undef, $filiere) or die ("ERROR: in _get_next_filiere, message is " . $pdbh->errstr);
550             # Récupération du 1er élément de la liste ordonnée des filieres.
551 0           my $next_filiere
552             = $pdbh->selectrow_array('select ED_IDFILIERE from EDTK_FILIERES where ED_IDMANUFACT =? and ED_TYPED =? and ED_MODEDI =? and ED_NBBACPRN >=? and ED_ACTIF =? and ED_IDFILIERE !=? and ED_PRIORITE >? and (ED_IDGPLOT = ? or ED_IDGPLOT = ?) order by ED_PRIORITE',
553             undef, $ed_idmanufact, $ed_typed, $ed_modedi, $ed_nbbacprn, 'O', $filiere, $ed_priorite, $ed_idgplot, '%');
554            
555 0   0       $next_filiere||=DEFFIL;
556             #warn "DEBUG: next_filiere is $next_filiere\n";
557 0           return $next_filiere;
558             }
559            
560            
561             sub _omgr_filiere($$$$$$) {
562 0     0     my ($dbh, $pdbh, $app, $idldoc, $numencs, $encpds) = @_;
563 0           my $cfg = config_read('EDTK_DB');
564            
565             # Récupération des paramètres de l'application documentaire.
566 0 0         my $doc = $pdbh->selectrow_hashref('SELECT * FROM EDTK_REFIDDOC WHERE ED_REFIDDOC = ?',
567             undef, $app) or die ("ERROR: die in _omgr_filiere, message is " . $pdbh->errstr);
568            
569             # # Récupération de la liste des encarts à joindre à ce document,
570             # # et en déduire le poids supplémentaire à ajouter à chaque pli.
571             # my @encarts = split(/,/, $doc->{'ED_REFIMP_REFIDDOC'});
572             # my $encpds = 0;
573             # my $sth = $pdbh->prepare('SELECT ED_POIDSUNIT FROM EDTK_SUPPORTS '
574             # . 'WHERE ED_REFIMP = ?')
575             # or die "ERROR: select on supports failed " . $pdbh->errstr;
576             # foreach my $encart (@encarts) {
577             # my $pref = $pdbh->selectrow_arrayref($sth, undef, $encart)
578             # or die "ERROR: on support weight " . $pdbh->errstr;
579             # $encpds += $pref->[0];
580             # }
581            
582             # Récupération du support pour la première page et les suivantes.
583 0 0         my $p1 = $pdbh->selectrow_hashref('SELECT * FROM EDTK_SUPPORTS WHERE ED_REFIMP = ?',
584             undef, $doc->{'ED_REFIMP_P1'}) or die ("ERROR: die in _omgr_filiere, message is " . $pdbh->errstr);
585 0 0         my $ps = $pdbh->selectrow_hashref('SELECT * FROM EDTK_SUPPORTS WHERE ED_REFIMP = ?',
586             undef, $doc->{'ED_REFIMP_PS'}) or die ("ERROR: die in _omgr_filiere, message is " . $pdbh->errstr);
587            
588             # On recherche toutes les entrées qui ont un lot assigné
589             # mais pas encore de filière cf EDTK LOTS
590 0           my $sql = 'SELECT DISTINCT ED_IDLOT FROM ' . $cfg->{'EDTK_DBI_OUTMNGR'} .
591             ' WHERE ED_IDLDOC = ? AND ED_IDLOT IS NOT NULL AND ED_IDFILIERE IS NULL';
592 0           my $lotids = $dbh->selectcol_arrayref($sql, undef, $idldoc);
593            
594 0           foreach my $lotid (@$lotids) {
595 0 0         my $lot = $pdbh->selectrow_hashref('SELECT * FROM EDTK_LOTS WHERE ED_IDLOT = ?',
596             undef, $lotid) or die ("ERROR: die in _omgr_filiere, message is " . $pdbh->errstr);
597            
598             # On essaye maintenant de matcher les documents avec chacune des filières.
599 0           my $sql = "SELECT * FROM EDTK_FILIERES WHERE ED_ACTIF = 'O' "
600             . "AND (ED_IDMANUFACT IS NULL OR ED_IDMANUFACT = '' OR ED_IDMANUFACT = ?) "
601             . "ORDER BY ED_PRIORITE ASC";
602 0 0         my $sth = $pdbh->prepare($sql) or die ("ERROR: die in _omgr_filiere, message is " . $pdbh->errstr);
603 0           $sth->execute($lot->{'ED_IDMANUFACT'});
604            
605             # LES CONTRAINTES EN NOMBRE MINIMUM/MAXIMUM DE PAGES ET PLIS SONT VÉRIFIÉES
606             # UNIQUEMENT LORSQU'ON EXPORTE LES LOTS DANS OMGR_EXPORT() POUR PERMETTRE
607             # LE REGROUPEMENT.
608 0           while (my $fil = $sth->fetchrow_hashref()) {
609             # compatibilite ascendante
610 0 0 0       if (defined $fil->{'ED_IDGPLOT'} && length($fil->{'ED_IDGPLOT'}) > 0) {
611 0 0 0       if ($lot->{'ED_IDGPLOT'} ne $fil->{'ED_IDGPLOT'} and $fil->{'ED_IDGPLOT'} ne "%") {
612 0           next;
613             }
614             }
615            
616 0 0 0       if (defined $fil->{'ED_NBENCMAX'} && length($fil->{'ED_NBENCMAX'}) > 0) {
617 0 0         next if $numencs > $fil->{'ED_NBENCMAX'};
618             }
619             # La formule nous permettant de calculer le nombre de feuilles d'un pli.
620             # à faire évoluer pour le regroupement xxxxx
621 0 0         my $sqlnbfpli = "$numencs + "
622             . ($fil->{'ED_MODEDI'} eq 'V' ? 'CEIL(ED_NBPGPLI / 2)' : 'ED_NBPGPLI');
623             # La formule calculant le poids total du pli, et les valeurs associées.
624             # xxxx la formule est fausse car $sqlnbfpli décompte déjà les encarts
625             # xxxx il faudrait faire la somme des poids des objets recto du plis (à condition de bien avoir 1 ligne / élément)
626 0           my $sqlpdspli = "$encpds + $p1->{'ED_POIDSUNIT'} + $ps->{'ED_POIDSUNIT'} * ($sqlnbfpli - 1)";
627            
628 0           my $sql = "UPDATE " . $cfg->{'EDTK_DBI_OUTMNGR'} . " SET ED_IDFILIERE = ?, " .
629             "ED_FORMFLUX = ?, ED_NBFPLI = $sqlnbfpli, ED_PDSPLI = $sqlpdspli " .
630             "WHERE ED_IDLDOC = ? AND ED_IDLOT = ? AND ED_IDFILIERE IS NULL " .
631             "AND ED_MODEDI LIKE ? AND ED_TYPED LIKE ? ";
632 0           my @vals = ($fil->{'ED_IDFILIERE'}, $fil->{'ED_FORMFLUX'}, $idldoc,
633             $lotid, $fil->{'ED_MODEDI'}, $fil->{'ED_TYPED'});
634 0 0 0       if (defined $fil->{'ED_POIDS_PLI'} && length($fil->{'ED_POIDS_PLI'}) > 0) {
635 0           $sql .= " AND $sqlpdspli <= ?";
636 0           push(@vals, $fil->{'ED_POIDS_PLI'});
637             }
638 0 0 0       if (defined $fil->{'ED_FEUILPLI'} && length($fil->{'ED_FEUILPLI'}) > 0) {
639 0           $sql .= " AND $sqlnbfpli <= ?";
640 0           push(@vals, $fil->{'ED_FEUILPLI'});
641             }
642 0           my $num = $dbh->do($sql, undef, @vals);
643 0 0         if ($num > 0) {
644 0           warn "INFO : Assigned $num pages to filiere \"$fil->{'ED_IDFILIERE'}\" " .
645             "($fil->{'ED_DESIGNATION'})\n";
646             }
647             }
648             }
649             }
650            
651            
652             sub omgr_export(%) {
653 0     0 0   my (%conds) = @_;
654            
655 0           my $cfg = config_read('EDTK_DB');
656 0           my $dbh = db_connect($cfg, 'EDTK_DBI_DSN', { AutoCommit => 0, RaiseError => 1 });
657 0           omgr_check_doclibs($dbh);
658            
659 0           my $pdbh= db_connect($cfg, 'EDTK_DBI_PARAM');
660             # _omgr_filiere2($dbh, $pdbh, $app, $idldoc, $numencs, $encpds);
661            
662 0           my $basedir = $cfg->{'EDTK_DIR_OUTMNGR'};
663            
664 0           my @done = ();
665 0           eval {
666             # Transformation des éventuels filtres utilisateurs en clause WHERE.
667 0           my $user_where = join(' AND ', map { "$_ = ?" } keys(%conds));
  0            
668            
669             # Cette requête sélectionne les couples (idlot,idfiliere) contenant des plis non affectés.
670 0           my $idsql = 'SELECT DISTINCT ED_IDLOT, ED_IDFILIERE, ED_CORP FROM ' . $cfg->{'EDTK_DBI_OUTMNGR'} .
671             ' WHERE ED_IDLOT IS NOT NULL AND ED_IDFILIERE IS NOT NULL AND ED_SEQLOT IS NULL';
672 0 0         if (length($user_where) > 0) {
673 0           $idsql .= " AND $user_where";
674             }
675 0           my $ids = $dbh->selectall_arrayref($idsql, undef, values(%conds));
676            
677 0           foreach (@$ids) { # il faut tenir compte de l'ordre de priorité des filières
678 0           my ($idlot, $idfiliere, $idcorp) = @$_;
679            
680 0           CHECK_FIL:
681             {
682 0           warn "INFO : Considering OMGR tuple : $idlot, $idfiliere, $idcorp\n";
683             # La clause WHERE que l'on réutilise dans la plupart des requêtes afin de ne
684             # traiter que les entrées qui nous intéressent.
685 0           my $where = 'WHERE ED_IDLOT = ? AND ED_IDFILIERE = ? AND ED_CORP = ? AND ED_SEQLOT IS NULL';
686 0 0         if (length($user_where) > 0) {
687 0           $where .= " AND $user_where";
688             }
689 0           my @wvals = ($idlot, $idfiliere, $idcorp, values(%conds));
690            
691 0           my $fil = $pdbh->selectrow_hashref('SELECT * FROM EDTK_FILIERES WHERE ED_IDFILIERE = ?',
692             undef, $idfiliere);
693 0           my $lot = $pdbh->selectrow_hashref('SELECT * FROM EDTK_LOTS WHERE ED_IDLOT = ?',
694             undef, $idlot);
695            
696             # On verrouille la table $cfg->{'EDTK_DBI_OUTMNGR'} pour s'assurer que des entrées ne soient pas
697             # ajoutées entre le moment ou on fait nos calculs et le moment ou on fait l'UPDATE.
698 0           $dbh->do('LOCK TABLE ' . $cfg->{'EDTK_DBI_OUTMNGR'} . ' IN SHARE ROW EXCLUSIVE MODE');
699            
700             # Si le lot définit une colonne pour la valeur de ED_GROUPBY, on doit découper
701             # les lots d'envoi en fonction de cette colonne. De plus, on découpe toujours
702             # par entité émettrice, format de papier, type de production et liste d'encarts.
703 0           my @gcols = ('ED_CORP', 'ED_FORMATP', 'ED_TYPPROD', 'ED_LISTEREFENC');
704            
705 0 0 0       if (defined($lot->{'ED_GROUPBY'}) && length($lot->{'ED_GROUPBY'}) > 0) {
706 0           push(@gcols, split(/,/, $lot->{'ED_GROUPBY'}));
707             }
708 0           my $groups = $dbh->selectall_arrayref("SELECT DISTINCT "
709             . join(', ', @gcols) . " FROM " . $cfg->{'EDTK_DBI_OUTMNGR'}
710             . " $where", { Slice => {} }, @wvals);
711            
712 0           foreach my $gvals (@$groups) {
713 0           my $where2 = $where; # vérifier qu'on l'utilise bien ...
714 0           my @wvals2 = @wvals;
715            
716 0 0         if (keys(%$gvals) > 0) {
717             # check if every value is defined and could be used (ED_LISTEREFENC could be defined or not)
718             ## which can produce this message : Issuing rollback() for database handle being DESTROY'd without explicit disconnect()
719 0           foreach my $key (keys (%$gvals)) {
720 0 0         if (defined $$gvals{$key}){} else {delete $$gvals{$key}}
  0            
721             }
722            
723 0           push(@wvals2, values(%$gvals));
724 0           $where2 .= ' AND ' . join(' AND ', map { "$_ = ?" } keys(%$gvals));
  0            
725             }
726            
727             # On calcule le nombre de plis de chaque taille.
728 0           my $innersql = 'SELECT DISTINCT ED_IDLDOC, ED_SEQDOC, ED_NBPGPLI FROM ' .
729             $cfg->{'EDTK_DBI_OUTMNGR'};
730            
731 0           my $sql = "SELECT COUNT(*), i.ED_NBPGPLI FROM ($innersql $where2) i " .
732             "GROUP BY i.ED_NBPGPLI ORDER BY i.ED_NBPGPLI DESC";
733 0           my $res = $dbh->selectall_arrayref($sql, undef, @wvals2);
734 0 0         next if @$res == 0;
735            
736             # Calcul du nombre total de plis et de pages à notre disposition.
737 0           my $availplis= sum(map { $$_[0] } @$res);
  0            
738 0           my $availpgs = sum(map { $$_[0] * $$_[1] } @$res);
  0            
739            
740             # Aura-t-on besoin de repasser un traitement pour ce couple (idlot/idfiliere)
741             # et pour le groupe définit par les colonnes de @gcols?
742 0           my $more = 0;
743            
744             # Le nombre maximal de plis/pages que l'on peut prendre (soit la
745             # limite de la filière, soit l'intégralité disponible).
746 0 0 0       if (defined($fil->{'ED_MAXPLIS'}) && $availplis > $fil->{'ED_MAXPLIS'}) {
747 0           $availplis = $fil->{'ED_MAXPLIS'};
748 0           $more = 1;
749             }
750            
751 0 0         if (defined($fil->{'ED_MAXFEUIL_L'})) {
752 0           my $maxpgs = $fil->{'ED_MAXFEUIL_L'};
753 0 0         if ($fil->{'ED_MODEDI'} eq 'V') {
754 0           $maxpgs *= 2;
755             }
756 0 0         if ($availpgs > $maxpgs) {
757 0           $availpgs = $maxpgs;
758 0           $more = 1;
759             }
760             }
761            
762 0           my @plis = ();
763 0           my $selplis = 0;
764 0           my $selpgs = 0;
765 0           foreach (@$res) {
766 0           my ($numplis, $nbpgpli) = @$_;
767            
768             # Si on ne peut plus rajouter de plis ou de pages, on arrête.
769 0 0 0       last if $availplis == 0 || $availpgs == 0;
770            
771             # Il n'y a pas suffisamment de pages disponibles pour ajouter de
772             # pli de cette taille, on essaye donc avec de plus petits plis.
773 0 0         next if $availpgs < $nbpgpli;
774            
775 0           my $nbplis = int($availpgs / $nbpgpli);
776 0 0         if ($nbplis > $availplis) {
777 0           $nbplis = $availplis;
778             }
779 0 0         if ($nbplis > $numplis) {
780 0           $nbplis = $numplis;
781             }
782 0           my $nbpgs = $nbplis * $nbpgpli;
783            
784 0           push(@plis, [$nbplis, $nbpgpli]);
785 0           $availplis -= $nbplis;
786 0           $availpgs -= $nbpgs;
787 0           $selplis += $nbplis;
788 0           $selpgs += $nbpgs;
789             }
790            
791             # On vérifie qu'on a sélectionné suffisamment de pages et de plis pour
792             # remplir les limites basses de la filière si elles existent.
793 0   0       my $min_feuilles = $fil->{'ED_MINFEUIL_L'} || 1;
794 0 0         if ($selpgs < $min_feuilles) {
795 0           warn "INFO : Not enough pages for filiere \"$idfiliere\" : "
796             ."got $selpgs, need $min_feuilles\n";
797 0           $more = 1; # à vérifier qu'on en a bien besoin
798             # _get_next_filiere($pdbh, $idfiliere);
799             # reset filiere avec relance eval ou completion liste @$ids ? xxxxxxxxxxxxx
800             # cf 388
801 0           my $sql = "UPDATE " . $cfg->{'EDTK_DBI_OUTMNGR'} . " SET ED_IDFILIERE = ? " .
802             "WHERE ED_IDLOT = ? AND ED_IDFILIERE = ? AND ED_CORP = ? AND ED_SEQLOT IS NULL ";
803 0           my $next_filiere = _get_next_filiere($pdbh, $idfiliere);
804 0           my @vals= ($next_filiere, $idlot, $idfiliere, $idcorp);
805 0           my $num = $dbh->do($sql, undef, @vals);
806 0           $dbh->commit; # voir si on peut éviter pour bénéficier du rollback en cas de besoin de reprise
807             #warn "DEBUG: downgrade filiere to $next_filiere for $num pages\n";
808 0           $idfiliere = $next_filiere;
809 0           redo CHECK_FIL;
810             }
811 0   0       my $minplis = $fil->{'ED_MINPLIS'} || 1;
812 0 0         if ($selplis < $minplis) {
813 0           warn "INFO : Not enough plis for filiere \"$idfiliere\" : "
814             ."got $selplis, need $minplis\n";
815 0           $more = 1; # à vérifier qu'on en a bien besoin
816             # _get_next_filiere($pdbh, $idfiliere);
817             # reset filiere avec relance eval ou completion liste @$ids ? xxxxxxxxxxxxx
818             # cf 388
819 0           my $sql = "UPDATE " . $cfg->{'EDTK_DBI_OUTMNGR'} . " SET ED_IDFILIERE = ? " .
820             "WHERE ED_IDLOT = ? AND ED_IDFILIERE = ? AND ED_CORP = ? AND ED_SEQLOT IS NULL ";
821 0           my $next_filiere = _get_next_filiere($pdbh, $idfiliere);
822 0           my @vals = ($next_filiere, $idlot, $idfiliere, $idcorp);
823 0           my $num = $dbh->do($sql, undef, @vals);
824 0           $dbh->commit; # voir si on peut éviter pour bénéficier du rollback en cas de besoin de reprise
825 0           warn "INFO : downgrade filiere to $next_filiere for $num pages\n";
826 0           $idfiliere = $next_filiere;
827 0           redo CHECK_FIL;
828             }
829            
830 0           my $seqlot = _get_seqlot($dbh);
831 0           my $name = "$gvals->{'ED_CORP'}.$lot->{'ED_IDMANUFACT'}.$seqlot.$lot->{'ED_LOTNAME'}.$fil->{'ED_IDFILIERE'}";
832            
833             # Préparation de l'ordre de tri pour cette filière.
834 0           my $order;
835 0 0 0       if (defined $fil->{'ED_SORT'} && length($fil->{'ED_SORT'}) > 0) {
836 0           $order = $fil->{'ED_SORT'};
837 0 0 0       if (defined $fil->{'ED_DIRECTION'} && length($fil->{'ED_DIRECTION'}) > 0) {
838 0           $order .= " $fil->{'ED_DIRECTION'}";
839             }
840             } else {
841 0           $order = "ED_IDLDOC, ED_SEQDOC";
842             }
843            
844             # La date d'aujourd'hui.
845 0           my $dtlot = sprintf("%04d%02d%02d", Today());
846            
847 0           foreach (@plis) {
848 0           my ($nbplis, $nbpgpli) = @$_;
849            
850             #warn "DEBUG: Assigning $nbplis of $nbpgpli pages each to lot $seqlot\n";
851             # Cette requête sélectionne les N premiers plis non affectés
852             # d'une taille donnée, les plis étant uniquement identifiés avec
853             # un identifiant de lot de document + un identifiant de pli.
854 0           $innersql = "SELECT j.ED_IDLDOC, j.ED_SEQDOC FROM (" .
855             "SELECT i.ED_IDLDOC, i.ED_SEQDOC, ROW_NUMBER() " .
856             "OVER (ORDER BY PGNUM) AS PLINUM FROM " .
857             "(SELECT " . $cfg->{'EDTK_DBI_OUTMNGR'} . ".*, ROW_NUMBER() OVER (ORDER BY $order) AS PGNUM " .
858             "FROM " . $cfg->{'EDTK_DBI_OUTMNGR'} . " $where2 AND ED_NBPGPLI = ?) i " .
859             "WHERE ED_SEQPGDOC = 1) j WHERE PLINUM <= ?";
860            
861             # On assigne le lot à tous les plis sélectionnés. On en profite
862             # aussi pour positionner la date de création du lot.
863 0           $sql = "UPDATE " . $cfg->{'EDTK_DBI_OUTMNGR'} . " SET ED_SEQLOT = ?, ED_DTLOT = ? " .
864             "WHERE (ED_IDLDOC, ED_SEQDOC) IN ($innersql)";
865 0           my $count = $dbh->do($sql, undef, $seqlot, $dtlot, @wvals2, $nbpgpli, $nbplis);
866 0           my $pages = $nbplis * $nbpgpli;
867 0 0         if ($count != $pages) {
868 0           die "ERROR: Unexpected UPDATE row count ($count != $pages)\n";
869             }
870             }
871 0           warn "INFO : Assigned $selpgs pages to lot \"$name\"\n";
872            
873             # Calcul des identifiants de pli. XXX Devrait être fait autrement...
874 0           $sql = "SELECT ED_IDLDOC, ED_SEQDOC, " .
875             "DENSE_RANK() OVER (ORDER BY ED_IDLDOC, ED_SEQDOC) AS ED_IDPLI " .
876             "FROM " . $cfg->{'EDTK_DBI_OUTMNGR'} . " WHERE ED_SEQLOT = ? ORDER BY $order";
877 0           my $rows = $dbh->selectall_arrayref($sql, { Slice => {} }, $seqlot);
878            
879 0           $sql = 'UPDATE ' . $cfg->{'EDTK_DBI_OUTMNGR'} . ' SET ED_IDPLI = ? ' .
880             'WHERE ED_IDLDOC = ? AND ED_SEQDOC = ? AND ED_SEQLOT = ?';
881 0           my $sth = $dbh->prepare($sql);
882 0           foreach my $row (@$rows) {
883 0           $sth->execute($row->{'ED_IDPLI'}, $row->{'ED_IDLDOC'},
884             $row->{'ED_SEQDOC'}, $seqlot);
885             }
886            
887             # Récupération de la liste des imprimés nécessaires pour ce lot.
888 0           $sql = 'SELECT DISTINCT ED_REFIMP FROM ' . $cfg->{'EDTK_DBI_OUTMNGR'} .
889             ' WHERE ED_SEQLOT = ?';
890 0           my @refimps = $dbh->selectrow_array($sql, undef, $seqlot);
891            
892             # Calcul du nombre total de feuilles dans le lot.
893 0           $sql = "SELECT SUM(i.ED_NBFPLI) "
894             . " FROM (SELECT DISTINCT ED_IDLDOC, ED_SEQDOC, ED_NBFPLI "
895             . " FROM " . $cfg->{'EDTK_DBI_OUTMNGR'}
896             . " WHERE ED_SEQLOT = ?) i ";
897 0           my ($nbfeuillot) = $dbh->selectrow_array($sql, undef, $seqlot);
898 0           my $nbfaceslot = $nbfeuillot;
899 0 0         if ($fil->{'ED_MODEDI'} ne 'R'){$nbfaceslot *= 2;}
  0            
900            
901            
902             # Extraction des données.
903 0           my $lotdir = "$basedir/$name";
904 0 0         mkdir("$lotdir") or die "ERROR: Cannot create directory \"$lotdir\": $!\n";
905 0           my $file = "$name.idx";
906 0           warn "INFO : Creating index file \"$file\"\n";
907 0           $sql = "SELECT * FROM " . $cfg->{'EDTK_DBI_OUTMNGR'} .
908             " WHERE ED_SEQLOT = ? ORDER BY $order";
909 0           $sth = $dbh->prepare($sql);
910 0           $sth->execute($seqlot);
911            
912 0 0         open(my $fh, ">$lotdir/$file") or die ("ERROR: die in omgr_export, message is " . $!);
913             # Génération de la ligne de header.
914 0           my $csv = Text::CSV->new({ binary => 1, eol => "\n", quote_space => 0 });
915 0           $csv->print($fh, [map { $$_[0] } @INDEX_COLS]);
  0            
916 0           my $doclib;
917 0           while (my $row = $sth->fetchrow_hashref()) {
918             # Gather the values in the same order as @INDEX_COLS.
919 0           my @fields = map { $row->{$$_[0]} } @INDEX_COLS;
  0            
920 0           $csv->print($fh, \@fields);
921            
922 0 0         $doclib = $row->{'ED_DOCLIB'} unless defined $doclib;
923             }
924 0           close($fh);
925            
926             # Generate a job ticket file.
927 0           $file = "$name.job";
928 0           warn "INFO : Creating job ticket file \"$file\"\n";
929 0   0       my @jobfields = (
      0        
930             ['ED_PRIORITE', $lot->{'ED_PRIORITE'}],
931             ['ED_REFIDDOC', $lot->{'ED_REFIDDOC'}],
932             ['ED_IDLOT', $idlot],
933             ['ED_SEQLOT', $seqlot],
934             ['ED_CORP', $gvals->{'ED_CORP'}],
935             ['ED_GROUPBY', $lot->{'ED_GROUPBY'}],
936             ['ED_CPDEST', $lot->{'ED_CPDEST'}],
937             ['ED_REFENC', $lot->{'ED_REFENC'}],
938             ['ED_LOTNAME', $lot->{'ED_LOTNAME'}],
939             ['ED_IDMANUFACT', $lot->{'ED_IDMANUFACT'}],
940             ['ED_IDFILIERE', $idfiliere],
941             ['ED_DESIGNATION', $fil->{'ED_DESIGNATION'}],
942             ['ED_MODEDI', $fil->{'ED_MODEDI'}],
943             ['ED_TYPED', $fil->{'ED_TYPED'}],
944             ['ED_NBBACPRN', $fil->{'ED_NBBACPRN'}],
945             ['ED_MINFEUIL_L', $fil->{'ED_MINFEUIL_L'}],
946             ['ED_MAXFEUIL_L', $fil->{'ED_MAXFEUIL_L'}],
947             ['ED_FEUILPLI', $fil->{'ED_FEUILPLI'}],
948             ['ED_MINPLIS', $fil->{'ED_MINPLIS'}],
949             ['ED_MAXPLIS', $fil->{'ED_MAXPLIS'}],
950             ['ED_POIDS_PLI', $fil->{'ED_POIDS_PLI'}],
951             ['ED_REF_ENV', $fil->{'ED_REF_ENV'}],
952             ['ED_FORMFLUX', $fil->{'ED_FORMFLUX'}],
953             ['ED_POSTCOMP', $fil->{'ED_POSTCOMP'}],
954             ['ED_NBFACESLOT', $nbfaceslot],
955             ['ED_NBFEUILLOT', $nbfeuillot],
956             ['ED_NBPLISLOT', $selplis],
957             ['ED_FORMATP', $gvals->{'ED_FORMATP'}],
958             ['ED_CONSIGNE', $lot->{'ED_CONSIGNE'}],
959             ['ED_LISTEREFENC', $gvals->{'ED_LISTEREFENC'} || ""],
960             ['ED_LISTEREFIMP', join(', ', @refimps) || ""], # si je mets ce champs en dernier, je plante latex...
961             ['ED_DTLOT', $dtlot]
962            
963             );
964 0 0         open($fh, ">$lotdir/$file") or die ("ERROR: die in omgr_export, message is " . $!);
965 0           $csv->print($fh, [map { $$_[0] } @jobfields]);
  0            
966 0           $csv->print($fh, [map { $$_[1] } @jobfields]);
  0            
967 0           close($fh);
968            
969             # Add this lot to the list of created ones.
970 0           $dbh->commit;
971 0           push(@done, [$name, $doclib]);
972            
973             # On reboucle le traitement si l'on a atteint les limites maximales en
974             # pages/plis et que l'on doit traiter d'autres lots.
975 0 0         redo if $more;
976             }
977             }
978             }
979             };
980 0 0         if ($@) {
981 0           warn "ERROR: $@\n";
982 0           eval { $dbh->rollback };
  0            
983 0           die "ERROR: die after outmngr rollback !\n";
984             }
985 0           return @done;
986             }
987            
988            
989             sub omgr_depot_poste($$$) {
990 0     0 0   my ($dbh, $seqlot, $dt_depot) = @_;
991 0           my $cfg = config_read('EDTK_DB');
992            
993 0 0         $dt_depot=~/^\d{8}$/ or die "ERROR: $dt_depot should be formated as yyyymmdd\n";
994            
995 0           my $sql = 'UPDATE ' . $cfg->{'EDTK_DBI_OUTMNGR'} . ' SET ED_STATUS = ? WHERE ED_SEQLOT like ?';
996 0 0         $dbh->do($sql, undef, $dt_depot, $seqlot) or die "ERROR: can't update $seqlot with $dt_depot";
997             }
998            
999            
1000             sub _omgr_purge_db($$) {
1001 0     0     my ($dbh, $value) = @_;
1002 0           my $cfg = config_read('EDTK_STATS');
1003 0           my $type = "";
1004 0           my $sql;
1005            
1006 0 0         if ($value =~ /^\d{6,7}$/) { # 381123 ou 1381123
    0          
1007 0           $type = "SEQLOT";
1008 0           warn "INFO : suppr $type $value from EDTK_STATS_OUTMNGR\n";
1009 0           $sql = 'DELETE FROM ' . $cfg->{'EDTK_STATS_OUTMNGR'} . ' WHERE ED_SEQLOT = ?';
1010 0 0         $dbh->do($sql, undef, $value) or die "ERROR: suppr $type $value from EDTK_STATS_OUTMNGR\n";
1011            
1012             #} elsif (length ($value) == 16) { # 1282152443057128
1013             } elsif ($value =~ /^\d{16}$/) { # 1282152443057128
1014 0           $type = "SNGL_ID"; # EDTK_STATS_TRACKING
1015 0           warn "INFO : suppr $type $value from EDTK_STATS_TRACKING\n";
1016 0           $sql = 'DELETE FROM ' . $cfg->{'EDTK_STATS_TRACKING'} . ' WHERE ED_SNGL_ID = ?';
1017 0 0         $dbh->do($sql, undef, $value) or die "ERROR: suppr $type $value from EDTK_STATS_TRACKING\n";
1018            
1019 0           warn "INFO : suppr $type $value from EDTK_STATS_OUTMNGR\n";
1020 0           $sql = 'DELETE FROM '.$cfg->{'EDTK_STATS_OUTMNGR'}.' WHERE ED_IDLDOC = ?';
1021 0 0         $dbh->do($sql, undef, $value) or die "ERROR: suppr $type $value from EDTK_STATS_OUTMNGR\n";
1022            
1023             } else {
1024 0           die "ERROR: $value doesn't seem to be SNGL_ID or SEQLOT";
1025             }
1026             }
1027            
1028            
1029             sub omgr_check_seqlot_ref ($$;$){
1030 0     0 0   my ($dbh, $value, $idseqpg) = @_;
1031 0           my $cfg = config_read('EDTK_STATS');
1032 0           my $type = "SEQLOT";
1033 0           my $sql;
1034 0           $sql = "SELECT COUNT (DISTINCT A.ED_IDLDOC||TO_CHAR(A.ED_SEQDOC,'FM0000000')) AS NBDOCS,"
1035             . " A.ED_REFIDDOC, A.ED_IDLDOC,"
1036             . " COUNT (DISTINCT A.ED_IDLDOC||TO_CHAR(A.ED_IDSEQPG,'FM0000000')) AS NBPGS,"
1037             . " A.ED_SEQLOT,"
1038             . " COUNT (DISTINCT A.ED_IDLDOC||A.ED_SEQLOT||TO_CHAR(A.ED_IDPLI,'FM0000000')) AS NBPLIS,"
1039             . " NVL(B.ED_STATUS, NVL(A.ED_STATUS, 'PENDING...')) AS STATUS,"
1040             . " B.ED_DTPOST AS DTPOST, B.ED_DTPOST2 AS DTPOST2"
1041             . " FROM " . $cfg->{'EDTK_STATS_OUTMNGR'} . " A, EDTK_ACQ B"
1042             . " WHERE A.ED_SEQLOT=B.ED_SEQLOT (+)";
1043            
1044            
1045 0 0         if ($value =~/^\d{6,7}$/) { # 381123 or 1381123
    0          
1046 0           $type = "SEQLOT";
1047 0           $sql .=" AND A.ED_SEQLOT = ?"
1048             . " GROUP BY A.ED_REFIDDOC, A.ED_IDLDOC, A.ED_SEQLOT, B.ED_STATUS, A.ED_STATUS, B.ED_DTPOST, B.ED_DTPOST2 ";
1049 0           $idseqpg=0;
1050            
1051             } elsif ($value =~/^\d{16}$/) { # 1282152443057128
1052 0           $type = "IDLDOC";
1053 0           $sql .=" AND A.ED_IDLDOC = ?";
1054 0 0 0       if (defined $idseqpg && $idseqpg>0) {
1055 0           $sql .=" AND A.ED_IDSEQPG = ?";
1056             }
1057 0           $sql .=" GROUP BY A.ED_REFIDDOC, A.ED_IDLDOC, A.ED_SEQLOT, B.ED_STATUS, A.ED_STATUS, B.ED_DTPOST, B.ED_DTPOST2 ";
1058            
1059             } else {
1060 0           die "ERROR: $value doesn't seem to be SEQLOT OR IDLDOC\n";
1061             }
1062            
1063 0           my $sth = $dbh->prepare($sql);
1064 0 0 0       if (defined $idseqpg && $idseqpg>0) {
1065 0           $sth->execute($value, $idseqpg);
1066             } else {
1067 0           $sth->execute($value);
1068             }
1069            
1070 0           my $rows = $sth->fetchall_arrayref();
1071 0 0         if ($#$rows<0) {
1072 0           warn "INFO : pas de donnees associees.\n";
1073 0           exit;
1074             }
1075 0           my $fmt = "%7s %-16s %-16s %6s %-7s %7s %10s %8s %8s";
1076 0           my @head= ("NB_DOCS", "REFIDDOC", "IDLDOC", "NB_PG", "SEQLOT", "NB_PLIS", "STATUS", "DTPOST", "DTPOST2");
1077            
1078 0           _filled_rows($rows);
1079 0           @$rows = (\$fmt, \@head, @$rows);
1080            
1081 0           return $rows;
1082             }
1083            
1084            
1085             sub omgr_stats_referent {
1086 0     0 0   my ($dbh, $pdbh) = @_;
1087 0           my $cfg = config_read('EDTK_STATS');
1088 0           my ($sql, $key);
1089            
1090 0           $sql = "SELECT A.ED_MAIL_REFERENT, A.ED_REFIDDOC ";
1091 0           $sql .=" FROM EDTK_REFIDDOC A, " . $cfg->{'EDTK_STATS_OUTMNGR'} . " B ";
1092 0           $sql .=" WHERE A.ED_REFIDDOC = B.ED_REFIDDOC ";
1093 0           $sql .=" AND A.ED_MASSMAIL != 'N' AND A.ED_MAIL_REFERENT IS NOT NULL ";
1094 0           $sql .=" AND B.ED_SEQLOT IS NULL AND B.ED_DTLOT IS NULL ";
1095 0           $sql .=" GROUP BY A.ED_MAIL_REFERENT, A.ED_REFIDDOC ";
1096 0           $sql .=" ORDER BY A.ED_MAIL_REFERENT ";
1097            
1098 0           my $sth = $dbh->prepare($sql);
1099 0           $sth->execute();
1100            
1101 0           my $rows = $sth->fetchall_arrayref();
1102 0           return $rows;
1103             }
1104            
1105            
1106             sub omgr_stats($$$$) {
1107 0     0 0   my ($dbh, $pdbh, $period, $typeRqt) = @_;
1108 0   0       $typeRqt = $typeRqt || "idlot";
1109 0           my $cfg = config_read('EDTK_STATS');
1110 0           my ($sql, $key);
1111 0           my $time = time;
1112 0           my ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
1113             Gmtime($time);
1114 0           my ($week,) = Week_of_Year($year,$month,$day);
1115            
1116 0 0         if ($period =~ /^day$/i) {
    0          
    0          
    0          
1117 0           $key = sprintf ("%1d%02d%1d", $year % 10, $week, $dow );
1118             } elsif ($period =~ /^week$/i){
1119 0           $key = sprintf("%1d%02d", $year % 10, $week);
1120             } elsif ($period =~ /^all$/i){
1121 0           $key="";
1122             } elsif ($period =~ /^\d+$/){
1123 0           $key = $period;
1124             } else {
1125 0           warn "INFO : implémentation en attente évolution base\n";
1126             }
1127            
1128 0           my @head;
1129 0 0         if ($typeRqt !~/idlot/i) {
1130 0           @head= ("CORP", "LOT", "PLIS", "DOCS", "FEUILLES", "PAGES", "FACES", "FIL.");
1131 0           $sql = "SELECT ED_CORP, ED_IDLOT, ";
1132             } else {
1133 0           @head= ("CORP", "LOT", "ID_SEQLOT", "PLIS", "DOCS", "FEUILLES", "PAGES", "FACES", "FIL.");
1134 0           $sql = "SELECT ED_CORP, ED_IDLOT, ED_SEQLOT, ";
1135             }
1136 0           $sql .="COUNT (DISTINCT ED_IDLDOC||TO_CHAR(ED_SEQDOC,'FM0000000')), "; # NB PLIS # ne tient pas compte des éventuels regroupement à revoir : (DISTINCT TO_CHAR(ED_SEQLOT,'FM0000000')||TO_CHAR(ED_IDPLI,'FM0000000'))
1137 0           $sql .="COUNT (DISTINCT ED_IDLDOC||TO_CHAR(ED_SEQDOC,'FM0000000')), "; # NB DOCS
1138 0           $sql .="SUM(ED_NBFPLI), "; # NB FEUILLES
1139 0           $sql .="SUM(ED_NBPGDOC), "; # NB FACES IMPRIMEES
1140 0           $sql .="CASE ED_MODEDI WHEN 'R' THEN 1 ELSE 2 END * SUM(ED_NBFPLI) "; # NB FACES
1141            
1142 0 0         if ($typeRqt !~/idlot/i) {
1143 0           $sql .=", ED_MODEDI ";
1144 0           $sql .=" FROM " . $cfg->{'EDTK_STATS_OUTMNGR'};
1145 0           $sql .=" GROUP BY ED_CORP, ED_IDLOT, ED_MODEDI ";
1146 0           $sql .=" ORDER BY ED_CORP, ED_IDLOT, ED_MODEDI ";
1147             } else {
1148 0           $sql .=", ED_IDFILIERE ";
1149 0           $sql .=" FROM " . $cfg->{'EDTK_STATS_OUTMNGR'};
1150 0           $sql .=" WHERE ED_SEQLOT LIKE ? AND ED_SEQPGDOC = 1 ";
1151 0           $sql .=" GROUP BY ED_CORP, ED_IDLOT, ED_SEQLOT, ED_IDFILIERE, ED_MODEDI ";
1152 0           $sql .=" ORDER BY ED_CORP, ED_IDFILIERE, ED_SEQLOT ";
1153             }
1154            
1155 0           my $sth = $dbh->prepare($sql);
1156 0 0         if ($typeRqt !~/idlot/i) {
1157 0           $sth->execute();
1158             } else {
1159 0           $sth->execute("$key%");
1160             }
1161            
1162 0           my $rows = $sth->fetchall_arrayref();
1163 0           foreach my $row (@$rows) {
1164 0           my ($lot) = $pdbh->selectrow_array('SELECT ED_LOTNAME FROM EDTK_LOTS WHERE ED_IDLOT = ?',
1165             undef, @$row[1]);
1166 0           @$row[1] = $lot;
1167             }
1168            
1169 0           my $fmt = "%-8s%-16s" . "%9s" x (@head - 3) . " %-6s\n";
1170 0           @$rows = (\$fmt, \@head, @$rows);
1171            
1172             #my $fmt = shift (@$rows);
1173             #my $head = shift (@$rows);
1174             #printf $$fmt . "\n", @$head;
1175             #
1176             #foreach my $row (@$rows) {
1177             # printf $$fmt . "\n", @$row;
1178             #}
1179            
1180 0           return $rows;
1181             }
1182            
1183            
1184             sub omgr_lot_pending($) {
1185             # RECHERCHE DES DOCUMENTS EN ATTENTE DE LOTISSEMENT
1186             # c'est à dire les documents dont le seqlot est null
1187             # Est utilisé par index_Purge_DCLIB
1188 0     0 0   my ($dbh) = @_;
1189 0           my $cfg = config_read('EDTK_DB');
1190            
1191             #-- RECHERCHE DES DOCUMENTS EN ATTENTE DE LOTISSEMENT --
1192 0           my $ctrl_sql = 'SELECT ED_CORP, ED_REFIDDOC, ED_IDLDOC, ED_DTEDTION FROM ' . $cfg->{'EDTK_DBI_OUTMNGR'}
1193             . ' WHERE ED_SEQLOT IS NULL'
1194             . ' GROUP BY ED_CORP, ED_REFIDDOC, ED_DTEDTION, ED_IDLDOC'
1195             . ' ORDER BY ED_CORP, ED_REFIDDOC, ED_DTEDTION, ED_IDLDOC';
1196            
1197 0           my $sth = $dbh->prepare($ctrl_sql);
1198 0           $sth->execute();
1199            
1200 0           my $rows = $sth->fetchall_arrayref();
1201 0           return $rows;
1202             }
1203            
1204            
1205             # LOOKS IF NEEDED DOCLIBS ARE IN EDTK_DIR_DOCLIB
1206             sub omgr_check_doclibs ($){
1207 0     0 0   my ($dbh) = shift;
1208            
1209 0           my $cfg = config_read('EDTK_DB');
1210 0           my $dir = $cfg->{'EDTK_DIR_DOCLIB'};
1211 0           my $host= hostname();
1212            
1213 0           my $sql = 'SELECT DISTINCT ED_DOCLIB FROM ' . $cfg->{'EDTK_DBI_OUTMNGR'} .
1214             ' WHERE ED_SEQLOT IS NULL AND ED_HOST = ? ';
1215            
1216             # Transform the list of needed doclibs into a hash for speed.
1217 0           my %needed = map { $_->[0] => 1 } @{$dbh->selectall_arrayref($sql, undef, $host)};
  0            
  0            
1218            
1219 0           foreach my $key (keys %needed) {
1220 0 0         if (-e "$dir/$key") {
1221             } else {
1222 0           die "ERROR: missing DOCLIB $key for current DSN\n";
1223             }
1224             }
1225            
1226             }
1227            
1228            
1229             # PURGE DOCLIBS THAT ARE NO LONGER REFERENCED IN THE DATABASE.
1230             sub omgr_purge_fs($) {
1231 0     0 0   my ($dbh) = shift;
1232 0           db_backup_agent($dbh);
1233            
1234 0           my $cfg = config_read('EDTK_DB');
1235 0           my $dir = $cfg->{'EDTK_DIR_DOCLIB'};
1236 0           my @doclibs = glob("$dir/*.pdf");
1237 0           my $weeks_kept=0;
1238            
1239 0 0 0       unless (defined ($cfg->{'EDTK_DCLIB_PURGE_WEEKS_KEPT'}) && $cfg->{'EDTK_DCLIB_PURGE_WEEKS_KEPT'} > 0){
1240 0           warn "INFO : EDTK_DCLIB_PURGE_WEEKS_KEPT not defined for optimization purge.\n";
1241             } else {
1242 0           $weeks_kept=$cfg->{'EDTK_DCLIB_PURGE_WEEKS_KEPT'};
1243             }
1244            
1245 0           my ($year,$month,$day) = Today();
1246 0           ($year,$month,$day) = Add_Delta_Days($year, $month, $day, (-7*$weeks_kept));
1247 0           my $search_date = sprintf("%04d%02d%02d", $year,$month,$day);;
1248            
1249 0           my $sql = "SELECT DISTINCT ED_DOCLIB FROM " . $cfg->{'EDTK_DBI_OUTMNGR'} .
1250             " WHERE ED_SEQLOT IS NULL OR ED_DTEDTION > '".$search_date."' ";
1251            
1252             # Transform the list of needed doclibs into a hash for speed.
1253 0           warn "INFO : omgr_purge_fs identifies needed doclibs to safe them.\n";
1254 0           my %needed = map { $_->[0] => 1 } @{$dbh->selectall_arrayref($sql)};
  0            
  0            
1255            
1256 0           my @torm = ();
1257 0           foreach my $path (@doclibs) {
1258 0           my $file = basename($path);
1259 0 0         if ($file =~ /^DCLIB_/) {
1260 0 0         if (!$needed{$file}) {
1261 0           push(@torm, $path);
1262             }
1263             } else {
1264 0           warn "INFO : Unexpected filename : \"$file\"\n";
1265             }
1266             }
1267            
1268 0           warn "INFO : omgr_purge_fs done.\n";
1269 0           return @torm;
1270             }
1271            
1272            
1273             # PRIVATE, NON-EXPORTED FUNCTIONS BELOW.
1274             ########################################
1275            
1276             # Compute a new and unique lot sequence.
1277             sub _get_seqlot {
1278 0     0     my $dbh = shift;
1279            
1280 0           my $sql;
1281 0 0         if ($dbh->{'Driver'}->{'Name'} eq 'Oracle') {
1282             # sysdate produit le seqlot pour avoir l'année iso sur 1 caractère I
1283             # http://www.techonthenet.com/oracle/functions/to_char.php
1284 0           $sql = "SELECT to_char(sysdate, 'IIWD') || " .
1285             "to_char(EDTK_IDLOT.NEXTVAL, 'FM000') FROM dual";
1286            
1287             } else {
1288             # http://developer.postgresql.org/pgdocs/postgres/functions-formatting.html
1289 0           $sql = "SELECT to_char(current_date, 'IIWID') || " .
1290             "to_char(nextval('EDTK_IDLOT'), 'FM000')";
1291             }
1292 0           my ($seqlot) = $dbh->selectrow_array($sql);
1293 0           return $seqlot;
1294             }
1295            
1296            
1297             sub _filled_rows(\@){
1298             # pour s'assurer que chaque cellule contient au moins un blanc et éviter les warning de printf en cas de fusion avec une cellule non définie
1299 0     0     my $refRows =shift;
1300            
1301 0           foreach my $row (@$refRows) {
1302 0           for (my $i=0; $i<=$#$row ; $i++){
1303 0   0       $$row[$i] = $$row[$i] || ""; # DANS LE CAS DE SEQLOT IL PEUT ARRIVER QU'IL NE SOIT PAS ENCORE RENSEIGNE
1304             }
1305             }
1306            
1307 0           return @{$refRows};
  0            
1308             }
1309            
1310            
1311             sub _print_All_rTab($){
1312             # EDITION DE L'ENSEMBLE DES DONNÉES D'UN TABLEAU PASSÉ EN REFÉRENCE
1313             # affichage du tableau en colonnes
1314 0     0     my $rTab=shift;
1315            
1316 0           for (my $i=0 ; $i<=$#{$rTab} ; $i++) {
  0            
1317 0           my $cols = $#{$$rTab[$i]};
  0            
1318 0           print "\n$i:\t";
1319            
1320 0           for (my $j=0 ;$j<=$cols ; $j++){
1321 0 0         print "$$rTab[$i][$j]" if (defined $$rTab[$i][$j]);
1322             }
1323             }
1324 0           print "\n";
1325 0           1;
1326             }
1327            
1328 1     1   7 END {
1329            
1330             }
1331            
1332             1;