Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 83914eeb

Von Moritz Bunkus vor mehr als 16 Jahren hinzugefügt

  • ID 83914eeb2e95cdf587565952eef54be59dd58693
  • Vorgänger 5c184abc
  • Nachfolger bb439145

Lagerverwaltung implementiert.

Unterschiede anzeigen:

SL/AM.pm
2407 2407
  $main::lxdebug->leave_sub();
2408 2408
}
2409 2409

  
2410
sub save_warehouse {
2411
  $main::lxdebug->enter_sub();
2412

  
2413
  my ($self, $myconfig, $form) = @_;
2414

  
2415
  # connect to database
2416
  my $dbh = $form->get_standard_dbh($myconfig);
2417

  
2418
  my ($query, @values, $sth);
2419

  
2420
  if (!$form->{id}) {
2421
    $query        = qq|SELECT nextval('id')|;
2422
    ($form->{id}) = selectrow_query($form, $dbh, $query);
2423

  
2424
    $query        = qq|INSERT INTO warehouse (id, sortkey) VALUES (?, (SELECT COALESCE(MAX(sortkey), 0) + 1 FROM warehouse))|;
2425
    do_query($form, $dbh, $query, $form->{id});
2426
  }
2427

  
2428
  do_query($form, $dbh, qq|UPDATE warehouse SET description = ?, invalid = ? WHERE id = ?|,
2429
           $form->{description}, $form->{invalid} ? 't' : 'f', conv_i($form->{id}));
2430

  
2431
  if (0 < $form->{number_of_new_bins}) {
2432
    $query = qq|INSERT INTO bin (warehouse_id, description) VALUES (?, ?)|;
2433
    $sth   = prepare_query($form, $dbh, $query);
2434

  
2435
    foreach my $i (1..$form->{number_of_new_bins}) {
2436
      do_statement($form, $sth, $query, conv_i($form->{id}), "$form->{prefix}${i}");
2437
    }
2438

  
2439
    $sth->finish();
2440
  }
2441

  
2442
  $dbh->commit();
2443

  
2444
  $main::lxdebug->leave_sub();
2445
}
2446

  
2447
sub save_bins {
2448
  $main::lxdebug->enter_sub();
2449

  
2450
  my ($self, $myconfig, $form) = @_;
2451

  
2452
  # connect to database
2453
  my $dbh = $form->get_standard_dbh($myconfig);
2454

  
2455
  my ($query, @values, $commit_necessary, $sth);
2456

  
2457
  @values = map { $form->{"id_${_}"} } grep { $form->{"delete_${_}"} } (1..$form->{rowcount});
2458

  
2459
  if (@values) {
2460
    $query = qq|DELETE FROM bin WHERE id IN (| . join(', ', ('?') x scalar(@values)) . qq|)|;
2461
    do_query($form, $dbh, $query, @values);
2462

  
2463
    $commit_necessary = 1;
2464
  }
2465

  
2466
  $query = qq|UPDATE bin SET description = ? WHERE id = ?|;
2467
  $sth   = prepare_query($form, $dbh, $query);
2468

  
2469
  foreach my $row (1..$form->{rowcount}) {
2470
    next if ($form->{"delete_${row}"});
2471

  
2472
    do_statement($form, $sth, $query, $form->{"description_${row}"}, conv_i($form->{"id_${row}"}));
2473

  
2474
    $commit_necessary = 1;
2475
  }
2476

  
2477
  $sth->finish();
2478

  
2479
  $dbh->commit() if ($commit_necessary);
2480

  
2481
  $main::lxdebug->leave_sub();
2482
}
2483

  
2484
sub delete_warehouse {
2485
  $main::lxdebug->enter_sub();
2486

  
2487
  my ($self, $myconfig, $form) = @_;
2488

  
2489
  # connect to database
2490
  my $dbh = $form->get_standard_dbh($myconfig);
2491

  
2492
  my $id      = conv_i($form->{id});
2493
  my $query   = qq|SELECT i.bin_id FROM inventory i WHERE i.bin_id IN (SELECT b.id FROM bin b WHERE b.warehouse_id = ?) LIMIT 1|;
2494
  my ($count) = selectrow_query($form, $dbh, $query, $id);
2495

  
2496
  if ($count) {
2497
    $main::lxdebug->leave_sub();
2498
    return 0;
2499
  }
2500

  
2501
  do_query($form, $dbh, qq|DELETE FROM warehouse_access WHERE warehouse_id = ?|, conv_i($form->{id}));
2502
  do_query($form, $dbh, qq|DELETE FROM bin              WHERE warehouse_id = ?|, conv_i($form->{id}));
2503
  do_query($form, $dbh, qq|DELETE FROM warehouse        WHERE id           = ?|, conv_i($form->{id}));
2504

  
2505
  $dbh->commit();
2506

  
2507
  $main::lxdebug->leave_sub();
2508

  
2509
  return 1;
2510
}
2511

  
2512
sub get_all_warehouses {
2513
  $main::lxdebug->enter_sub();
2514

  
2515
  my ($self, $myconfig, $form) = @_;
2516

  
2517
  # connect to database
2518
  my $dbh = $form->get_standard_dbh($myconfig);
2519

  
2520
  my $query = qq|SELECT w.id, w.description, w.invalid
2521
                 FROM warehouse w
2522
                 ORDER BY w.sortkey|;
2523

  
2524
  $form->{WAREHOUSES} = selectall_hashref_query($form, $dbh, $query);
2525

  
2526
  $main::lxdebug->leave_sub();
2527
}
2528

  
2529
sub get_warehouse {
2530
  $main::lxdebug->enter_sub();
2531

  
2532
  my ($self, $myconfig, $form) = @_;
2533

  
2534
  # connect to database
2535
  my $dbh = $form->get_standard_dbh($myconfig);
2536

  
2537
  my $id    = conv_i($form->{id});
2538
  my $query = qq|SELECT w.description, w.invalid
2539
                 FROM warehouse w
2540
                 WHERE w.id = ?|;
2541

  
2542
  my $ref   = selectfirst_hashref_query($form, $dbh, $query, $id, $id);
2543

  
2544
  map { $form->{$_} = $ref->{$_} } keys %{ $ref };
2545

  
2546
  $query = qq|SELECT b.*, EXISTS
2547
                (SELECT i.warehouse_id
2548
                 FROM inventory i
2549
                 WHERE i.bin_id = b.id
2550
                 LIMIT 1)
2551
                AS in_use
2552
              FROM bin b
2553
              WHERE b.warehouse_id = ?|;
2554

  
2555
  $form->{BINS} = selectall_hashref_query($form, $dbh, $query, conv_i($form->{id}));
2556

  
2557
  $main::lxdebug->leave_sub();
2558
}
2410 2559

  
2411 2560
1;
SL/Auth.pm
636 636
    ["purchase_order_edit",            $locale->text("Create and edit purchase orders")],
637 637
    ["purchase_delivery_order_edit",   $locale->text("Create and edit purchase delivery orders")],
638 638
    ["vendor_invoice_edit",            $locale->text("Create and edit vendor invoices")],
639
    ["--warehouse_management",         $locale->text("Warehouse management")],
640
    ["warehouse_contents",             $locale->text("View warehouse content")],
641
    ["warehouse_management",           $locale->text("Warehouse management")],
639 642
    ["--general_ledger_cash",          $locale->text("General ledger and cash")],
640 643
    ["general_ledger",                 $locale->text("Transactions, AR transactions, AP transactions")],
