Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision ae32e420

Von Jan Büren vor mehr als 3 Jahren hinzugefügt

  • ID ae32e420b4016d27bd80f866a28bfdbcf20ebe2f
  • Vorgänger 693c0013
  • Nachfolger 19cc452b

DeliveryPlan: Berechnung nur noch über verlinkte Positionen

Unterschiede anzeigen:

SL/Controller/DeliveryPlan.pm
15 15
use Carp;
16 16

  
17 17
use Rose::Object::MakeMethods::Generic (
18
  'scalar --get_set_init' => [ qw(models all_edit_right vc use_linked_items all_employees all_businesses all_departments) ],
18
  'scalar --get_set_init' => [ qw(models all_edit_right vc all_employees all_businesses all_departments) ],
19 19
);
20 20

  
21 21
__PACKAGE__->run_before(sub { $::auth->assert('delivery_plan'); });
......
90 90
  );
91 91
  $report->set_columns(%column_defs);
92 92
  $report->set_column_order(@columns);
93
  $report->set_export_options(qw(list filter vc use_linked_items));
93
  $report->set_export_options(qw(list filter vc));
94 94
  $report->set_options_from_form;
95 95
  $self->models->disable_plugin('paginated') if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
96 96
  $self->models->finalize; # for filter laundering
......
107 107
  return unless scalar @$orderitems;
108 108

  
109 109
  SL::Helper::ShippedQty
110
    ->new(fill_up => !$self->use_linked_items)
110
    ->new()
111 111
    ->calculate($orderitems)
112 112
    ->write_to_objects;
113 113
}
......
158 158
  $self->{filter_summary} = join ', ', @filter_strings;
