Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 62726dfd

Von Sven Schöling vor mehr als 8 Jahren hinzugefügt

  • ID 62726dfdf4f763efa65c25fcfe8658d98649c8a8
  • Vorgänger b8376fba
  • Nachfolger 12727b13

Drafts: Ausgelagert in Controller

Unterschiede anzeigen:

SL/Controller/Draft.pm
1
package SL::Controller::Draft;
2

  
3
use strict;
4

  
5
use parent qw(SL::Controller::Base);
6

  
7
use SL::Helper::Flash qw(flash);
8
use SL::Locale::String qw(t8);
9
use SL::Request;
10
use SL::DB::Draft;
11
use SL::DBUtils qw(selectall_hashref_query);
12
use YAML;
13
use List::Util qw(max);
14

  
15
use Rose::Object::MakeMethods::Generic (
16
 scalar => [ qw() ],
17
 'scalar --get_set_init' => [ qw(module submodule draft) ],
18
);
19

  
20
__PACKAGE__->run_before('check_auth');
21

  
22
my %allowed_modules = map { $_ => "bin/mozilla/$_.pl" } qw(is ir ar ap);
23

  
24
#
25
# actions
26
#
27

  
28
sub action_draft_dialog {
29
  my ($self) = @_;
30
  $self->js
31
    ->dialog->open({
32
      html   => $self->dialog_html,
33
      id     => 'save_draft',
34
      dialog => {
35
        title => t8('Drafts'),
36
      },
37
    })
38
    ->render;
39
}
40

  
41
sub action_save {
42
  my ($self) = @_;
43

  
44
  my $id          = $::form->{id};
45
  my $description = $::form->{description} or die 'need description';
46
  my $form        = $self->_build_form;
47

  
48
  my $draft = SL::DB::Manager::Draft->find_by_or_create(id => $id);
49

  
50
  $draft->id($self->module . '-' . $self->submodule . '-' . Common::unique_id()) unless $draft->id;
51

  
52
  $draft->assign_attributes(
53
    module      => $self->module,
54
    submodule   => $self->submodule,
55
    description => $description,
56
    form        => YAML::Dump($form),
57
    employee_id => SL::DB::Manager::Employee->current->id,
58
  );
59

  
60
  $self->draft($draft);
61

  
62
  if (!$draft->save) {
63
    flash('error', t8('There was an error saving the draft'));
64
    $self->js
65
      ->html('#save_draft', $self->dialog_html)
66
      ->render;
67
  } else {
68
    $self->js
69
      ->flash('info', t8("Draft saved."))
70
      ->dialog->close('#save_draft')
71
      ->render;
72
  }
73
}
74

  
75
sub action_load {
76
  my ($self) = @_;
77

  
78
  if (!$allowed_modules{ $self->draft->module }) {
79
    $::form->error(t8('Unknown module: #1', $self->draft->module));
80
  } else {
81
    package main;
82
    require $allowed_modules{ $self->draft->module };
83
  }
84

  
85
  my $new_form = YAML::Load($self->draft->form);
86
  $::form->{$_} = $new_form->{$_} for keys %$new_form;
87
  $::form->{"draft_$_"} = $self->draft->$_ for qw(id description);
88

  
89
  $::form->{script} = $self->draft->module . '.pl';
90
  ::update();
91
}
92

  
93
sub action_delete {
94
  my ($self) = @_;
95

  
96
  $self->module($self->draft->module);
97
  $self->submodule($self->draft->submodule);
98

  
99
  if (!$self->draft->delete) {
100
    flash('error', t8('There was an error deleting the draft'));
101
    $self->js
102
      ->html('#save_draft', $self->dialog_html)
103
      ->render;
104
  } else {
105
    flash('info', t8('Draft deleted'));
106

  
107
    $self->js
108
      ->html('#save_draft', $self->dialog_html)
109
      ->render;
110
  }
111
}
112

  
113
#
114
# helpers
115
#
116

  
117
sub _build_form {
118
  my $last_index = max map { /form\[(\d+)\]/ ? $1 : 0 } keys %$::form;
119
  my $new_form = {};
120

  
121
  for my $i (0..$last_index) {
122
    SL::Request::_store_value($new_form, $::form->{"form[$i][name]"}, $::form->{"form[$i][value]"});
123
  }
124

  
125
  return $new_form;
126
}
127

  
128
sub draft_list {
129
  my ($self) = @_;
130

  
131
  my $result = selectall_hashref_query($::form, $::form->get_standard_dbh, <<SQL, $self->module, $self->submodule);
132
    SELECT d.*, date(d.itime) AS date, e.name AS employee_name
133
    FROM drafts d
134
    LEFT JOIN employee e ON d.employee_id = e.id
135
    WHERE (d.module = ?) AND (d.submodule = ?)
136
    ORDER BY d.itime
137
SQL
138
}
139

  
140
sub dialog_html {
141
  my ($self) = @_;
142

  
143
  $self->render('drafts/form', { layout => 0, output => 0 },
144
    drafts_list => $self->draft_list
145
  )
146
}
147

  
148
sub init_module {
149
  $::form->{module}      or die 'need module';
150
}
151

  
152
sub init_submodule {
153
  $::form->{submodule}   or die 'need submodule';
154
}
155

  
156
sub init_draft {
157
  SL::DB::Manager::Draft->find_by(id => $::form->{id}) or die t8('Could not load this draft');
158
}
159

  
160
sub check_auth {
161
  $::auth->assert('vendor_invoice_edit | invoice_edit | general_ledger');
162
}
163

  
164
1;
165

  
166
__END__
167

  
168
=encoding utf-8
169

  
170
=head1 NAME
171

  
172
SL::Controller::Draft
173

  
174
=head1 DESCRIPTION
175

  
176
Encapsulates the old draft mechanism. Use and improvement are discuraged as
177
long as the storage is not upgrade safe.
178

  
179
=head1 TODO
180

  
181
  - optional popup on entry