641 644
    ["datev_export",                   $locale->text("DATEV Export")],
SL/IC.pm
325 325
    }
326 326

  
327 327
    if ($form->{item} eq 'assembly') {
328
      if ($form->{onhand} != 0) {
329
        &adjust_inventory($dbh, $form, $form->{id}, $form->{onhand} * -1);
330
      }
331

  
332 328
      # delete assembly records
333 329
      do_query($form, $dbh, qq|DELETE FROM assembly WHERE id = ?|, conv_i($form->{id}));
334

  
335
      $form->{onhand} += $form->{stock};
336 330
    }
337 331

  
338 332
    # delete tax records
......
352 346
    do_query($form, $dbh, qq|INSERT INTO parts (id, partnumber) VALUES (?, '')|, $form->{id});
353 347

  
354 348
    $form->{orphaned} = 1;
355
    $form->{onhand} = $form->{stock} if $form->{item} eq 'assembly';
356 349
    if ($form->{partnumber} eq "" && $form->{"item"} eq "service") {
357 350
      $form->{partnumber} = $form->update_defaults($myconfig, "servicenumber");
358 351
    }
......
532 525
      }
533 526
    }
534 527

  
535
    # adjust onhand for the parts
536
    if ($form->{onhand} != 0) {
537
      &adjust_inventory($dbh, $form, $form->{id}, $form->{onhand});
538
    }
539

  
540 528
    @a = localtime;
541 529
    $a[5] += 1900;
542 530
    $a[4]++;
......
544 532

  
545 533
    $form->get_employee($dbh);
546 534

  
547
    # add inventory record
548
    $query =
549
      qq|INSERT INTO inventory (warehouse_id, parts_id, qty, shippingdate, employee_id)
550
         VALUES (0, ?, ?, '$shippingdate', ?)|;
551
    @values = (conv_i($form->{id}), $form->{stock}, conv_i($form->{employee_id}));
552
    do_query($form, $dbh, $query, @values);
553

  
554 535
  }
555 536

  
556 537
  #set expense_accno=inventory_accno if they are different => bilanz
......
650 631
  $main::lxdebug->leave_sub();
651 632
}
652 633

  
653
sub restock_assemblies {
654
  $main::lxdebug->enter_sub();
655

  
656
  my ($self, $myconfig, $form) = @_;
657

  
658
  # connect to database
659
  my $dbh = $form->dbconnect_noauto($myconfig);
660

  
661
  for my $i (1 .. $form->{rowcount}) {
662

  
663
    $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
664

  
665
    if ($form->{"qty_$i"} != 0) {
666
      &adjust_inventory($dbh, $form, $form->{"id_$i"}, $form->{"qty_$i"});
667
    }
668

  
669
  }
670

  
671
  my $rc = $dbh->commit;
672
  $dbh->disconnect;
673

  
674
  $main::lxdebug->leave_sub();
675

  
676
  return $rc;
677
}
678

  
679
sub adjust_inventory {
680
  $main::lxdebug->enter_sub();
681

  
682
  my ($dbh, $form, $id, $qty) = @_;
683

  
684
  my $query =
685
    qq|SELECT p.id, p.inventory_accno_id, p.assembly, a.qty
686
       FROM parts p, assembly a
687
       WHERE (a.parts_id = p.id) AND (a.id = ?)|;
688
  my $sth = prepare_execute_query($form, $dbh, $query, conv_i($id));
689

  
690
  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
691

  
692
    my $allocate = $qty * $ref->{qty};
693

  
694
    # is it a service item, then loop
695
    $ref->{inventory_accno_id} *= 1;
696
    next if (($ref->{inventory_accno_id} == 0) && !$ref->{assembly});
697

  
698
    # adjust parts onhand
699
    $form->update_balance($dbh, "parts", "onhand",
700
                          qq|id = $ref->{id}|,
701
                          $allocate * -1);
702
  }
703

  
704
  $sth->finish;
705

  
706
  # update assembly
707
  my $rc = $form->update_balance($dbh, "parts", "onhand", qq|id = ?|, $qty, $id);
708

  
709
  $main::lxdebug->leave_sub();
710

  
711
  return $rc;
712
}
713

  
714 634
sub delete {
715 635
  $main::lxdebug->enter_sub();
716 636

  
......
1014 934

  
1015 935
  $form->{parts} = selectall_hashref_query($form, $dbh, $query, @bind_vars);
1016 936

  
937
  map { $_->{onhand} *= 1 } @{ $form->{parts} };
938

  
1017 939
##  my $where = qq|1 = 1|;
1018 940
##  my (@values, $var, $flds, $group, $limit);
1019 941
##
SL/IR.pm
178 178
      @values = ($form->{"sellprice_$i"}, conv_i($form->{"id_$i"}));
179 179
      do_query($form, $dbh, $query, @values);
180 180

  
181
      $form->update_balance($dbh, "parts", "onhand", qq|id = ?|, $baseqty, $form->{"id_$i"}) if !$form->{shipped};
182

  
183 181
      # check if we sold the item already and
184 182
      # make an entry for the expense and inventory
185 183
      $query =
......
572 570

  
573 571
    next unless $ref->{inventory_accno_id};
574 572

  
575
    # update onhand
576
    $form->update_balance($dbh, "parts", "onhand", qq|id = $ref->{parts_id}|, $ref->{qty});
577

  
578 573
    # if $ref->{allocated} > 0 than we sold that many items
579 574
    next if ($ref->{allocated} <= 0);
580 575

  
......
1057 1052
    $stw->finish();
1058 1053
    chop $ref->{taxaccounts};
1059 1054

  
1055
    $ref->{onhand} *= 1;
1056

  
1060 1057
    push @{ $form->{item_list} }, $ref;
1061 1058

  
1062 1059
  }
SL/IS.pm
645 645

  
646 646
      if ($form->{"inventory_accno_$i"} || $form->{"assembly_$i"}) {
647 647

  
648
        # adjust parts onhand quantity
649

  
650 648
        if ($form->{"assembly_$i"}) {
651

  
652
          # do not update if assembly consists of all services
653
          $query =
654
            qq|SELECT sum(p.inventory_accno_id)
655
               FROM parts p
656
               JOIN assembly a ON (a.parts_id = p.id)
657
               WHERE a.id = ?|;
658
          $sth = prepare_execute_query($form, $dbh, $query, conv_i($form->{"id_$i"}));
659

  
660
          if ($sth->fetchrow_array) {
661
            $form->update_balance($dbh, "parts", "onhand", qq|id = ?|,
662
                                  $baseqty * -1, $form->{"id_$i"})
663
              unless $form->{shipped};
664
          }
665
          $sth->finish;
666

  
667 649
          # record assembly item as allocated
668 650
          &process_assembly($dbh, $form, $form->{"id_$i"}, $baseqty);
669 651
        } else {
670
          $form->update_balance($dbh, "parts", "onhand", qq|id = ?|,
671
                                $baseqty * -1, $form->{"id_$i"})
672
            unless $form->{shipped};
673

  
674 652
          $allocated = &cogs($dbh, $form, $form->{"id_$i"}, $baseqty, $basefactor, $i);
675 653
        }
676 654
      }
......
1236 1214

  
1237 1215
  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
