Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 2632ced6

Von Bernd Bleßmann vor mehr als 3 Jahren hinzugefügt

  • ID 2632ced6322ae7837105306b55d82448b750fe9d
  • Vorgänger 2e6998c4
  • Nachfolger 64fab360

Zeiterfassung: Lieferschein new_from_time_recording

Unterschiede anzeigen:

SL/DB/DeliveryOrder.pm
14 14
use SL::DB::Helper::LinkedRecords;
15 15
use SL::DB::Helper::TransNumberGenerator;
16 16

  
17
use List::Util qw(first);
17
use SL::DB::Part;
18
use SL::DB::Unit;
19

  
20
use SL::Helper::Number qw(_format_total _round_total);
21

  
22
use List::Util qw(first notall);
23
use List::MoreUtils qw(any);
18 24

  
19 25
__PACKAGE__->meta->add_relationship(orderitems => { type         => 'one to many',
20 26
                                                    class        => 'SL::DB::DeliveryOrderItem',
......
172 178
  return $delivery_order;
173 179
}
174 180

  
181
sub new_from_time_recordings {
182
  my ($class, $sources, %params) = @_;
183

  
184
  croak("Unsupported object type in sources")                                      if any { ref($_) ne 'SL::DB::TimeRecording' }            @$sources;
185
  croak("Cannot create delivery order from source records of different customers") if any { $_->customer_id != $sources->[0]->customer_id } @$sources;
186

  
187
  my %args = (
188
    is_sales    => 1,
189
    delivered   => 1,
190
    customer_id => $sources->[0]->customer_id,
191
    taxzone_id  => $sources->[0]->customer->taxzone_id,
192
    currency_id => $sources->[0]->customer->currency_id,
193
    employee_id => SL::DB::Manager::Employee->current->id,
194
    salesman_id => SL::DB::Manager::Employee->current->id,
195
    items       => [],
196
  );
197
  my $delivery_order = $class->new(%args);
198
  $delivery_order->assign_attributes(%{ $params{attributes} }) if $params{attributes};
199

  
200
  # - one item per part (article)
201
  # - qty is sum of duration
202
  # - description goes to item longdescription
203
  #  - ordered and summed by date
204
  #  - each description goes to an ordered list
205
  #  - (as time recording descriptions are formatted text by now, use stripped text)
206
  #  - merge same descriptions (todo)
207
  #
208

  
209
  ### config
210
  my $default_partnummer = 6;
211
  my $default_part_id    = SL::DB::Manager::Part->find_by(partnumber => $default_partnummer)->id;
212

  
213
  # check parts and collect entries
214
  my %part_by_part_id;
215
  my $entries;
216
  foreach my $source (@$sources) {
217
    my $part_id  = $source->part_id ? $source->part_id
218
                 : $default_part_id ? $default_part_id
219
                 : undef;
220

  
221
    die 'article not found for entry "' . $source->displayable_times . '"' if !$part_id;
222

  
223
    if (!$part_by_part_id{$part_id}) {
224
      $part_by_part_id{$part_id} = SL::DB::Part->new(id => $part_id)->load;
225
      die 'article unit must be time based for entry "' . $source->displayable_times . '"' if !$part_by_part_id{$part_id}->unit_obj->is_time_based;
226
    }
227

  
228
    my $date = $source->start_time->to_kivitendo;
229
    $entries->{$part_id}->{$date}->{duration} += _round_total($source->duration_in_hours);
230
    $entries->{$part_id}->{$date}->{content}  .= '<li>' . $source->description_as_stripped_html . '</li>';
231
    $entries->{$part_id}->{$date}->{date_obj}  = $source->start_time; # for sorting
232
  }
233

  
234
  my $h_unit = SL::DB::Manager::Unit->find_h_unit;
235

  
236
  my @keys = sort { $part_by_part_id{$a}->partnumber cmp $part_by_part_id{$b}->partnumber } keys %$entries;
237
  foreach my $key (@keys) {
238
    my $qty = 0;
239
    my $longdescription = '';
240

  
241
    my @dates = sort { $entries->{$key}->{$a}->{date_obj} <=> $entries->{$key}->{$b}->{date_obj} } keys %{$entries->{$key}};
242
    foreach my $date (@dates) {
243
      my $entry = $entries->{$key}->{$date};
244

  
245
      $qty             += $entry->{duration};
246
      $longdescription .= $date . ' <strong>' . _format_total($entry->{duration}) . ' h</strong>';
247
      $longdescription .= '<ul>';
248
      $longdescription .= $entry->{content};
249
      $longdescription .= '</ul>';
250
    }
251

  
252
    my $item = SL::DB::DeliveryOrderItem->new(
253
      parts_id        => $part_by_part_id{$key}->id,
254
      description     => $part_by_part_id{$key}->description,
255
      qty             => $qty,
256
      unit_obj        => $h_unit,
257
      sellprice       => $part_by_part_id{$key}->sellprice,
258
      longdescription => $longdescription,
259
    );
260

  
261
    $delivery_order->add_items($item);
262
  }
263

  
264
  return $delivery_order;
265
}
266

  
175 267
sub customervendor {
176 268
  $_[0]->is_sales ? $_[0]->customer : $_[0]->vendor;
177 269
}
......
301 393

  
302 394
=back
303 395

  
396
=item C<new_from_time_recordings $sources, %params>
397

  
398
Creates a new C<SL::DB::DeliveryOrder> instace from the time recordings
399
given as C<$sources>. All time recording entries must belong to the same
400
customer. Time recordings are sorted by article and date. For each article
401
a new delivery order item is created. If no article is associated with an
402
entry, a default article will be used (hard coded).
403
Entries of the same date (for each article) are summed together and form a
404
list entry in the long description of the item.
405

  
406
The created delivery order object will be returnd but not saved.
407

  
408
C<$sources> must be an array reference of C<SL::DB::TimeRecording> instances.
409

  
410
C<%params> can include the following options:
411

  
412
=over 2
413

  
414
=item C<attributes>
415

  
416
An optional hash reference. If it exists then it is used to set
417
attributes of the newly created delivery order object.
418

  
419
=back
420

  
304 421
=item C<sales_order>
305 422

  
306 423
TODO: Describe sales_order

Auch abrufbar als: Unified diff