Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 76779674

Von Tamino Steinert vor 5 Monaten hinzugefügt

  • ID 76779674ead38193793027fa54902f7d86bb1336
  • Vorgänger bd1f6060
  • Nachfolger c123e944

S:LiquidityProjection: Nutze Helferfunktion zum Berechnen von Wied. Rech.

Unterschiede anzeigen:

SL/LiquidityProjection.pm
5 5
use List::MoreUtils qw(uniq);
6 6

  
7 7
use SL::DBUtils;
8
use SL::Helper::DateTime;
8 9
use SL::DB::PeriodicInvoicesConfig;
9 10

  
10 11
sub new {
......
109 110

  
110 111
  $params{months} ||= 6;
111 112

  
112
  # 1. Auslesen aller erzeugten periodischen Rechnungen im
113
  # Betrachtungszeitraum
114
  my $q_min_date = $dbh->quote($self->{min_date} . '-01');
115
  $query         = <<SQL;
116
    SELECT pi.config_id, to_char(pi.period_start_date, 'YYYY-MM') AS period_start_date
117
    FROM periodic_invoices pi
118
    LEFT JOIN periodic_invoices_configs pcfg ON (pi.config_id = pcfg.id)
119
    WHERE pcfg.active
120
      AND NOT pcfg.periodicity = 'o'
121
      AND (pi.period_start_date >= to_date($q_min_date, 'YYYY-MM-DD'))
122
SQL
123

  
124
  my %periodic_invoices;
125
  $sth = prepare_execute_query($::form, $dbh, $query);
126
  while ($ref = $sth->fetchrow_hashref) {
127
    $periodic_invoices{ $ref->{config_id} }                                ||= { };
128
    $periodic_invoices{ $ref->{config_id} }->{ $ref->{period_start_date} }   = 1;
129
  }
130
  $sth->finish;
131

  
132
  # 2. Auslesen aktiver Wartungsvertragskonfigurationen
133
  $query = <<SQL;
134
    SELECT (oi.qty * (1 - oi.discount) * oi.sellprice) AS linetotal, oi.recurring_billing_mode,
135
      bg.description AS buchungsgruppe,
136
      pg.partsgroup AS parts_group,
137
      CASE WHEN COALESCE(e.name, '') = '' THEN e.login ELSE e.name END AS salesman,
138
      pcfg.periodicity, pcfg.order_value_periodicity, pcfg.id AS config_id,
139
      EXTRACT(year FROM pcfg.start_date) AS start_year, EXTRACT(month FROM pcfg.start_date) AS start_month
140
    FROM orderitems oi
141
    LEFT JOIN oe                             ON (oi.trans_id                              = oe.id)
142
    LEFT JOIN periodic_invoices_configs pcfg ON (oi.trans_id                              = pcfg.oe_id)
143
    LEFT JOIN parts p                        ON (oi.parts_id                              = p.id)
144
    LEFT JOIN buchungsgruppen bg             ON (p.buchungsgruppen_id                     = bg.id)
145
    LEFT JOIN partsgroup pg                  ON (p.partsgroup_id                          = pg.id)
146
    LEFT JOIN employee e                     ON (COALESCE(oe.salesman_id, oe.employee_id) = e.id)
147
    WHERE pcfg.active
148
      AND (pcfg.periodicity <> 'o')
149
      AND (   (oi.recurring_billing_mode = 'always')
150
           OR (    (oi.recurring_billing_mode = 'once')
151
               AND (oi.recurring_billing_invoice_id IS NULL)))
152
SQL
153

  
154
  # 3. Iterieren über Saldierungsintervalle, vormerken
155 113
  my @scentries;
156
  $sth = prepare_execute_query($::form, $dbh, $query);
157
  while ($ref = $sth->fetchrow_hashref) {
158
    my ($year, $month) = ($ref->{start_year}, $ref->{start_month});
159
    my $date;
160

  
161
    while (($date = _the_date($year, $month)) le $self->{max_date}) {
162
      my $billing_len = $SL::DB::PeriodicInvoicesConfig::PERIOD_LENGTHS{ $ref->{periodicity} } || 1;
163

  
164
      if (($date ge $self->{min_date}) && (!$periodic_invoices{ $ref->{config_id} } || !$periodic_invoices{ $ref->{config_id} }->{$date})) {
165
        if ($ref->{recurring_billing_mode} eq 'once') {
166
          push @scentries, { buchungsgruppe => $ref->{buchungsgruppe},
167
                             salesman       => $ref->{salesman},
168
                             linetotal      => $ref->{linetotal},
169
                             date           => $date,
170
                           };
171
          last;
172
        }
173

  
174
        my $order_value_periodicity = $ref->{order_value_periodicity} eq 'p' ? $ref->{periodicity} : $ref->{order_value_periodicity};
175
        my $order_value_len         = $SL::DB::PeriodicInvoicesConfig::ORDER_VALUE_PERIOD_LENGTHS{$order_value_periodicity} || 1;
176

  
177
        push @scentries, { buchungsgruppe => $ref->{buchungsgruppe},
178
                           salesman       => $ref->{salesman},
179
                           linetotal      => $ref->{linetotal} * $billing_len / $order_value_len,
180
                           date           => $date,
181
                           parts_group    => $ref->{parts_group},
182
                         };
183
      }
184 114

  
185
      ($year, $month) = _fix_date($year, $month + $billing_len);
115
  # 1. Auslesen aller erzeugten periodischen Rechnungen im Betrachtungszeitraum
116
  my $configs = SL::DB::Manager::PeriodicInvoicesConfig->get_all(query => [ active => 1 ]);
117
  foreach my $config (@{ $configs }) {
118
    my $open_orders = $config->get_open_orders_for_period(
119
      end_date => DateTime->from_ymd(
120
        $self->{max_date} . '-01'
121
      )->add(months => 1, days => -1)
122
    );
123
    foreach my $order (@$open_orders) {
124
      my $month_date = _the_date($order->reqdate->year, $order->reqdate->month);
125
      foreach my $order_item ($order->items()) {
126
        push @scentries, {
127
          buchungsgruppe => $order_item->part->buchungsgruppe->description,
128
          salesman       => $order->salesman ? $order->salesman->name : $order->employee->name,
129
          linetotal      => $order_item->qty * (1 - $order_item->discount) * $order_item->sellprice,
130
          date           => $month_date,
131
          parts_group    => $order_item->part->partsgroup,
132
        };
133
      }
186 134
    }
187 135
  }
188
  $sth->finish;
189 136

  
190
  # 4. Auslesen offener Aufträge
137
  # 2. Auslesen offener Aufträge
191 138
  $query = <<SQL;
192 139
    SELECT (oi.qty * (1 - oi.discount) * oi.sellprice) AS linetotal,
193 140
      bg.description AS buchungsgruppe,
......
202 149
    LEFT JOIN employee e         ON (COALESCE(oe.salesman_id, oe.employee_id) = e.id)
203 150
    WHERE oe.record_type = 'sales_order'
204 151
      AND NOT COALESCE(oe.closed,    FALSE)
205
      AND (oe.id NOT IN (SELECT oe_id FROM periodic_invoices_configs WHERE periodicity <> 'o'))
152
      AND (oe.id NOT IN (SELECT oe_id FROM periodic_invoices_configs))
206 153
SQL
207 154

  
208
  # 5. Initialisierung der Datenstrukturen zum Speichern der
155
  # 3. Initialisierung der Datenstrukturen zum Speichern der
209 156
  # Ergebnisse
210 157
  my @entries               = selectall_hashref_query($::form, $dbh, $query);
211 158
  my @salesmen              = uniq map { $_->{salesman}       } (@entries, @scentries);
......
232 179
                                          },
233 180
                      };
234 181

  
235
  # 6. Aufsummieren der Auftragspositionen
182
  # 4. Aufsummieren der Auftragspositionen
236 183
  foreach $ref (@entries) {
237 184
    my $date = $self->_date_for($ref);
238 185

  
......
243 190
    $projection->{parts_group}->{ $ref->{parts_group} }->{$date}       += $ref->{linetotal};
244 191
  }
245 192

  
246
  # 7. Aufsummieren der Wartungsvertragspositionen
193
  # 5. Aufsummieren der Wartungsvertragspositionen
247 194
  foreach $ref (@scentries) {
248 195
    my $date = $ref->{date};
249 196

  
......
346 293
  $calc_params{end_date} //= $calc_params{start_date}->clone->add(years => 1);
347 294

  
348 295
  foreach my $config (@{ $configs }) {
349
    my @dates = $config->calculate_invoice_dates(%calc_params);
350
    next unless @dates;
351 296

  
352
    my $order = SL::DB::Order->new(id => $config->oe_id)->load(with_objects => [ qw(customer employee) ]);
353
    $order->{is_recurring} = 1;
297
    my $rec_orders = $config->get_open_orders_for_period(%calc_params);
298
    next unless scalar $rec_orders;
299

  
300
    $_->{is_recurring} = 1 for @$rec_orders;
354 301

  
355
    push @recurring_orders, $order;
302
    push @recurring_orders, @$rec_orders;
356 303
  }
357 304

  
358 305
  my @where = (

Auch abrufbar als: Unified diff