1238 1216

  
1239
    if ($ref->{inventory_accno_id} || $ref->{assembly}) {
1240

  
1241
      # if the invoice item is not an assemblyitem adjust parts onhand
1242
      if (!$ref->{assemblyitem}) {
1243

  
1244
        # adjust onhand in parts table
1245
        $form->update_balance($dbh, "parts", "onhand", qq|id = $ref->{parts_id}|, $ref->{qty});
1246
      }
1247

  
1248
      # loop if it is an assembly
1249
      next if ($ref->{assembly});
1250

  
1217
    if ($ref->{inventory_accno_id}) {
1251 1218
      # de-allocated purchases
1252 1219
      $query =
1253 1220
        qq|SELECT i.id, i.trans_id, i.allocated
......
1825 1792
      }
1826 1793
    }
1827 1794

  
1795
    $ref->{onhand} *= 1;
1796

  
1828 1797
    push @{ $form->{item_list} }, $ref;
1829 1798

  
1830 1799
    if ($form->{lizenzen}) {
SL/LICENSES.pm
68 68
  $sth->execute || $form->dberror($query);
69 69
  $sth->finish();
70 70

  
71
  if ($form->{own_product}) {
72
    $form->update_balance($dbh, "parts", "onhand", qq|id = ?|,
73
                          1, $form->{parts_id});
74
  }
75

  
76 71
  $dbh->disconnect();
77 72

  
78 73
  $main::lxdebug->leave_sub();
SL/OE.pm
242 242

  
243 243
  if ($form->{id}) {
244 244

  
245
    &adj_onhand($dbh, $form, $ml) if $form->{type} =~ /_order$/;
246

  
247 245
    $query = qq|DELETE FROM orderitems WHERE trans_id = ?|;
248 246
    do_query($form, $dbh, $query, $form->{id});
249 247

  
......
382 380
      }
383 381
      $query .= qq|?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
384 382
                   (SELECT factor FROM price_factors WHERE id = ?), ?)|;
385
        push(@values,
383
      push(@values,
386 384
           conv_i($form->{id}), conv_i($form->{"id_$i"}),
387 385
           $form->{"description_$i"}, $form->{"longdescription_$i"},
388 386
           $form->{"qty_$i"}, $baseqty,
......
476 474
    }
477 475
  }
478 476

  
479
  if ($form->{type} =~ /_order$/) {
480

  
481
    # adjust onhand
482
    &adj_onhand($dbh, $form, $ml * -1);
483
  }
484

  
485 477
  $form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ?
486 478
                                       "quonumber" : "ordnumber"};
487 479

  
......
556 548
  }
557 549
  $sth->finish;
558 550

  
559
  $query = qq|SELECT o.parts_id, o.ship FROM orderitems o | .
560
           qq|WHERE o.trans_id = ?|;
561
  @values = (conv_i($form->{id}));
562
  $sth = $dbh->prepare($query);
563
  $sth->execute(@values) || $self->dberror($query);
564

  
565
  while (my ($id, $ship) = $sth->fetchrow_array) {
566
    $form->update_balance($dbh, "parts", "onhand", qq|id = $id|, $ship * -1);
567
  }
568
  $sth->finish;
569

  
570 551
  # delete-values
571 552
  @values = (conv_i($form->{id}));
572 553

  
573
  # delete inventory
574
  $query = qq|DELETE FROM inventory | .
575
           qq|WHERE oe_id = ?|;
576
  do_query($form, $dbh, $query, @values);
577

  
578 554
  # delete status entries
579 555
  $query = qq|DELETE FROM status | .
580 556
           qq|WHERE trans_id = ?|;
......
1153 1129
  return $value;
1154 1130
}
1155 1131

  
1156
sub adj_onhand {
1157
  $main::lxdebug->enter_sub();
1158

  
1159
  my ($dbh, $form, $ml) = @_;
1160

  
1161
  my $all_units = $form->{all_units};
1162

  
1163
  my $query =
1164
    qq|SELECT oi.parts_id, oi.ship, oi.unit, p.inventory_accno_id, p.assembly | .
1165
    qq|   FROM orderitems oi | .
1166
    qq|   JOIN parts p ON (p.id = oi.parts_id) | .
1167
    qq|   WHERE oi.trans_id = ?|;
1168
  my @values = ($form->{id});
1169
  my $sth = $dbh->prepare($query);
1170
  $sth->execute(@values) || $form->dberror($query);
1171

  
1172
  $query =
1173
    qq|SELECT sum(p.inventory_accno_id) | .
1174
    qq|FROM parts p | .
1175
    qq|JOIN assembly a ON (a.parts_id = p.id) | .
1176
    qq|WHERE a.id = ?|;
1177
  my $ath = $dbh->prepare($query) || $form->dberror($query);
1178

  
1179
  my $ispa;
1180

  
1181
  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
1182
    if ($ref->{inventory_accno_id} || $ref->{assembly}) {
1183

  
1184
      # do not update if assembly consists of all services
1185
      if ($ref->{assembly}) {
1186
        $ath->execute($ref->{parts_id}) || $form->dberror($query);
1187

  
1188
        ($ispa) = $sth->fetchrow_array;
1189
        $ath->finish;
1190

  
1191
        next unless $ispa;
1192

  
1193
      }
1194

  
1195
      # get item baseunit
1196
      $query = qq|SELECT unit FROM parts WHERE id = ?|;
1197
      my ($item_unit) = selectrow_query($form, $dbh, $query, $ref->{parts_id});
1198

  
1199
      my $basefactor = 1;
1200
      if (defined($all_units->{$item_unit}->{factor}) && (($all_units->{$item_unit}->{factor} * 1) != 0)) {
1201
        $basefactor = $all_units->{$ref->{unit}}->{factor} / $all_units->{$item_unit}->{factor};
1202
      }
1203
      my $baseqty = $ref->{ship} * $basefactor;
1204

  
1205
      # adjust onhand in parts table
1206
      $form->update_balance($dbh, "parts", "onhand", qq|id = $ref->{parts_id}|, $baseqty * $ml);
1207
    }
1208
  }
1209

  
1210
  $sth->finish;
1211

  
1212
  $main::lxdebug->leave_sub();