159 159
}
160 160

  
161
sub delivery_plan_query {
162
  my ($self) = @_;
163
  my $vc     = $self->vc;
164
  my $employee_id = SL::DB::Manager::Employee->current->id;
165
  my $oe_owner = $_[0]->all_edit_right ? '' : " oe.employee_id = $employee_id AND";
166

  
167
  [
168
  "order.${vc}_id" => { gt => 0 },
169
  'order.closed' => 0,
170
  or => [ 'order.quotation' => 0, 'order.quotation' => undef ],
171

  
172
  # filter by shipped_qty < qty, read from innermost to outermost
173
  'id' => [ \"
174
    -- 3. resolve the desired information about those
175
    SELECT oi.id FROM (
176
      -- 2. slice only part, orderitem and both quantities from it
177
      SELECT parts_id, trans_id, qty, SUM(doi_qty) AS doi_qty FROM (
178
        -- 1. join orderitems and deliverorder items via record_links.
179
        --    also add customer data to filter for sales_orders
180
        SELECT oi.parts_id, oi.trans_id, oi.id, oi.qty, doi.qty AS doi_qty
181
        FROM orderitems oi, oe, record_links rl, delivery_order_items doi
182
        WHERE
183
          oe.id = oi.trans_id AND
184
          oe.${vc}_id IS NOT NULL AND
185
          (oe.quotation = 'f' OR oe.quotation IS NULL) AND
186
          NOT oe.closed AND
187
          $oe_owner
188
          rl.from_id = oe.id AND
189
          rl.from_id = oi.trans_id AND
190
          oe.id = oi.trans_id AND
191
          rl.from_table = 'oe' AND
192
          rl.to_table = 'delivery_orders' AND
193
          rl.to_id = doi.delivery_order_id AND
194
          oi.parts_id = doi.parts_id
195
      ) tuples GROUP BY parts_id, trans_id, qty
196
    ) partials
197
    LEFT JOIN orderitems oi ON partials.parts_id = oi.parts_id AND partials.trans_id = oi.trans_id
198
    WHERE oi.qty > doi_qty
199

  
200
    UNION ALL
201

  
202
    -- 4. since the join over record_links fails for sales_orders without any delivery order
203
    --    retrieve those without record_links at all
204
    SELECT oi.id FROM orderitems oi, oe
205
    WHERE
206
      oe.id = oi.trans_id AND
207
      oe.${vc}_id IS NOT NULL AND
208
      (oe.quotation = 'f' OR oe.quotation IS NULL) AND
209
      NOT oe.closed AND
210
      $oe_owner
211
      oi.trans_id NOT IN (
212
        SELECT from_id
213
        FROM record_links rl
214
        WHERE
215
          rl.from_table ='oe' AND
216
          rl.to_table = 'delivery_orders'
217
      )
218

  
219
    UNION ALL
220

  
221
    -- 5. now for the really nasty cases.
222
    --    If someone partially delivered an order in several delivery orders,
223
    --    there will be lots of record_links (4 doesn't catch those) but those
224
    --    won't have matching part_ids in delivery_order_items, so 1-3 can't
225
    --    find anything
226
    --    In this case aggreg record_links - delivery_order - delivery_order_items
227
    --    slice only oe.id, parts_id and sum of of qty
228
    --    left join that onto orderitems to get matching qtys in doi while retaining
229
    --    entrys without matches and then throw out those without record_links
230
    --    TODO: join this and 1-3 into a general case
231
                  -- need debug info? uncomment these:
232
    SELECT oi.id  -- ,oi.trans_id, oi.parts_id, coalesce(sum, 0), agg.parts_id
233
    FROM orderitems oi LEFT JOIN (
234
      SELECT rl.from_id as oid, doi.parts_id, sum(doi.qty) FROM (
235
        SELECT from_id, to_id
236
        FROM record_links rl
237
        LEFT JOIN oe ON oe.id = from_id
238
        WHERE
239
          rl.from_table = 'oe' AND
240
          rl.to_table = 'delivery_orders' AND
241

  
242
          oe.${vc}_id IS NOT NULL AND
243
          $oe_owner
244
          (oe.quotation = 'f' OR oe.quotation IS NULL) AND NOT oe.closed
245
      ) rl
246
      LEFT JOIN delivery_order_items doi ON (rl.to_id = doi.delivery_order_id)
247
      GROUP BY rl.from_id, doi.parts_id
248
    ) agg ON (agg.oid = oi.trans_id AND agg.parts_id = oi.parts_id)
249
    LEFT JOIN oe ON oe.id = oi.trans_id
250
    WHERE
251
      EXISTS (
252
        SELECT to_id
253
        FROM record_links rl
254
        WHERE oi.trans_id = rl.from_id AND rl.from_table = 'oe' AND rl.to_table = 'delivery_orders'
255
      ) AND
256
      coalesce(sum, 0) < oi.qty AND
257
      oe.${vc}_id IS NOT NULL AND
258
      $oe_owner
259
      (oe.quotation = 'f' OR oe.quotation IS NULL) AND NOT oe.closed
260
  " ], # make emacs happy again: '
261
  ]
262
}
263

  
264 161
sub delivery_plan_query_linked_items {
265 162
  my ($self) = @_;
266 163
  my $vc     = $self->vc;
......
318 215
  my ($self) = @_;
319 216
  my $vc     = $self->vc;
320 217

  
321
  my $query = $self->use_linked_items ? $self->delivery_plan_query_linked_items
322
            :                           $self->delivery_plan_query;
218
  my $query = $self->delivery_plan_query_linked_items;
323 219

  
324 220
  SL::Controller::Helper::GetModels->new(
325 221
    controller   => $self,
......
333 229
    },
334 230
    query        => $query,
335 231
    with_objects => [ 'order', "order.$vc", 'part' ],
336
    additional_url_params => { vc => $vc, use_linked_items => $self->use_linked_items },
232
    additional_url_params => { vc => $vc },
337 233
  );
338 234
}
339 235

  
......
344 240
  return $::form->{vc} if ($::form->{vc} eq 'customer' || $::form->{vc} eq 'vendor') || croak "self (DeliveryPlan) has no vc defined";
345 241
}
346 242

  
347
sub init_use_linked_items {
348
  !!$::form->{use_linked_items};
349
}
350

  
351 243
sub init_all_employees {
352 244
  return SL::DB::Manager::Employee->get_all_sorted;
353 245
}
templates/webpages/delivery_plan/_filter.html
97 97
     [% END %]
98 98
   </td>
99 99
  </tr>
100
  <tr>
101
   <th align="right">[% 'Query Type' | $T8 %]</th>
102
   <td>
103
     [% L.checkbox_tag('use_linked_items', checked=use_linked_items, value='1', label=LxERP.t8('Use linked items')) %]
104
   </td>
105
  </tr>
106 100
 </table>
107 101

  
108 102
[% L.hidden_tag('sort_by', FORM.sort_by) %]

Auch abrufbar als: Unified diff