182

  
183
=head1 AUTHOR
184

  
185
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
186

  
187
=cut
SL/Drafts.pm
1
#======================================================================
2
# LX-Office ERP
3
#
4
#======================================================================
5
#
6
# Saving and loading drafts
7
#
8
#======================================================================
9

  
10
package Drafts;
11

  
12
use YAML;
13

  
14
use SL::Common;
15
use SL::DBUtils;
16

  
17
use strict;
18

  
19
sub get_module {
20
  $main::lxdebug->enter_sub();
21

  
22
  my ($self, $form) = @_;
23

  
24
  my ($module, $submodule);
25

  
26
  $module = $form->{"script"};
27
  $module =~ s/\.pl$//;
28
  if (grep({ $module eq $_ } qw(is ir ar ap))) {
29
    $submodule = "invoice";
30
  } else {
31
    $submodule = "unknown";
32
  }
33

  
34
  $main::lxdebug->leave_sub();
35

  
36
  return ($module, $submodule);
37
}
38

  
39
my @dont_save = qw(login password action);
40

  
41
sub dont_save {
42
  return @dont_save;
43
}
44

  
45
sub save {
46
  $main::lxdebug->enter_sub();
47

  
48
  my ($self, $myconfig, $form, $draft_id, $draft_description) = @_;
49

  
50
  my ($dbh, $sth, $query, %saved, $dumped);
51

  
52
  $dbh = $form->get_standard_dbh;
53
  $dbh->begin_work;
54

  
55
  my ($module, $submodule) = $self->get_module($form);
56

  
57
  $query = "SELECT COUNT(*) FROM drafts WHERE id = ?";
58
  my ($res) = selectrow_query($form, $dbh, $query, $draft_id);
59

  
60
  if (!$res) {
61
    $draft_id = $module . "-" . $submodule . "-" . Common::unique_id();
62
    $query    = "INSERT INTO drafts (id, module, submodule) VALUES (?, ?, ?)";
63
    do_query($form, $dbh, $query, $draft_id, $module, $submodule);
64
  }
65

  
66
  map({ $saved{$_} = $form->{$_};
67
        delete($form->{$_}); } @dont_save);
68

  
69
  $dumped = YAML::Dump($form);
70
  map({ $form->{$_} = $saved{$_}; } @dont_save);
71

  
72
  $query =
73
    qq|UPDATE drafts SET description = ?, form = ?, employee_id = | .
74
    qq|  (SELECT id FROM employee WHERE login = ?) | .
75
    qq|WHERE id = ?|;
76

  
77
  do_query($form, $dbh, $query, $draft_description, $dumped, $::myconfig{login}, $draft_id);
78

  
79
  $dbh->commit();
80

  
81
  $form->{draft_id}          = $draft_id;
82
  $form->{draft_description} = $draft_description;
83

  
84
  $main::lxdebug->leave_sub();
85
}
86

  
87
sub load {
88
  $main::lxdebug->enter_sub();
89

  
90
  my ($self, $myconfig, $form, $draft_id) = @_;
91

  
92
  my ($dbh, $sth, $query, @values);
93

  
94
  $dbh = $form->get_standard_dbh;
95

  
96
  $query = qq|SELECT id, description, form FROM drafts WHERE id = ?|;
97

  
98
  $sth = prepare_execute_query($form, $dbh, $query, $draft_id);
99

  
100
  if (my $ref = $sth->fetchrow_hashref()) {
101
    @values = ($ref->{form}, $ref->{id}, $ref->{description});
102
  }
103
  $sth->finish();
104

  
105
  $main::lxdebug->leave_sub();
106

  
107
  return @values;
108
}
109

  
110
sub remove {
111
  $main::lxdebug->enter_sub();
112

  
113
  my ($self, $myconfig, $form, @draft_ids) = @_;
114

  
115
  return $main::lxdebug->leave_sub() unless (@draft_ids);
116

  
117
  my ($dbh, $sth, $query);
118

  
119
  $dbh = $form->get_standard_dbh;
120

  
121
  $query = qq|DELETE FROM drafts WHERE id IN (| . join(", ", map { "?" } @draft_ids) . qq|)|;
122
  do_query($form, $dbh, $query, @draft_ids);
123

  
124
  $dbh->commit;
125

  
126
  $main::lxdebug->leave_sub();
127
}
128

  
129
sub list {
130
  $::lxdebug->enter_sub;
131

  
132
  my $self     = shift;
133
  my $myconfig = shift || \%::myconfig;
134
  my $form     = shift ||  $::form;
135
  my $dbh      = $form->get_standard_dbh;
136

  
137
  my @list = selectall_hashref_query($form, $dbh, <<SQL, $self->get_module($form));
138
    SELECT d.id, d.description, d.itime::timestamp(0) AS itime,
139
      e.name AS employee_name
140
    FROM drafts d
141
    LEFT JOIN employee e ON d.employee_id = e.id
142
    WHERE (d.module = ?) AND (d.submodule = ?)
143
    ORDER BY d.itime
144
SQL
145

  
146
  $::lxdebug->leave_sub;
147

  
148
  return @list;
149
}
150

  
151
1;
bin/mozilla/ap.pl
46 46

  
47 47
require "bin/mozilla/arap.pl";
48 48
require "bin/mozilla/common.pl";
49
require "bin/mozilla/drafts.pl";
50 49
require "bin/mozilla/reportgenerator.pl";
51 50

  
52 51
use strict;
......
91 90

  
92 91
  $main::auth->assert('general_ledger');