1213
}
1214

  
1215 1132
1;
SL/WH.pm
1
#====================================================================
2
# LX-Office ERP
3
# Copyright (C) 2004
4
# Based on SQL-Ledger Version 2.1.9
5
# Web http://www.lx-office.org
6
#
7
#=====================================================================
8
# SQL-Ledger Accounting
9
# Copyright (C) 1999-2003
10
#
11
#  Author: Dieter Simader
12
#   Email: dsimader@sql-ledger.org
13
#     Web: http://www.sql-ledger.org
14
#
15
#  Contributors:
16
#
17
# This program is free software; you can redistribute it and/or modify
18
# it under the terms of the GNU General Public License as published by
19
# the Free Software Foundation; either version 2 of the License, or
20
# (at your option) any later version.
21
#
22
# This program is distributed in the hope that it will be useful,
23
# but WITHOUT ANY WARRANTY; without even the implied warranty of
24
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
# GNU General Public License for more details.
26
# You should have received a copy of the GNU General Public License
27
# along with this program; if not, write to the Free Software
28
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29
#======================================================================
30
#
31
#  Warehouse module
32
#
33
#======================================================================
34

  
35
package WH;
36

  
37
use SL::AM;
38
use SL::DBUtils;
39
use SL::Form;
40

  
41
sub transfer {
42
  $main::lxdebug->enter_sub();
43

  
44
  my $self = shift;
45

  
46
  if (!@_) {
47
    $main::lxdebug->leave_sub();
48
    return;
49
  }
50

  
51
  my $myconfig = \%main::myconfig;
52
  my $form     = $main::form;
53

  
54
  my $dbh      = $form->get_standard_dbh($myconfig);
55

  
56
  my $units    = AM->retrieve_units($myconfig, $form);
57

  
58
  my $query    = qq|SELECT * FROM transfer_type|;
59
  my $sth      = prepare_execute_query($form, $dbh, $query);
60

  
61
  my %transfer_types;
62

  
63
  while (my $ref = $sth->fetchrow_hashref()) {
64
    $transfer_types{$ref->{direction}} ||= { };
65
    $transfer_types{$ref->{direction}}->{$ref->{description}} = $ref->{id};
66
  }
67

  
68
  my @part_ids  = map { $_->{parts_id} } @_;
69
  my %partunits = selectall_as_map($form, $dbh, qq|SELECT id, unit FROM parts WHERE id IN (| . join(', ', map { '?' } @part_ids ) . qq|)|, 'id', 'unit', @part_ids);
70

  
71
  my ($now)     = selectrow_query($form, $dbh, qq|SELECT current_date|);
72

  
73
  $query = qq|INSERT INTO inventory (warehouse_id, bin_id, parts_id, chargenumber, oe_id, orderitems_id, shippingdate,
74
                                     employee_id, project_id, trans_id, trans_type_id, comment, qty)
75
              VALUES (?, ?, ?, ?, ?, ?, ?, (SELECT id FROM employee WHERE login = ?), ?, ?, ?, ?, ?)|;
76

  
77
  $sth   = prepare_query($form, $dbh, $query);
78

  
79
  my @directions = (undef, 'out', 'in', 'transfer');
80

  
81
  while (@_) {
82
    my $transfer   = shift;
83
    my ($trans_id) = selectrow_query($form, $dbh, qq|SELECT nextval('id')|);
84

  
85
    my ($direction, @values) = (0);
86

  
87
    $direction |= 1 if ($transfer->{src_warehouse_id} && $transfer->{src_bin_id});
88
    $direction |= 2 if ($transfer->{dst_warehouse_id} && $transfer->{dst_bin_id});
89

  
90
    push @values, conv_i($transfer->{parts_id}), "$transfer->{chargenumber}", conv_i($transfer->{oe_id}), conv_i($transfer->{orderitems_id});
91
    push @values, $transfer->{shippingdate} eq 'current_date' ? $now : conv_date($transfer->{shippingdate}), $form->{login}, conv_i($transfer->{project_id}), $trans_id;
92

  
93
    if ($transfer->{transfer_type_id}) {
94
      push @values, $transfer->{transfer_type_id};
95
    } else {
96
      push @values, $transfer_types{$directions[$direction]}->{$transfer->{transfer_type}};
97
    }
98

  
99
    push @values, "$transfer->{comment}";
100

  
101
    $qty = $transfer->{qty};
102

  
103
    if ($transfer->{unit}) {
104
      my $partunit = $partunits{$transfer->{parts_id}};
105

  
106
      $qty *= $units->{$transfer->{unit}}->{factor};
107
      $qty /= $units->{$partunit}->{factor} || 1 if ($partunit);
108
    }
109

  
110
    if ($direction & 1) {
111
      do_statement($form, $sth, $query, conv_i($transfer->{src_warehouse_id}), conv_i($transfer->{src_bin_id}), @values, $qty * -1);
112
    }
113

  
114
    if ($direction & 2) {
115
      do_statement($form, $sth, $query, conv_i($transfer->{dst_warehouse_id}), conv_i($transfer->{dst_bin_id}), @values, $qty);
116
    }
117
  }
118

  
119
  $sth->finish();
120

  
121
  $dbh->commit();
122

  
123
  $main::lxdebug->leave_sub();
124
}
125

  
126
sub get_warehouse_journal {
127
  $main::lxdebug->enter_sub();
128

  
129
  my $self      = shift;
130
  my %filter    = @_;
131

  
132
  my $myconfig  = \%main::myconfig;
133
  my $form      = $main::form;
134

  
135
  my $all_units = AM->retrieve_units($myconfig, $form);
136

  
137
  # connect to database
138
  my $dbh = $form->get_standard_dbh($myconfig);
139

  
140
  # filters
141
  my (@filter_ary, @filter_vars, $joins);
142

  
143
  if ($filter{warehouse_id} ne '') {
144
    push @filter_ary, "w1.id = ? OR w2.id = ?";
145
    push @filter_vars, $filter{warehouse_id}, $filter{warehouse_id};
146
  }
147

  
148
  if ($filter{bin_id} ne '') {
149
    push @filter_ary, "b1.id = ? OR b2.id = ?";
150
    push @filter_vars, $filter{bin_id}, $filter{bin_id};
151
  }
152

  
153
  if ($filter{partnumber}) {
154
    push @filter_ary, "p.partnumber ILIKE ?";
155
    push @filter_vars, '%' . $filter{partnumber} . '%';
156
  }
157

  
158
  if ($filter{description}) {
159
    push @filter_ary, "(p.description ILIKE ?)";
160
    push @filter_vars, '%' . $filter{description} . '%';
161
  }
162

  
163
  if ($filter{chargenumber}) {
164
    push @filter_ary, "w1.chargenumber ILIKE ?";
165
    push @filter_vars, '%' . $filter{chargenumber} . '%';
166
  }
167

  
168
  if ($form->{fromdate}) {
169
    push @filter_ary, "?::DATE <= i1.itime::DATE";
170
    push @filter_vars, $form->{fromdate};
171
  }
172

  
173
  if ($form->{todate}) {
174
    push @filter_ary, "?::DATE >= i1.itime::DATE";
175
    push @filter_vars, $form->{todate};
176
  }
177

  
178
  if ($form->{l_employee}) {
179
    $joins .= "";
180
  }
181

  
182
  # prepare qty comparison for later filtering
183
  my ($f_qty_op, $f_qty, $f_qty_base_unit);
184
  if ($filter{qty_op} && defined($filter{qty}) && $filter{qty_unit} && $all_units->{$filter{qty_unit}}) {
185
    $f_qty_op        = $filter{qty_op};
186
    $f_qty           = $filter{qty} * $all_units->{$filter{qty_unit}}->{factor};
187
    $f_qty_base_unit = $all_units->{$filter{qty_unit}}->{base_unit};
188
  }
189

  
190
  map { $_ = "(${_})"; } @filter_ary;
191

  
192
  # if of a property number or description is requested,
193
  # automatically check the matching id too.
194
  map { $form->{"l_${_}id"} = "Y" if ($form->{"l_${_}description"} || $form->{"l_${_}number"}); } qw(warehouse bin);
195

  
196
  # customize shown entry for not available fields.
197
  $filter{na} = '-' unless $filter{na};
198

  
199
  # make order, search in $filter and $form
200
  $form->{sort}   = $filter{sort}             unless $form->{sort};
201
  $form->{order}  = ($form->{sort} = 'itime') unless $form->{sort};
202
  $form->{sort}   = 'itime'                   if     $form->{sort} eq "date";
203
  $form->{order}  = $filter{order}            unless $form->{order};
204
  $form->{sort}  .= (($form->{order}) ? " DESC" : " ASC");
205

  
206
  my $where_clause = join(" AND ", @filter_ary) . " AND " if (@filter_ary);
207

  
208
  $select_tokens{'trans'} = {
209
     "parts_id"             => "i1.parts_id",
210
     "qty"                  => "ABS(SUM(i1.qty))",
211
     "partnumber"           => "p.partnumber",
212
     "partdescription"      => "p.description",
213
     "bindescription"       => "b.description",
214
     "chargenumber"         => "i1.chargenumber",
215
     "warehousedescription" => "w.description",
216
     "partunit"             => "p.unit",
217
     "bin_from"             => "b1.description",
218
     "bin_to"               => "b2.description",
219
     "warehouse_from"       => "w1.description",
220
     "warehouse_to"         => "w2.description",
221
     "comment"              => "i1.comment",
222
     "trans_type"           => "tt.description",
223
     "trans_id"             => "i1.trans_id",
224
     "date"                 => "i1.itime::DATE",
225
     "itime"                => "i1.itime",
226
     "employee"             => "e.name",
227
     "projectnumber"        => "COALESCE(pr.projectnumber, '$filter{na}')",
228
     };
229

  
230
  $select_tokens{'out'} = {
231
     "bin_to"               => "'$filter{na}'",
232
     "warehouse_to"         => "'$filter{na}'",
233
     };
234

  
235
  $select_tokens{'in'} = {
236
     "bin_from"             => "'$filter{na}'",
237
     "warehouse_from"       => "'$filter{na}'",
238
     };
239

  
240
  # build the select clauses.
241
  # take all the requested ones from the first hash and overwrite them from the out/in hashes if present.
242
  for my $i ('trans', 'out', 'in') {
243
    $select{$i} = join ', ', map { +/l_/; ($select_tokens{$i}{"$'"} || $select_tokens{'trans'}{"$'"}) . " AS r_$'" }
244
          ( grep( { !/qty$/ and /l_/ and $form->{$_} eq 'Y' } keys %$form), qw(l_parts_id l_qty l_partunit l_itime) );
245
  }
246

  
247
  my $group_clause = join ", ", map { +/^l_/; "r_$'" }
248
        ( grep( { !/qty$/ and /l_/ and $form->{$_} eq 'Y' } keys %$form), qw(l_parts_id l_partunit l_itime) );
249

  
250
  my $query =
251
  qq|SELECT DISTINCT $select{trans}
252
    FROM inventory i1
253
    LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id
254
    LEFT JOIN parts p ON i1.parts_id = p.id
255
    LEFT JOIN bin b1 ON i1.bin_id = b1.id
256
    LEFT JOIN bin b2 ON i2.bin_id = b2.id
257
    LEFT JOIN warehouse w1 ON i1.warehouse_id = w1.id
258
    LEFT JOIN warehouse w2 ON i2.warehouse_id = w2.id
259
    LEFT JOIN transfer_type tt ON i1.trans_type_id = tt.id
260
    LEFT JOIN project pr ON i1.project_id = pr.id
261
    LEFT JOIN employee e ON i1.employee_id = e.id
262
    WHERE $where_clause i2.qty = -i1.qty AND i2.qty > 0 AND
263
          i1.trans_id IN ( SELECT i.trans_id FROM inventory i GROUP BY i.trans_id HAVING COUNT(i.trans_id) = 2 )
264
    GROUP BY $group_clause
265

  
266
    UNION
267

  
268
    SELECT DISTINCT $select{out}
269
    FROM inventory i1
270
    LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id
271
    LEFT JOIN parts p ON i1.parts_id = p.id
272
    LEFT JOIN bin b1 ON i1.bin_id = b1.id
273
    LEFT JOIN bin b2 ON i2.bin_id = b2.id
274
    LEFT JOIN warehouse w1 ON i1.warehouse_id = w1.id
275
    LEFT JOIN warehouse w2 ON i2.warehouse_id = w2.id
276
    LEFT JOIN transfer_type tt ON i1.trans_type_id = tt.id
277
    LEFT JOIN project pr ON i1.project_id = pr.id
278
    LEFT JOIN employee e ON i1.employee_id = e.id
279
    WHERE $where_clause i1.qty < 0 AND
280
          i1.trans_id IN ( SELECT i.trans_id FROM inventory i GROUP BY i.trans_id HAVING COUNT(i.trans_id) = 1 )
281
    GROUP BY $group_clause
282

  
283
    UNION
284

  
285
    SELECT DISTINCT $select{in}
286
    FROM inventory i1
287
    LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id
288
    LEFT JOIN parts p ON i1.parts_id = p.id
289
    LEFT JOIN bin b1 ON i1.bin_id = b1.id
290
    LEFT JOIN bin b2 ON i2.bin_id = b2.id
291
    LEFT JOIN warehouse w1 ON i1.warehouse_id = w1.id
292
    LEFT JOIN warehouse w2 ON i2.warehouse_id = w2.id
293
    LEFT JOIN transfer_type tt ON i1.trans_type_id = tt.id
294
    LEFT JOIN project pr ON i1.project_id = pr.id
295
    LEFT JOIN employee e ON i1.employee_id = e.id
296
    WHERE $where_clause i1.qty > 0 AND
297
          i1.trans_id IN ( SELECT i.trans_id FROM inventory i GROUP BY i.trans_id HAVING COUNT(i.trans_id) = 1 )
298
    GROUP BY $group_clause
299
    ORDER BY r_$form->{sort}|;
300

  
301
  my $sth = prepare_execute_query($form, $dbh, $query, @filter_vars, @filter_vars, @filter_vars);
302

  
303
  my @contents = ();
304
  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
305
    map { /^r_/; $ref->{"$'"} = $ref->{$_} } keys %$ref;
306
    my $qty = $ref->{"qty"} * 1;
307

  
308
    next unless ($qty > 0);
309

  
310
    if ($f_qty_op) {
311
      my $part_unit = $all_units->{$ref->{"partunit"}};
312
      next unless ($part_unit && ($part_unit->{"base_unit"} eq $f_qty_base_unit));
313
      $qty *= $part_unit->{"factor"};
314
      next if (('=' eq $f_qty_op) && ($qty != $f_qty));
315
      next if (('>=' eq $f_qty_op) && ($qty < $f_qty));
316
      next if (('<=' eq $f_qty_op) && ($qty > $f_qty));
317
    }
318

  
319
    push @contents, $ref;
320
  }
