In einem neuen Reiter können Notizen zum Beleg erfasst werden.
use SL::DB::PartClassification;
use SL::DB::PartsGroup;
use SL::DB::Printer;
+use SL::DB::Note;
use SL::DB::Language;
use SL::DB::RecordLink;
use SL::DB::RequirementSpec;
$self->js->render();
}
+sub action_save_phone_note {
+ my ($self) = @_;
+
+ if (!$::form->{phone_note}->{subject} || !$::form->{phone_note}->{body}) {
+ return $self->js->flash('error', t8('Phone note needs a subject and a body.'))->render;
+ }
+
+ my $phone_note;
+ if ($::form->{phone_note}->{id}) {
+ $phone_note = first { $_->id == $::form->{phone_note}->{id} } @{$self->order->phone_notes};
+ return $self->js->flash('error', t8('Phone note not found for this order.'))->render if !$phone_note;
+ }
+
+ $phone_note = SL::DB::Note->new() if !$phone_note;
+ my $is_new = !$phone_note->id;
+
+ $phone_note->assign_attributes(%{ $::form->{phone_note} },
+ trans_id => $self->order->id,
+ trans_module => 'oe',
+ employee => SL::DB::Manager::Employee->current);
+
+ $phone_note->save;
+ $self->order(SL::DB::Order->new(id => $self->order->id)->load);
+
+ my $tab_as_html = $self->p->render('order/tabs/phone_notes', SELF => $self);
+
+ return $self->js
+ ->replaceWith('#phone-notes', $tab_as_html)
+ ->html('#num_phone_notes', (scalar @{$self->order->phone_notes}) ? ' (' . scalar @{$self->order->phone_notes} . ')' : '')
+ ->flash('info', $is_new ? t8('Phone note has been created.') : t8('Phone note has been updated.'))
+ ->render;
+}
+
+sub action_delete_phone_note {
+ my ($self) = @_;
+
+ my $phone_note = first { $_->id == $::form->{phone_note}->{id} } @{$self->order->phone_notes};
+
+ return $self->js->flash('error', t8('Phone note not found for this order.'))->render if !$phone_note;
+
+ $phone_note->delete;
+ $self->order(SL::DB::Order->new(id => $self->order->id)->load);
+
+ my $tab_as_html = $self->p->render('order/tabs/phone_notes', SELF => $self);
+
+ return $self->js
+ ->replaceWith('#phone-notes', $tab_as_html)
+ ->html('#num_phone_notes', (scalar @{$self->order->phone_notes}) ? ' (' . scalar @{$self->order->phone_notes} . ')' : '')
+ ->flash('info', t8('Phone note has been deleted.'))
+ ->render;
+}
+
sub js_load_second_row {
my ($self, $item, $item_id, $do_parse) = @_;
my $errors = [];
my $db = $self->order->db;
+ # check for new or updated phone note
+ if ($::form->{phone_note}->{subject} || $::form->{phone_note}->{body}) {
+ if (!$::form->{phone_note}->{subject} || !$::form->{phone_note}->{body}) {
+ return [t8('Phone note needs a subject and a body.')];
+ die;
+ }
+
+ my $phone_note;
+ if ($::form->{phone_note}->{id}) {
+ $phone_note = first { $_->id == $::form->{phone_note}->{id} } @{$self->order->phone_notes};
+ return [t8('Phone note not found for this order.')] if !$phone_note;
+ }
+
+ $phone_note = SL::DB::Note->new() if !$phone_note;
+ my $is_new = !$phone_note->id;
+
+ $phone_note->assign_attributes(%{ $::form->{phone_note} },
+ trans_id => $self->order->id,
+ trans_module => 'oe',
+ employee => SL::DB::Manager::Employee->current);
+
+ $self->order->add_phone_notes($phone_note) if $is_new;
+ }
+
$db->with_transaction(sub {
# delete custom shipto if it is to be deleted or if it is empty
if ($self->order->custom_shipto && ($self->is_custom_shipto_to_delete || $self->order->custom_shipto->is_empty)) {
$self->get_item_cvpartnumber($_) for @{$self->order->items_sorted};
+ $self->{template_args}->{num_phone_notes} = scalar @{ $self->order->phone_notes || [] };
+
$::request->{layout}->use_javascript("${_}.js") for qw(kivi.Validator kivi.SalesPurchase kivi.Order kivi.File ckeditor/ckeditor ckeditor/adapters/jquery
edit_periodic_invoices_config calculate_qty follow_up show_history);
$self->setup_edit_action_bar;
class => 'SL::DB::Exchangerate',
column_map => { currency_id => 'currency_id', transdate => 'transdate' },
},
+ phone_notes => {
+ type => 'one to many',
+ class => 'SL::DB::Note',
+ column_map => { id => 'trans_id' },
+ query_args => [ trans_module => 'oe' ],
+ manager_args => {
+ with_objects => [ 'employee' ],
+ sort_by => 'notes.itime',
+ }
+ },
);
SL::DB::Helper::Attr::make(__PACKAGE__, daily_exchangerate => 'numeric');
ns.create_part = function() {
var data = $('#order_form').serializeArray();
data.push({ name: 'action', value: 'Order/create_part' });
-
$.post("controller.pl", data, kivi.eval_json_result);
};
return true;
};
+ ns.load_phone_note = function(id, subject, body) {
+ $('#phone_note_edit_text').html(kivi.t8('Edit note'));
+ $('#phone_note_id').val(id);
+ $('#phone_note_subject').val(subject);
+ $('#phone_note_body').val(body);
+ $('#phone_note_delete_button').show();
+ };
+
+ ns.cancel_phone_note = function() {
+ $('#phone_note_edit_text').html(kivi.t8('Add note'));
+ $('#phone_note_id').val('');
+ $('#phone_note_subject').val('');
+ $('#phone_note_body').val('');
+ $('#phone_note_delete_button').hide();
+ };
+
+ ns.save_phone_note = function() {
+ var data = $('#order_form').serializeArray();
+ data.push({ name: 'action', value: 'Order/save_phone_note' });
+
+ $.post("controller.pl", data, kivi.eval_json_result);
+ };
+
+ ns.delete_phone_note = function() {
+ if ($('#phone_note_id').val() === '') return;
+
+ var data = $('#order_form').serializeArray();
+ data.push({ name: 'action', value: 'Order/delete_phone_note' });
+
+ $.post("controller.pl", data, kivi.eval_json_result);
+ };
+
});
$(function() {
"Add function block":"Funktionsblock hinzufügen",
"Add linked record":"Verknüpften Beleg hinzufügen",
"Add multiple items":"Mehrere Artikel hinzufügen",
+"Add note":"Notiz erfassen",
"Add picture":"Bild hinzufügen",
"Add picture to text block":"Bild dem Textblock hinzufügen",
"Add section":"Abschnitt hinzufügen",
"Edit":"Bearbeiten",
"Edit article/section assignments":"Zuweisung Artikel/Abschnitte bearbeiten",
"Edit custom shipto":"Individuelle Lieferadresse bearbeiten",
+"Edit note":"Notiz bearbeiten",
"Edit picture":"Bild bearbeiten",
"Edit project link":"Projektverknüpfung bearbeiten",
"Edit text block":"Textblock bearbeiten",
"Add function block":"",
"Add linked record":"",
"Add multiple items":"",
+"Add note":"",
"Add picture":"",
"Add picture to text block":"",
"Add section":"",
"Edit":"",
"Edit article/section assignments":"",
"Edit custom shipto":"",
+"Edit note":"",
"Edit picture":"",
"Edit project link":"",
"Edit text block":"",
'Perpetual inventory' => 'Bestandsmethode',
'Personal settings' => 'Persönliche Einstellungen',
'Phone' => 'Telefon',
+ 'Phone Notes' => 'Telefonnotizen',
'Phone extension' => 'Durchwahl',
'Phone extension missing in user configuration' => 'Durchwahl fehlt in der Benutzerkonfiguration',
+ 'Phone note has been created.' => 'Die Telefonnotiz wurde angelegt.',
+ 'Phone note has been deleted.' => 'Die Telefonnotiz wurde gelöscht.',
+ 'Phone note has been updated.' => 'Die Telefonnotiz wurde aktualisiert.',
+ 'Phone note needs a subject and a body.' => 'Eine Telefonnotiz muss einen Betreff und einen Text haben.',
+ 'Phone note not found for this order.' => 'Diese Telefonnotiz wurde für dieses Dokument nicht gefunden.',
'Phone password' => 'Telefonpasswort',
'Phone password missing in user configuration' => 'Telefonpasswort fehlt in der Benutzerkonfiguration',
'Phone1' => 'Telefon 1 ',
'Perpetual inventory' => '',
'Personal settings' => '',
'Phone' => '',
+ 'Phone Notes' => '',
'Phone extension' => '',
'Phone extension missing in user configuration' => '',
+ 'Phone note has been created.' => '',
+ 'Phone note has been deleted.' => '',
+ 'Phone note has been updated.' => '',
+ 'Phone note needs a subject and a body.' => '',
+ 'Phone note not found for this order.' => '',
'Phone password' => '',
'Phone password missing in user configuration' => '',
'Phone1' => '',
[%- IF SELF.order.id %]
<li><a href="controller.pl?action=RecordLinks/ajax_list&object_model=Order&object_id=[% HTML.url(SELF.order.id) %]">[% 'Linked Records' | $T8 %]</a></li>
[%- END %]
+[% IF SELF.order.id %]
+ <li><a href="#ui-tabs-phone-notes">[% 'Phone Notes' | $T8 %]<span id="num_phone_notes">[%- num_phone_notes ? ' (' _ num_phone_notes _ ')' : '' -%]</span></a></li>
+[% END %]
</ul>
[% PROCESS "order/tabs/basic_data.html" %]
<div id="ui-tabs-1">
[%- LxERP.t8("Loading...") %]
</div>
-
+[% IF SELF.order.id %]
+ <div id="ui-tabs-phone-notes">
+ [% PROCESS "order/tabs/phone_notes.html" %]
+ </div>
+[% END %]
<div id="shipto_inputs" class="hidden">
[%- PROCESS 'common/_ship_to_dialog.html'
vc_obj=SELF.order.customervendor
--- /dev/null
+[%- USE T8 %]
+[%- USE HTML %]
+[%- USE L %]
+[%- USE LxERP %]
+[%- USE P %]
+
+<div id="phone-notes">
+ [% IF ( SELF.order.phone_notes && SELF.order.phone_notes.size ) %]
+ <table>
+ <tr>
+ <th class="listheading">[% 'Subject' | $T8 %]</th>
+ <th class="listheading">[% 'Created on' | $T8 %]</th>
+ <th class="listheading">[% 'Created by' | $T8 %]</th>
+ </tr>
+
+ [%- FOREACH row = SELF.order.phone_notes %]
+ <tr class="listrow">
+ <td>[% P.link_tag('#', row.subject, onclick="kivi.Order.load_phone_note(" _ HTML.url(row.id) _ ", '" _ HTML.escape(row.subject) _ "', '" _ HTML.escape(row.body) _ "')") %]</td>
+ <td>[% row.itime.to_kivitendo | html %]</td>
+ <td>[% row.employee.safe_name | html %]</td>
+ </tr>
+ [% END %]
+ </table>
+ [% END %]
+
+ <h2 id='phone_note_edit_text'>[% 'Add note' | $T8 %]</h2>
+
+ [% L.hidden_tag('phone_note.id') %]
+
+ <table>
+ <tr>
+ <td valign="right">[% 'Subject' | $T8 %]</td>
+ <td>[% L.input_tag('phone_note.subject', '', size = 50) %]</td>
+ </tr>
+ <tr>
+ <td valign="right" align="top">[% 'Body' | $T8 %]</td>
+ <td align="top">[% L.textarea_tag('phone_note.body', '', cols = 50 rows = 10) %]</td>
+ </tr>
+ </table>
+
+ <p>
+ [% P.button_tag("kivi.Order.save_phone_note()", LxERP.t8('Save')) %]
+ [% P.button_tag("kivi.Order.delete_phone_note()", LxERP.t8('Delete'), id = 'phone_note_delete_button', style='display:none') %]
+ [% P.button_tag("kivi.Order.cancel_phone_note()", LxERP.t8('Cancel')) %]
+ </p>
+
+</div>