Revision 93a1b332
Von Moritz Bunkus vor etwa 8 Jahren hinzugefügt
SL/Controller/RequirementSpecOrder.pm | ||
---|---|---|
318 | 318 |
longdescription => $longdescription, |
319 | 319 |
qty => $is_time_based ? $section->time_estimation * 1 : 1, |
320 | 320 |
unit => $is_time_based ? $self->h_unit_name : $part->unit, |
321 |
sellprice => $::form->round_amount($self->requirement_spec->hourly_rate * ($is_time_based ? 1 : $section->time_estimation), 2), |
|
322 |
lastcost => $part->lastcost, |
|
321 |
sellprice => $::form->round_amount($self->requirement_spec->hourly_rate * ($is_time_based ? 1 : $section->time_estimation * $section->sellprice_factor), 2),
|
|
322 |
lastcost => $part->lastcost * $section->sellprice_factor,
|
|
323 | 323 |
discount => 0, |
324 | 324 |
project_id => $self->requirement_spec->project_id, |
325 | 325 |
); |
SL/DB/MetaSetup/RequirementSpecItem.pm | ||
---|---|---|
24 | 24 |
position => { type => 'integer', not_null => 1 }, |
25 | 25 |
requirement_spec_id => { type => 'integer', not_null => 1 }, |
26 | 26 |
risk_id => { type => 'integer' }, |
27 |
sellprice_factor => { type => 'numeric', default => 1, precision => 10, scale => 5 }, |
|
27 | 28 |
time_estimation => { type => 'numeric', default => '0', not_null => 1, precision => 12, scale => 2 }, |
28 | 29 |
title => { type => 'text' }, |
29 | 30 |
); |
locale/de/all | ||
---|---|---|
624 | 624 |
'Copy requirement spec' => 'Pflichtenheft kopieren', |
625 | 625 |
'Copy template' => 'Vorlage kopieren', |
626 | 626 |
'Correct taxkey' => 'Richtiger Steuerschlüssel', |
627 |
'Cost' => 'Kosten', |
|
628 | 627 |
'Costs' => 'Kosten', |
629 | 628 |
'Could not load class #1 (#2): "#3"' => 'Konnte Klasse #1 (#2) nicht laden: "#3"', |
630 | 629 |
'Could not load class #1, #2' => 'Konnte Klasse #1 nicht laden: "#2"', |
... | ... | |
3185 | 3184 |
'This will set an exact price.' => 'Diese Option setzt einen festen Preis.', |
3186 | 3185 |
'Three Options:' => 'Drei Optionen:', |
3187 | 3186 |
'Time Format' => 'Uhrzeitformat', |
3188 |
'Time and cost estimate' => 'Zeit- und Kostenschätzung', |
|
3187 |
'Time Tracking' => 'Zeiterfassung', |
|
3188 |
'Time and price estimate' => 'Zeit- und Preisschätzung', |
|
3189 | 3189 |
'Time estimate' => 'Zeitschätzung', |
3190 | 3190 |
'Time period for the analysis:' => 'Analysezeitraum:', |
3191 | 3191 |
'Time/cost estimate actions' => 'Aktionen für Kosten-/Zeitabschätzung', |
sql/Pg-upgrade2/requirement_spec_items_price_factor.sql | ||
---|---|---|
1 |
-- @tag: requirement_spec_items_price_factor |
|
2 |
-- @description: Pflichtenheftabschnitte: Faktor für Verkaufspreis |
|
3 |
-- @depends: requirement_specs |
|
4 |
ALTER TABLE requirement_spec_items |
|
5 |
ADD COLUMN sellprice_factor NUMERIC(10, 5), |
|
6 |
ALTER COLUMN sellprice_factor SET DEFAULT 1; |
|
7 |
|
|
8 |
UPDATE requirement_spec_items |
|
9 |
SET sellprice_factor = 1; |
templates/webpages/requirement_spec/_show_time_and_cost_estimate.html | ||
---|---|---|
1 | 1 |
[%- USE LxERP -%][%- USE L -%][%- USE HTML -%][%- USE P -%] |
2 | 2 |
[%- DEFAULT id_prefix = 'time_and_cost_estimate_form' %] |
3 |
[%- SET total_cost = 0 %] |
|
3 | 4 |
|
4 | 5 |
<div id="time_cost_estimate"[% IF initially_hidden %] style="display: none;"[% END %]> |
5 | 6 |
[%- IF !SELF.requirement_spec.sections.size %] |
... | ... | |
18 | 19 |
<th>[%- LxERP.t8("Risk") %]</th> |
19 | 20 |
<th align="right">[%- LxERP.t8("Time estimate") %]</th> |
20 | 21 |
[%- UNLESS SELF.requirement_spec.is_template %] |
21 |
<th align="right">[%- LxERP.t8("Cost") %]</th>
|
|
22 |
<th align="right">[%- LxERP.t8("Price") %]</th>
|
|
22 | 23 |
[%- END %] |
23 | 24 |
</tr> |
24 | 25 |
|
... | ... | |
30 | 31 |
[%- SET at_least_one_function_block = 1 %] |
31 | 32 |
[%- FOREACH child = section.children_sorted %] |
32 | 33 |
[%- INCLUDE 'requirement_spec/_show_time_and_cost_estimate_item.html' |
33 |
item = child |
|
34 |
level = 1 %] |
|
34 |
section = section |
|
35 |
item = child |
|
36 |
level = 1 %] |
|
35 | 37 |
[%- END %] |
36 | 38 |
|
37 | 39 |
<tr class="listrow subtotal"> |
38 | 40 |
<td style="padding-left: 50px" colspan="3" class="sum">[%- LxERP.t8("Sum for section") -%]:</td> |
39 | 41 |
<td align="right" nowrap>[%- P.format_man_days(section.time_estimation, 'skip_zero'=1) -%]</td> |
40 | 42 |
[%- UNLESS SELF.requirement_spec.is_template %] |
41 |
<td align="right" nowrap>[%- LxERP.format_amount(section.time_estimation * SELF.requirement_spec.hourly_rate, 2) -%] EUR</td> |
|
43 |
[%- SET section_cost = section.time_estimation * SELF.requirement_spec.hourly_rate * section.sellprice_factor; |
|
44 |
total_cost = total_cost + section_cost %] |
|
45 |
<td align="right" nowrap>[%- LxERP.format_amount(section_cost, 2) -%] EUR</td> |
|
42 | 46 |
[%- END %] |
43 | 47 |
</tr> |
44 | 48 |
[%- END -%] |
... | ... | |
50 | 54 |
<td colspan="3">[%- LxERP.t8("Sum for #1", SELF.requirement_spec.type.description) -%]:</td> |
51 | 55 |
<td align="right" nowrap>[%- P.format_man_days(SELF.requirement_spec.time_estimation) -%]</td> |
52 | 56 |
[%- UNLESS SELF.requirement_spec.is_template %] |
53 |
<td align="right" nowrap>[%- LxERP.format_amount(SELF.requirement_spec.time_estimation * SELF.requirement_spec.hourly_rate, 2) -%] EUR</td>
|
|
57 |
<td align="right" nowrap>[%- LxERP.format_amount(total_cost, 2) -%] EUR</td>
|
|
54 | 58 |
[%- END %] |
55 | 59 |
</tr> |
56 | 60 |
</tfoot> |
templates/webpages/requirement_spec/_show_time_and_cost_estimate_item.html | ||
---|---|---|
8 | 8 |
[%- IF !item.children.size -%] |
9 | 9 |
<td align="right" nowrap>[%- P.format_man_days(item.time_estimation, skip_zero=1) -%]</td> |
10 | 10 |
[%- UNLESS SELF.requirement_spec.is_template %] |
11 |
<td align="right" nowrap>[%- LxERP.format_amount(item.time_estimation * SELF.requirement_spec.hourly_rate, 2) -%] EUR</td> |
|
11 |
<td align="right" nowrap>[%- LxERP.format_amount(item.time_estimation * SELF.requirement_spec.hourly_rate * section.sellprice_factor, 2) -%] EUR</td>
|
|
12 | 12 |
[%- END %] |
13 | 13 |
[%- ELSE -%] |
14 | 14 |
<td> </td> |
... | ... | |
19 | 19 |
[%- IF item.children.size -%] |
20 | 20 |
[%- FOREACH child = item.children_sorted -%] |
21 | 21 |
[%- INCLUDE 'requirement_spec/_show_time_and_cost_estimate_item.html' |
22 |
item = child |
|
23 |
level = level + 1 -%] |
|
22 |
section = section |
|
23 |
item = child |
|
24 |
level = level + 1 -%] |
|
24 | 25 |
[%- END -%] |
25 | 26 |
|
26 | 27 |
<tr class="listrow subtotal"> |
27 | 28 |
<td style="padding-left: [%- (level + 1) * 50 -%]px" colspan="3">[%- LxERP.t8("Sum for #1", item.fb_number) -%]:</td> |
28 | 29 |
<td align="right" nowrap>[%- P.format_man_days(item.time_estimation, skip_zero=1) -%]</td> |
29 | 30 |
[%- UNLESS SELF.requirement_spec.is_template %] |
30 |
<td align="right" nowrap>[%- LxERP.format_amount(item.time_estimation * SELF.requirement_spec.hourly_rate, 2) -%] EUR</td> |
|
31 |
<td align="right" nowrap>[%- LxERP.format_amount(item.time_estimation * SELF.requirement_spec.hourly_rate * section.sellprice_factor, 2) -%] EUR</td>
|
|
31 | 32 |
[%- END %] |
32 | 33 |
</tr> |
33 | 34 |
[%- END -%] |
templates/webpages/requirement_spec/show.html | ||
---|---|---|
11 | 11 |
<ul> |
12 | 12 |
<li id="tab-header-function-block"><a href="#function-blocks-tab">[%- LxERP.t8("Content") %]</a></li> |
13 | 13 |
<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> |
14 |
<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>
|
|
14 |
<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 price estimate") %]</a></li>
|
|
15 | 15 |
<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> |
16 | 16 |
[%- UNLESS SELF.requirement_spec.is_template %] |
17 | 17 |
<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> |
templates/webpages/requirement_spec_item/_section_form.html | ||
---|---|---|
33 | 33 |
</p> |
34 | 34 |
[%- END %] |
35 | 35 |
|
36 |
<p> |
|
37 |
[%- LxERP.t8("Description") %]:<br> |
|
38 |
[% L.textarea_tag(id_base _ '.description_as_restricted_html', SELF.item.description_as_restricted_html, id=id_base _ '_description', rows=8, cols=80, style=style, class='texteditor') %] |
|
39 |
</p> |
|
40 |
|
|
41 |
<p> |
|
42 |
[% L.ajax_submit_tag('controller.pl?action=RequirementSpecItem/ajax_' _ (SELF.item.id ? 'update' : 'create'), '#' _ id_base _ '_form', LxERP.t8('Save')) %] |
|
43 |
<a href="#" onclick="kivi.requirement_spec.cancel_edit_item_form('[% id_base %]', { to_show: '[% hidden %]' })">[%- LxERP.t8("Cancel") %]</a> |
|
44 |
</p> |
|
36 |
<table border="0"> |
|
37 |
<tr valign="top"> |
|
38 |
<td> |
|
39 |
[%- LxERP.t8("Description") %]:<br> |
|
40 |
[% L.textarea_tag(id_base _ '.description_as_restricted_html', SELF.item.description_as_restricted_html, id=id_base _ '_description', rows=8, cols=80, style=style, class='texteditor') %]<br> |
|
41 |
[% L.ajax_submit_tag('controller.pl?action=RequirementSpecItem/ajax_' _ (SELF.item.id ? 'update' : 'create'), '#' _ id_base _ '_form', LxERP.t8('Save')) %] |
|
42 |
<a href="#" onclick="kivi.requirement_spec.cancel_edit_item_form('[% id_base %]', { to_show: '[% hidden %]' })">[%- LxERP.t8("Cancel") %]</a> |
|
43 |
</td> |
|
44 |
|
|
45 |
<td> |
|
46 |
[% LxERP.t8("Price Factor") %]:<br> |
|
47 |
[% L.input_tag(id_base _ ".sellprice_factor_as_number", SELF.item.sellprice_factor_as_number, size="6") %]<br> |
|
48 |
</td> |
|
49 |
</tr> |
|
50 |
</table> |
|
45 | 51 |
|
46 | 52 |
[%- IF SELF.predefined_texts.size %] |
47 | 53 |
<script type="text/javascript"> |
templates/webpages/requirement_spec_item/_section_header.html | ||
---|---|---|
18 | 18 |
<span class="dimmed-text">[%- LxERP.t8("No text has been entered yet.") %]</span> |
19 | 19 |
[%- END %] |
20 | 20 |
</div> |
21 |
|
|
22 |
<div class="smaller gray" style="text-align:right"> |
|
23 |
[%- LxERP.t8("Price Factor") -%]: [%- LxERP.format_amount(requirement_spec_item.sellprice_factor, -2) -%] |
|
24 |
</div> |
Auch abrufbar als: Unified diff
Pflichtenhefte: Faktor für Verkaufspreis in Abschnitten & »Kostenschätzung« umbenannt
Aktuell haben wir nur einen Verkaufsbasispreis im Pflichtenheft: den
Stundensatz in den Grundeinstellungen. Dies ist allerdings der
Stundensatz, der Kunden gegenüber in Rechnung gestellt wird, und damit
ein Verkaufspreis und kein Kostenfaktor. Die Kosten anhand des
Verkaufspreises abzuschätzen ist aber unsinnig.
Daher ist es sinnvoller, erst mal von »Zeit- und Preisschätzung«
anstelle von »Zeit- und Kostenschätzung«.
Der neu eingeführte Faktor, der an Abschnitten angegeben werden kann,
ist dann ein Multiplikator für die Verkaufspreisschätzung. Er kann
z.B. benutzt werden, um geplante Wochenendarbeiten höher zu bepreisen.
Eine Einführung von echter Kostenschätzungen würde etwas mehr Arbeit
erfordern.