Revision 3d945302
Von Tamino Steinert vor mehr als 1 Jahr hinzugefügt
| SL/Controller/Part.pm | ||
|---|---|---|
| use SL::DB::PriceRuleItem;
 | ||
| use SL::DB::Shop;
 | ||
| use SL::Helper::Flash;
 | ||
| use SL::Helper::PrintOptions;
 | ||
| use SL::JSON;
 | ||
| use SL::Locale::String qw(t8);
 | ||
| use SL::MoreCommon qw(save_form);
 | ||
| ... | ... | |
|   }
 | ||
| }
 | ||
|  | ||
| sub action_showdetails {
 | ||
|   my ($self, %params) = @_;
 | ||
|  | ||
|   eval {
 | ||
|       my @bindata;
 | ||
|       my $bins = SL::DB::Manager::Bin->get_all(with_objects => ['warehouse' ]);
 | ||
|       my %bins_by_id = map { $_->id => $_ } @$bins;
 | ||
|       my $inventories = SL::DB::Manager::Inventory->get_all(where => [ parts_id => $self->part->id],
 | ||
|                              with_objects => ['parts', 'trans_type' ], sort_by => 'bin_id ASC');
 | ||
|       foreach my $bin (@{ $bins }) {
 | ||
|           $bin->{qty} = 0;
 | ||
|       }
 | ||
|  | ||
|       foreach my $inv (@{ $inventories }) {
 | ||
|           my $bin = $bins_by_id{ $inv->bin_id };
 | ||
|           $bin->{qty}      += $inv->qty;
 | ||
|           $bin->{unit}     =  $inv->parts->unit;
 | ||
|           $bin->{reserved} =  defined $inv->reserve_for_id ? 1 : 0;
 | ||
|       }
 | ||
|       my $sum = 0;
 | ||
|       my $reserve_sum = 0;
 | ||
|       for my $bin (@{ $bins }) {
 | ||
|         push @bindata , {
 | ||
|           'warehouse'    => $bin->warehouse->forreserve ? $bin->warehouse->description.' (R)' : $bin->warehouse->description,
 | ||
|           'description'  => $bin->description,
 | ||
|           'qty'          => $bin->{qty},
 | ||
|           'unit'         => $bin->{unit},
 | ||
|         } if $bin->{qty} != 0;
 | ||
|  | ||
|         $sum += $bin->{qty};
 | ||
|         if($bin->warehouse->forreserve || defined $bin->warehouse->{reserve_for_id}){
 | ||
|           $reserve_sum += $bin->{qty};
 | ||
|         }
 | ||
|       }
 | ||
|       # Einfacher ? $sum = $self->part->onhand
 | ||
|       my $todate   = DateTime->now_local;
 | ||
|       my $fromdate = DateTime->now_local->add_duration(DateTime::Duration->new(years => -1));
 | ||
|       my $average  = 0;
 | ||
|       foreach my $inv (@{ $inventories }) {
 | ||
|         $average += abs($inv->qty) if $inv->shippingdate && $inv->trans_type->direction eq 'out' &&
 | ||
|           DateTime->compare($inv->shippingdate,$fromdate) != -1 &&
 | ||
|           DateTime->compare($inv->shippingdate,$todate)   == -1;
 | ||
|       }
 | ||
|       my $openitems = SL::DB::Manager::OrderItem->get_all(where => [ parts_id => $self->part->id, 'order.closed' => 0 ],
 | ||
|                                                            with_objects => ['order'],);
 | ||
|       my ($not_delivered, $ordered) = 0;
 | ||
|       for my $openitem (@{ $openitems }) {
 | ||
|         if($openitem -> order -> type eq 'sales_order') {
 | ||
|           $not_delivered += $openitem->qty - $openitem->shipped_qty;
 | ||
|         } elsif ( $openitem->order->type eq 'purchase_order' ) {
 | ||
|           $ordered += $openitem->qty - $openitem->delivered_qty;
 | ||
|         }
 | ||
|       }
 | ||
|       my $print_form = Form->new('');
 | ||
|       my $part = $self->part;
 | ||
|  | ||
|       my $stock_amounts = $self->part->get_simple_stock_sql;
 | ||
|       $print_form->{type}      = 'part';
 | ||
|       $print_form->{printers}  = SL::DB::Manager::Printer->get_all_sorted;
 | ||
|       my $output = SL::Presenter->get->render('part/showdetails',
 | ||
|           part          => $self->part,
 | ||
|           BINS          => \@bindata,
 | ||
|           stock_amounts => $stock_amounts,
 | ||
|           average       => $average/12,
 | ||
|           fromdate      => $fromdate,
 | ||
|           todate        => $todate,
 | ||
|           sum           => $sum,
 | ||
|           reserve_sum   => $reserve_sum,
 | ||
|           not_delivered => $not_delivered,
 | ||
|           ordered       => $ordered,
 | ||
|           type_beleg    => $::form->{type},
 | ||
|           type_id       => $::form->{type_id},
 | ||
|           maker_id      => $::form->{maker_id},
 | ||
|           drawing       => $::form->{drawing},
 | ||
|     print_options   => SL::Helper::PrintOptions->get_print_options(
 | ||
|       form => $print_form,
 | ||
|       options => {dialog_name_prefix => 'print_options.',
 | ||
|                   show_headers       => 1,
 | ||
|                   no_queue           => 1,
 | ||
|                   no_postscript      => 1,
 | ||
|                   no_opendocument    => 1,
 | ||
|                   hide_language_id_print => 1,
 | ||
|                   no_html            => 1},
 | ||
|     ),
 | ||
|       );
 | ||
|       $self->render(\$output, { layout => 0, process => 0 });
 | ||
|     1;
 | ||
|   } or do {
 | ||
|   };
 | ||
| }
 | ||