321

  
322
  $sth->finish();
323

  
324
  $main::lxdebug->leave_sub();
325

  
326
  return @contents;
327
}
328

  
329
#
330
# This sub is the primary function to retrieve information about items in warehouses.
331
# $filter is a hashref and supports the following keys:
332
#  - warehouse_id - will return matches with this warehouse_id only
333
#  - partnumber   - will return only matches where the given string is a substring of the partnumber
334
#  - partsid      - will return matches with this parts_id only
335
#  - description  - will return only matches where the given string is a substring of the description
336
#  - chargenumber - will return only matches where the given string is a substring of the chargenumber
337
#  - charge_ids   - must be an arrayref. will return contents with these ids only
338
#  - expires_in   - will only return matches that expire within the given number of days
339
#                   will also add a column named 'has_expired' containing if the match has already expired or not
340
#  - hazardous    - will return matches with the flag hazardous only
341
#  - oil          - will return matches with the flag oil only
342
#  - qty, qty_op  - quantity filter (more info to come)
343
#  - sort, order_by - sorting (more to come)
344
#  - reservation  - will provide an extra column containing the amount reserved of this match
345
# note: reservation flag turns off warehouse_* or bin_* information. both together don't make sense, since reserved info is stored separately
346
#
347
sub get_warehouse_report {
348
  $main::lxdebug->enter_sub();
349

  
350
  my $self      = shift;
351
  my %filter    = @_;
352

  
353
  my $myconfig  = \%main::myconfig;
354
  my $form      = $main::form;
355

  
356
  my $all_units = AM->retrieve_units($myconfig, $form);
357

  
358
  # connect to database
359
  my $dbh = $form->get_standard_dbh($myconfig);
360

  
361
  # filters
362
  my (@filter_ary, @filter_vars, @wh_bin_filter_ary, @wh_bin_filter_vars, $columns, $group_by);
363

  
364
  delete $form->{include_empty_bins} unless ($form->{l_warehousedescription} || $form->{l_bindescription});
365

  
366
  if ($filter{warehouse_id}) {
367
    push @wh_bin_filter_ary,  "w.id = ?";
368
    push @wh_bin_filter_vars, $filter{warehouse_id};
369
  }
370

  
371
  if ($filter{bin_id}) {
372
    push @wh_bin_filter_ary,  "b.id = ?";
373
    push @wh_bin_filter_vars, $filter{bin_id};
374
  }
375

  
376
  push @filter_ary,  @wh_bin_filter_ary;
377
  push @filter_vars, @wh_bin_filter_vars;
378

  
379
  if ($filter{partnumber}) {
380
    push @filter_ary,  "p.partnumber ILIKE ?";
381
    push @filter_vars, '%' . $filter{partnumber} . '%';
382
  }
383

  
384
  if ($filter{description}) {
385
    push @filter_ary,  "p.description ILIKE ?";
386
    push @filter_vars, '%' . $filter{description} . '%';
387
  }
388

  
389
  if ($filter{partsid}) {
390
    push @filter_ary,  "p.id = ?";
391
    push @filter_vars, $filter{partsid};
392
  }
393

  
394
  if ($filter{chargenumber}) {
395
    push @filter_ary,  "i.chargenumber ILIKE ?";
396
    push @filter_vars, '%' . $filter{chargenumber} . '%';
397
  }
398

  
399
  # prepare qty comparison for later filtering
400
  my ($f_qty_op, $f_qty, $f_qty_base_unit);
401

  
402
  if ($filter{qty_op} && defined $filter{qty} && $filter{qty_unit} && $all_units->{$filter{qty_unit}}) {
403
    $f_qty_op        = $filter{qty_op};
404
    $f_qty           = $filter{qty} * $all_units->{$filter{qty_unit}}->{factor};
405
    $f_qty_base_unit = $all_units->{$filter{qty_unit}}->{base_unit};
406
  }
407

  
408
  map { $_ = "(${_})"; } @filter_ary;
409

  
410
  # if of a property number or description is requested,
411
  # automatically check the matching id too.
412
  map { $form->{"l_${_}id"} = "Y" if ($form->{"l_${_}description"} || $form->{"l_${_}number"}); } qw(warehouse bin);
413

  
414
  # make order, search in $filter and $form
415
  $form->{sort}  =  $filter{sort}  unless $form->{sort};
416
  $form->{sort}  =  "parts_id"     unless $form->{sort};
417
  $form->{order} =  $filter{order} unless $form->{order};
418
  $form->{sort}  =~ s/ASC|DESC//; # kill stuff left in from previous queries
419
  my $orderby    =  $form->{sort};
420
  $form->{sort} .=  (($form->{order}) ? " DESC" : " ASC");
421

  
422
  my $where_clause = join " AND ", ("1=1", @filter_ary);
423

  
424
  my %select_tokens = (
425
     "parts_id"              => "i.parts_id",
426
     "qty"                  => "SUM(i.qty)",
427
     "warehouseid"          => "i.warehouse_id",
428
     "partnumber"           => "p.partnumber",
429
     "partdescription"      => "p.description",
430
     "bindescription"       => "b.description",
431
     "binid"                => "b.id",
432
     "chargenumber"         => "i.chargenumber",
433
     "chargeid"             => "c.id",
434
     "warehousedescription" => "w.description",
435
     "partunit"             => "p.unit",
436
  );
437
  my $select_clause = join ', ', map { +/l_/; "$select_tokens{$'} AS $'" }
438
        ( grep( { !/qty/ and /l_/ and $form->{$_} eq 'Y' } keys %$form),
439
          qw(l_parts_id l_qty l_partunit) );
440

  
441
  my $group_clause = join ", ", map { +/^l_/; "$'" }
442
        ( grep( { !/qty/ and /l_/ and $form->{$_} eq 'Y' } keys %$form),
443
          qw(l_parts_id l_partunit) );
444

  
445
  my $query =
446
    qq|SELECT $select_clause
447
      $columns
448
      FROM inventory i
449
      LEFT JOIN parts     p ON i.parts_id     = p.id
450
      LEFT JOIN bin       b ON i.bin_id       = b.id
451
      LEFT JOIN warehouse w ON i.warehouse_id = w.id
452
      WHERE $where_clause
453
      GROUP BY $group_clause $group_by
454
      ORDER BY $form->{sort}|;
455

  
456
  my $sth = prepare_execute_query($form, $dbh, $query, @filter_vars);
457

  
458
  my (%non_empty_bins, @all_fields, @contents);
459

  
460
  while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
461
    $ref->{qty} *= 1;
462
    my $qty      = $ref->{qty};
463

  
464
    next unless ($qty > 0);
465

  
466
    if ($f_qty_op) {
467
      my $part_unit = $all_units->{$ref->{partunit}};
468
      next if (!$part_unit || ($part_unit->{base_unit} ne $f_qty_base_unit));
469
      $qty *= $part_unit->{factor};
470
      next if (('='  eq $f_qty_op) && ($qty != $f_qty));
471
      next if (('>=' eq $f_qty_op) && ($qty <  $f_qty));
472
      next if (('<=' eq $f_qty_op) && ($qty >  $f_qty));
473
    }
474

  
475
    if ($form->{include_empty_bins}) {
476
      $non_empty_bins{$ref->{binid}} = 1;
477
      @all_fields                    = keys %{ $ref } unless (@all_fields);
478
    }
479

  
480
    push @contents, $ref;
481
  }
