Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 90651b58

Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt

  • ID 90651b58b14d7e2dc26a996124d2ba2ef0ea42c2
  • Vorgänger c1f5a8f3
  • Nachfolger 1cc65ebc

Pflichtenhefte: Anlegen von Angeboten/Aufträgen

Unterschiede anzeigen:

SL/Controller/RequirementSpecOrder.pm
5 5

  
6 6
use parent qw(SL::Controller::Base);
7 7

  
8
use List::MoreUtils qw(uniq);
9
use List::Util qw(first);
10

  
8 11
use SL::ClientJS;
9 12
use SL::DB::Customer;
13
use SL::DB::Order;
10 14
use SL::DB::Part;
11 15
use SL::DB::RequirementSpec;
12 16
use SL::DB::RequirementSpecOrder;
13 17
use SL::Helper::Flash;
14 18
use SL::Locale::String;
15 19

  
20
use constant TAB_ID => 'ui-tabs-4';
21

  
16 22
use Rose::Object::MakeMethods::Generic
17 23
(
18
  'scalar --get_set_init' => [ qw(requirement_spec js all_customers all_parts) ],
24
  scalar                  => [ qw(parts) ],
25
  'scalar --get_set_init' => [ qw(requirement_spec js h_unit_name all_customers all_parts) ],
19 26
);
20 27

  
21 28
__PACKAGE__->run_before('setup');
......
24 31
# actions
25 32
#
26 33

  
27

  
28 34
sub action_list {
29 35
  my ($self) = @_;
30 36

  
......
35 41
  my ($self) = @_;
36 42

  
37 43
  my $html   = $self->render('requirement_spec_order/new', { output => 0 }, make_part_title => sub { $_[0]->partnumber . ' ' . $_[0]->description });
38
  $self->js->html('#ui-tabs-4', $html)
44
  $self->js->html('#' . TAB_ID(), $html)
45
           ->render($self);
46
}
47

  
48
sub action_create {
49
  my ($self)         = @_;
50

  
51
  # 1. Update sections with selected part IDs.
52
  my $section_attrs  = $::form->{sections} || [];
53
  my $sections       = SL::DB::Manager::RequirementSpecItem->get_all(where => [ id => [ map { $_->{id} } @{ $section_attrs } ] ]);
54
  my %sections_by_id = map { ($_->{id} => $_) } @{ $sections };
55

  
56
  $sections_by_id{ $_->{id} }->update_attributes(order_part_id => $_->{order_part_id}) for @{ $section_attrs };
57

  
58
  # 2. Create actual quotation/order.
59
  my $order = $self->create_order(sections => $sections);
60
  $order->save;
61

  
62
  $self->requirement_spec->orders(
63
    @{ $self->requirement_spec->orders },
64
    SL::DB::RequirementSpecOrder->new(order => $order, version => $self->requirement_spec->version)
65
  );
66
  $self->requirement_spec->save;
67
  $self->init_requirement_spec;
68

  
69
  # 3. Notify the user and return to list.
70
  my $html = $self->render('requirement_spec_order/list', { output => 0 });
71
  $self->js->html('#' . TAB_ID(), $html)
72
           ->flash('info', $::form->{quotation} ? t8('Sales quotation #1 has been created.', $order->quonumber) : t8('Sales order #1 has been created.', $order->ordnumber))
39 73
           ->render($self);
40 74
}
41 75

  
......
43 77
  my ($self) = @_;
44 78

  
45 79
  my $html   = $self->render('requirement_spec_order/edit_assignment', { output => 0 }, make_part_title => sub { $_[0]->partnumber . ' ' . $_[0]->description });
46
  $self->js->html('#ui-tabs-4', $html)
80
  $self->js->html('#' . TAB_ID(), $html)
47 81
           ->render($self);
48 82
}
49 83

  
......
53 87
  SL::DB::RequirementSpecItem->new(id => $_->{id})->load->update_attributes(order_part_id => ($_->{order_part_id} || undef)) for @{ $sections };
54 88

  
55 89
  my $html = $self->render('requirement_spec_order/list', { output => 0 });
56
  $self->js->html('#ui-tabs-4', $html)
