Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision cbb1668f

Von Bernd Bleßmann vor mehr als 3 Jahren hinzugefügt

  • ID cbb1668fb815449b20be91641debf16e94fb6421
  • Vorgänger 47cbf8da

Zeiterfassung: Im Bericht Aufträge zuordnen können

Unterschiede anzeigen:

SL/Controller/TimeRecording.pm
5 5

  
6 6
use DateTime;
7 7
use English qw(-no_match_vars);
8
use List::Util qw(sum0);
8
use List::Util qw(sum0 notall);
9 9
use POSIX qw(strftime);
10 10

  
11 11
use SL::Controller::Helper::GetModels;
......
18 18
use SL::DB::Project;
19 19
use SL::DB::TimeRecording;
20 20
use SL::DB::TimeRecordingArticle;
21
use SL::Helper::Flash qw(flash);
21
use SL::Helper::Flash qw(flash flash_later);
22 22
use SL::Helper::Number qw(_round_number _parse_number _round_total);
23 23
use SL::Helper::UserPreferences::TimeRecording;
24 24
use SL::Locale::String qw(t8);
......
35 35
# safety
36 36
__PACKAGE__->run_before('check_auth');
37 37
__PACKAGE__->run_before('check_auth_edit',     only => [ qw(edit save delete) ]);
38
__PACKAGE__->run_before('check_auth_edit_all', only => [ qw(mark_as_booked) ]);
38
__PACKAGE__->run_before('check_auth_edit_all', only => [ qw(mark_as_booked assign_order_dialog assign_order) ]);
39 39

  
40 40

  
41 41
my %sort_columns = (
......
99 99
  $self->redirect_to(safe_callback());
100 100
}
101 101

  
102
sub action_assign_order_dialog {
103
  my ($self) = @_;
104

  
105
  if (!scalar @{ $::form->{ids} }) {
106
    return $self->js->flash('warning', t8('No entries have been selected.'))->render;
107
  }
108

  
109
  # Sanity check: all entries must have the same customer assigned.
110
  my $trs = SL::DB::Manager::TimeRecording->get_all(where => [id => $::form->{ids}]);
111
  if (notall { $_->customer_id == $trs->[0]->customer_id } @$trs) {
112
    return $self->js->flash('error', t8('All entries must have the same customer assigned.'))->render;
113
  };
114

  
115
  # Search assigneable orders
116
  my $orders = SL::DB::Manager::Order->get_all(query => [or             => [ closed    => 0, closed    => undef ],
117
                                                         or             => [ quotation => 0, quotation => undef ],
118
                                                         customer_id    => $trs->[0]->customer_id]);
119
  $orders = [ map { [$_->id, sprintf("%s %s", $_->number, $_->customervendor->name) ] } sort { $a->number <=> $b->number } @{$orders||[]} ];
120

  
121
  # Prepare dialog
122
  my $dialog_html = $self->render('time_recording/_assign_order_dialog', { output => 0 },
123
                                  orders          => $orders,
124
                                  time_recordings => $trs,
125
                                  callback        => $::form->escape($::form->{callback}),
126
  );
127

  
128
  my %dialog_params = (
129
    html => $dialog_html,
130
    id   => 'assign_order_dialog',
131
    dialog => {
132
      title  => t8('Assign an order to entries'),
133
      width  => 500,
134
      height => 600,
135
    },
136
  );
137

  
138
  $self->js
139
    ->dialog->open(\%dialog_params)
140
    ->render;
141
}
142

  
143
sub action_assign_order {
144
  my ($self) = @_;
145

  
146
  if (!$::form->{assign}->{order_id}) {
147
    return $self->js->flash('warning', t8('No order has been selected.'))->render;
148
  }
149

  
150
  if (!scalar @{ $::form->{ids} }) {
151
    return $self->js->flash('warning', t8('No entries have been selected.'))->render;
152
  }
153

  
154
  # Sanity check: all entries must have the same customer assigned.
155
  my $trs = SL::DB::Manager::TimeRecording->get_all(where => [id => $::form->{ids}]);
156
  if (notall { $_->customer_id == $trs->[0]->customer_id } @$trs) {
157
    return $self->js->flash('error', t8('All entries must have the same customer assigned.'))->render;
158
  };
159

  
160
  my $errors_occurred;
161
  foreach my $tr (@$trs) {
162
    $tr->assign_attributes(order_id => $::form->{assign}->{order_id});
163
    my @errors = $tr->validate;
164
    if (@errors) {
165
      $self->js->flash('error', $tr->displayable_times . ': ' . $_) for @errors;
166
      $errors_occurred = 1;
167
    }
168
  }
169

  
170
  if ($errors_occurred) {
171
    return $self->js->flash('warning', t8('No changes were saved.'))->render;
172

  
173
  } else {
174
    $_->save for @$trs;
175
    flash_later('info', t8('The changes have been saved.'));
176
  }
177

  
178
  $self->redirect_to($::form->unescape($::form->{assign}->{callback}));
179
}
180

  
102 181
sub action_edit {
103 182
  my ($self) = @_;
104 183

  
......
415 494
          confirm => $::locale->text('Do you really want to mark the selected entries as booked?'),
416 495
          only_if => $self->can_edit_all,
417 496
        ],