482

  
483
  $sth->finish();
484

  
485
  if ($form->{include_empty_bins}) {
486
    $query =
487
      qq|SELECT
488
           w.id AS warehouseid, w.description AS warehousedescription,
489
           b.id AS binid, b.description AS bindescription
490
         FROM bin b
491
         LEFT JOIN warehouse w ON (b.warehouse_id = w.id)|;
492

  
493
    @filter_ary  = @wh_bin_filter_ary;
494
    @filter_vars = @wh_bin_filter_vars;
495

  
496
    my @non_empty_bin_ids = keys %non_empty_bins;
497
    if (@non_empty_bin_ids) {
498
      push @filter_ary,  qq|NOT b.id IN (| . join(', ', map { '?' } @non_empty_bin_ids) . qq|)|;
499
      push @filter_vars, @non_empty_bin_ids;
500
    }
501

  
502
    $query .= qq| WHERE | . join(' AND ', map { "($_)" } @filter_ary) if (@filter_ary);
503

  
504
    $sth    = prepare_execute_query($form, $dbh, $query, @filter_vars);
505

  
506
    while ($ref = $sth->fetchrow_hashref()) {
507
      map { $ref->{$_} ||= "" } @all_fields;
508
      push @contents, $ref;
509
    }
510
    $sth->finish();
511

  
512
    if (grep { $orderby eq $_ } qw(bindescription warehousedescription)) {
513
      @contents = sort { ($a->{$orderby} cmp $b->{$orderby}) * (($form->{order}) ? 1 : -1) } @contents;
514
    }
515
  }