|  | ||
| sub action_print_label {
 | ||
|   my ($self) = @_;
 | ||
|   # TODO: implement
 | ||
|   return $self->render('generic/error', { layout => 1 }, label_error => t8('Not implemented yet!'));
 | ||
| }
 | ||
|  | ||
| sub action_export_assembly_assortment_components {
 | ||
|   my ($self) = @_;
 | ||
|  | ||
| js/kivi.Part.js | ||
|---|---|---|
|     $('#ic').submit();
 | ||
|   };
 | ||
|  | ||
|   ns.print_from_showdetail = function(part_id) {
 | ||
|     var data = $('#print_options_form').serializeArray();
 | ||
|     data.push({ name: 'action', value: 'Part/print_label' });
 | ||
|     data.push({ name: 'part.id', value: part_id });
 | ||
|   $.download("controller.pl", data);
 | ||
|   };
 | ||
|  | ||
|   ns.delete = function() {
 | ||
|     var data = $('#ic').serializeArray();
 | ||
|     data.push({ name: 'action', value: 'Part/delete' });
 | ||
| templates/webpages/part/showdetails.html | ||
|---|---|---|
| [%- USE LxERP -%][% USE L %][% USE HTML %][%- USE JavaScript -%][% USE T8 %][%- USE Dumper %]
 | ||
|  | ||
| <div style="padding-bottom: 15px">
 | ||
|   <table style="width: 100%" border="0px" ><tbody>
 | ||
|       <tr>
 | ||
|         <td><b>[%  LxERP.t8('Description') %]</b></td><td colspan="3">[% part.description %]</td>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td style="background:wheat;"><b>[%  LxERP.t8('Internal Notes') %]</b></td><td colspan="3" style="background:wheat;">[% part.intnotes %]</td>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td><b>[%  LxERP.t8('Default Warehouse') %]</b></td><td>[% part.warehouse.description %]</td>
 | ||
|         <td><b>[%  LxERP.t8('Default Bin') %]</b></td><td>[% part.bin.description %]</td>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td><b>[%  LxERP.t8('ROP') %]</b></td><td>[% part.rop_as_number %]</td>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         [%- IF stock_amounts.size %]
 | ||
|         <td colspan="4"><table style="width: 100%">
 | ||
|           <tr class='listheading'>
 | ||
|            <th class="listheading">[% 'Warehouse'   | $T8 %]</th>
 | ||
|            <th class="listheading">[% 'Bin'         | $T8 %]</th>
 | ||
|            <th class="listheading">[% 'Chargenumber'         | $T8 %]</th>
 | ||
|            <th class="listheading">[% 'Qty'         | $T8 %]</th>
 | ||
|            <th class="listheading">[% 'Unit'        | $T8 %]</th>
 | ||
|          </tr>
 | ||
|          [% FOREACH stock = stock_amounts %]
 | ||
|           <tr class='listrow'>
 | ||
|            <td                >[% HTML.escape(stock.warehouse_description)  %]</td>
 | ||
|            <td                >[% IF stock.order_link %]<a target="_blank" href="[% stock.order_link %]">[% END %]
 | ||
|                                [% HTML.escape(stock.bin_description)        %]
 | ||
|                                [% IF stock.order_link %]</a>[% END %]
 | ||
|            </td>
 | ||
|            <td                >[% HTML.escape(stock.chargenumber)                   %]</td>
 | ||
|            <td class='numeric'>[% LxERP.format_amount(stock.qty, dec)       %]</td>
 | ||
|            <td                >[% HTML.escape(stock.unit)                   %]</td>
 | ||
|           </tr>
 | ||
|           [% IF stock.wh_lead != stock.warehouse_description %]
 | ||
|           <tr class='listheading'>
 | ||
|            <th class="listheading"                >[% HTML.escape(stock.warehouse_description)           %]</th>
 | ||
|            <td></td>
 | ||
|            <td></td>
 | ||
|            <td class='numeric bold'>[% LxERP.format_amount(stock.wh_run_qty, dec)         %]</td>
 | ||
|            <td></td>
 | ||
|           </tr>
 | ||
|           [% END %]
 | ||
|           [% IF loop.last %]
 | ||
|           <tr class='listheading'>
 | ||
|            <th class="listheading">[% 'Total' | $T8 %]</th>
 | ||
|            <td></td>
 | ||
|            <td></td>
 | ||
|            <td class='numeric bold'>[% LxERP.format_amount(stock.run_qty, dec)         %]</td>
 | ||
|            <td></td>
 | ||
|           </tr>
 | ||
|           [% END %]
 | ||
|          [% END %]
 | ||
|         [% ELSE %]
 | ||
|         <td>
 | ||
|           <p>[% 'No transactions yet.' | $T8 %]</p>
 | ||
|         [% END %]
 | ||
|         </td>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td><b>[%  LxERP.t8('Sum Amount') %]</b></td><td>[% LxERP.format_amount(sum, 2) %] [% part.unit %]</td>
 | ||
|         <td rowspan="5">
 | ||
|           [% file = part.default_partimage %]
 | ||
|           [%- IF file && INSTANCE_CONF.get_parts_show_image %]
 | ||
|           <img src="controller.pl?action=File/download&id=[% file.id %][%- IF file.version %]&version=[%- file.version %][%- END %]" alt="[% file.title %]" style="[% INSTANCE_CONF.get_parts_image_css %]">
 | ||
|           [% END %]
 | ||
|         </td>
 | ||
|         <td rowspan="5">
 | ||
|   [%- FOREACH file = part.get_files %]
 | ||
|       <a href="controller.pl?action=File/download&id=[% file.id %][%- IF file.version %]&version=[%- file.version %][%- END %]">
 | ||
|         <span id="[% "filename_" _ file.id %][%- IF file.version %]_[% file.version %][%- END %]">[% file.file_name %]</span></a><br><br>
 | ||
|   [%- END %]
 | ||
|         </td>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td><b>[%  LxERP.t8('Not delivered amount') %]</b></td><td colspan="3">[% LxERP.format_amount(not_delivered, 2) %] [% part.unit %]</td></tr>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td><b>[%  LxERP.t8('Ordered, but not delivered (purchase)') %]</b></td><td colspan="3">[% LxERP.format_amount(ordered, 2) %] [% part.unit %]</td></tr>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td><b>[%  LxERP.t8('Reserved amount') %]</b></td><td colspan="3">[% LxERP.format_amount(part.stockqty - part.onhandqty, 2) %] [% part.unit %]</td></tr>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td><b>[%  LxERP.t8('Available amount') %]</b></td><td colspan="3">[% LxERP.format_amount(part.onhandqty, 2) %] [% part.unit %]</td></tr>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td><b>[%  LxERP.t8('Consume average') %]</b></td><td colspan="3">[% LxERP.format_amount(average, 2) %] [% part.unit %] [% LxERP.t8('per month') %]</td></tr>
 | ||
|         <tr><td colspan="4" nowrap>([%  LxERP.t8('in the time between') %] [% fromdate.to_kivitendo %] - [% todate.to_kivitendo %])</td>
 | ||
|       </tr>
 | ||
|       <tr>
 | ||
|         <td>[%- L.button_tag("return \$('#detail_menu').dialog('close');", LxERP.t8('Close Details'), class => "submit") %]</td>
 | ||
|       </tr>
 | ||
|   </tbody></table>
 | ||
| </div>
 | ||
| <div id="print_options" >
 | ||
|   <form id="print_options_form">
 | ||
|     [% print_options %]
 | ||
|     <br>
 | ||
|     [% L.button_tag('kivi.Part.print_from_showdetail(' _ part.id _ ')', LxERP.t8('Print')) %]
 | ||
|   </form>
 | ||
| </div>
 | ||
|  | ||
Auch abrufbar als: Unified diff
Part: Detailansicht als Popup hinzugefügt