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
use DateTime;
use English qw(-no_match_vars);
use List::Util qw(sum0);
use List::Util qw(sum0 notall);
use POSIX qw(strftime);
use SL::Controller::Helper::GetModels;
......
use SL::DB::Project;
use SL::DB::TimeRecording;
use SL::DB::TimeRecordingArticle;
use SL::Helper::Flash qw(flash);
use SL::Helper::Flash qw(flash flash_later);
use SL::Helper::Number qw(_round_number _parse_number _round_total);
use SL::Helper::UserPreferences::TimeRecording;
use SL::Locale::String qw(t8);
......
# safety
__PACKAGE__->run_before('check_auth');
__PACKAGE__->run_before('check_auth_edit', only => [ qw(edit save delete) ]);
__PACKAGE__->run_before('check_auth_edit_all', only => [ qw(mark_as_booked) ]);
__PACKAGE__->run_before('check_auth_edit_all', only => [ qw(mark_as_booked assign_order_dialog assign_order) ]);
my %sort_columns = (
......
$self->redirect_to(safe_callback());
}
sub action_assign_order_dialog {
my ($self) = @_;
if (!scalar @{ $::form->{ids} }) {
return $self->js->flash('warning', t8('No entries have been selected.'))->render;
}
# Sanity check: all entries must have the same customer assigned.
my $trs = SL::DB::Manager::TimeRecording->get_all(where => [id => $::form->{ids}]);
if (notall { $_->customer_id == $trs->[0]->customer_id } @$trs) {
return $self->js->flash('error', t8('All entries must have the same customer assigned.'))->render;
};
# Search assigneable orders
my $orders = SL::DB::Manager::Order->get_all(query => [or => [ closed => 0, closed => undef ],
or => [ quotation => 0, quotation => undef ],
customer_id => $trs->[0]->customer_id]);
$orders = [ map { [$_->id, sprintf("%s %s", $_->number, $_->customervendor->name) ] } sort { $a->number <=> $b->number } @{$orders||[]} ];
# Prepare dialog
my $dialog_html = $self->render('time_recording/_assign_order_dialog', { output => 0 },
orders => $orders,
time_recordings => $trs,
callback => $::form->escape($::form->{callback}),
);
my %dialog_params = (
html => $dialog_html,
id => 'assign_order_dialog',
dialog => {
title => t8('Assign an order to entries'),
width => 500,
height => 600,
},
);
$self->js
->dialog->open(\%dialog_params)
->render;
}
sub action_assign_order {
my ($self) = @_;
if (!$::form->{assign}->{order_id}) {
return $self->js->flash('warning', t8('No order has been selected.'))->render;
}
if (!scalar @{ $::form->{ids} }) {
return $self->js->flash('warning', t8('No entries have been selected.'))->render;
}
# Sanity check: all entries must have the same customer assigned.
my $trs = SL::DB::Manager::TimeRecording->get_all(where => [id => $::form->{ids}]);
if (notall { $_->customer_id == $trs->[0]->customer_id } @$trs) {
return $self->js->flash('error', t8('All entries must have the same customer assigned.'))->render;
};
my $errors_occurred;
foreach my $tr (@$trs) {
$tr->assign_attributes(order_id => $::form->{assign}->{order_id});
my @errors = $tr->validate;
if (@errors) {
$self->js->flash('error', $tr->displayable_times . ': ' . $_) for @errors;
$errors_occurred = 1;
}
}
if ($errors_occurred) {
return $self->js->flash('warning', t8('No changes were saved.'))->render;
} else {
$_->save for @$trs;
flash_later('info', t8('The changes have been saved.'));
}
$self->redirect_to($::form->unescape($::form->{assign}->{callback}));
}
sub action_edit {
my ($self) = @_;
......
confirm => $::locale->text('Do you really want to mark the selected entries as booked?'),
only_if => $self->can_edit_all,
],
action => [
t8('Assign Order'),
call => [ 'kivi.TimeRecording.assign_order_dialog', { callback => $self->models->get_callback } ],
checks => [ [ 'kivi.check_if_entries_selected', '[name="ids[]"]' ] ],
only_if => $self->can_edit_all,
],
],
action => [
t8('Add'),
js/kivi.TimeRecording.js
});
};
ns.assign_order_dialog = function(params) {
var callback = params.callback;
var data = $('#form').serializeArray();
data = data.concat($('#filter_form').serializeArray());
data.push({name: 'action', value: 'TimeRecording/assign_order_dialog'},
{name: 'callback', value: callback});
$.post("controller.pl", data, kivi.eval_json_result);
};
ns.assign_order = function() {
var data = $('#form').serializeArray();
data = data.concat($('#assign_order_form').serializeArray());
data.push({name: 'action', value: 'TimeRecording/assign_order'});
$('#assign_order_dialog').dialog('close');
$.post("controller.pl", data, kivi.eval_json_result);
};
});
$(function() {
locale/de/all
'All changes in that file have been reverted.' => 'Alle Änderungen in dieser Datei wurden rückgängig gemacht.',
'All clients' => 'Alle Mandanten',
'All employees' => 'Alle Angestellten',
'All entries must have the same customer assigned.' => 'Alle Einträge müssen den selben Kunden zugeordnet haben.',
'All general ledger entries' => 'Alle Hauptbucheinträge',
'All groups' => 'Alle Gruppen',
'All modules' => 'Alle Module',
......
'Asset' => 'Aktiva/Mittelverwendung',
'Assets' => 'Aktiva',
'Assign' => 'Übernehmen',
'Assign Order' => 'Auftrag zuordnen',
'Assign an order to entries' => 'Auftrag den Einträgen zuordnen',
'Assign article' => 'Artikel zuweisen',
'Assign invoice' => 'Rechnung zuweisen',
'Assign the following article to all sections' => 'Den folgenden Artikel allen Abschnitten zuweisen',
......
'No bins have been added to this warehouse yet.' => 'Es wurden zu diesem Lager noch keine Lagerplätze angelegt.',
'No carry-over chart configured!' => 'Kein Saldenvortragskonto konfiguriert!',
'No changes since previous version.' => 'Keine Änderungen seit der letzten Version.',
'No changes were saved.' => 'Es wurden keine Änderungen gespeichert.',
'No clients have been created yet.' => 'Es wurden noch keine Mandanten angelegt.',
'No contact selected to delete' => 'Keine Ansprechperson zum Löschen ausgewählt',
'No contra account selected!' => 'Kein Gegenkonto ausgewählt!',
......
'No groups have been created yet.' => 'Es wurden noch keine Gruppen angelegt.',
'No internal phone extensions have been configured yet.' => 'Es wurden noch keine internen Durchwahlen konfiguriert.',
'No invoices have been selected.' => 'Es wurden keine Rechnungen ausgewählt.',
'No order has been selected.' => 'Es wurde kein Auftrag ausgewählt',
'No part was selected.' => 'Es wurde kein Artikel ausgewählt',
'No payment term has been created yet.' => 'Es wurden noch keine Zahlungsbedingungen angelegt.',
'No picture has been uploaded' => 'Es wurde kein Bild hochgeladen',
......
'Select Mulit-Item Options' => 'Multi-Treffer Auswahlliste',
'Select a Customer' => 'Endkunde auswählen',
'Select a period' => 'Bitte Zeitraum auswählen',
'Select an order to assign' => 'Wählen Sie einen Auftrag zum Zuordnen',
'Select federal state...' => 'Bundesland auswählen...',
'Select file to upload' => 'Datei zum Hochladen auswählen',
'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
......
'Select type of transfer in' => 'Grund der Einlagerung auswählen:',
'Selected' => 'Ausgewählt',
'Selected identity fields' => 'Ausgewählte Felder',
'Selected time recordings' => 'Ausgewählte Zeiterfassungs-Einträge',
'Selection' => 'Auswahlbox',
'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\'.',
'Sell Price' => 'Verkaufspreis',
......
'The booking group needs an inventory account.' => 'Die Buchungsgruppe braucht ein Warenbestandskonto.',
'The buchungsgruppe is missing.' => 'Die Buchungsgruppe fehlt.',
'The categories has been saved.' => 'Artikelgruppe gespeichert',
'The changes have been saved.' => 'Die Änderungen wurden gespeichert.',
'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.',
'The chart is not valid.' => 'Das Konto ist nicht gültig.',
'The client could not be deleted.' => 'Der Mandant konnte nicht gelöscht werden.',
......
'correction' => 'Korrektur',
'correction_br' => 'Korr.',
'cp_greeting to cp_gender migration' => 'Datenumwandlung von Titel nach Geschlecht (cp_greeting to cp_gender)',
'current order' => 'aktueller Auftrag',
'customer_list' => 'kundenliste',
'dated' => 'datiert',
'delete' => 'Löschen',
......
'taxnumber' => 'Automatikkonto',
'terminated' => 'gekündigt',
'time and effort based position' => 'Aufwandsposition',
'time recording entry' => 'Zeiterfassungs-Eintrag',
'time_recordings' => 'zeiterfassung',
'to' => 'bis',
'to (date)' => 'bis',
locale/en/all
'All changes in that file have been reverted.' => '',
'All clients' => '',
'All employees' => '',
'All entries must have the same customer assigned.' => '',
'All general ledger entries' => '',
'All groups' => '',
'All modules' => '',
......
'Asset' => '',
'Assets' => '',
'Assign' => '',
'Assign Order' => '',
'Assign an order to entries' => '',
'Assign article' => '',
'Assign invoice' => '',
'Assign the following article to all sections' => '',
......
'No bins have been added to this warehouse yet.' => '',
'No carry-over chart configured!' => '',
'No changes since previous version.' => '',
'No changes were saved.' => '',
'No clients have been created yet.' => '',
'No contact selected to delete' => '',
'No contra account selected!' => '',
......
'No groups have been created yet.' => '',
'No internal phone extensions have been configured yet.' => '',
'No invoices have been selected.' => '',
'No order has been selected.' => '',
'No part was selected.' => '',
'No payment term has been created yet.' => '',
'No picture has been uploaded' => '',
......
'Select Mulit-Item Options' => '',
'Select a Customer' => '',
'Select a period' => '',
'Select an order to assign' => '',
'Select federal state...' => '',
'Select file to upload' => '',
'Select from one of the items below' => '',
......
'Select type of transfer in' => '',
'Selected' => '',
'Selected identity fields' => '',
'Selected time recordings' => '',
'Selection' => '',
'Selection fields: The option field must contain the available options for the selection. Options are separated by \'##\', for example \'Early##Normal##Late\'.' => '',
'Sell Price' => '',
......
'The booking group needs an inventory account.' => '',
'The buchungsgruppe is missing.' => '',
'The categories has been saved.' => '',
'The changes have been saved.' => '',
'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. ' => '',
'The chart is not valid.' => '',
'The client could not be deleted.' => '',
......
'correction' => '',
'correction_br' => 'correction',
'cp_greeting to cp_gender migration' => '',
'current order' => '',
'customer_list' => '',
'dated' => '',
'delete' => '',
......
'taxnumber' => '',
'terminated' => '',
'time and effort based position' => '',
'time recording entry' => '',
'time_recordings' => '',
'to' => '',
'to (date)' => '',
templates/webpages/time_recording/_assign_order_dialog.html
[%- USE T8 %][%- USE HTML %][%- USE L %][%- USE P %][%- USE LxERP %]
<form method="POST" id="assign_order_form">
[% L.hidden_tag('assign.callback', HTML.escape(callback)) %]
<p>
<h3>[% 'Selected time recordings' | $T8 %]</h3>
<table>
<tr class="listheading">
<th>[% 'time recording entry' | $T8 %]</th>
<th>[% 'current order' | $T8 %]</th>
</tr>
[% FOREACH tr = time_recordings %]
<tr class="listrow">
<td>[% tr.displayable_times %]</td>
<td align="right">[% tr.order_id ? tr.order.number : '-' %]</td>
</tr>
[% END %]
</table>
</p>
<p>
<h3>[% 'Select an order to assign' | $T8 %]</h3>
[% P.select_tag('assign.order_id', orders, with_empty=1, style='width: 300px') %]
</p>
<p>
[% L.button_tag("kivi.TimeRecording.assign_order()", LxERP.t8('Continue')) %]
</p>
</form>

Auch abrufbar als: Unified diff