Die Funktion Form::parse_html_template2() in Form::parse_html_template() umbenannt...
[kivitendo-erp.git] / sql / Pg-upgrade / Pg-upgrade-2.2.0.25-2.2.0.26.pl
1 #!/usr/bin/perl
2
3 # Datenbankupgrade: Einfuehrung von Einheiten
4
5 die("This script cannot be run from the command line.") unless ($main::form);
6
7 sub mydberror {
8   my ($msg) = @_;
9   die($dbup_locale->text("Database update error:") .
10       "<br>$msg<br>" . $DBI::errstr);
11 }
12
13 sub myshowerror {
14   my ($msg) = @_;
15
16   print $main::form->parse_html_template("dbupgrade/units_error", { "message" => $msg });
17   return 2;
18 }
19
20 sub get_base_unit {
21   my ($units, $unit_name, $factor) = @_;
22
23   $factor = 1 unless ($factor);
24
25   my $unit = $units->{$unit_name};
26
27   if (!defined($unit) || !$unit->{"base_unit"} ||
28       ($unit_name eq $unit->{"base_unit"})) {
29     return ($unit_name, $factor);
30   }
31
32   return get_base_unit($units, $unit->{"base_unit"}, $factor * $unit->{"factor"});
33 }
34
35 sub retrieve_units {
36   my ($myconfig, $form, $type, $prefix) = @_;
37
38   my $query = "SELECT *, base_unit AS original_base_unit FROM units";
39   my @values;
40   if ($type) {
41     $query .= " WHERE (type = ?)";
42     @values = ($type);
43   }
44
45   my $sth = $dbh->prepare($query);
46   $sth->execute(@values) || $form->dberror($query . " (" . join(", ", @values) . ")");
47
48   my $units = {};
49   while (my $ref = $sth->fetchrow_hashref()) {
50     $units->{$ref->{"name"}} = $ref;
51   }
52   $sth->finish();
53
54   my $query_lang = "SELECT id, template_code FROM language ORDER BY description";
55   $sth = $dbh->prepare($query_lang);
56   $sth->execute() || $form->dberror($query_lang);
57   my @languages;
58   while ($ref = $sth->fetchrow_hashref()) {
59     push(@languages, $ref);
60   }
61   $sth->finish();
62
63   foreach my $unit (values(%{$units})) {
64     ($unit->{"${prefix}base_unit"}, $unit->{"${prefix}factor"}) = get_base_unit($units, $unit->{"name"});
65   }
66
67   return $units;
68 }
69
70 sub unit_select_data {
71   my ($units, $selected, $empty_entry) = @_;
72
73   my $select = [];
74
75   if ($empty_entry) {
76     push(@{$select}, { "name" => "", "base_unit" => "", "factor" => "", "selected" => "" });
77   }
78
79   foreach my $unit (sort({ lc($a) cmp lc($b) } keys(%{$units}))) {
80     push(@{$select}, { "name" => $unit,
81                        "base_unit" => $units->{$unit}->{"base_unit"},
82                        "factor" => $units->{$unit}->{"factor"},
83                        "selected" => ($unit eq $selected) ? "selected" : "" });
84   }
85
86   return $select;
87 }
88
89 sub update_units_add_unit {
90   my $form = $main::form;
91
92   return 0 unless ($form->{"new_name"});
93
94   return myshowerror($dbup_locale->text("The name is missing."))
95     if ($form->{"new_name"} eq "");
96   my $units = retrieve_units(\%dbup_myconfig, $form);
97   return myshowerror($dbup_locale->text("A unit with this name does already exist."))
98     if ($units->{$form->{"new_name"}});
99   $units = retrieve_units(\%dbup_myconfig, $form, $form->{"unit_type"});
100
101   my ($base_unit, $factor);
102   if ($form->{"new_base_unit"}) {
103     return myshowerror($dbup_locale->text("The base unit does not exist."))
104       unless (defined($units->{$form->{"new_base_unit"}}));
105
106     return myshowerror($dbup_locale->text("The factor is missing."))
107       if ($form->{"new_factor"} eq "");
108     $factor = $form->parse_amount(\%dbup_myconfig, $form->{"new_factor"});
109     return myshowerror($dbup_locale->text("The factor is missing."))
110       unless ($factor);
111     $base_unit = $form->{"new_base_unit"};
112   }
113
114   my $query = "INSERT INTO units " .
115     "(name, base_unit, factor, type) " .
116     "VALUES (?, ?, ?, ?)";
117   $dbh->do($query, undef, $form->{"new_name"}, $base_unit, $factor,
118            $form->{"unit_type"}) ||
119     mydberror($query .
120               " ($form->{new_name}, $base_unit, $factor, $form->{unit_type})");
121   $dbh->commit();
122   $dbh->begin_work();
123
124   $form->{"saved_message"} = $dbup_locale->text("The unit has been saved.");
125
126   return 0;
127 }
128
129 sub update_units_assign_units {
130   my ($query, $sth, @values);
131
132   my $form = $main::form;
133
134   foreach my $table (qw(parts invoice orderitems rmaitems)) {
135     $query = "UPDATE $table SET unit = ? WHERE lower(unit) = ?";
136     $sth = $dbh->prepare($query);
137
138     for (my $i = 1; $i <= $form->{"rowcount"}; $i++) {
139       next unless ($form->{"new_unit_$i"} && $form->{"old_unit_$i"});
140       @values = ($form->{"new_unit_$i"}, lc($form->{"old_unit_$i"}));
141       $sth->execute(@values) ||
142         mydberror($query . " (" . join(", ", @values) . ")");
143     }
144   }
145
146   $sth->finish();
147   $dbh->commit();
148   $dbh->begin_work();
149 }
150
151 sub update_units_assign_known {
152   my $form = $main::form;
153
154   my %unit_name_mapping = (
155     "st" => "Stck",
156     "st." => "Stck",
157     "stk" => "Stck",
158     "pc" => "Stck",
159     "pcs" => "Stck",
160     "ea" => "Stck",
161
162     "h" => "Std",
163     "stunde" => "Std",
164     "tage" => "Tag",
165     );
166
167   my $i = 1;
168   foreach my $k (keys(%unit_name_mapping)) {
169     $form->{"old_unit_$i"} = $k;
170     $form->{"new_unit_$i"} = $unit_name_mapping{$k};
171     $i++;
172   }
173   $form->{"rowcount"} = scalar(keys(%unit_name_mapping));
174
175   update_units_assign_units();
176 }
177
178 sub update_units_steps_1_2 {
179   my (%unknown_dimension_units, %unknown_service_units);
180
181   my $form = $main::form;
182
183   foreach my $table (qw(parts invoice orderitems rmaitems)) {
184     my ($query, $sth, $ref);
185
186     if ($table eq "parts") {
187       $query = "SELECT unit, inventory_accno_id, assembly FROM parts " .
188         "WHERE NOT ((unit = '') OR unit ISNULL OR " .
189         "           unit IN (SELECT name FROM units))";
190
191     } else {
192       $query = "SELECT t.unit, p.inventory_accno_id, p.assembly " .
193         "FROM $table t " .
194         "LEFT JOIN parts p ON p.id = t.parts_id " .
195         "WHERE NOT ((t.unit = '') OR t.unit ISNULL OR " .
196         "           t.unit IN (SELECT name FROM units))";
197     }
198     $sth = $dbh->prepare($query);
199     $sth->execute() || mydberror($query);
200
201     while ($ref = $sth->fetchrow_hashref()) {
202       if ($ref->{"inventory_accno_id"} || $ref->{"assembly"}) {
203         $unknown_dimension_units{$ref->{"unit"}} = 1;
204
205       } else {
206         $unknown_service_units{$ref->{"unit"}} = 1;
207       }
208     }
209
210     $sth->finish();
211   }
212
213   if (scalar(keys(%unknown_dimension_units)) != 0) {
214     my $units = retrieve_units(\%dbup_myconfig, $form, "dimension");
215     my $ddbox = unit_select_data($units, undef, 1);
216
217     my @unknown_parts;
218     map({ push(@unknown_parts, { "name" => $_, "NEW_UNITS" => $ddbox }); }
219         sort({ lc($a) cmp lc($b) } keys(%unknown_dimension_units)));
220
221     print $form->parse_html_template("dbupgrade/units_parts",
222                                      { "NEW_BASE_UNIT_DDBOX" => $ddbox,
223                                        "UNKNOWN_PART_UNITS"  => \@unknown_parts,
224                                      });
225
226     return 2;
227
228   } else {
229     print $form->parse_html_template("dbupgrade/units_parts_done");
230   }
231
232   if (scalar(keys(%unknown_service_units)) != 0) {
233     my $units = retrieve_units(\%dbup_myconfig, $form, "service");
234     my $ddbox = unit_select_data($units, undef, 1);
235
236     my @unknown_services;
237     map({ push(@unknown_services, { "name" => $_, "NEW_UNITS" => $ddbox }); }
238         sort({ lc($a) cmp lc($b) } keys(%unknown_service_units)));
239
240     print $form->parse_html_template("dbupgrade/units_services",
241                                      { "NEW_BASE_UNIT_DDBOX" => $ddbox,
242                                        "UNKNOWN_PART_UNITS"  => \@unknown_services,
243                                      }));
244
245     return 2;
246
247   } else {
248     print $form->parse_html_template("dbupgrade/units_services_done");
249   }
250
251   return 0;
252 }
253
254 sub update_units_step_3 {
255   my $form = $main::form;
256
257   my $query = "SELECT ";
258   foreach my $table (qw(parts invoice orderitems rmaitems)) {
259     $query .= "(SELECT COUNT(*) FROM $table " .
260       "WHERE (unit ISNULL) OR (unit = '')) +";
261   }
262   substr($query, -1, 1) = "AS has_unassigned";
263   my ($has_unassigned) = $dbh->selectrow_array($query);
264
265   if ($has_unassigned) {
266     my $dimension_units = retrieve_units(\%dbup_myconfig, $form,
267                                              "dimension");
268     my $dimension_ddbox = unit_select_data($dimension_units);
269
270     my $service_units = retrieve_units(\%dbup_myconfig, $form, "service");
271     my $service_ddbox = unit_select_data($service_units);
272
273     print $form->parse_html_template("dbupgrade/units_set_default",
274                                      { "DIMENSION_DDBOX" => $dimension_ddbox,
275                                        "SERVICE_DDBOX"   => $service_ddbox });
276     return 2;
277
278   } else {
279     print $form->parse_html_template("dbupgrade/units_set_default_done");
280     return 1;
281   }
282 }
283
284 sub update_units_set_default {
285   my $form = $main::form;
286
287   foreach my $table (qw(parts invoice orderitems rmaitems)) {
288     my $base_query = "UPDATE $table SET unit = " .
289       $dbh->quote($form->{"default_service_unit"}) . " " .
290       "WHERE ((unit ISNULL) OR (unit = '')) AND ";
291     my $query;
292
293     if ($table eq "parts") {
294       $query = "UPDATE $table SET unit = " .
295         $dbh->quote($form->{"default_dimension_unit"}) . " " .
296         "WHERE ((unit ISNULL) OR (unit = '')) AND " .
297         "(assembly OR (inventory_accno_id > 0))";
298     } else {
299       $query = "UPDATE $table SET unit = " .
300         $dbh->quote($form->{"default_dimension_unit"}) . " " .
301         "WHERE ((unit ISNULL) OR (unit = '')) AND " .
302         "parts_id IN (SELECT id FROM parts WHERE " .
303         "(assembly OR (inventory_accno_id > 0)))";
304     }
305
306     $dbh->do($query) || mydberror($query);
307
308     if ($table eq "parts") {
309       $query = "UPDATE $table SET unit = " .
310         $dbh->quote($form->{"default_service_unit"}) . " " .
311         "WHERE ((unit ISNULL) OR (unit = '')) AND " .
312         "((inventory_accno_id ISNULL) OR (inventory_accno_id = 0)) AND " .
313         "NOT assembly";
314     } else {
315       $query = "UPDATE $table SET unit = " .
316         $dbh->quote($form->{"default_service_unit"}) . " " .
317         "WHERE ((unit ISNULL) OR (unit = '')) AND " .
318         "parts_id IN (SELECT id FROM parts " .
319         "WHERE ((inventory_accno_id ISNULL) OR (inventory_accno_id = 0)) " .
320         "AND NOT assembly)";
321     }
322
323     $dbh->do($query) || mydberror($query);
324   }
325 }
326
327 sub update_units {
328   my $form = $main::form;
329
330   my $res;
331
332   print $form->parse_html_template("dbupgrade/units_header");
333
334   if ($form->{"action2"} eq "add_unit") {
335     $res = update_units_add_unit();
336     return $res if ($res);
337
338   } elsif ($form->{"action2"} eq "assign_units") {
339     update_units_assign_units();
340
341   } elsif ($form->{"action2"} eq "set_default") {
342     update_units_set_default();
343
344   }
345
346   update_units_assign_known();
347
348   $res = update_units_steps_1_2();
349   return $res if ($res);
350
351   return update_units_step_3();
352 }
353
354 update_units();