Revision fec397bf
Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt
SL/Controller/RequirementSpec.pm | ||
---|---|---|
29 | 29 |
( |
30 | 30 |
scalar => [ qw(requirement_spec_item visible_item visible_section) ], |
31 | 31 |
'scalar --get_set_init' => [ qw(requirement_spec customers types statuses complexities risks projects project_types project_statuses default_project_type default_project_status copy_source js |
32 |
current_text_block_output_position models) ], |
|
32 |
current_text_block_output_position models time_based_units) ],
|
|
33 | 33 |
); |
34 | 34 |
|
35 | 35 |
__PACKAGE__->run_before('setup'); |
... | ... | |
289 | 289 |
sub init_projects { SL::DB::Manager::Project->get_all_sorted } |
290 | 290 |
sub init_risks { SL::DB::Manager::RequirementSpecRisk->get_all_sorted } |
291 | 291 |
sub init_statuses { SL::DB::Manager::RequirementSpecStatus->get_all_sorted } |
292 |
sub init_time_based_units { SL::DB::Manager::Unit->time_based_units } |
|
292 | 293 |
sub init_types { SL::DB::Manager::RequirementSpecType->get_all_sorted } |
293 | 294 |
|
294 | 295 |
sub init_customers { |
SL/Controller/RequirementSpecOrder.pm | ||
---|---|---|
23 | 23 |
use Rose::Object::MakeMethods::Generic |
24 | 24 |
( |
25 | 25 |
scalar => [ qw(parts) ], |
26 |
'scalar --get_set_init' => [ qw(requirement_spec rs_order js h_unit_name all_customers all_parts_time_unit) ], |
|
26 |
'scalar --get_set_init' => [ qw(requirement_spec rs_order js h_unit_name all_customers all_parts_time_unit section_order_part) ],
|
|
27 | 27 |
); |
28 | 28 |
|
29 | 29 |
__PACKAGE__->run_before('setup'); |
... | ... | |
156 | 156 |
my $html = $self->render('requirement_spec_order/edit_assignment', { output => 0 }, make_part_title => sub { $_[0]->partnumber . ' ' . $_[0]->description }); |
157 | 157 |
$self->js->hide(LIST_SELECTOR()) |
158 | 158 |
->after(LIST_SELECTOR(), $html) |
159 |
->reinit_widgets |
|
159 | 160 |
->render($self); |
160 | 161 |
} |
161 | 162 |
|
... | ... | |
209 | 210 |
} |
210 | 211 |
|
211 | 212 |
sub init_all_customers { SL::DB::Manager::Customer->get_all_sorted } |
212 |
sub init_h_unit_name { first { SL::DB::Manager::Unit->find_by(name => $_) } qw(Std h Stunde) };
|
|
213 |
sub init_h_unit_name { SL::DB::Manager::Unit->find_h_unit->name };
|
|
213 | 214 |
sub init_rs_order { SL::DB::RequirementSpecOrder->new(id => $::form->{rs_order_id})->load }; |
215 |
sub init_section_order_part { my $id = $::instance_conf->get_requirement_spec_section_order_part_id; return $id ? SL::DB::Part->new(id => $id)->load : undef } |
|
214 | 216 |
|
215 | 217 |
sub init_all_parts_time_unit { |
216 | 218 |
my ($self) = @_; |
217 | 219 |
|
218 | 220 |
return [] unless $self->h_unit_name; |
219 | 221 |
|
220 |
my @convertible_unit_names = map { $_->name } @{ SL::DB::Manager::Unit->find_by(name => $self->h_unit_name)->convertible_units };
|
|
222 |
my @convertible_unit_names = map { $_->name } @{ SL::DB::Manager::Unit->time_based_units };
|
|
221 | 223 |
|
222 | 224 |
return SL::DB::Manager::Part->get_all_sorted(where => [ unit => \@convertible_unit_names ]); |
223 | 225 |
} |
SL/DB/Manager/Unit.pm | ||
---|---|---|
8 | 8 |
use SL::DB::Helper::Sorted; |
9 | 9 |
use SL::DB::Helper::Filtered; |
10 | 10 |
|
11 |
use List::Util qw(first); |
|
12 |
|
|
11 | 13 |
sub object_class { 'SL::DB::Unit' } |
12 | 14 |
|
13 | 15 |
__PACKAGE__->make_manager_methods; |
... | ... | |
46 | 48 |
$::request->cache('all_units')->{sorted} //= $class->get_all_sorted; |
47 | 49 |
} |
48 | 50 |
|
51 |
sub find_h_unit { |
|
52 |
my ($class) = @_; |
|
53 |
|
|
54 |
return $::request->cache('unit_manager')->{h_unit} //= first { $_->name =~ m{^(?: Std | h | Stunde )$}x } @{ $class->all_units }; |
|
55 |
} |
|
56 |
|
|
57 |
sub time_based_units { |
|
58 |
my ($class) = @_; |
|
59 |
|
|
60 |
my $h_unit = $class->find_h_unit; |
|
61 |
return [] if !$h_unit; |
|
62 |
return $::request->cache('unit_manager')->{units} //= $h_unit->convertible_units; |
|
63 |
} |
|
64 |
|
|
49 | 65 |
1; |
SL/DB/Unit.pm | ||
---|---|---|
1 | 1 |
package SL::DB::Unit; |
2 | 2 |
|
3 |
use List::MoreUtils qw(any); |
|
4 |
|
|
5 |
|
|
3 | 6 |
use strict; |
4 | 7 |
|
5 | 8 |
use SL::DB::MetaSetup::Unit; |
... | ... | |
57 | 60 |
return $qty * $my_base_factor / $other_base_factor; |
58 | 61 |
} |
59 | 62 |
|
63 |
sub is_time_based { |
|
64 |
my ($self) = @_; |
|
65 |
|
|
66 |
return any { $_->id == $self->id } @{ SL::DB::Manager::Unit->time_based_units }; |
|
67 |
} |
|
68 |
|
|
60 | 69 |
1; |
js/locale/de.js | ||
---|---|---|
70 | 70 |
"Transaction description":"Vorgangsbezeichnung", |
71 | 71 |
"Update":"Erneuern", |
72 | 72 |
"Update quotation/order":"Auftrag/Angebot aktualisieren", |
73 |
"Version actions":"Aktionen für Versionen" |
|
73 |
"Version actions":"Aktionen für Versionen", |
|
74 |
"flat-rate position":"Pauschalposition", |
|
75 |
"time and effort based position":"Aufwandsposition" |
|
74 | 76 |
}); |
js/requirement_spec.js | ||
---|---|---|
153 | 153 |
|
154 | 154 |
ns.create_context_menus(data.is_template); |
155 | 155 |
$('#requirement_spec_tabs').on("tabsbeforeactivate", ns.tabs_before_activate); |
156 |
|
|
157 |
ns.time_based_units = data.time_based_units; |
|
156 | 158 |
}; |
157 | 159 |
|
158 | 160 |
// ------------------------------------------------------------------------- |
... | ... | |
565 | 567 |
}).each(function(idx, elt) { |
566 | 568 |
$(elt).val(order_part_name); |
567 | 569 |
}); |
570 |
|
|
571 |
var unit = $('#quotations_and_orders_order_id').closest('td').data('unit'); |
|
572 |
var text = ns.time_based_units[unit] ? kivi.t8("time and effort based position") : kivi.t8("flat-rate position"); |
|
573 |
|
|
574 |
$('#quotations_and_orders_form [data-unit-column=1]').html(unit); |
|
575 |
$('#quotations_and_orders_form [data-position-type-column=1]').html(text); |
|
576 |
}; |
|
577 |
|
|
578 |
ns.assign_order_part_on_part_picked = function(event, item) { |
|
579 |
if (!item || !item.unit) |
|
580 |
return; |
|
581 |
|
|
582 |
var $elt = $(this), |
|
583 |
id = $elt.prop('id'); |
|
584 |
|
|
585 |
if (id == 'quotations_and_orders_order_id') |
|
586 |
$elt.closest('td').data('unit', item.unit); |
|
587 |
|
|
588 |
else { |
|
589 |
var $tr = $elt.closest('tr'); |
|
590 |
var text = ns.time_based_units[item.unit] ? kivi.t8("time and effort based position") : kivi.t8("flat-rate position"); |
|
591 |
|
|
592 |
$tr.find('[data-unit-column=1]').html(item.unit); |
|
593 |
$tr.find('[data-position-type-column=1]').html(text); |
|
594 |
} |
|
568 | 595 |
}; |
569 | 596 |
|
570 | 597 |
// ------------------------------------------------------------------------- |
... | ... | |
1037 | 1064 |
}; |
1038 | 1065 |
|
1039 | 1066 |
}); // end of namespace(...., function() {... |
1067 |
|
|
1068 |
function local_reinit_widgets() { |
|
1069 |
kivi.run_once_for('#quotations_and_orders_order_id,[name="sections[].order_part_id"]', "assign_order_part_on_part_picked", function(elt) { |
|
1070 |
$(elt).on('set_item:PartPicker', kivi.requirement_spec.assign_order_part_on_part_picked); |
|
1071 |
}); |
|
1072 |
} |
locale/de/all | ||
---|---|---|
1791 | 1791 |
'Plural' => 'Plural', |
1792 | 1792 |
'Port' => 'Port', |
1793 | 1793 |
'Portrait' => 'Hochformat', |
1794 |
'Position type in quotation/order' => 'Positionstyp in Angebot/Auftrag', |
|
1794 | 1795 |
'Post' => 'Buchen', |
1795 | 1796 |
'Post Payment' => 'Zahlung buchen', |
1796 | 1797 |
'Post and E-mail' => 'Buchen und E-Mail', |
... | ... | |
2976 | 2977 |
'executed' => 'ausgeführt', |
2977 | 2978 |
'failed' => 'fehlgeschlagen', |
2978 | 2979 |
'female' => 'weiblich', |
2980 |
'flat-rate position' => 'Pauschalposition', |
|
2979 | 2981 |
'follow_up_list' => 'wiedervorlageliste', |
2980 | 2982 |
'for' => 'für', |
2981 | 2983 |
'for Period' => 'für den Zeitraum', |
... | ... | |
3102 | 3104 |
'taxkey 0 with taxrate 0 was created.' => 'Steuerschlüssel 0 wurde angelegt.', |
3103 | 3105 |
'taxnumber' => 'Automatikkonto', |
3104 | 3106 |
'terminated' => 'gekündigt', |
3107 |
'time and effort based position' => 'Aufwandsposition', |
|
3105 | 3108 |
'to (date)' => 'bis', |
3106 | 3109 |
'to (time)' => 'bis', |
3107 | 3110 |
'transfer' => 'Umlagerung', |
templates/webpages/requirement_spec/show.html | ||
---|---|---|
1 |
[%- USE JSON -%][%- USE HTML %][%- USE L %][%- USE LxERP %][%- USE P -%] |
|
1 |
[%- USE JSON -%][%- USE HTML %][%- USE L %][%- USE LxERP %][%- USE P -%][%- USE JavaScript -%]
|
|
2 | 2 |
[% SET sections = SELF.requirement_spec.sections_sorted || [] %] |
3 | 3 |
|
4 | 4 |
[%- INCLUDE 'common/flash.html' %] |
... | ... | |
95 | 95 |
[% IF SELF.requirement_spec_item %] |
96 | 96 |
, initially_selected_node: '#fb-[% SELF.requirement_spec_item.id %]' |
97 | 97 |
[% END %] |
98 |
, time_based_units: { |
|
99 |
[% FOREACH unit = SELF.time_based_units %] |
|
100 |
[% UNLESS loop.first %], [% END %] "[% JavaScript.escape(unit.name) %]": true |
|
101 |
[% END %] |
|
102 |
} |
|
98 | 103 |
}); |
99 | 104 |
}); |
100 | 105 |
|
templates/webpages/requirement_spec_order/_assignment_form.html | ||
---|---|---|
17 | 17 |
|
18 | 18 |
<tr> |
19 | 19 |
<td>[% LxERP.t8("Assign the following article to all sections") %]:</td> |
20 |
<td> |
|
21 |
[% P.part_picker('quotations_and_orders_dummy', INSTANCE_CONF.get_requirement_spec_section_order_part_id, convertible_unit=SELF.h_unit_name, id='quotations_and_orders_order_id', style=style) %]
|
|
20 |
<td data-unit="[% HTML.escape(SELF.section_order_part.unit) %]">
|
|
21 |
[% P.part_picker('quotations_and_orders_dummy', SELF.section_order_part.id, id='quotations_and_orders_order_id', style=style) %]
|
|
22 | 22 |
[% L.button_tag('kivi.requirement_spec.assign_order_part_id_to_all()', LxERP.t8('Assign article')) %] |
23 | 23 |
</td> |
24 | 24 |
</tr> |
... | ... | |
31 | 31 |
<th>[% LxERP.t8("Title") %]</th> |
32 | 32 |
<th>[% LxERP.t8("Description") %]</th> |
33 | 33 |
<th>[% LxERP.t8("Article") %]</th> |
34 |
<th>[% LxERP.t8("Unit") %]</th> |
|
35 |
<th>[% LxERP.t8("Position type in quotation/order") %]</th> |
|
34 | 36 |
</tr> |
35 | 37 |
</thead> |
36 | 38 |
|
... | ... | |
41 | 43 |
<td>[% HTML.escape(section.fb_number) %]</td> |
42 | 44 |
<td>[% HTML.escape(section.title) %]</td> |
43 | 45 |
<td>[% HTML.escape(P.truncate(section.description_as_stripped_html)) %]</td> |
44 |
<td>[% P.part_picker('sections[].order_part_id', section.order_part_id, convertible_unit=SELF.h_unit_name, id='quotations_and_orders_sections_order_pard_id_' _ loop.count, style=style) %]</td> |
|
46 |
<td>[% P.part_picker('sections[].order_part_id', section.order_part_id, id='quotations_and_orders_sections_order_pard_id_' _ loop.count, style=style) %]</td> |
|
47 |
<td data-unit-column=1>[% HTML.escape(section.order_part.unit) %]</td> |
|
48 |
<td data-position-type-column=1> |
|
49 |
[% IF section.order_part_id && section.order_part.unit_obj.is_time_based %] |
|
50 |
[% LxERP.t8("time and effort based position") %] |
|
51 |
[% ELSIF section.order_part_id %] |
|
52 |
[% LxERP.t8("flat-rate position") %] |
|
53 |
[% END %] |
|
54 |
</td> |
|
45 | 55 |
</tr> |
46 | 56 |
[% END %] |
47 | 57 |
</tbody> |
templates/webpages/requirement_spec_order/list.html | ||
---|---|---|
15 | 15 |
<th>[% LxERP.t8("Title") %]</th> |
16 | 16 |
<th>[% LxERP.t8("Description") %]</th> |
17 | 17 |
<th>[% LxERP.t8("Article") %]</th> |
18 |
<th>[% LxERP.t8("Unit") %]</th> |
|
19 |
<th>[% LxERP.t8("Position type in quotation/order") %]</th> |
|
18 | 20 |
</tr> |
19 | 21 |
</thead> |
20 | 22 |
|
... | ... | |
31 | 33 |
[% LxERP.t8("no article assigned yet") %] |
32 | 34 |
[% END %] |
33 | 35 |
</td> |
36 |
<td>[% HTML.escape(section.order_part.unit) %]</td> |
|
37 |
<td> |
|
38 |
[% IF section.order_part_id && section.order_part.unit_obj.is_time_based %] |
|
39 |
[% LxERP.t8("time and effort based position") %] |
|
40 |
[% ELSIF section.order_part_id %] |
|
41 |
[% LxERP.t8("flat-rate position") %] |
|
42 |
[% END %] |
|
43 |
</td> |
|
34 | 44 |
</tr> |
35 | 45 |
[% END %] |
36 | 46 |
</tbody> |
Auch abrufbar als: Unified diff
Pflichtenheftaufträge: beliebige Artikel auswählen können
Zusätzlich werden dann Spalten angezeigt, die die Einheit und den im
Angebot/Auftrag verwendeten Positionstypen (Pauschalposition/
Auwandsposition) angeben.