93 92

  
94
  return $main::lxdebug->leave_sub() if (load_draft_maybe());
95

  
96 93
  $form->{title} = "Add";
97 94

  
98
  $form->{callback} = "ap.pl?action=add&DONT_LOAD_DRAFT=1" unless $form->{callback};
95
  $form->{callback} = "ap.pl?action=add" unless $form->{callback};
99 96

  
100 97
  AP->get_transdate(\%myconfig, $form);
101 98
  $form->{initial_transdate} = $form->{transdate};
......
326 323
  $form->{javascript} .= qq|<script type="text/javascript" src="js/common.js"></script>|;
327 324
  $form->{javascript} .= qq|<script type="text/javascript" src="js/show_vc_details.js"></script>|;
328 325
  $form->{javascript} .= qq|<script type="text/javascript" src="js/follow_up.js"></script>|;
326
  $form->{javascript} .= qq|<script type="text/javascript" src="js/kivi.Draft.js"></script>|;
329 327

  
330 328
  $form->header();
331 329

  
......
714 712
      $form->save_history;
715 713
    }
716 714
    # /saving the history
717
    remove_draft() if $form->{remove_draft};
718 715
    # Dieser Text wird niemals ausgegeben: Probleme beim redirect?
719 716
    $form->redirect($locale->text('Transaction posted!')) unless $inline;
