Belegvorlagen: employee_id bei Umwandlung aus Drafts beibehalten
[kivitendo-erp.git] / sql / Pg-upgrade2 / convert_drafts_to_record_templates.pl
1 # @tag: convert_drafts_to_record_templates
2 # @description: Umwandlung von existierenden Entwürfen in Buchungsvorlagen für die Finanzbuchhaltung
3 # @depends: create_record_template_tables
4 package SL::DBUpgrade2::convert_drafts_to_record_templates;
5
6 use strict;
7 use utf8;
8
9 use YAML;
10
11 use parent qw(SL::DBUpgrade2::Base);
12
13 use SL::DBUtils;
14
15 sub prepare_statements {
16   my ($self) = @_;
17
18   $self->{q_draft} = qq|
19     SELECT description, form, employee_id
20     FROM drafts
21     WHERE module = ?
22 |;
23
24   $self->{q_template} = qq|
25     INSERT INTO record_templates (
26       template_name, template_type,  customer_id,    vendor_id,
27       currency_id,   department_id,  project_id,     employee_id,
28       taxincluded,   direct_debit,   ob_transaction, cb_transaction,
29       reference,     description,    ordnumber,      notes,
30       ar_ap_chart_id
31     ) VALUES (
32       ?, ? ,?, ?,
33       ?, ? ,?, ?,
34       ?, ? ,?, ?,
35       ?, ? ,?, ?,
36       ?
37     )
38     RETURNING id
39 |;
40
41   $self->{q_item} = qq|
42     INSERT INTO record_template_items (
43       record_template_id,
44       chart_id, tax_id,  project_id,
45       amount1,  amount2, source, memo
46     ) VALUES (
47       ?,
48       ?, ?, ?,
49       ?, ?, ?, ?
50     )
51 |;
52
53   $self->{h_draft}    = $self->dbh->prepare($self->{q_draft})    || die;
54   $self->{h_template} = $self->dbh->prepare($self->{q_template}) || die;
55   $self->{h_item}     = $self->dbh->prepare($self->{q_item})     || die;
56 }
57
58 sub fetch_auxilliary_data {
59   my ($self) = @_;
60
61   $self->{default_currency_id}  = selectfirst_hashref_query($::form, $self->dbh, qq|SELECT currency_id FROM defaults|)->{currency_id};
62   $self->{chart_ids_by_accno}   = { selectall_as_map($::form, $self->dbh, qq|SELECT id, accno FROM chart|,      'accno', 'id') };
63   $self->{currency_ids_by_name} = { selectall_as_map($::form, $self->dbh, qq|SELECT id, name  FROM currencies|, 'name',  'id') };
64 }
65
66 sub finish_statements {
67   my ($self) = @_;
68
69   $self->{h_item}->finish;
70   $self->{h_template}->finish;
71   $self->{h_draft}->finish;
72 }
73
74 sub migrate_ar_drafts {
75   my ($self) = @_;
76
77   $self->{h_draft}->execute('ar') || die $self->{h_draft}->errstr;
78
79   while (my $draft_record = $self->{h_draft}->fetchrow_hashref) {
80     my $draft       = YAML::Load($draft_record->{form});
81     my $currency_id = $self->{currency_ids_by_name}->{$draft->{currency}};
82     my $employee_id = $draft_record->{employee_id} || $draft->{employee_id} || (split m{--}, $draft->{employee})[1] || undef;
83
84     next unless $currency_id;
85
86     my @values = (
87       # template_name, template_type, customer_id, vendor_id,
88       $draft_record->{description} // $::locale->text('unnamed record template'),
89       'ar_transaction',
90       $draft->{customer_id} || undef,
91       undef,
92
93       # currency_id, department_id, project_id, employee_id,
94       $currency_id,
95       $draft->{department_id}    || undef,
96       $draft->{globalproject_id} || undef,
97       $employee_id,
98
99       # taxincluded,   direct_debit, ob_transaction, cb_transaction,
100       $draft->{taxincluded}  ? 1 : 0,
101       $draft->{direct_debit} ? 1 : 0,
102       0,
103       0,
104
105       # reference, description, ordnumber, notes,
106       undef,
107       undef,
108       $draft->{ordnumber},
109       $draft->{notes},
110
111       # ar_ap_chart_id
112       $self->{chart_ids_by_accno}->{$draft->{ARselected}},
113     );
114
115     $self->{h_template}->execute(@values) || die $self->{h_template}->errstr;
116     my ($template_id) = $self->{h_template}->fetchrow_array;
117
118     foreach my $row (1..$draft->{rowcount}) {
119       my ($chart_accno) = split m{--}, $draft->{"AR_amount_${row}"};
120       my ($tax_id)      = split m{--}, $draft->{"taxchart_${row}"};
121       my $chart_id      = $self->{chart_ids_by_accno}->{$chart_accno // ''};
122       my $amount        = $::form->parse_amount($self->{format}, $draft->{"amount_${row}"});
123
124       # $tax_id may be 0 as there's an entry in tax with id = 0.
125       # $chart_id must not be 0 as there's no entry in chart with id = 0.
126       next unless $chart_id && (($tax_id // '') ne '');
127
128       @values = (
129         # record_template_id,
130         $template_id,
131
132         # chart_id, tax_id, project_id,
133         $chart_id,
134         $tax_id,
135         $draft->{"project_id_${row}"} || undef,
136
137         # amount1, amount2, source, memo
138         $amount,
139         undef,
140         undef,
141         undef,
142       );
143
144       $self->{h_item}->execute(@values) || die $self->{h_item}->errstr;
145     }
146   }
147 }
148
149 sub migrate_ap_drafts {
150   my ($self) = @_;
151
152   $self->{h_draft}->execute('ap') || die $self->{h_draft}->errstr;
153
154   while (my $draft_record = $self->{h_draft}->fetchrow_hashref) {
155     my $draft       = YAML::Load($draft_record->{form});
156     my $currency_id = $self->{currency_ids_by_name}->{$draft->{currency}};
157     my $employee_id = $draft_record->{employee_id} || $draft->{employee_id} || (split m{--}, $draft->{employee})[1] || undef;
158
159     next unless $currency_id;
160
161     my @values = (
162       # template_name, template_type, customer_id, vendor_id,
163       $draft_record->{description} // $::locale->text('unnamed record template'),
164       'ap_transaction',
165       undef,
166       $draft->{vendor_id} || undef,
167
168       # currency_id, department_id, project_id, employee_id,
169       $currency_id,
170       $draft->{department_id}    || undef,
171       $draft->{globalproject_id} || undef,
172       $employee_id,
173
174       # taxincluded,   direct_debit, ob_transaction, cb_transaction,
175       $draft->{taxincluded}   ? 1 : 0,
176       $draft->{direct_credit} ? 1 : 0,
177       0,
178       0,
179
180       # reference, description, ordnumber, notes,
181       undef,
182       undef,
183       $draft->{ordnumber},
184       $draft->{notes},
185
186       # ar_ap_chart_id
187       $self->{chart_ids_by_accno}->{$draft->{APselected}},
188     );
189
190     $self->{h_template}->execute(@values) || die $self->{h_template}->errstr;
191     my ($template_id) = $self->{h_template}->fetchrow_array;
192
193     foreach my $row (1..$draft->{rowcount}) {
194       my ($chart_accno) = split m{--}, $draft->{"AP_amount_${row}"};
195       my ($tax_id)      = split m{--}, $draft->{"taxchart_${row}"};
196       my $chart_id      = $self->{chart_ids_by_accno}->{$chart_accno // ''};
197       my $amount        = $::form->parse_amount($self->{format}, $draft->{"amount_${row}"});
198
199       # $tax_id may be 0 as there's an entry in tax with id = 0.
200       # $chart_id must not be 0 as there's no entry in chart with id = 0.
201       next unless $chart_id && (($tax_id // '') ne '');
202
203       @values = (
204         # record_template_id,
205         $template_id,
206
207         # chart_id, tax_id, project_id,
208         $chart_id,
209         $tax_id,
210         $draft->{"project_id_${row}"} || undef,
211
212         # amount1, amount2, source, memo
213         $amount,
214         undef,
215         undef,
216         undef,
217       );
218
219       $self->{h_item}->execute(@values) || die $self->{h_item}->errstr;
220     }
221   }
222 }
223
224 sub migrate_gl_drafts {
225   my ($self) = @_;
226
227   $self->{h_draft}->execute('gl') || die $self->{h_draft}->errstr;
228
229   while (my $draft_record = $self->{h_draft}->fetchrow_hashref) {
230     my $draft       = YAML::Load($draft_record->{form});
231     my $employee_id = $draft_record->{employee_id} || $draft->{employee_id} || (split m{--}, $draft->{employee})[1] || undef;
232
233     my @values = (
234       # template_name, template_type, customer_id, vendor_id,
235       $draft_record->{description} // $::locale->text('unnamed record template'),
236       'gl_transaction',
237       undef,
238       undef,
239
240       # currency_id, department_id, project_id, employee_id,
241       $self->{default_currency_id},
242       $draft->{department_id} || undef,
243       undef,
244       $employee_id,
245
246       # taxincluded,   direct_debit, ob_transaction, cb_transaction,
247       $draft->{taxincluded}    ? 1 : 0,
248       0,
249       $draft->{ob_transaction} ? 1 : 0,
250       $draft->{cb_transaction} ? 1 : 0,
251
252       # reference, description, ordnumber, notes,
253       $draft->{reference},
254       $draft->{description},
255       undef,
256       undef,
257
258       # ar_ap_chart_id
259       undef,
260     );
261
262     $self->{h_template}->execute(@values) || die $self->{h_template}->errstr;
263     my ($template_id) = $self->{h_template}->fetchrow_array;
264
265     foreach my $row (1..$draft->{rowcount}) {
266       my ($chart_accno) = split m{--}, $draft->{"accno_${row}"};
267       my ($tax_id)      = split m{--}, $draft->{"taxchart_${row}"};
268       my $chart_id      = $self->{chart_ids_by_accno}->{$chart_accno // ''};
269       my $debit         = $::form->parse_amount($self->{format}, $draft->{"debit_${row}"});
270       my $credit        = $::form->parse_amount($self->{format}, $draft->{"credit_${row}"});
271
272       # $tax_id may be 0 as there's an entry in tax with id = 0.
273       # $chart_id must not be 0 as there's no entry in chart with id = 0.
274       next unless $chart_id && (($tax_id // '') ne '');
275
276       @values = (
277         # record_template_id,
278         $template_id,
279
280         # chart_id, tax_id, project_id,
281         $chart_id,
282         $tax_id,
283         $draft->{"project_id_${row}"} || undef,
284
285         # amount1, amount2, source, memo
286         $debit,
287         $credit,
288         $draft->{"source_${row}"},
289         $draft->{"memo_${row}"},
290       );
291
292       $self->{h_item}->execute(@values) || die $self->{h_item}->errstr;
293     }
294   }
295 }
296
297 sub clean_drafts {
298   my ($self) = @_;
299
300   $self->db_query(qq|DELETE FROM drafts WHERE module IN ('ar', 'ap', 'gl')|);
301 }
302
303 sub run {
304   my ($self) = @_;
305
306   # A dummy for %::myconfig used for parsing numbers. The existing
307   # drafts have a fundamental flaw: they store numbers & dates in the
308   # database still formatted to the user's preferences. Determining
309   # the correct format is not possible. Therefore this script simply
310   # assumes that the installation is used by people with German
311   # preferences regarding both settings.
312   $self->{format} = {
313     numberformat => '1000,00',
314     dateformat   => 'dd.mm.yy',
315   };
316
317   $self->prepare_statements;
318   $self->fetch_auxilliary_data;
319   $self->migrate_ar_drafts;
320   $self->migrate_ap_drafts;
321   $self->migrate_gl_drafts;
322   $self->clean_drafts;
323   $self->finish_statements;
324
325   return 1;
326 }
327
328 1;