516

  
517
  $main::lxdebug->leave_sub();
518

  
519
  return @contents;
520
}
521

  
522
sub convert_qty_op {
523
  $main::lxdebug->enter_sub();
524

  
525
  my ($self, $qty_op) = @_;
526

  
527
  if (!$qty_op || ($qty_op eq "dontcare")) {
528
    $main::lxdebug->leave_sub();
529
    return undef;
530
  }
531

  
532
  if ($qty_op eq "atleast") {
533
    $qty_op = '>=';
534
  } elsif ($qty_op eq "atmost") {
535
    $qty_op = '<=';
536
  } else {
537
    $qty_op = '=';
538
  }
539

  
540
  $main::lxdebug->leave_sub();
541

  
542
  return $qty_op;
543
}
544

  
545
sub retrieve_transfer_types {
546
  $main::lxdebug->enter_sub();
547

  
548
  my $self      = shift;
549
  my $direction = shift;
550

  
551
  my $myconfig  = \%main::myconfig;
552
  my $form      = $main::form;
553

  
554
  my $dbh       = $form->get_standard_dbh($myconfig);
555

  
556
  my $types     = selectall_hashref_query($form, $dbh, qq|SELECT * FROM transfer_type WHERE direction = ? ORDER BY sortkey|, $direction);
557

  
558
  $main::lxdebug->leave_sub();
559

  
560
  return $types;
561
}
562

  
563
sub get_basic_bin_info {
564
  $main::lxdebug->enter_sub();
565

  
566
  my $self     = shift;
567
  my %params   = @_;
568

  
569
  Common::check_params(\%params, qw(id));
570

  
571
  my $myconfig = \%main::myconfig;
572
  my $form     = $main::form;
573

  
574
  my $dbh      = $params{dbh} || $form->get_standard_dbh();
575

  
576
  my @ids      = 'ARRAY' eq ref $params{id} ? @{ $params{id} } : ($params{id});
577

  
578
  my $query    =
579
    qq|SELECT b.id AS bin_id, b.description AS bin_description,
580
         w.id AS warehouse_id, w.description AS warehouse_description
581
       FROM bin b
582
       LEFT JOIN warehouse w ON (b.warehouse_id = w.id)
583
       WHERE b.id IN (| . join(', ', ('?') x scalar(@ids)) . qq|)|;
584

  
585
  my $result = selectall_hashref_query($form, $dbh, $query, map { conv_i($_) } @ids);
586

  
587
  if ('' eq ref $params{id}) {
588
    $result = $result->[0] || { };
589
    $main::lxdebug->leave_sub();
590

  
591
    return $result;
592
  }
593

  
594
  $main::lxdebug->leave_sub();
595

  
596
  return map { $_->{bin_id} => $_ } @{ $result };
597
}
598

  
599

  
600
1;
bin/mozilla/am.pl
3136 3136
  $lxdebug->leave_sub();