720 717
  } else {
bin/mozilla/ar.pl
45 45

  
46 46
require "bin/mozilla/arap.pl";
47 47
require "bin/mozilla/common.pl";
48
require "bin/mozilla/drafts.pl";
49 48
require "bin/mozilla/reportgenerator.pl";
50 49

  
51 50
use strict;
......
87 86
  my $form     = $main::form;
88 87
  my %myconfig = %main::myconfig;
89 88

  
90
  return $main::lxdebug->leave_sub() if (load_draft_maybe());
91

  
92 89
  # saving the history
93 90
  if(!exists $form->{addition} && ($form->{id} ne "")) {
94 91
    $form->{snumbers} = qq|invnumber_| . $form->{invnumber};
......
98 95
  # /saving the history
99 96

  
100 97
  $form->{title}    = "Add";
101
  $form->{callback} = "ar.pl?action=add&DONT_LOAD_DRAFT=1" unless $form->{callback};
98
  $form->{callback} = "ar.pl?action=add" unless $form->{callback};
102 99

  
103 100
  AR->get_transdate(\%myconfig, $form);
104 101
  $form->{initial_transdate} = $form->{transdate};
......
332 329

  
333 330
  $form->{javascript} .=
334 331
    qq|<script type="text/javascript" src="js/show_vc_details.js"></script>| .
335
    qq|<script type="text/javascript" src="js/follow_up.js"></script>|;
332
    qq|<script type="text/javascript" src="js/follow_up.js"></script>| .
333
    qq|<script type="text/javascript" src="js/kivi.Draft.js"></script>|;
336 334

  
337 335
#  $amount  = $locale->text('Amount');
338 336
#  $project = $locale->text('Project');
......
740 738
    $form->save_history;
741 739
  }
742 740
  # /saving the history
743
  remove_draft() if $form->{remove_draft};
744 741

  
745 742
  $form->redirect($locale->text('Transaction posted!')) unless $inline;
746 743

  
bin/mozilla/drafts.pl
1
#======================================================================
2
# LX-Office ERP
3
#
4
#======================================================================
5
#
6
# Saving and loading drafts
7
#
8
#======================================================================
9

  
10
use YAML;
11

  
12
use SL::Drafts;
13

  
14
require "bin/mozilla/common.pl";
15

  
16
use strict;
17

  
18
sub save_draft {
19
  $main::lxdebug->enter_sub();
20

  
21
  my $form     = $main::form;
22
  my %myconfig = %main::myconfig;
23
  my $locale   = $main::locale;
24

  
25
  if (!$form->{draft_id} && !$form->{draft_description}) {
26
    restore_form($form->{SAVED_FORM}, 1) if ($form->{SAVED_FORM});
27
    delete $form->{SAVED_FORM};
28

  
29
    $form->{SAVED_FORM}   = save_form(qw(login password));
30
    $form->{remove_draft} = 1;
31

  
32
    $form->header();
33
    print($form->parse_html_template("drafts/save_new"));
34

  
35
    return $main::lxdebug->leave_sub();
36
  }
37

  
38
  my ($draft_id, $draft_description) = ($form->{draft_id}, $form->{draft_description});
39

  
40
  restore_form($form->{SAVED_FORM}, 1);
41
  delete $form->{SAVED_FORM};
42

  
43
  Drafts->save(\%myconfig, $form, $draft_id, $draft_description);
44

  
45
  $form->{saved_message} = $locale->text("Draft saved.");
46

  
47
  update();
48

  
49
  $main::lxdebug->leave_sub();
50
}
51

  
52
sub remove_draft {
53
  $main::lxdebug->enter_sub();
54

  
55
  my $form     = $main::form;
56
  my %myconfig = %main::myconfig;
57

  
58
  Drafts->remove(\%myconfig, $form, $form->{draft_id}) if ($form->{draft_id});
59

  
60
  delete @{$form}{qw(draft_id draft_description)};
61

  
62
  $main::lxdebug->leave_sub();
63
}
64

  
65
sub load_draft_maybe {
66
  $main::lxdebug->enter_sub();
67

  
68
  my $form     = $main::form;
69
  my %myconfig = %main::myconfig;
70

  
71
  $main::lxdebug->leave_sub() and return 0 if ($form->{DONT_LOAD_DRAFT});
72

  
73
  my ($draft_nextsub) = @_;
74

  
75
  my @drafts = Drafts->list(\%myconfig, $form);
76

  
77
  $main::lxdebug->leave_sub() and return 0 unless (@drafts);
78

  
79
  $draft_nextsub = "add" unless ($draft_nextsub);
80

  
81
  delete $form->{action};
82
  my $saved_form = save_form(qw(login password));
83

  
84
  $form->header();
85
  print($form->parse_html_template("drafts/load",
86
                                   { "DRAFTS"        => \@drafts,
87
                                     "SAVED_FORM"    => $saved_form,
88
                                     "draft_nextsub" => $draft_nextsub }));
89

  
90
  $main::lxdebug->leave_sub();
91

  
92
  return 1;
93
}
94

  
95
sub dont_load_draft {
96
  $main::lxdebug->enter_sub();
97

  
98
  my $form     = $main::form;
99

  
100
  my $draft_nextsub = $form->{draft_nextsub} || "add";
101

  
102
  restore_form($form->{SAVED_FORM}, 1);
103
  delete $form->{SAVED_FORM};
104

  
105
  $form->{DONT_LOAD_DRAFT} = 1;
106

  
107
  call_sub($draft_nextsub);
108

  
109
  $main::lxdebug->leave_sub();
110
}
111

  
112
sub load_draft {
113
  $main::lxdebug->enter_sub();
114

  
115
  my $form     = $main::form;
116
  my %myconfig = %main::myconfig;
117

  
118
  # check and store certain form parameters that might have been passed as get, so we can later overwrite the values from the draft
119
  # the overwrite happens at the end of this function
120
  my @valid_overwrite_vars = qw(remove_draft amount_1 invnumber ordnumber transdate duedate notes datepaid_1 paid_1 callback AP_paid_1 currency);  # reference description
121
  my $overwrite_hash;
122
  # my @valid_fields;
123
  foreach ( @valid_overwrite_vars ) {
124
    $overwrite_hash->{$_} = $form->{$_} if exists $form->{$_};  # variant 1
125
    # push(@valid_fields, $_) if exists $form->{$_}; # variant 2
126
  };
127

  
128
  my ($old_form, $id, $description) = Drafts->load(\%myconfig, $form, $form->{id});
129

  
130
  if ($old_form) {
131
    $old_form = YAML::Load($old_form);
132

  
133
    my %dont_save_vars      = map { $_ => 1 } Drafts->dont_save;
134
    my @restore_vars        = grep { !$dont_save_vars{$_} } keys %{ $old_form };
135

  
136
    @{$form}{@restore_vars} = @{$old_form}{@restore_vars};
137

  
138
    $form->{draft_id}              = $id;
139
    $form->{draft_description}     = $description;
140
    $form->{remove_draft}          = 'checked';
141
  }
142
  # Ich vergesse bei Rechnungsentwürfe das Rechnungsdatum zu ändern. Dadurch entstehen
143
  # ungültige Belege. Vielleicht geht es anderen ähnlich jan 19.2.2011
144
  $form->{invdate} = $form->current_date(\%myconfig); # Aktuelles Rechnungsdatum  ...
145
  $form->{duedate} = $form->current_date(\%myconfig); # Aktuelles Fälligkeitsdatum  ...
146

  
147
  if ( $overwrite_hash ) {
148
    foreach ( keys %$overwrite_hash ) {
149
      $form->{$_} = $overwrite_hash->{$_};  # variante 1
150
    };
151
  };
152
  # @{$form}{@valid_fields} = @{$overwrite_hash}{@valid_fields};  # variante 2
153

  
154
  update();
155

  
156
  $main::lxdebug->leave_sub();
157
}
158

  
159
sub delete_drafts {
160
  $main::lxdebug->enter_sub();
161

  
162
  my $form     = $main::form;
163
  my %myconfig = %main::myconfig;
164

  
165
  my @ids;
166
  foreach (keys %{$form}) {
167
    push @ids, $1 if (/^checked_(.*)/ && $form->{$_});
168
  }
169
  Drafts->remove(\%myconfig, $form, @ids) if (@ids);
170

  
171
  restore_form($form->{SAVED_FORM}, 1);
172
  delete $form->{SAVED_FORM};
173

  
174
  add();
175

  
176
  $main::lxdebug->leave_sub();
177
}
178

  
179
sub draft_action_dispatcher {
180
  $main::lxdebug->enter_sub();
181

  
182
  my $form     = $main::form;
183
  my $locale   = $main::locale;
184

  
185
  if ($form->{draft_action} eq $locale->text("Skip")) {
186
    dont_load_draft();
187

  
188
  } elsif ($form->{draft_action} eq $locale->text("Delete drafts")) {
189
    delete_drafts();
190
  }
191

  
192
  $main::lxdebug->leave_sub();
193
}
194

  
195
1;
bin/mozilla/ir.pl
43 43
require "bin/mozilla/io.pl";
44 44
require "bin/mozilla/arap.pl";
45 45
require "bin/mozilla/common.pl";
46
require "bin/mozilla/drafts.pl";
47 46

  
48 47
use strict;
49 48

  
......
63 62
    $::form->show_generic_error($::locale->text("You do not have the permissions to access this function."));
64 63
  }