90
  $self->js->html('#' . TAB_ID(), $html)
57 91
           ->render($self);
58 92
}
59 93

  
......
61 95
  my ($self) = @_;
62 96

  
63 97
  my $html = $self->render('requirement_spec_order/list', { output => 0 });
64
  $self->js->html('#ui-tabs-4', $html)
98
  $self->js->html('#' . TAB_ID(), $html)
65 99
           ->render($self);
66 100
}
67 101

  
......
74 108

  
75 109
  $::auth->assert('sales_quotation_edit');
76 110
  $::request->{layout}->use_stylesheet("${_}.css") for qw(jquery.contextMenu requirement_spec);
77
  $::request->{layout}->use_javascript("${_}.js") for qw(jquery.jstree jquery/jquery.contextMenu client_js requirement_spec);
111
  $::request->{layout}->use_javascript("${_}.js")  for qw(jquery.jstree jquery/jquery.contextMenu client_js requirement_spec);
78 112

  
79 113
  return 1;
80 114
}
......
95 129

  
96 130
sub init_all_customers { SL::DB::Manager::Customer->get_all_sorted }
97 131
sub init_all_parts     { SL::DB::Manager::Part->get_all_sorted     }
132
sub init_h_unit_name   { first { SL::DB::Manager::Unit->find_by(name => $_) } qw(Std h Stunde) };
133

  
134
sub load_parts_for_sections {
135
  my ($self, %params) = @_;
136

  
137
  $self->parts({ map { ($_->{id} => $_) } @{ SL::DB::Manager::Part->get_all(where => [ id => [ uniq map { $_->{order_part_id} } @{ $params{sections} } ] ]) } });
138
}
139

  
140
sub create_order_item {
141
  my ($self, %params) = @_;
142

  
143
  my $section         = $params{section};
144
  my $item            = $params{item} || SL::DB::OrderItem->new;
145
  my $part            = $self->parts->{ $section->order_part_id };
146
  my $description     = $section->{keep_description} ? $item->description : $part->description;
147

  
148
  if (!$section->{keep_description}) {
149
    $description =  '<%fb_number%> <%title%>' unless $description =~ m{<%};
150
    $description =~ s{<% (.+?) %>}{$section->$1}egx;
151
  }
152

  
153
  $item->assign_attributes(
154
    parts_id    => $part->id,
155
    description => $description,
156
    qty         => $section->time_estimation * 1,
157
    unit        => $self->h_unit_name,
158
    sellprice   => $::form->round_amount($self->requirement_spec->hourly_rate, 2),
159
    discount    => 0,
160
    project_id  => $self->requirement_spec->project_id,
161
  );
162

  
163
  return $item;
164
}
165

  
166
sub create_order {
167
  my ($self, %params) = @_;
168

  
169
  $self->load_parts_for_sections(%params);
170

  
171
  my @orderitems = map { $self->create_order_item(section => $_) } @{ $params{sections} };
172
  my $employee   = SL::DB::Manager::Employee->current;
173
  my $customer   = SL::DB::Customer->new(id => $::form->{customer_id})->load;
174
  my $order      = SL::DB::Order->new(
175
    globalproject_id        => $self->requirement_spec->project_id,
176
    transdate               => DateTime->today_local,
177
    reqdate                 => $::form->{quotation} && $customer->payment_id ? $customer->payment->calc_date : undef,
178
    quotation               => !!$::form->{quotation},
179
    orderitems              => \@orderitems,
180
    customer_id             => $customer->id,
181
    taxincluded             => $customer->taxincluded,
182
    intnotes                => $customer->notes,
183
    language_id             => $customer->language_id,
184
    payment_id              => $customer->payment_id,
185
    taxzone_id              => $customer->taxzone_id,
186
    employee_id             => $employee->id,
187
    salesman_id             => $employee->id,
188
    transaction_description => $self->requirement_spec->displayable_name,
189
    currency_id             => $::instance_conf->get_currency_id,
190
  );
191

  
192
  $order->calculate_prices_and_taxes;
193

  
194
  return $order;
195
}
98 196

  
99 197
1;
js/locale/de.js
8 8
"Copy":"Kopieren",
9 9
"Copy requirement spec":"Pflichtenheft kopieren",
10 10
"Copy template":"Vorlage kopieren",
11
"Create":"Anlegen",
11 12
"Create PDF":"PDF erzeugen",
13
"Create new quotation/order":"Neues Angebot/neuen Auftrag anlegen",
12 14
"Create new qutoation/order":"Neues Angebot/neuen Auftrag anlegen",
13 15
"Create new version":"Neue Version anlegen",
14 16
"Database Connection Test":"Test der Datenbankverbindung",
js/requirement_spec.js
332 332
  var data = 'action=RequirementSpecOrder/' + key