3137 3137
}
3138 3138

  
3139
sub add_warehouse {
3140
  $lxdebug->enter_sub();
3141

  
3142
  $auth->assert('config');
3143

  
3144
  $form->{title}      = $locale->text('Add Warehouse');
3145
  $form->{callback} ||= build_std_url('action=add_warehouse');
3146
  $form->{fokus}      = 'description';
3147

  
3148
  $form->header();
3149
  print $form->parse_html_template('am/edit_warehouse');
3150

  
3151
  $lxdebug->leave_sub();
3152
}
3153

  
3154
sub edit_warehouse {
3155
  $lxdebug->enter_sub();
3156

  
3157
  $auth->assert('config');
3158

  
3159
  AM->get_warehouse(\%myconfig, $form);
3160

  
3161
  $form->get_lists('employees' => 'EMPLOYEES');
3162

  
3163
  $form->{title}      = $locale->text('Edit Warehouse');
3164
  $form->{callback} ||= build_std_url('action=list_warehouses');
3165
  $form->{fokus}      = 'description';
3166

  
3167
  $form->header();
3168
  print $form->parse_html_template('am/edit_warehouse');
3169

  
3170
  $lxdebug->leave_sub();
3171
}
3172

  
3173
sub list_warehouses {
3174
  $lxdebug->enter_sub();
3175

  
3176
  $auth->assert('config');
3177

  
3178
  AM->get_all_warehouses(\%myconfig, $form);
3179

  
3180
  my $previous;
3181
  foreach my $current (@{ $form->{WAREHOUSES} }) {
3182
    if ($previous) {
3183
      $previous->{next_id}    = $current->{id};
3184
      $current->{previous_id} = $previous->{id};
3185
    }
3186

  
3187
    $previous = $current;
3188
  }
3189

  
3190
  $form->{callback} = build_std_url('action=list_warehouses');
3191
  $form->{title}    = $locale->text('Warehouses');
3192
  $form->{url_base} = build_std_url('callback');
3193

  
3194
  $form->header();
3195
  print $form->parse_html_template('am/list_warehouses');
3196

  
3197
  $lxdebug->leave_sub();
3198
}
3199

  
3200
sub save_warehouse {
3201
  $lxdebug->enter_sub();
3202

  
3203
  $auth->assert('config');
3204

  
3205
  $form->isblank("description", $locale->text('Description missing!'));
3206

  
3207
  $form->{number_of_new_bins} = $form->parse_amount(\%myconfig, $form->{number_of_new_bins});
3208

  
3209
  AM->save_warehouse(\%myconfig, $form);
3210

  
3211
  $form->{callback} .= '&saved_message=' . E($locale->text('Warehouse saved.')) if ($form->{callback});
3212

  
3213
  $form->redirect($locale->text('Warehouse saved.'));
3214

  
3215
  $lxdebug->leave_sub();
3216
}
3217

  
3218
sub swap_warehouses {
3219
  $lxdebug->enter_sub();
3220

  
3221
  $auth->assert('config');
3222

  
3223
  AM->swap_sortkeys(\%myconfig, $form, 'warehouse');
3224
  list_warehouses();
3225

  
3226
  $lxdebug->leave_sub();
3227
}
3228

  
3229
sub delete_warehouse {
3230
  $lxdebug->enter_sub();
3231

  
3232
  $auth->assert('config');
3233

  
3234
  if (!$form->{confirmed}) {
3235
    $form->{title} = $locale->text('Confirmation');
3236

  
3237
    $form->header();
3238
    print $form->parse_html_template('am/confirm_delete_warehouse');
3239
    exit 0;
3240
  }
3241

  
3242
  if (AM->delete_warehouse(\%myconfig, $form)) {
3243
    $form->{callback} .= '&saved_message=' . E($locale->text('Warehouse deleted.')) if ($form->{callback});
3244
    $form->redirect($locale->text('Warehouse deleted.'));
3245

  
3246
  } else {
3247
    $form->error($locale->text('The warehouse could not be deleted because it has already been used.'));
3248
  }
3249

  
3250
  $lxdebug->leave_sub();
3251
}
3252

  
3253
sub save_bin {
3254
  $lxdebug->enter_sub();
3255

  
3256
  $auth->assert('config');
3257

  
3258
  AM->save_bins(\%myconfig, $form);
3259

  
3260
  $form->{callback} .= '&saved_message=' . E($locale->text('Bins saved.')) if ($form->{callback});
3261

  
3262
  $form->redirect($locale->text('Bins saved.'));
3263

  
3264
  $lxdebug->leave_sub();
3265
}
3266

  
bin/mozilla/common.pl
47 47

  
48 48
# -------------------------------------------------------------------------
49 49

  
50
sub select_part {
51
  $lxdebug->enter_sub();
52

  
53
  my ($callback_sub, @parts) = @_;
54

  
55
  my $remap_parts_id = 0;
56
  if (defined($parts[0]->{parts_id}) && !defined($parts[0]->{id})) {
57
    $remap_parts_id = 1;
58
    map { $_->{id} = $_->{parts_id}; } @parts;
59
  }
60

  
61
  my $remap_partnumber = 0;
62
  if (defined($parts[0]->{partnumber}) && !defined($parts[0]->{number})) {
63
    $remap_partnumber = 1;
64
    map { $_->{number} = $_->{partnumber}; } @parts;
65
  }
66

  
67
  my $has_charge = 0;
68
  if (defined($parts[0]->{chargenumber})) {
69
    $has_charge = 1;
70
    map { $_->{has_charge} = 1; } @parts;
71
  }
72

  
73
  my $old_form = save_form();
74

  
75
  $form->header();
76
  print $form->parse_html_template("generic/select_part",
77
                                   { "PARTS"            => \@parts,
78
                                     "old_form"         => $old_form,
79
                                     "title"            => $locale->text("Select a part"),
80
                                     "nextsub"          => "select_part_internal",
81
                                     "callback_sub"     => $callback_sub,
82
                                     "has_charge"       => $has_charge,
83
                                     "remap_parts_id"   => $remap_parts_id,
84
                                     "remap_partnumber" => $remap_partnumber });
85

  
86
  $lxdebug->leave_sub();
87
}
88

  
89
sub select_part_internal {
90
  $lxdebug->enter_sub();
91

  
92
  my ($new_item, $callback_sub);
93

  
94
  my $re = "^new_.*_" . $form->{selection};
95

  
96
  foreach (grep /$re/, keys %{ $form }) {
97
    my $new_key           =  $_;
98
    $new_key              =~ s/^new_//;
99
    $new_key              =~ s/_\d+$//;
100
    $new_item->{$new_key} =  $form->{$_};
101
  }
102

  
103
  if ($form->{remap_parts_id}) {
104
    $new_item->{parts_id} = $new_item->{id};
105
    delete $new_item->{id};
106
  }
107

  
108
  if ($form->{remap_partnumber}) {
109
    $new_item->{partnumber} = $new_item->{number};
110
    delete $new_item->{number};
111
  }
112

  
113
  my $callback_sub = $form->{callback_sub};
114

  
115
  restore_form($form->{old_form});
116

  
117
  call_sub($callback_sub, $new_item);
118

  
119
  $lxdebug->leave_sub();
120
}
121

  
122
sub part_selection_internal {
123
  $lxdebug->enter_sub();
124

  
125
  $order_by  = "description";
126
  $order_by  = $form->{"order_by"} if (defined($form->{"order_by"}));
127
  $order_dir = 1;
128
  $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"}));
129

  
130
  %options   = map { $_ => 1 } split m/:/, $form->{options};
131

  
132
  map { $form->{$_} = 1 if ($options{$_}) } qw(no_services no_assemblies stockable);
133

  
134
  $parts = Common->retrieve_parts(\%myconfig, $form, $order_by, $order_dir);
135

  
136
  if (0 == scalar(@{$parts})) {
137
    $form->show_generic_information($locale->text("No part was found matching the search parameters."));
138
  } elsif (1 == scalar(@{$parts})) {
139
    $onload = "part_selected('1')";
140
  }
141

  
142
  map { $parts->[$_]->{selected} = $_ ? 0 : 1; } (0..$#{$parts});
143

  
144
  my $callback = build_std_url('action=part_selection_internal', qw(partnumber description input_partnumber input_description input_partsid),
145
                               grep({ /^[fl]_/ } keys %{ $form }));
146

  
147
  my @header_sort  = qw(partnumber description);
148
  my %header_title = ( "partnumber"  => $locale->text("Part Number"),
149
                       "description" => $locale->text("Part description"),
150
                       );
151

  
152
  my @header =
153
    map(+{ "column_title" => $header_title{$_},
154
           "column"       => $_,
155
           "callback"     => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir),
156
         },
157
        @header_sort);
158

  
159
  $form->{title} = $locale->text("Select a part");
160
  $form->header();
161
  print $form->parse_html_template("generic/part_selection", { "HEADER" => \@header,
162
                                                               "PARTS"  => $parts,
163
                                                               "onload" => $onload });
164

  
165
  $lxdebug->leave_sub();
166
}
167

  
168
# -------------------------------------------------------------------------
169

  
50 170
sub delivery_customer_selection {
51 171
  $lxdebug->enter_sub();
52 172

  
bin/mozilla/wh.pl
1
#=====================================================================
2
# LX-Office ERP
3
# Copyright (C) 2004
4
# Based on SQL-Ledger Version 2.1.9
5
# Web http://www.lx-office.org
6
#############################################################################
7
# SQL-Ledger, Accounting
8
# Copyright (c) 1998-2002
9
#
10
#  Author: Dieter Simader
11
#   Email: dsimader@sql-ledger.org
12
#     Web: http://www.sql-ledger.org
13
#
14
#
15
# This program is free software; you can redistribute it and/or modify
16
# it under the terms of the GNU General Public License as published by
17
# the Free Software Foundation; either version 2 of the License, or
18
# (at your option) any later version.
19
#
20
# This program is distributed in the hope that it will be useful,
21
# but WITHOUT ANY WARRANTY; without even the implied warranty of
22
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
# GNU General Public License for more details.
24
# You should have received a copy of the GNU General Public License
25
# along with this program; if not, write to the Free Software
26
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
#
28
#######################################################################
29
#
30
# warehouse and packinglist
31
#
32
#######################################################################
33

  
34
use List::Util qw(min max first);
35
use POSIX qw(strftime);
36

  
37
use SL::Form;
38
use SL::User;
39

  
40
use SL::AM;
41
use SL::CT;
42
use SL::IC;
43
use SL::WH;
44
use SL::OE;
45
use SL::ReportGenerator;
46

  
47
use Data::Dumper;
48

  
49
require "bin/mozilla/common.pl";
50
require "bin/mozilla/reportgenerator.pl";
51

  
52
# parserhappy(R):
53

  
54
# contents of the "transfer_type" table:
55
#  $locale->text('back')
56
#  $locale->text('correction')
57
#  $locale->text('disposed')
58
#  $locale->text('found')
59
#  $locale->text('missing')
60
#  $locale->text('stock')
61
#  $locale->text('transfer')
62
#  $locale->text('used')
63
#  $locale->text('return_material')
64
#  $locale->text('release_material')
65

  
66
# --------------------------------------------------------------------
67
# Transfer
68
# --------------------------------------------------------------------
69

  
70
sub transfer_warehouse_selection {
71
  $lxdebug->enter_sub();
72

  
73
  $auth->assert('warehouse_management');
74

  
... Dieser Diff wurde abgeschnitten, weil er die maximale Anzahl anzuzeigender Zeilen überschreitet.

Auch abrufbar als: Unified diff