Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 4f43ec85

Von Kivitendo Admin vor fast 9 Jahren hinzugefügt

  • ID 4f43ec85816b8f5c9031ff35adfa9e0d33c4306f
  • Vorgänger 6418adee
  • Nachfolger 3f924c0f

Neue Methoden um Debitorenbuchungen zu erstellen

Vorbereitung für Debitorenbuchungsimport, neue Methoden für SL::DB::Invoice
Objekte:

add_ar_amount_row - Erlösbuchungen hinzufügen, mit Steuerschlüssel
create_ar_row - acc-trans für Forderung hinzufügen
validate_acc_trans - Prüfen ob alle acc_trans-Einträge aufgehen
recalculate_amount - anhand acc_trans-Zeilen amount und netamount berechnen

Unterschiede anzeigen:

SL/DB/Invoice.pm
3 3
use strict;
4 4

  
5 5
use Carp;
6
use List::Util qw(first);
6
use List::Util qw(first sum);
7 7

  
8
use Rose::DB::Object::Helpers ();
8
use Rose::DB::Object::Helpers qw(has_loaded_related);
9 9
use SL::DB::MetaSetup::Invoice;
10 10
use SL::DB::Manager::Invoice;
11 11
use SL::DB::Helper::Payment qw(:ALL);
......
282 282
  }
