Revision 0c319351
Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt
SL/Controller/RequirementSpecOrder.pm | ||
---|---|---|
$order->db->with_transaction(sub {
|
||
$order->save;
|
||
|
||
$self->requirement_spec->orders(
|
||
@{ $self->requirement_spec->orders },
|
||
SL::DB::RequirementSpecOrder->new(order => $order, version => $self->requirement_spec->version)
|
||
);
|
||
$self->requirement_spec->add_orders(SL::DB::RequirementSpecOrder->new(order => $order, version => $self->requirement_spec->version));
|
||
$self->requirement_spec->save;
|
||
|
||
$self->requirement_spec->link_to_record($order);
|
||
... | ... | |
# helpers
|
||
#
|
||
|
||
sub load_parts_for_sections {
|
||
my ($self, %params) = @_;
|
||
|
||
}
|
||
|
||
sub create_order_item {
|
||
my ($self, %params) = @_;
|
||
|
SL/Controller/RequirementSpecPart.pm | ||
---|---|---|
package SL::Controller::RequirementSpecPart;
|
||
|
||
use strict;
|
||
|
||
use parent qw(SL::Controller::Base);
|
||
|
||
use Carp;
|
||
use List::MoreUtils qw(any);
|
||
|
||
use SL::ClientJS;
|
||
use SL::DB::Customer;
|
||
use SL::DB::Project;
|
||
use SL::DB::RequirementSpec;
|
||
use SL::DB::RequirementSpecPart;
|
||
use SL::Helper::Flash;
|
||
use SL::Locale::String;
|
||
|
||
use Rose::Object::MakeMethods::Generic
|
||
(
|
||
'scalar --get_set_init' => [ qw(requirement_spec js) ],
|
||
);
|
||
|
||
__PACKAGE__->run_before('check_auth');
|
||
|
||
#
|
||
# actions
|
||
#
|
||
|
||
sub action_show {
|
||
my ($self, %params) = @_;
|
||
|
||
$self->render('requirement_spec_part/show', { layout => 0 });
|
||
}
|
||
|
||
sub action_ajax_edit {
|
||
my ($self, %params) = @_;
|
||
|
||
my $html = $self->render('requirement_spec_part/_edit', { output => 0 });
|
||
|
||
$self->js
|
||
->hide('#additional_parts_list_container')
|
||
->after('#additional_parts_list_container', $html)
|
||
->on('#edit_additional_parts_form INPUT[type=text]', 'keydown', 'kivi.requirement_spec.additional_parts_input_key_down')
|
||
->focus('#additional_parts_add_part_id_name')
|
||
->run('kivi.requirement_spec.prepare_edit_additional_parts_form')
|
||
->reinit_widgets
|
||
->render;
|
||
}
|
||
|
||
sub action_ajax_add {
|
||
my ($self) = @_;
|
||
|
||
my $part = SL::DB::Part->new(id => $::form->{part_id})->load(with_objects => [ qw(unit_obj) ]);
|
||
my $rs_part = SL::DB::RequirementSpecPart->new(
|
||
part => $part,
|
||
qty => 1,
|
||
unit => $part->unit_obj,
|
||
description => $part->description,
|
||
);
|
||
my $row = $self->render('requirement_spec_part/_part', { output => 0 }, part => $rs_part);
|
||
|
||
$self->js
|
||
->val( '#additional_parts_add_part_id', '')
|
||
->val( '#additional_parts_add_part_id_name', '')
|
||
->focus('#additional_parts_add_part_id_name')
|
||
->append('#edit_additional_parts_list tbody', $row)
|
||
->hide('#edit_additional_parts_list_empty')
|
||
->show('#edit_additional_parts_list')
|
||
->render;
|
||
}
|
||
|
||
sub action_ajax_save {
|
||
my ($self) = @_;
|
||
|
||
my $db = $self->requirement_spec->db;
|
||
$db->do_transaction(sub {
|
||
# Make Emacs happy
|
||
1;
|
||
my $parts = $::form->{additional_parts} || [];
|
||
my $position = 1;
|
||
$_->{position} = $position++ for @{ $parts };
|
||
|
||
$self->requirement_spec->update_attributes(parts => $parts)->load;
|
||
|
||
1;
|
||
}) or do {
|
||
return $self->js->error(t8('Saving failed. Error message from the database: #1', $db->error))->render;
|
||
};
|
||
|
||
my $html = $self->render('requirement_spec_part/show', { output => 0 }, initially_hidden => !!$::form->{keep_open});
|
||
|
||
$self->js
|
||
->replaceWith('#additional_parts_list_container', $html)
|
||
->action_if(!$::form->{keep_open}, 'remove', '#additional_parts_form_container')
|
||
->render;
|
||
}
|
||
|
||
#
|
||
# filters
|
||
#
|
||
|
||
sub check_auth {
|
||
my ($self, %params) = @_;
|
||
$::auth->assert('requirement_spec_edit');
|
||
}
|
||
|
||
#
|
||
# helpers
|
||
#
|
||
|
||
sub init_js { SL::ClientJS->new(controller => $_[0]) }
|
||
|
||
sub init_requirement_spec {
|
||
SL::DB::RequirementSpec->new(id => $::form->{requirement_spec_id})->load(
|
||
with_objects => [ qw(parts parts.part parts.unit) ],
|
||
);
|
||
}
|
||
|
||
1;
|
SL/DB/Helper/ALL.pm | ||
---|---|---|
use SL::DB::RequirementSpecDependency;
|
||
use SL::DB::RequirementSpecItem;
|
||
use SL::DB::RequirementSpecOrder;
|
||
use SL::DB::RequirementSpecPart;
|
||
use SL::DB::RequirementSpecPicture;
|
||
use SL::DB::RequirementSpecPredefinedText;
|
||
use SL::DB::RequirementSpecRisk;
|
SL/DB/Helper/Mappings.pm | ||
---|---|---|
requirement_spec_item_dependencies => 'RequirementSpecDependency',
|
||
requirement_spec_items => 'RequirementSpecItem',
|
||
requirement_spec_orders => 'RequirementSpecOrder',
|
||
requirement_spec_parts => 'RequirementSpecPart',
|
||
requirement_spec_pictures => 'RequirementSpecPicture',
|
||
requirement_spec_predefined_texts => 'RequirementSpecPredefinedText',
|
||
requirement_spec_risks => 'RequirementSpecRisk',
|
SL/DB/Manager/RequirementSpecPart.pm | ||
---|---|---|
# This file has been auto-generated only because it didn't exist.
|
||
# Feel free to modify it at will; it will not be overwritten automatically.
|
||
|
||
package SL::DB::Manager::RequirementSpecPart;
|
||
|
||
use strict;
|
||
|
||
use SL::DB::Helper::Manager;
|
||
use base qw(SL::DB::Helper::Manager);
|
||
|
||
sub object_class { 'SL::DB::RequirementSpecPart' }
|
||
|
||
__PACKAGE__->make_manager_methods;
|
||
|
||
1;
|
SL/DB/MetaSetup/RequirementSpecPart.pm | ||
---|---|---|
# This file has been auto-generated. Do not modify it; it will be overwritten
|
||
# by rose_auto_create_model.pl automatically.
|
||
package SL::DB::RequirementSpecPart;
|
||
|
||
use strict;
|
||
|
||
use base qw(SL::DB::Object);
|
||
|
||
__PACKAGE__->meta->table('requirement_spec_parts');
|
||
|
||
__PACKAGE__->meta->columns(
|
||
id => { type => 'serial', not_null => 1 },
|
||
description => { type => 'text', not_null => 1 },
|
||
part_id => { type => 'integer', not_null => 1 },
|
||
position => { type => 'integer', not_null => 1 },
|
||
qty => { type => 'numeric', not_null => 1, precision => 15, scale => 5 },
|
||
requirement_spec_id => { type => 'integer', not_null => 1 },
|
||
unit_id => { type => 'integer', not_null => 1 },
|
||
);
|
||
|
||
__PACKAGE__->meta->primary_key_columns([ 'id' ]);
|
||
|
||
__PACKAGE__->meta->foreign_keys(
|
||
part => {
|
||
class => 'SL::DB::Part',
|
||
key_columns => { part_id => 'id' },
|
||
},
|
||
|
||
requirement_spec => {
|
||
class => 'SL::DB::RequirementSpec',
|
||
key_columns => { requirement_spec_id => 'id' },
|
||
},
|
||
|
||
unit => {
|
||
class => 'SL::DB::Unit',
|
||
key_columns => { unit_id => 'id' },
|
||
},
|
||
);
|
||
|
||
1;
|
||
;
|
SL/DB/RequirementSpec.pm | ||
---|---|---|
class => 'SL::DB::RequirementSpecOrder',
|
||
column_map => { id => 'requirement_spec_id' },
|
||
},
|
||
parts => {
|
||
type => 'one to many',
|
||
class => 'SL::DB::RequirementSpecPart',
|
||
column_map => { id => 'requirement_spec_id' },
|
||
},
|
||
);
|
||
|
||
__PACKAGE__->meta->initialize;
|
||
... | ... | |
return \@copies;
|
||
}
|
||
|
||
sub parts_sorted {
|
||
my ($self, @rest) = @_;
|
||
|
||
croak "This sub is not a writer" if @rest;
|
||
|
||
return [ sort { $a->position <=> $b->position } @{ $self->parts } ];
|
||
}
|
||
|
||
sub create_copy {
|
||
my ($self, %params) = @_;
|
||
|
||
... | ... | |
given then only the text blocks belonging to that C<output_position>
|
||
are returned.
|
||
|
||
=item C<parts_sorted>
|
||
|
||
Returns an array reference of additional parts sorted by their
|
||
positional column in ascending order.
|
||
|
||
=item C<validate>
|
||
|
||
Validate values before saving. Returns list or human-readable error
|
SL/DB/RequirementSpecPart.pm | ||
---|---|---|
package SL::DB::RequirementSpecPart;
|
||
|
||
use strict;
|
||
|
||
use SL::DB::MetaSetup::RequirementSpecPart;
|
||
use SL::DB::Manager::RequirementSpecPart;
|
||
use SL::DB::Helper::ActsAsList;
|
||
|
||
__PACKAGE__->meta->initialize;
|
||
|
||
1;
|
js/locale/de.js | ||
---|---|---|
"Add section":"Abschnitt hinzufügen",
|
||
"Add sub function block":"Unterfunktionsblock hinzufügen",
|
||
"Add text block":"Textblock erfassen",
|
||
"Additional articles actions":"Aktionen zu zusätzlichen Artikeln",
|
||
"Are you sure?":"Sind Sie sicher?",
|
||
"Basic settings actions":"Aktionen zu Grundeinstellungen",
|
||
"Cancel":"Abbrechen",
|
||
... | ... | |
"Paste template":"Vorlage einfügen",
|
||
"Project link actions":"Projektverknüpfungs-Aktionen",
|
||
"Quotations/Orders actions":"Aktionen für Angebote/Aufträge",
|
||
"Remove article":"Artikel entfernen",
|
||
"Requirement spec actions":"Pflichtenheftaktionen",
|
||
"Requirement spec template actions":"Pflichtenheftvorlagen-Aktionen",
|
||
"Revert to version":"Auf Version zurücksetzen",
|
js/requirement_spec.js | ||
---|---|---|
return true;
|
||
};
|
||
|
||
// -------------------------------------------------------------------------
|
||
// -------------------------- time/cost estimate ---------------------------
|
||
// -------------------------------------------------------------------------
|
||
|
||
ns.standard_time_cost_estimate_ajax_call = function(key, opt) {
|
||
if (key == 'cancel') {
|
||
if (confirm(kivi.t8('Do you really want to cancel?'))) {
|
||
$('#time_cost_estimate').show();
|
||
$('#time_cost_estimate_form_container').remove();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
var add_data = '';
|
||
if (key == 'save_keep_open') {
|
||
key = 'save';
|
||
add_data = 'keep_open=1&';
|
||
}
|
||
|
||
var data = "action=RequirementSpec/ajax_" + key + "_time_and_cost_estimate&" + add_data;
|
||
|
||
if (key == 'save')
|
||
data += $('#edit_time_cost_estimate_form').serialize()
|
||
+ '&' + $('#current_content_type').serialize()
|
||
+ '&' + $('#current_content_id').serialize();
|
||
else
|
||
data += 'id=' + encodeURIComponent($('#requirement_spec_id').val());
|
||
|
||
$.post("controller.pl", data, kivi.eval_json_result);
|
||
|
||
return true;
|
||
};
|
||
|
||
ns.time_cost_estimate_input_key_down = function(event) {
|
||
if(event.keyCode == 13) {
|
||
event.preventDefault();
|
||
ns.standard_time_cost_estimate_ajax_call('save');
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// -------------------------------------------------------------------------
|
||
// -------------------------- additional parts -----------------------------
|
||
// -------------------------------------------------------------------------
|
||
|
||
ns.standard_additional_parts_ajax_call = function(key, opt) {
|
||
var add_data = '';
|
||
if (key == 'save_keep_open') {
|
||
key = 'save';
|
||
add_data = 'keep_open=1&';
|
||
}
|
||
|
||
var data = "action=RequirementSpecPart/ajax_" + key + "&" + add_data + 'requirement_spec_id=' + encodeURIComponent($('#requirement_spec_id').val()) + '&';
|
||
|
||
if (key == 'save')
|
||
data += $('#edit_additional_parts_form').serialize();
|
||
|
||
$.post("controller.pl", data, kivi.eval_json_result);
|
||
|
||
return true;
|
||
};
|
||
|
||
ns.prepare_edit_additional_parts_form = function() {
|
||
$("#edit_additional_parts_list tbody").sortable({
|
||
distance: 5,
|
||
handle: '.dragdrop',
|
||
helper: function(event, ui) {
|
||
ui.children().each(function() {
|
||
$(this).width($(this).width());
|
||
});
|
||
return ui;
|
||
}
|
||
|
||
});
|
||
};
|
||
|
||
ns.cancel_edit_additional_parts_form = function() {
|
||
if (confirm(kivi.t8('Do you really want to cancel?'))) {
|
||
$('#additional_parts_list_container').show();
|
||
$('#additional_parts_form_container').remove();
|
||
}
|
||
return true;
|
||
};
|
||
|
||
ns.additional_parts_input_key_down = function(event) {
|
||
if(event.keyCode == 13) {
|
||
event.preventDefault();
|
||
ns.standard_additional_parts_ajax_call('save');
|
||
return false;
|
||
}
|
||
};
|
||
|
||
ns.add_additional_part = function() {
|
||
var part_id = $('#additional_parts_add_part_id').val();
|
||
if (!part_id || (part_id == ''))
|
||
return false;
|
||
|
||
var rspec_id = $('#requirement_spec_id').val();
|
||
var data = 'action=RequirementSpecPart/ajax_add&requirement_spec_id=' + encodeURIComponent(rspec_id) + '&part_id=' + encodeURIComponent(part_id);
|
||
|
||
$.post("controller.pl", data, kivi.eval_json_result);
|
||
|
||
return true;
|
||
};
|
||
|
||
ns.delete_additional_part = function(key, opt) {
|
||
opt.$trigger.remove();
|
||
if (!$('#edit_additional_parts_list tbody tr').size()) {
|
||
$('#edit_additional_parts_list_empty').show();
|
||
$('#edit_additional_parts_list').hide();
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
// -------------------------------------------------------------------------
|
||
// ------------------------------- tab widget ------------------------------
|
||
// -------------------------------------------------------------------------
|
||
... | ... | |
'tab-header-function-block': 'function-blocks-tab'
|
||
, 'tab-header-basic-settings': 'ui-tabs-1'
|
||
, 'tab-header-time-cost-estimate': 'ui-tabs-2'
|
||
, 'tab-header-versions': 'ui-tabs-3'
|
||
, 'tab-header-quotations-orders': 'ui-tabs-4'
|
||
, 'tab-header-additional-parts': 'ui-tabs-3'
|
||
, 'tab-header-versions': 'ui-tabs-4'
|
||
, 'tab-header-quotations-orders': 'ui-tabs-5'
|
||
};
|
||
|
||
ns.tabs_before_activate = function(event, ui) {
|
||
... | ... | |
}, general_actions)
|
||
});
|
||
|
||
$.contextMenu({
|
||
selector: '.additional-parts-context-menu',
|
||
items: $.extend({
|
||
heading: { name: kivi.t8('Additional articles actions'), className: 'context-menu-heading' }
|
||
, edit: { name: kivi.t8('Edit'), icon: "edit", callback: kivi.requirement_spec.standard_additional_parts_ajax_call }
|
||
}, general_actions)
|
||
});
|
||
|
||
var additional_parts_actions = {
|
||
save: { name: kivi.t8('Save'), icon: "save", callback: kivi.requirement_spec.standard_additional_parts_ajax_call }
|
||
, save_keep_open: { name: kivi.t8('Save and keep open'), icon: "save", callback: kivi.requirement_spec.standard_additional_parts_ajax_call }
|
||
, cancel: { name: kivi.t8('Cancel'), icon: "close", callback: kivi.requirement_spec.cancel_edit_additional_parts_form }
|
||
};
|
||
|
||
$.contextMenu({
|
||
selector: '.edit-additional-parts-context-menu',
|
||
items: $.extend({
|
||
heading: { name: kivi.t8('Additional articles actions'), className: 'context-menu-heading' }
|
||
}, additional_parts_actions, general_actions)
|
||
});
|
||
|
||
$.contextMenu({
|
||
selector: '.edit-additional-parts-row-context-menu',
|
||
items: $.extend({
|
||
heading: { name: kivi.t8('Additional articles actions'), className: 'context-menu-heading' }
|
||
, delete: { name: kivi.t8('Remove article'), icon: "delete", callback: kivi.requirement_spec.delete_additional_part }
|
||
}, additional_parts_actions, general_actions)
|
||
});
|
||
|
||
$.contextMenu({
|
||
selector: '.quotations-and-orders-context-menu,.quotations-and-orders-order-context-menu',
|
||
items: $.extend({
|
locale/de/all | ||
---|---|---|
'Add new currency' => 'Neue Währung hinzufügen',
|
||
'Add new custom variable' => 'Neue benutzerdefinierte Variable erfassen',
|
||
'Add note' => 'Notiz erfassen',
|
||
'Add part' => 'Artikel hinzufügen',
|
||
'Add picture' => 'Bild hinzufügen',
|
||
'Add picture to text block' => 'Bild dem Textblock hinzufügen',
|
||
'Add section' => 'Abschnitt hinzufügen',
|
||
... | ... | |
'Add unit' => 'Einheit hinzufügen',
|
||
'Added sections and function blocks: #1' => 'Hinzugefügte Abschnitte und Funktionsblöcke: #1',
|
||
'Added text blocks: #1' => 'Hinzugefügte Textblöcke: #1',
|
||
'Additional articles' => 'Zusätzliche Artikel',
|
||
'Additional articles actions' => 'Aktionen zu zusätzlichen Artikeln',
|
||
'Address' => 'Adresse',
|
||
'Admin' => 'Administration',
|
||
'Administration' => 'Administration',
|
||
... | ... | |
'Edit Vendor Invoice' => 'Einkaufsrechnung bearbeiten',
|
||
'Edit Warehouse' => 'Lager bearbeiten',
|
||
'Edit acceptance status' => 'Abnahmestatus bearbeiten',
|
||
'Edit additional articles' => 'Zusätzliche Artikel bearbeiten',
|
||
'Edit article/section assignments' => 'Zuweisung Artikel/Abschnitte bearbeiten',
|
||
'Edit assignment of articles to sections' => 'Zuweisung Artikel zu Abschnitten bearbeiten',
|
||
'Edit background job' => 'Hintergrund-Job bearbeiten',
|
||
... | ... | |
'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
|
||
'No acceptance statuses has been created yet.' => 'Es wurde noch kein Abnahmestatus angelegt.',
|
||
'No action defined.' => 'Keine Aktion definiert.',
|
||
'No articles have been added yet.' => 'Es wurden noch keine Artikel hinzugefügt.',
|
||
'No background job has been created yet.' => 'Es wurden noch keine Hintergrund-Jobs angelegt.',
|
||
'No bank information has been entered in this customer\'s master data entry. You cannot create bank collections unless you enter bank information.' => 'Für diesen Kunden wurden in seinen Stammdaten keine Kontodaten hinterlegt. Solange dies nicht geschehen ist, können Sie keine Überweisungen für den Lieferanten anlegen.',
|
||
'No bank information has been entered in this vendor\'s master data entry. You cannot create bank transfers unless you enter bank information.' => 'Für diesen Lieferanten wurden in seinen Stammdaten keine Kontodaten hinterlegt. Solange dies nicht geschehen ist, können Sie keine Überweisungen für den Lieferanten anlegen.',
|
||
... | ... | |
'Removal qty' => 'Entnahmemenge',
|
||
'Remove' => 'Entfernen',
|
||
'Remove Draft' => 'Entwurf löschen',
|
||
'Remove article' => 'Artikel entfernen',
|
||
'Remove draft when posting' => 'Entwurf beim Buchen löschen',
|
||
'Removed sections and function blocks: #1' => 'Entfernte Abschnitte und Funktionsblöcke: #1',
|
||
'Removed spoolfiles!' => 'Druckdateien entfernt!',
|
sql/Pg-upgrade2/requirement_spec_parts.sql | ||
---|---|---|
-- @tag: requirement_spec_parts
|
||
-- @description: Artikelzuweisung zu Pflichtenheften
|
||
-- @depends: release_3_1_0
|
||
CREATE TABLE requirement_spec_parts (
|
||
id SERIAL NOT NULL,
|
||
requirement_spec_id INTEGER NOT NULL,
|
||
part_id INTEGER NOT NULL,
|
||
unit_id INTEGER NOT NULL,
|
||
qty NUMERIC(15, 5) NOT NULL,
|
||
description TEXT NOT NULL,
|
||
position INTEGER NOT NULL,
|
||
|
||
PRIMARY KEY (id),
|
||
FOREIGN KEY (requirement_spec_id) REFERENCES requirement_specs (id),
|
||
FOREIGN KEY (part_id) REFERENCES parts (id),
|
||
FOREIGN KEY (unit_id) REFERENCES units (id)
|
||
);
|
templates/webpages/requirement_spec/show.html | ||
---|---|---|
<li id="tab-header-function-block"><a href="#function-blocks-tab">[%- LxERP.t8("Content") %]</a></li>
|
||
<li id="tab-header-basic-settings"><a href="controller.pl?action=RequirementSpec/ajax_show_basic_settings&id=[% HTML.url(SELF.requirement_spec.id) %]">[%- LxERP.t8("Basic settings") %]</a></li>
|
||
<li id="tab-header-time-cost-estimate"><a href="controller.pl?action=RequirementSpec/ajax_show_time_and_cost_estimate&id=[% HTML.url(SELF.requirement_spec.id) %]">[%- LxERP.t8("Time and cost estimate") %]</a></li>
|
||
<li id="tab-header-additional-parts"><a href="controller.pl?action=RequirementSpecPart/show&requirement_spec_id=[% HTML.url(SELF.requirement_spec.id) %]">[%- LxERP.t8("Additional articles") %]</a></li>
|
||
[%- UNLESS SELF.requirement_spec.is_template %]
|
||
<li id="tab-header-versions"><a href="controller.pl?action=RequirementSpecVersion/list&requirement_spec_id=[% HTML.url(SELF.requirement_spec.id) %]">[%- LxERP.t8("Versions") %]</a></li>
|
||
<li id="tab-header-quotations-orders"><a href="[% SELF.url_for(controller='RequirementSpecOrder', action='list', requirement_spec_id=SELF.requirement_spec.id) %]">[%- LxERP.t8("Quotations and orders") %]</a></li>
|
templates/webpages/requirement_spec_part/_edit.html | ||
---|---|---|
[%- USE LxERP -%][%- USE L -%][%- USE P -%]
|
||
[% SET parts = SELF.requirement_spec.parts_sorted %]
|
||
|
||
<div id="additional_parts_form_container" class="edit-additional-parts-context-menu">
|
||
|
||
<h2>[% LxERP.t8("Edit additional articles") %]</h2>
|
||
|
||
<div>
|
||
[% LxERP.t8("Add part") %]:
|
||
[% P.part_picker('additional_parts_add_part_id', '', style="width: 300px") %]
|
||
[% L.button_tag('kivi.requirement_spec.add_additional_part()', LxERP.t8('Add part')) %]
|
||
</div>
|
||
|
||
<form method="post" id="edit_additional_parts_form">
|
||
<div id="edit_additional_parts_list_empty"[% IF parts.size %] style="display: none;"[% END %]>
|
||
[% LxERP.t8("No articles have been added yet.") %]
|
||
</div>
|
||
|
||
<table id="edit_additional_parts_list"[% IF !parts.size %] style="display: none;"[% END %]>
|
||
<thead>
|
||
<tr class="listheading">
|
||
<th></th>
|
||
<th>[%- LxERP.t8("Part Number") %]</th>
|
||
<th>[%- LxERP.t8("Description") %]</th>
|
||
<th>[%- LxERP.t8("Qty") %]</th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
[%- FOREACH part = parts %]
|
||
[%- INCLUDE 'requirement_spec_part/_part.html' part=part %]
|
||
[%- END %]
|
||
</tbody>
|
||
</table>
|
||
|
||
[% L.button_tag("kivi.requirement_spec.standard_additional_parts_ajax_call('save')", LxERP.t8("Save")) %]
|
||
</form>
|
||
</div>
|
templates/webpages/requirement_spec_part/_part.html | ||
---|---|---|
[%- USE HTML -%][%- USE L -%][%- USE LxERP -%]
|
||
<tr class="listrow edit-additional-parts-row-context-menu">
|
||
<td align="center">
|
||
[% L.hidden_tag("additional_parts[+].part_id", part.part.id) %]
|
||
[% L.hidden_tag("additional_parts[].id", part.id) %]
|
||
[% L.img_tag(src="image/updown.png", alt=LxERP.t8("reorder item"), class="dragdrop") %]
|
||
</td>
|
||
<td>[% HTML.escape(part.part.partnumber) %]</td>
|
||
<td>[% L.input_tag("additional_parts[].description", part.description, size="30") %]</td>
|
||
<td>
|
||
[% L.input_tag("additional_parts[].qty_as_number", part.qty_as_number, size="10") %]
|
||
[% L.select_tag("additional_parts[].unit_id", part.unit.convertible_units, title_key="name", default=part.unit.id) %]
|
||
</td>
|
||
</tr>
|
templates/webpages/requirement_spec_part/show.html | ||
---|---|---|
[%- USE LxERP -%][%- USE L -%][%- USE P -%][%- USE HTML -%]
|
||
[% SET parts = SELF.requirement_spec.parts_sorted %]
|
||
|
||
<div id="additional_parts_list_container" class="additional-parts-context-menu"[% IF initially_hidden %] style="display: none;"[% END %]>
|
||
|
||
<h2>[% LxERP.t8("Additional articles") %]</h2>
|
||
|
||
<div id="additional_parts_list_empty"[% IF parts.size %] style="display: none;"[% END %]>
|
||
[% LxERP.t8("No articles have been added yet.") %]
|
||
</div>
|
||
|
||
<table id="additional_parts_list"[% IF !parts.size %] style="display: none;"[% END %]>
|
||
<thead>
|
||
<tr class="listheading">
|
||
<th>[%- LxERP.t8("Part Number") %]</th>
|
||
<th>[%- LxERP.t8("Description") %]</th>
|
||
<th>[%- LxERP.t8("Qty") %]</th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
[% FOREACH part = parts %]
|
||
<tr class="listrow">
|
||
<td>[% HTML.escape(part.part.partnumber) %]</td>
|
||
<td>[% HTML.escape(part.description) %]</td>
|
||
<td valign="right">[% HTML.escape(part.qty_as_number) %] [% HTML.escape(part.unit.name) %]</td>
|
||
</tr>
|
||
[% END %]
|
||
</tbody>
|
||
</table>
|
||
</div>
|
Auch abrufbar als: Unified diff
Pflichtenhefte: zusätzliche Artikel zuweisen und bearbeiten können