65 64

  
66
  return $main::lxdebug->leave_sub() if (load_draft_maybe());
67

  
68 65
  $form->{show_details} = $::myconfig{show_form_details};
69 66

  
70 67
  $form->{title} = $locale->text('Record Vendor Invoice');
......
344 341
  $TMPL_VAR{payment_terms_obj} = get_payment_terms_for_invoice();
345 342
  $form->{duedate}             = $TMPL_VAR{payment_terms_obj}->calc_date(reference_date => $form->{invdate}, due_date => $form->{due_due})->to_kivitendo if $TMPL_VAR{payment_terms_obj};
346 343

  
347
  $::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.SalesPurchase ckeditor/ckeditor ckeditor/adapters/jquery kivi.io autocomplete_customer autocomplete_part client_js));
344
  $::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.Draft kivi.SalesPurchase ckeditor/ckeditor ckeditor/adapters/jquery kivi.io autocomplete_customer autocomplete_part client_js));
348 345

  
349 346
  $form->header();
350 347

  
......
806 803
      $form->save_history;
807 804
    }
808 805
    # /saving the history
809
    remove_draft() if $form->{remove_draft};
810 806
    $form->redirect(  $locale->text('Invoice')
811 807
                  . " $form->{invnumber} "
812 808
                  . $locale->text('posted!'));
bin/mozilla/is.pl
49 49

  
50 50
require "bin/mozilla/io.pl";
51 51
require "bin/mozilla/arap.pl";
52
require "bin/mozilla/drafts.pl";
53 52

  
54 53
use strict;
55 54

  
......
65 64

  
66 65
  $main::auth->assert('invoice_edit');
67 66

  
68
  return $main::lxdebug->leave_sub() if (load_draft_maybe());
69

  
70 67
  $form->{show_details} = $::myconfig{show_form_details};
71 68

  
72 69
  if ($form->{type} eq "credit_note") {
......
396 393
  ), @custom_hiddens,
397 394
  map { $_.'_rate', $_.'_description', $_.'_taxnumber' } split / /, $form->{taxaccounts}];
398 395

  
399
  $::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.SalesPurchase ckeditor/ckeditor ckeditor/adapters/jquery kivi.io autocomplete_customer autocomplete_part client_js));
396
  $::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.Draft kivi.SalesPurchase ckeditor/ckeditor ckeditor/adapters/jquery kivi.io autocomplete_customer autocomplete_part client_js));
400 397

  
401 398
  $TMPL_VAR{payment_terms_obj} = get_payment_terms_for_invoice();
402 399
  $form->{duedate}             = $TMPL_VAR{payment_terms_obj}->calc_date(reference_date => $form->{invdate}, due_date => $form->{duedate})->to_kivitendo if $TMPL_VAR{payment_terms_obj};
......
863 860
    }
864 861
  }
865 862

  
866
  remove_draft() if $form->{remove_draft};