283 283
}
284 284

  
285
sub add_ar_amount_row {
286
  my ($self, %params ) = @_;
287

  
288
  # only allow this method for ar invoices (Debitorenbuchung)
289
  die "not an ar invoice" if $self->invoice and not $self->customer_id;
290

  
291
  die "add_ar_amount_row needs a chart object as chart param" unless $params{chart} && $params{chart}->isa('SL::DB::Chart');
292
  die unless $params{chart}->link =~ /AR_amount/;
293

  
294
  my $acc_trans = [];
295

  
296
  my $roundplaces = 2;
297
  my ($netamount,$taxamount);
298

  
299
  $netamount = $params{amount} * 1;
300
  my $tax = SL::DB::Manager::Tax->find_by(id => $params{tax_id}) || die "Can't find tax with id " . $params{tax_id};
301

  
302
  if ( $tax and $tax->rate != 0 ) {
303
    ($netamount, $taxamount) = Form->calculate_tax($params{amount}, $tax->rate, $self->taxincluded, $roundplaces);
304
  };
305
  next unless $netamount; # netamount mustn't be zero
306

  
307
  my $sign = $self->customer_id ? 1 : -1;
308
  my $acc = SL::DB::AccTransaction->new(
309
    amount     => $netamount * $sign,
310
    chart_id   => $params{chart}->id,
311
    chart_link => $params{chart}->link,
312
    transdate  => $self->transdate,
313
    taxkey     => $tax->taxkey,
314
    tax_id     => $tax->id,
315
    project_id => $params{project_id},
316
  );
317

  
318
  $self->add_transactions( $acc );
319
  push( @$acc_trans, $acc );
320

  
321
  if ( $taxamount ) {
322
     my $acc = SL::DB::AccTransaction->new(
323
       amount     => $taxamount * $sign,
324
       chart_id   => $tax->chart_id,
325
       chart_link => $tax->chart->link,
326
       transdate  => $self->transdate,
327
       taxkey     => $tax->taxkey,
328
       tax_id     => $tax->id,
329
     );
330
     $self->add_transactions( $acc );
331
     push( @$acc_trans, $acc );
332
  };
333
  return $acc_trans;
334
};
335

  
336
sub create_ar_row {
337
  my ($self, %params) = @_;
338
  # to be called after adding all AR_amount rows, adds an AR row
339

  
340
  # only allow this method for ar invoices (Debitorenbuchung)
341
  die if $self->invoice and not $self->customer_id;
342
  die "create_ar_row needs a chart object as a parameter" unless $params{chart} and ref($params{chart}) eq 'SL::DB::Chart';
343

  
344
  my @transactions = @{$self->transactions};
345
  # die "invoice has no acc_transactions" unless scalar @transactions > 0;
346
  return 0 unless scalar @transactions > 0;
347

  
348
  my $chart = $params{chart} || SL::DB::Manager::Chart->find_by(id => $::instance_conf->get_ar_chart_id);
349
  die "illegal chart in create_ar_row" unless $chart;
350

  
351
  die "receivables chart must have link 'AR'" unless $chart->link eq 'AR';
352

  
353
  my $acc_trans = [];
354

  
355
  # hardcoded entry for no tax: tax_id and taxkey should be 0
356
  my $tax = SL::DB::Manager::Tax->find_by(id => 0, taxkey => 0) || die "Can't find tax with id 0 and taxkey 0";
357

  
358
  my $sign = $self->customer_id ? -1 : 1;
359
  my $acc = SL::DB::AccTransaction->new(
360
    amount     => $self->amount * $sign,
361
    chart_id   => $params{chart}->id,
362
    chart_link => $params{chart}->link,
363
    transdate  => $self->transdate,
364
    taxkey     => $tax->taxkey,
365
    tax_id     => $tax->id,
366
  );
367
  $self->add_transactions( $acc );
368
  push( @$acc_trans, $acc );
369
  return $acc_trans;
370
};
371

  
372
sub validate_acc_trans {
373
  my ($self, %params) = @_;
374
  # should be able to check unsaved invoice objects with several acc_trans lines
375

  
376
  die "validate_acc_trans can't check invoice object with empty transactions" unless $self->transactions;
377

  
378
  my @transactions = @{$self->transactions};
379
  # die "invoice has no acc_transactions" unless scalar @transactions > 0;
380
  return 0 unless scalar @transactions > 0;
381
  return 0 unless $self->has_loaded_related('transactions');
382
  if ( $params{debug} ) {
383
    printf("starting validatation of invoice %s with trans_id %s and taxincluded %s\n", $self->invnumber, $self->id, $self->taxincluded);
384
    foreach my $acc ( @transactions ) {
385
      printf("chart: %s  amount: %s   tax_id: %s  link: %s\n", $acc->chart->accno, $acc->amount, $acc->tax_id, $acc->chart->link);
386
    };
387
  };
388

  
389
  my $acc_trans_sum = sum map { $_->amount } @transactions;
390

  
391
  unless ( $::form->round_amount($acc_trans_sum, 10) == 0 ) {
392
    my $string = "sum of acc_transactions isn't 0: $acc_trans_sum\n";
393

  
394
    if ( $params{debug} ) {
395
      foreach my $trans ( @transactions ) {
396
          $string .= sprintf("  %s %s %s\n", $trans->chart->accno, $trans->taxkey, $trans->amount);
397
      };
398
    };
399
    return 0;
400
  };
401

  
402
  # only use the first AR entry, so it also works for paid invoices
403
  my @ar_transactions = map { $_->amount } grep { $_->chart_link eq 'AR' } @transactions;
404
  my $ar_sum = $ar_transactions[0];
405
  # my $ar_sum = sum map { $_->amount } grep { $_->chart_link eq 'AR' } @transactions;
406

  
407
  unless ( $::form->round_amount($ar_sum * -1,2) == $::form->round_amount($self->amount,2) ) {
408
    if ( $params{debug} ) {
409
      printf("debug: (ar_sum) %s = %s (amount)\n",  $::form->round_amount($ar_sum * -1,2) , $::form->round_amount($self->amount, 2) );
410
      foreach my $trans ( @transactions ) {
411
        printf("  %s %s %s %s\n", $trans->chart->accno, $trans->taxkey, $trans->amount, $trans->chart->link);
412
      };
413
    };
414
    die sprintf("sum of ar (%s) isn't equal to invoice amount (%s)", $::form->round_amount($ar_sum * -1,2), $::form->round_amount($self->amount,2));
415
  };
416

  
417
  return 1;
418
};
419

  
420
sub recalculate_amounts {
421
  my ($self, %params) = @_;
422
  # calculate and set amount and netamount from acc_trans objects
423

  
424
  croak ("Can only recalculate amounts for ar transactions") if $self->invoice;
425

  
426
  return undef unless $self->has_loaded_related('transactions');
427

  
428
  my ($netamount, $taxamount);
429

  
430
  my @transactions = @{$self->transactions};
431

  
432
  foreach my $acc ( @transactions ) {
433
    $netamount += $acc->amount if $acc->chart->link =~ /AR_amount/;
434
    $taxamount += $acc->amount if $acc->chart->link =~ /AR_tax/;
435
  };
436

  
437
  $self->amount($netamount+$taxamount);
438
  $self->netamount($netamount);
439
};
440

  
441

  
285 442
sub _post_create_assemblyitem_entries {
286 443
  my ($self, $assembly_entries) = @_;
287 444

  
......
502 659

  
503 660
See L<SL::DB::Object::basic_info>.
504 661

  
662
=item C<recalculate_amounts %params>
663

  
664
Calculate and set amount and netamount from acc_trans objects by summing up the
665
values of acc_trans objects with AR_amount and AR_tax link charts.
666
amount and netamount are set to the calculated values.
667

  
668
=item C<validate_acc_trans>
669

  
670
Checks if the sum of all associated acc_trans objects is 0 and checks whether
671
the amount of the AR acc_transaction matches the AR amount. Only the first AR
672
line is checked, because the sum of all AR lines is 0 for paid invoices.
673

  
674
Returns 0 or 1.
675

  
676
Can be called with a debug parameter which writes debug info to STDOUT, which is
677
useful in console mode or while writing tests.
678

  
679
 my $ar = SL::DB::Manager::Invoice->get_first();
680
 $ar->validate_acc_trans(debug => 1);
681

  
682
=item C<create_ar_row %params>
683

  
684
Creates a new acc_trans entry for the receivable (AR) entry of an existing AR
685
invoice object, which already has some income and tax acc_trans entries.
686

  
687
The acc_trans entry is also returned inside an array ref.
688

  
689
Mandatory params are
690

  
691
=over 2
692

  
693
=item * chart as an RDBO object, e.g. for bank. Must be a 'paid' chart.
694

  
695
=back
696

  
697
Currently the amount of the invoice object is used for the acc_trans amount.
698
Use C<recalculate_amounts> before calling this mehtod if amount it isn't known
699
yet or you didn't set it manually.
700

  
701
=item C<add_ar_amount_row %params>
702

  
703
Add a new entry for an existing AR invoice object. Creates an acc_trans entry,
704
and also adds an acc_trans tax entry, if the tax has an associated tax chart.
705
Also all acc_trans entries that were created are returned inside an array ref.
706

  
707
Mandatory params are
708

  
709
=over 2
710

  
711
=item * chart as an RDBO object, should be an income chart (link = AR_amount)
712

  
713
=item * tax_id
714

  
715
=item * amount
716

  
717
=back
718

  
505 719
=back
506 720

  
507 721
=head1 TODO

Auch abrufbar als: Unified diff