333 333
           + '&' + $('#requirement_spec_id').serialize();
334 334

  
335
  if (key == 'save_assignment')
335
  if ((key == 'save_assignment') || (key == 'create'))
336 336
    data += '&' + $('#quotations_and_orders_article_assignment_form').serialize();
337 337
  else
338 338
    data += '&id=' + encodeURIComponent(ns.find_quotation_order_id(opt.$trigger));
......
538 538
    }, general_actions)
539 539
  });
540 540

  
541
  $.contextMenu({
542
    selector: '.quotations-and-orders-new-context-menu',
543
    items:    $.extend({
544
        heading: { name: kivi.t8('Create new quotation/order'), className: 'context-menu-heading'    }
545
      , create:  { name: kivi.t8('Create'), icon: "edit",  callback: ns.standard_quotation_order_ajax_call }
546
      , cancel:  { name: kivi.t8('Cancel'), icon: "close", callback: ns.standard_quotation_order_ajax_call }
547
    }, general_actions)
548
  });
549

  
541 550
  $.contextMenu({
542 551
    selector: '#content',
543 552
    items:    general_actions
locale/de/all
540 540
  'Could not spawn the printer command.' => 'Die Druckanwendung konnte nicht gestartet werden.',
541 541
  'Could not update prices!'    => 'Preise konnten nicht aktualisiert werden!',
542 542
  'Country'                     => 'Land',
543
  'Create'                      => 'Anlegen',
543 544
  'Create Assembly'             => 'Erzeugnis fertigen',
544 545
  'Create Chart of Accounts'    => 'Zu verwendender Kontenplan',
545 546
  'Create Dataset'              => 'Neue Datenbank anlegen',
......
593 594
  'Create new payment term'     => 'Neue Zahlungsbedingung anlegen',
594 595
  'Create new project type'     => 'Neuen Projekttypen anlegen',
595 596
  'Create new quotation or order' => 'Neues Angebot oder neuen Auftrag anlegen',
597
  'Create new quotation/order'  => 'Neues Angebot/neuen Auftrag anlegen',
596 598
  'Create new qutoation/order'  => 'Neues Angebot/neuen Auftrag anlegen',
597 599
  'Create new templates from master templates' => 'Neue Druckvorlagen aus Vorlagensatz erstellen',
598 600
  'Create new version'          => 'Neue Version anlegen',
......
1951 1953
  'Sales margin'                => 'Marge',
1952 1954
  'Sales margin %'              => 'Marge prozentual',
1953 1955
  'Sales net amount'            => 'VK-Betrag',
1956
  'Sales order #1 has been created.' => 'Kundenauftrag #1 wurde angelegt.',
1954 1957
  'Sales price'                 => 'VK-Preis',
1955 1958
  'Sales price total'           => 'VK-Betrag',
1956 1959
  'Sales quotation'             => 'Angebot',
1960
  'Sales quotation #1 has been created.' => 'Angebot #1 wurde angelegt.',
1957 1961
  'Salesman'                    => 'Verkäufer/in',
1958 1962
  'Salesman (database ID)'      => 'Verkäufer (Datenbank-ID)',
1959 1963
  'Salesperson'                 => 'Verkäufer',
templates/webpages/requirement_spec_order/_assignment_form.html
1 1
[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE P -%]
2 2
[% SET style="width: 400px" %]
3 3

  
4
<table>
5
[% IF for_new %]
6
 <tr>
7
  <td>[% LxERP.t8("Record type to create") %]:</td>
8
  <td>[% L.select_tag('quotation', [ [ 1, LxERP.t8('Sales quotation') ], [ 0, LxERP.t8('Sales Order') ] ], style=style, no_id=1) %]</td>
9
 </tr>
4
<form id="quotations_and_orders_article_assignment_form">
5
 <table>
6
  [% IF for_new %]
7
  <tr>
8
   <td>[% LxERP.t8("Record type to create") %]:</td>
9
   <td>[% L.select_tag('quotation', [ [ 1, LxERP.t8('Sales quotation') ], [ 0, LxERP.t8('Sales Order') ] ], style=style, no_id=1) %]</td>
10
  </tr>
10 11

  
11
 <tr>
12
  <td>[% LxERP.t8("Customer") %]:</td>
13
  <td>[% L.select_tag('customer_id', SELF.all_customers, default=SELF.requirement_spec.customer_id, title_key='name', style=style, no_id=1) %]</td>
14
 </tr>
15
[% END %]
12
  <tr>
13
   <td>[% LxERP.t8("Customer") %]:</td>
14
   <td>[% L.select_tag('customer_id', SELF.all_customers, default=SELF.requirement_spec.customer_id, title_key='name', style=style, no_id=1) %]</td>
15
  </tr>
16
  [% END %]
16 17

  
17
 <tr>
18
  <td>[% LxERP.t8("Assign the following article to all sections") %]:</td>
19
  <td>
20
   [% L.select_tag('quotations_and_orders_dummy', SELF.all_parts, default=INSTANCE_CONF.get_requirement_spec_section_order_part_id, title_sub=\make_part_title, id='quoations_and_orders_order_id', style=style) %]
21
   [% L.button_tag('kivi.requirement_spec.assign_order_part_id_to_all()', LxERP.t8('Assign article')) %]
22
  </td>
23
 </tr>
24
</table>
18
  <tr>
19
   <td>[% LxERP.t8("Assign the following article to all sections") %]:</td>
20
   <td>
21
    [% L.select_tag('quotations_and_orders_dummy', SELF.all_parts, default=INSTANCE_CONF.get_requirement_spec_section_order_part_id, title_sub=\make_part_title, id='quoations_and_orders_order_id', style=style) %]
22
    [% L.button_tag('kivi.requirement_spec.assign_order_part_id_to_all()', LxERP.t8('Assign article')) %]
23
   </td>
24
  </tr>
25
 </table>
25 26

  
26
<form id="quotations_and_orders_article_assignment_form">
27 27
 <table style="width: 100%">
28 28
  <thead>
29 29
   <tr class="listheading">
templates/webpages/requirement_spec_order/list.html
68 68
       [% LxERP.t8("working copy") %]
69 69
      [% END %]
70 70
     </td>
71
     <td>[% HTML.escape(rs_order.order.quotation ? rs_order.order.quonumber : rs_order.order.ordnumber) %]</td>
71
     <td>
72
      <a href="oe.pl?action=edit&id=[% HTML.url(rs_order.order_id) %]&type=[% HTML.url(rs_order.order.type) %]">
73
       [% HTML.escape(rs_order.order.quotation ? rs_order.order.quonumber : rs_order.order.ordnumber) %]
74
      </a>
75
     </td>
72 76
     <td>[% HTML.escape(rs_order.order.transaction_description) %]</td>
73 77
     <td>[% rs_order.order.transdate.to_kivitendo(precision='day') %]</td>
74 78
     <td>[% rs_order.itime.to_kivitendo(precision='day') %]</td>
templates/webpages/requirement_spec_order/new.html
1 1
[%- USE LxERP -%][%- USE L -%]
2
<div id="quotations_and_orders_new" class="quotations-and-orders-edit-assignment-context-menu">
2
<div id="quotations_and_orders_new" class="quotations-and-orders-new-context-menu">
3 3
 <h2>[% LxERP.t8("Create new quotation or order") %]</h2>
4 4

  
5 5
 [% INCLUDE 'requirement_spec_order/_assignment_form.html'

Auch abrufbar als: Unified diff