867

  
868 863
  if(!exists $form->{addition}) {
869 864
    $form->{snumbers}  =  'invnumber' .'_'. $form->{invnumber}; # ($form->{type} eq 'credit_note' ? 'cnnumber' : 'invnumber') .'_'. $form->{invnumber};
870 865
    $form->{what_done} = 'invoice';
......
1127 1122
sub dispatcher {
1128 1123
  for my $action (qw(
1129 1124
    print update ship_to e_mail storno post_payment use_as_new credit_note
1130
    delete post order preview post_and_e_mail print_and_post save_draft
1125
    delete post order preview post_and_e_mail print_and_post
1131 1126
    mark_as_paid
1132 1127
  )) {
1133 1128
    if ($::form->{"action_$action"}) {
bin/mozilla/vk.pl
42 42

  
43 43
require "bin/mozilla/arap.pl";
44 44
require "bin/mozilla/common.pl";
45
require "bin/mozilla/drafts.pl";
46 45
require "bin/mozilla/reportgenerator.pl";
47 46

  
48 47
use strict;
js/kivi.Draft.js
1
namespace('kivi.Draft', function(ns) {
2
  'use strict';
3

  
4
  ns.popup = function(module, submodule, id, description) {
5
    $.get('controller.pl', {
6
      action: 'Draft/draft_dialog.js',
7
      module: module,
8
      submodule: submodule,
9
      id: id,
10
      description: description
11
    }, kivi.eval_json_result)
12
  }
13

  
14
  ns.save = function(module, submodule) {
15
    $.post('controller.pl', {
16
      action: 'Draft/save.js',
17
      module: module,
18
      submodule: submodule,
19
      form: $('form').serializeArray(),
20
      id: $('#new_draft_id').val(),
21
      description: $('#new_draft_description').val()
22
    }, kivi.eval_json_result)
23
  }
24

  
25
  ns.delete = function(id) {
26
    if (!confirm(kivi.t8('Do you really want to delete this draft?'))) return;
27

  
28
    $.post('controller.pl', {
29
      action: 'Draft/delete.js',
30
      id: id
31
    }, kivi.eval_json_result)
32

  
33
  }
34
});
js/locale/de.js
35 35
"Delete text block":"Textblock löschen",
36 36
"Do you really want do continue?":"Wollen Sie wirklich fortfahren?",
37 37
"Do you really want to cancel?":"Wollen Sie wirklich abbrechen?",
38
"Do you really want to delete this draft?":"Wollen Sie diesen Entwurf wirklich löschen?",
38 39
"Do you really want to revert to this version?":"Wollen Sie wirklich auf diese Version zurücksetzen?",
39 40
"Do you really want to save?":"Wollen Sie wirklich speichern?",
40 41
"Do you want to set the account number \"#1\" to \"#2\" and the name \"#3\" to \"#4\"?":"Soll die Kontonummer \"#1\" zu \"#2\" und den Name \"#3\" zu \"#4\" geändert werden?",
locale/de/all
617 617
  'Could not load employee'     => 'Konnte Benutzer nicht laden',
618 618
  'Could not load this business' => 'Konnte diesen Kunden-/Lieferantentyp nicht laden',
619 619
  'Could not load this customer' => 'Konnte diesen Kunden nicht laden',
620
  'Could not load this draft'   => 'Dieser Entwurf konnte nicht geladen werden',
620 621
  'Could not load this vendor'  => 'Konnte diesen Lieferanten nicht laden',
621 622
  'Could not print dunning.'    => 'Die Mahnungen konnten nicht gedruckt werden.',
622 623
  'Could not reconcile chosen elements!' => 'Die gewählten Elemente konnten nicht ausgeglichen werden!',
......
944 945
  'Do you really want to delete AR transaction #1?' => 'Wollen Sie wirklich die Debitorenbuchung #1 löschen?',
945 946
  'Do you really want to delete GL transaction #1?' => 'Wollen Sie wirklich die Dialogbuchung #1 löschen?',
946 947
  'Do you really want to delete the selected links?' => 'Wollen Sie wirklich die ausgewählten Verknüpfungen löschen?',
948
  'Do you really want to delete this draft?' => 'Wollen Sie diesen Entwurf wirklich löschen?',
947 949
  'Do you really want to delete this invoice?' => 'Wollen Sie diese Rechnung wirklich löschen?',
948 950
  'Do you really want to delete this object?' => 'Wollen Sie dieses Objekt wirklich löschen?',
949 951
  'Do you really want to delete this warehouse?' => 'Wollen Sie dieses Lager wirklich l&ouml;schen?',
......
970 972
  'Download SEPA XML export file' => 'SEPA-XML-Exportdatei herunterladen',
971 973
  'Download picture'            => 'Bild herunterladen',
972 974
  'Download sample file'        => 'Beispieldatei herunterladen',
975
  'Draft deleted'               => 'Entwurf gelöscht',
973 976
  'Draft for this Letter saved!' => 'Briefentwurf gespeichert!',
974 977
  'Draft from:'                 => 'Entwurf vom:',
975 978
  'Draft saved.'                => 'Entwurf gespeichert.',
976 979
  'Draft suggestions'           => 'Entwurfsvorschläge',
980
  'Drafts'                      => 'Entwürfe',
977 981
  'Drawing'                     => 'Zeichnung',
978 982
  'Dropdown Limit'              => 'Auswahllistenbegrenzung',
979 983
  'Due'                         => 'Fällig',
......
1119 1123
  'Enabled Quick Searched'      => 'Aktivierte Schnellsuchen',
1120 1124
  'Enabled modules'             => 'Aktivierte Module',
1121 1125
  'End date'                    => 'Enddatum',
1122
  'Enter a description for this new draft.' => 'Geben Sie eine Beschreibung f&uuml;r diesen Entwurf ein.',
1123 1126
  'Enter longdescription'       => 'Langtext eingeben',
1124 1127
  'Enter the requested execution date or leave empty for the quickest possible execution:' => 'Geben Sie das jeweils gewünschte Ausführungsdatum an, oder lassen Sie das Feld leer für die schnellstmögliche Ausführung:',
1125 1128
  'Entries for which automatic conversion failed:' => 'Einträge, für die die automatische Umstellung fehlschlug:',
......
1610 1613
  'List of database upgrades to be applied:' => 'Liste der noch einzuspielenden Datenbankupgrades:',
1611 1614
  'List of tax zones'           => 'Liste der Steuerzonen',
1612 1615
  'List open SEPA exports'      => 'Noch nicht ausgeführte SEPA-Exporte anzeigen',
1616
  'Load an existing draft'      => 'Einen bestehenden Entwurf laden',
1613 1617
  'Load draft'                  => 'Entwurf laden',
1614 1618
  'Load letter draft'           => 'Briefentwurf laden',
1615 1619
  'Load profile'                => 'Profil laden',
......
2400 2404
  'Save and close'              => 'Speichern und schließen',
2401 2405
  'Save and execute'            => 'Speichern und ausführen',
2402 2406
  'Save and keep open'          => 'Speichern und geöffnet lassen',
2407
  'Save as a new draft.'        => 'Als neuen Entwurf speichern',
2403 2408
  'Save as new'                 => 'als neu speichern',
2404 2409
  'Save document in WebDAV repository' => 'Dokument in WebDAV-Ablage speichern',
2405 2410
  'Save draft'                  => 'Entwurf speichern',
......
3033 3038
  'There is not enough available of \'#1\' at warehouse \'#2\', bin \'#3\', #4, for the transfer of #5.' => 'Von \'#1\' ist in Lager \'#2\', Lagerplatz \'#3\', #4 nicht gen&uuml;gend eingelagert, um insgesamt #5 auszulagern.',
3034 3039
  'There is not enough left of \'#1\' in bin \'#2\' for the removal of #3.' => 'In Lagerplatz \'#2\' ist nicht genug von \'#1\' vorhanden, um #3 zu entnehmen.',
3035 3040
  'There is one or more sections for which no part has been assigned yet; therefore creating the new record is not possible yet.' => 'Es gibt einen oder mehrere Abschnitte ohne Artikelzuweisung; daher kann der neue Beleg noch nicht erstellt werden.',
3041
  'There was an error deleting the draft' => 'Beim Löschen des Entwurfs ist ein Fehler aufgetretetn',
3036 3042
  'There was an error executing the background job.' => 'Bei der Ausführung des Hintergrund-Jobs trat ein Fehler auf.',
3037 3043
  'There was an error parsing the csv file: #1 in line #2: #3' => 'Es gab einen Fehler beim Parsen der CSV Datei: "#1" in der Zeile "#2": "#3"',
3044
  'There was an error saving the draft' => 'Beim Speichern des Entwurfs ist ein Fehler aufgetretetn',
3038 3045
  'There was an error saving the letter' => 'Ein Fehler ist aufgetreten. Der Brief konnte nicht gespeichert werden.',
3039 3046
  'There was an error saving the letter draft' => 'Ein Fehler ist aufgetreten. Der Briefentwurf konnte nicht gespeichert werden.',
3040 3047
  'There you can let kivitendo create the basic tables for you, even in an already existing database.' => 'Dort können Sie kivitendo diese grundlegenden Tabellen erstellen lassen, selbst in einer bereits existierenden Datenbank.',
......
3192 3199
  'Unknown Category'            => 'Unbekannte Kategorie',
3193 3200
  'Unknown Link'                => 'Unbekannte Verknüpfung',
3194 3201
  'Unknown dependency \'%s\'.'  => 'Unbekannte Abh&auml;ngigkeit \'%s\'.',
3202
  'Unknown module: #1'          => 'Unbekanntes Modul #1',
3195 3203
  'Unknown problem type.'       => 'Unbekannter Problem-Typ',
3196 3204
  'Unlock System'               => 'System entsperren',
3197 3205
  'Unsuccessfully executed:\n'  => 'Erfolglos ausgeführt:',
......
3208 3216
  'Update quotation/order'      => 'Auftrag/Angebot aktualisieren',
3209 3217
  'Update sales order #1'       => 'Kundenauftrag #1 aktualisieren',
3210 3218
  'Update sales quotation #1'   => 'Angebot #1 aktualisieren',
3219
  'Update this draft.'          => 'Aktuellen Entwurf speichern',
3211 3220
  'Update with section'         => 'Mit Abschnitt aktualisieren',
3212 3221
  'Updated'                     => 'Erneuert am',
3213 3222
  'Updating existing entry in database' => 'Existierenden Eintrag in Datenbank aktualisieren',
......
3295 3304
  'Warehouses'                  => 'Lager',
3296 3305
  'Warn before saving orders with duplicate parts (new controller only)' => 'Beim Speichern warnen, wenn doppelte Artikel in einem Auftrag sind',
3297 3306
  'Warning'                     => 'Warnung',
3307
  'Warning! Loading a draft will discard unsaved data!' => 'Achtung! Beim Laden eines Entwurfs werden ungespeicherte Daten verworfen!',
3298 3308
  'WebDAV'                      => 'WebDAV',
3299 3309
  'WebDAV link'                 => 'WebDAV-Link',
3300 3310
  'WebDAV save documents'       => 'Belege in WebDAV-Ablage speichern',
templates/webpages/ap/form_footer.html
12 12
<input type=hidden name=draft_id value="[% draft_id %]">
13 13
<input type=hidden name=draft_description value="[% draft_description | html %]">
14 14

  
15
[%- IF ( !id && draft_id ) %]
16
  [% L.checkbox_tag('remove_draft', checked=remove_draft, label=LxERP.t8('Remove draft when posting')) %]
17
  <br>
18
[%- END %]
19

  
20 15
<br>
21 16

  
22 17
<input class="submit" type="submit" name="action" id="update_button" value="[% 'Update' | $T8 %]">
......
37 32

  
38 33
[%- ELSIF show_post_draft %]
39 34
    <input class=submit type=submit name=action value="[% 'Post' | $T8 %]">
40
    <input type="submit" name="action" value="[% 'Save draft' | $T8 %]" class="submit">
35
    [% L.button_tag('kivi.Draft.popup("ap", "invoice", "' _ draft_id _ '", "' _ draft_description _ '")', LxERP.t8('Drafts')) %]
41 36
[%- END %]
42 37

  
43 38
[%- IF id %]
templates/webpages/ar/form_footer.html
1 1
[% USE LxERP %]
2 2
[% USE T8 %]
3
[% USE L %]
3 4

  
4 5
  [% IF ( follow_up_length && follow_up_due_length ) %]
5 6
    [% LxERP.t8('There are #1 unfinished follow-ups of which #2 are due.', follow_up_length , follow_up_due_length) %]
......
12 13

  
13 14
  <br>
14 15

  
15
  [% IF ( !id && draft_id ) %]
16
    <input type="checkbox" name="remove_draft" id="remove_draft" value="1" [% IF ( remove_draft ) %]checked[% END %]>
17
    <label for="remove_draft">[% 'Remove draft when posting' | $T8 %]</label>
18
  [% END %]
19

  
20
  <br>
21

  
22 16
  <input class="submit" type="submit" name="action" id="update_button" value="[% 'Update' | $T8 %]">
23 17

  
24 18
  [% IF ( show_storno_button ) %]
......
41 35
  [% ELSE %]
42 36
    [% IF ( !is_closed ) %]
43 37
      <input class="submit" type="submit" name="action" value="[% 'Post' | $T8 %]">
44
      <input class="submit" type="submit" name="action" value="[% 'Save draft' | $T8 %]">
38
      [% L.button_tag('kivi.Draft.popup("ar", "invoice", "' _ draft_id _ '", "' _ draft_description _ '")', LxERP.t8('Drafts')) %]
45 39
    [% END %]
46 40
  [% END %]
47 41

  
templates/webpages/drafts/form.html
1
[%- USE T8 %]
2
[%- USE L %]
3
[%- USE LxERP %]
4
[%- USE HTML %]
5

  
6
[% PROCESS 'common/flash.html' %]
7

  
8
[%- IF FORM.id %]
9
<h3>[% 'Update this draft.' | $T8 %]</h3>
10
[%- ELSE %]
11
<h3>[% 'Save as a new draft.' | $T8 %]</h3>
12
[%- END %]
13

  
14
[% L.hidden_tag('', FORM.id, id='new_draft_id') %]
15
[% 'Description' | $T8 %]: <input id='new_draft_description' value='[% FORM.description | html %]'>
16
[% L.button_tag('kivi.Draft.save("' _ HTML.escape(SELF.module) _ '", "' _ HTML.escape(SELF.submodule) _ '")', LxERP.t8('Save draft')) %]
17

  
18
[%- IF drafts_list.size %]
19
<h3>[% 'Load an existing draft' | $T8 %]</h3>
20

  
21
<p>[% 'Warning! Loading a draft will discard unsaved data!' | $T8 %]</p>
22

  
23
<table>
24
 <tr class="listheading">
25
  <th>[% 'Date' | $T8 %]</th>
26
  <th>[% 'Description' | $T8 %]</th>
27
  <th>[% 'Employee' | $T8 %]</th>
28
 </tr>
29

  
30
[% FOREACH row = drafts_list %]
31
 <tr class="listrow">
32
  <td>[% row.date | html %]</td>
33
  <td>
34
  [%- IF row.id == FORM.id %]
35
   <b>[% row.description | html %]</b>
36
  [%- ELSE %]
37
   [% L.link(SELF.url_for(action='load',id=row.id), row.description) %]
38
  [%- END %]
39
  </td>
40
  <td>[% row.employee_name | html %]</td>
41
  <td>[% L.html_tag('span', LxERP.t8('Delete'), class='cursor-pointer interact', onclick="kivi.Draft.delete('" _ row.id _ "')") %]</a></td>
42
 </tr>
43
[% END %]
44
</table>
45
[%- END %]
46

  
templates/webpages/drafts/save_new.html
1
[%- USE T8 %]
2
[%- USE HTML %]
3
<h1>[% 'Save draft' | $T8 %]</h1>
4

  
5
 <form action="[% HTML.escape(script) %]" method="post">
6

  
7
  <input type="hidden" name="SAVED_FORM" value="[% HTML.escape(SAVED_FORM) %]">
8

  
9
  <table width="100%">
10
   <tr>
11
    <td>[% 'Enter a description for this new draft.' | $T8 %]</td>
12
   </tr>
13

  
14
   <tr>
15
    <td>
16
    [% 'Description' | $T8 %]:
17
    <input name="draft_description">
18
    </td>
19
   </tr>
20

  
21
   <tr>
22
    <td>
23
     <input type="submit" class="submit" name="action" value="[% 'Save draft' | $T8 %]">
24
    </td>
25
   </tr>
26
  </table>
27

  
28
 </form>
templates/webpages/ir/form_footer.html
138 138
   [% UNLESS locked %]
139 139
      <input class="submit" type="submit" name="action" value="[% 'Post' | $T8 %]">
140 140
   [%- END %]
141
      <input class="submit" type="submit" name="action" value="[% 'Save Draft' | $T8 %]">
141
      [% L.button_tag('kivi.Draft.popup("ir", "invoice", "' _ draft_id _ '", "' _ draft_description _ '")', LxERP.t8('Drafts')) %]
142 142
 [% END # id %]
143 143

  
144 144
  [% IF id %]
templates/webpages/is/form_footer.html
154 154
<hr size="3" noshade>
155 155

  
156 156
<p>[% print_options %]</p>
157

  
158
<div id='form_action_bar'>
157 159
  <input type="hidden" name="action" value="dispatcher">
158 160

  
159 161
  [% IF id %]
......
187 189
      <input class="submit" type="submit" name="action_post_and_e_mail" value="[% 'Post and E-mail' | $T8 %]" data-require-transaction-description="[% INSTANCE_CONF.get_require_transaction_description_ps %]">
188 190
      <input class="submit" type="submit" name="action_print_and_post" value="[% 'Print and Post' | $T8 %]" data-require-transaction-description="[% INSTANCE_CONF.get_require_transaction_description_ps %]">
189 191
      <input class="submit" type="submit" name="action_post" value="[% 'Post' | $T8 %]" data-require-transaction-description="[% INSTANCE_CONF.get_require_transaction_description_ps %]">
190
      <input class="submit" type="submit" name="action_save_draft" value="[% 'Save Draft' | $T8 %]">
192
      [% L.button_tag('kivi.Draft.popup("is", "invoice", "' _ draft_id _ '", "' _ draft_description _ '")', LxERP.t8('Drafts')) %]
191 193
   [%- END %]
192 194
 [% END # id %]
193 195

  
......
202 204
  [% IF callback %]
203 205
    <a href="[% callback %]">[% 'back' | $T8  %]</a>
204 206
  [% END %]
207
</div>
205 208

  
206 209
<input type="hidden" name="rowcount" value="[% rowcount %]">
207 210
<input type="hidden" name="callback" value="[% callback | html %]">

Auch abrufbar als: Unified diff