497
        action => [
498
          t8('Assign Order'),
499
          call    => [ 'kivi.TimeRecording.assign_order_dialog', { callback => $self->models->get_callback } ],
500
          checks  => [ [ 'kivi.check_if_entries_selected', '[name="ids[]"]' ] ],
501
          only_if => $self->can_edit_all,
502
        ],
418 503
      ],
419 504
      action => [
420 505
        t8('Add'),
js/kivi.TimeRecording.js
80 80
    });
81 81
  };
82 82

  
83
  ns.assign_order_dialog = function(params) {
84
    var callback = params.callback;
85

  
86
    var data = $('#form').serializeArray();
87
    data     = data.concat($('#filter_form').serializeArray());
88
    data.push({name: 'action',   value: 'TimeRecording/assign_order_dialog'},
89
              {name: 'callback', value: callback});
90

  
91
    $.post("controller.pl", data, kivi.eval_json_result);
92
  };
93

  
94
  ns.assign_order = function() {
95
    var data = $('#form').serializeArray();
96
    data     = data.concat($('#assign_order_form').serializeArray());
97
    data.push({name: 'action',   value: 'TimeRecording/assign_order'});
98

  
99
    $('#assign_order_dialog').dialog('close');
100

  
101
    $.post("controller.pl", data, kivi.eval_json_result);
102
  };
103

  
83 104
});
84 105

  
85 106
$(function() {
locale/de/all
269 269
  'All changes in that file have been reverted.' => 'Alle Änderungen in dieser Datei wurden rückgängig gemacht.',
270 270
  'All clients'                 => 'Alle Mandanten',
271 271
  'All employees'               => 'Alle Angestellten',
272
  'All entries must have the same customer assigned.' => 'Alle Einträge müssen den selben Kunden zugeordnet haben.',
272 273
  'All general ledger entries'  => 'Alle Hauptbucheinträge',
273 274
  'All groups'                  => 'Alle Gruppen',
274 275
  'All modules'                 => 'Alle Module',
......
353 354
  'Asset'                       => 'Aktiva/Mittelverwendung',
354 355
  'Assets'                      => 'Aktiva',
355 356
  'Assign'                      => 'Übernehmen',
357
  'Assign Order'                => 'Auftrag zuordnen',
358
  'Assign an order to entries'  => 'Auftrag den Einträgen zuordnen',
356 359
  'Assign article'              => 'Artikel zuweisen',
357 360
  'Assign invoice'              => 'Rechnung zuweisen',
358 361
  'Assign the following article to all sections' => 'Den folgenden Artikel allen Abschnitten zuweisen',
......
2118 2121
  'No bins have been added to this warehouse yet.' => 'Es wurden zu diesem Lager noch keine Lagerplätze angelegt.',
2119 2122
  'No carry-over chart configured!' => 'Kein Saldenvortragskonto konfiguriert!',
2120 2123
  'No changes since previous version.' => 'Keine Änderungen seit der letzten Version.',
2124
  'No changes were saved.'      => 'Es wurden keine Änderungen gespeichert.',
2121 2125
  'No clients have been created yet.' => 'Es wurden noch keine Mandanten angelegt.',
2122 2126
  'No contact selected to delete' => 'Keine Ansprechperson zum Löschen ausgewählt',
2123 2127
  'No contra account selected!' => 'Kein Gegenkonto ausgewählt!',
......
2146 2150
  'No groups have been created yet.' => 'Es wurden noch keine Gruppen angelegt.',
2147 2151
  'No internal phone extensions have been configured yet.' => 'Es wurden noch keine internen Durchwahlen konfiguriert.',
2148 2152
  'No invoices have been selected.' => 'Es wurden keine Rechnungen ausgewählt.',
2153
  'No order has been selected.' => 'Es wurde kein Auftrag ausgewählt',
2149 2154
  'No part was selected.'       => 'Es wurde kein Artikel ausgewählt',
2150 2155
  'No payment term has been created yet.' => 'Es wurden noch keine Zahlungsbedingungen angelegt.',
2151 2156
  'No picture has been uploaded' => 'Es wurde kein Bild hochgeladen',
......
2939 2944
  'Select Mulit-Item Options'   => 'Multi-Treffer Auswahlliste',
2940 2945
  'Select a Customer'           => 'Endkunde auswählen',
2941 2946
  'Select a period'             => 'Bitte Zeitraum auswählen',
2947
  'Select an order to assign'   => 'Wählen Sie einen Auftrag zum Zuordnen',
2942 2948
  'Select federal state...'     => 'Bundesland auswählen...',
2943 2949
  'Select file to upload'       => 'Datei zum Hochladen auswählen',
2944 2950
  'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
......
2950 2956
  'Select type of transfer in'  => 'Grund der Einlagerung auswählen:',
2951 2957
  'Selected'                    => 'Ausgewählt',
2952 2958
  'Selected identity fields'    => 'Ausgewählte Felder',
2959
  'Selected time recordings'    => 'Ausgewählte Zeiterfassungs-Einträge',
2953 2960
  'Selection'                   => 'Auswahlbox',
2954 2961
  'Selection fields: The option field must contain the available options for the selection. Options are separated by \'##\', for example \'Early##Normal##Late\'.' => 'Auswahlboxen: Das Optionenfeld muss die für die Auswahl verfügbaren Einträge enthalten. Die Einträge werden mit \'##\' voneinander getrennt. Beispiel: \'Früh##Normal##Spät\'.',
2955 2962
  'Sell Price'                  => 'Verkaufspreis',
......
3381 3388
  'The booking group needs an inventory account.' => 'Die Buchungsgruppe braucht ein Warenbestandskonto.',
3382 3389
  'The buchungsgruppe is missing.' => 'Die Buchungsgruppe fehlt.',
3383 3390
  'The categories has been saved.' => 'Artikelgruppe gespeichert',
3391
  'The changes have been saved.' => 'Die Änderungen wurden gespeichert.',
3384 3392
  'The changing of tax-o-matic account is NOT recommended, but if you do so please also (re)configure booking groups and reconfigure ALL charts which point to this tax-o-matic account. ' => 'Es wird nicht empfohlen Steuerkonten (Umsatzsteuer oder Vorsteuer) "umzuhängen", aber falls es gemacht wird, bitte auch entsprechend konsequent die Buchungsgruppen und die Konten die mit dieser Steuer verknüpft sind umkonfigurieren.',
3385 3393
  'The chart is not valid.'     => 'Das Konto ist nicht gültig.',
3386 3394
  'The client could not be deleted.' => 'Der Mandant konnte nicht gelöscht werden.',
......
4242 4250
  'correction'                  => 'Korrektur',
4243 4251
  'correction_br'               => 'Korr.',
4244 4252
  'cp_greeting to cp_gender migration' => 'Datenumwandlung von Titel nach Geschlecht (cp_greeting to cp_gender)',
4253
  'current order'               => 'aktueller Auftrag',
4245 4254
  'customer_list'               => 'kundenliste',
4246 4255
  'dated'                       => 'datiert',
4247 4256
  'delete'                      => 'Löschen',
......
4447 4456
  'taxnumber'                   => 'Automatikkonto',
4448 4457
  'terminated'                  => 'gekündigt',
4449 4458
  'time and effort based position' => 'Aufwandsposition',
4459
  'time recording entry'        => 'Zeiterfassungs-Eintrag',
4450 4460
  'time_recordings'             => 'zeiterfassung',
4451 4461
  'to'                          => 'bis',
4452 4462
  'to (date)'                   => 'bis',
locale/en/all
269 269
  'All changes in that file have been reverted.' => '',
270 270
  'All clients'                 => '',
271 271
  'All employees'               => '',
272
  'All entries must have the same customer assigned.' => '',
272 273
  'All general ledger entries'  => '',
273 274
  'All groups'                  => '',
274 275
  'All modules'                 => '',
......
353 354
  'Asset'                       => '',
354 355
  'Assets'                      => '',
355 356
  'Assign'                      => '',
357
  'Assign Order'                => '',
358
  'Assign an order to entries'  => '',
356 359
  'Assign article'              => '',
357 360
  'Assign invoice'              => '',
358 361
  'Assign the following article to all sections' => '',
......
2118 2121
  'No bins have been added to this warehouse yet.' => '',
2119 2122
  'No carry-over chart configured!' => '',
2120 2123
  'No changes since previous version.' => '',
2124
  'No changes were saved.'      => '',
2121 2125
  'No clients have been created yet.' => '',
2122 2126
  'No contact selected to delete' => '',
2123 2127
  'No contra account selected!' => '',
......
2146 2150
  'No groups have been created yet.' => '',
2147 2151
  'No internal phone extensions have been configured yet.' => '',
2148 2152
  'No invoices have been selected.' => '',
2153
  'No order has been selected.' => '',
2149 2154
  'No part was selected.'       => '',
2150 2155
  'No payment term has been created yet.' => '',
2151 2156
  'No picture has been uploaded' => '',
......
2939 2944
  'Select Mulit-Item Options'   => '',
2940 2945
  'Select a Customer'           => '',
2941 2946
  'Select a period'             => '',
2947
  'Select an order to assign'   => '',
2942 2948
  'Select federal state...'     => '',
2943 2949
  'Select file to upload'       => '',
2944 2950
  'Select from one of the items below' => '',
......
2950 2956
  'Select type of transfer in'  => '',
2951 2957
  'Selected'                    => '',
2952 2958
  'Selected identity fields'    => '',
2959
  'Selected time recordings'    => '',
2953 2960
  'Selection'                   => '',
2954 2961
  'Selection fields: The option field must contain the available options for the selection. Options are separated by \'##\', for example \'Early##Normal##Late\'.' => '',
2955 2962
  'Sell Price'                  => '',
......
3380 3387
  'The booking group needs an inventory account.' => '',
3381 3388
  'The buchungsgruppe is missing.' => '',
3382 3389
  'The categories has been saved.' => '',
3390
  'The changes have been saved.' => '',
3383 3391
  'The changing of tax-o-matic account is NOT recommended, but if you do so please also (re)configure booking groups and reconfigure ALL charts which point to this tax-o-matic account. ' => '',
3384 3392
  'The chart is not valid.'     => '',
3385 3393
  'The client could not be deleted.' => '',
......
4241 4249
  'correction'                  => '',
4242 4250
  'correction_br'               => 'correction',
4243 4251
  'cp_greeting to cp_gender migration' => '',
4252
  'current order'               => '',
4244 4253
  'customer_list'               => '',
4245 4254
  'dated'                       => '',
4246 4255
  'delete'                      => '',
......
4446 4455
  'taxnumber'                   => '',
4447 4456
  'terminated'                  => '',
4448 4457
  'time and effort based position' => '',
4458
  'time recording entry'        => '',
4449 4459
  'time_recordings'             => '',
4450 4460
  'to'                          => '',
4451 4461
  'to (date)'                   => '',
templates/webpages/time_recording/_assign_order_dialog.html
1
[%- USE T8 %][%- USE HTML %][%- USE L %][%- USE P %][%- USE LxERP %]
2

  
3
<form method="POST" id="assign_order_form">
4
  [% L.hidden_tag('assign.callback', HTML.escape(callback)) %]
5

  
6
  <p>
7
    <h3>[% 'Selected time recordings' | $T8 %]</h3>
8
    <table>
9
      <tr class="listheading">
10
        <th>[% 'time recording entry' | $T8 %]</th>
11
        <th>[% 'current order' | $T8 %]</th>
12
      </tr>
13
      [% FOREACH tr = time_recordings %]
14
      <tr class="listrow">
15
        <td>[% tr.displayable_times %]</td>
16
        <td align="right">[% tr.order_id ? tr.order.number : '-' %]</td>
17
      </tr>
18
      [% END %]
19
    </table>
20
  </p>
21

  
22
  <p>
23
    <h3>[% 'Select an order to assign' | $T8 %]</h3>
24
    [% P.select_tag('assign.order_id', orders, with_empty=1, style='width: 300px') %]
25
  </p>
26

  
27
  <p>
28
    [% L.button_tag("kivi.TimeRecording.assign_order()", LxERP.t8('Continue')) %]
29
  </p>
30
</form>

Auch abrufbar als: Unified diff