Remove redondant argument numbers check
[eda-utils.git] / bomgen / bomgen.php
index 4883b72..1108cf1 100755 (executable)
  * (at your option) any later version.
  */
 
-require_once 'Spreadsheet/Excel/Writer.php';
-require_once 'Bomgen/functions.inc.php';
-require_once 'Bomgen/refdes.inc.php';
-require_once 'Bomgen/digikey.inc.php';
-require_once 'Bomgen/conf.inc.php';
-
-$debug = 0;
+require_once 'Console/Getopt.php';
 
-$digikey_bom = false;
-
-define("DATA_ROW_START", 3);
+define("XLS_DATA_ROW_START", 3);
 
 define("PAPER_US_LETTER", 1);
 
-/* width = 0 -> Ne pas afficher la colonne. */
-$csv_infos =
-  array(QTY_COL_NAME     => array("nom"   => "Qty",
-                                  "width" => 5),
-        DESIGNATOR_COL_NAME => array("nom"   => "Designator",
-                                  "width" => 30),
-        "Description"    => array("nom"   => "Description",
-                                  "width" => 45),
-        "Value"          => array("nom"   => "Value",
-                                  "width" => 15),
-        "Voltage"        => array("nom"   => "Voltage",
-                                  "width" => 10),
-        "Current"        => array("nom"   => "Current",
-                                  "width" => 10),
-        "Power"          => array("nom"   => "Power",
-                                  "width" => 10),
-        "Manufacturer"   => array("nom"   => "Manufacturer",
-                                  "width" => 30),
-        "Part Number"    => array("nom"   => "Manuf. P/N",
-                                  "width" => 30),
-        COMPANY_PN_COL_NAME => array("nom"   => "LSI P/N",
-                                  "width" => 15),
-        "PatternName"    => array("nom"   => "Footprint",
-                                  "width" => 20),
-        ASSEMBLY_COL_NAME => array("nom"   => "Assembly",
-                                  "width" => 0),
-        "UnitCost"       => array("nom"   => "Unit Cost",
-                                  "width" => 7),
-        "TotalCost"      => array("nom"   => "Total Cost", /* Colonne ajoutée par ce script. */
-                                  "width" => 8),
-        "Type"           => array("nom"   => "Type", /* Colonne ajoutée par ce script. */
-                                  "width" => 0),
-        );
+$debug = 0;
 
-function usage()
-{
-  echo "Usage: bomgen.php [OPTIONS] [INPUT FILE]\n";
-  echo "Generate an Excel BOM from a PCAD CSV-exported BOM.\n";
-  echo "Output file has same name as input file, but with a .xls or .txt extension.\n";
-  echo "\n";
-  echo "Options:\n";
-  echo "  -c  Add cost information to the BOM\n";
-  echo "  -k  Create digiley BOM submission file (tab-separated fields)\n";
-  echo "  -h  Display this help and exit\n";
-}
+/* Default values. */
+$add_cost = false;
+$digikey_bom = false;
+$kits = 1;
+$use_inventory = false;
+$comp_total = 0;
+$titre = "BOM";
 
 /*
  * Clé    = Nom de la colonne.
@@ -92,82 +48,24 @@ $col_num_to_id = array();
 
 $entete = array();
 
-/*
- * value: clé
- * c:     Numéro de colonne dans le fichier CSV.
- * xls_c: Numéro de colonne dans Excel.
- */
-function determine_col_index($value, $c, $xls_c)
-{
-  global $col_id_to_num, $col_num_to_id, $col_id_to_xls_num;
+$short_opts = "hci:kn:t:";
 
-  $col_id_to_num[$value] = $c;
-  $col_num_to_id[$c] = $value;
-  $col_id_to_xls_num[$value] = $xls_c;
-}
-
-/* Conversion colonne numérique à lettre:
- *   0 -> A
- *   1 -> B
- *   ...
- */
-function col_to_letter($c)
-{
-  $c = intval($c + 1); /* c part à 0. */
-
-  if ($c <= 0)
-    return '';
-
-  $letter = '';
-
-  while($c != 0) {
-    $p = ($c - 1) % 26;
-    $c = intval(($c - $p) / 26);
-    $letter = chr(65 + $p) . $letter;
-  }
-
-  return $letter;
-}
-
-function xls_configure($workbook, $worksheet)
+function usage()
 {
-  global $col_id_to_xls_num, $csv_infos;
-
-  /* Configration des couleurs de cellules. */
-  xls_set_colors($workbook);
-
-  foreach ($csv_infos as $key => $value) {
-    $width = $value['width'];
-
-    /* Ajustement de la largeur de chaque colonne. */
-    if ($width) {
-      /* S'assure que la colonne a été exportée dans le fichier CSV. */
-      if (isset($col_id_to_xls_num[$key])) {
-        $worksheet->setColumn($col_id_to_xls_num[$key], $col_id_to_xls_num[$key],
-                              $width);
-      } else {
-        echo "Colonne '$key' manquante.\n";
-      }
-    }
-  }
-
-  $worksheet->setLandscape();
-  $worksheet->setPaper(PAPER_US_LETTER);
-}
-
-if ($argc < 2) {
-  echo "Missing source filename\n";
-  usage();
-  exit(1);
+  echo "Usage: bomgen.php [OPTIONS] [INPUT FILE]\n";
+  echo "Generate an Excel BOM from a PCAD or Altium CSV-exported BOM.\n";
+  echo "Output file has same name as input file, but with a .xls or .txt extension.\n";
+  echo "\n";
+  echo "Options:\n";
+  echo "  -c  Add cost information to the BOM\n";
+  echo "  -i  Specifiy inventory CSV file\n";
+  echo "  -k  Create digikey BOM submission file (tab-separated fields)\n";
+  echo "  -h  Display this help and exit\n";
+  echo "  -n  Number of cards/kits for digikey BOM submission\n";
+  echo "  -t  BOM input type:\n";
+  echo "          pcad or altium\n";
 }
 
-$add_cost = false;
-
-$comp_total = 0;
-$titre = "BOM";
-
-$short_opts = "hck";
-
 $cg = new Console_Getopt();
 
 /* Read the command line. */
@@ -180,7 +78,6 @@ $ret = $cg->getopt($args, $short_opts);
 if (PEAR::isError($ret)) {
   die ("Error in command line: " . $ret->getMessage() . "\n");
 }
-
 /* Now parse the options array. */
 $opts = $ret[0];
 
@@ -190,12 +87,22 @@ if (sizeof($opts) > 0) {
         case 'c':
           $add_cost = true;
           break;
+        case 'i':
+          $use_inventory = true;
+          $inventory_filename = $o[1];
+          break;
         case 'k':
           $digikey_bom = true;
           break;
+        case 'n':
+          $kits = $o[1];
+          break;
         case 'h':
           usage();
           exit(1);
+        case 't':
+          $bom_type = strtolower($o[1]);
+          break;
         }
     }
 }
@@ -215,6 +122,29 @@ if (sizeof($args) == 0) {
   exit(1);
 }
 
+switch ($bom_type) {
+case 'pcad':
+  require_once 'Bomgen/pcad.inc.php';
+  break;
+case 'altium':
+  require_once 'Bomgen/altium.inc.php';
+  break;
+default:
+  echo "Invalid BOM type: " . $bom_type . "\n";
+  exit(1);
+  break;
+}
+
+/* These files must be included before others. */
+require_once 'Bomgen/mapping.inc.php';
+require_once 'Bomgen/digikey.inc.php';
+
+require_once 'Spreadsheet/Excel/Writer.php';
+
+require_once 'Bomgen/conf.inc.php';
+require_once 'Bomgen/functions.inc.php';
+require_once 'Bomgen/refdes.inc.php';
+
 $dest = strip_ext($src);
 
 /* Importation du BOM CSV. */
@@ -227,98 +157,53 @@ if ($add_cost == false) {
   $csv_infos['UnitCost']['width'] = 0;
 }
 
-if (($handle = fopen($src, "r")) !== FALSE) {
-  while (($row = fgetcsv($handle, 1024, ',')) !== false) {
-    $num = count($row);
-
-    if ($num < 2) {
-      /* Ligne vide. */
-      continue;
-    }
-
-    if ($row_num == 1) {
-      /* Entête. */
-
-      if ($add_cost == true) {
-        /* Ajout colonne temporaire pour le total cost. */
-        $row[$num] = "TotalCost";
-        $num++;
-      }
-
-      /* Ajout colonne temporaire selon le type de composant. Cela est
-       * nécessaire pour faire le tri correctement. */
-      $row[$num] = "Type";
-      $num++;
-
-      /* Index de la prochaine colonne disponible pour affichage. */
-      $k = 0;
-
-      for ($c = 0; $c < $num; $c++) {
-        $id = $row[$c];
-
-        determine_col_index($id, $c, $k);
-
-        if (isset($csv_infos[$id])) {
-          if ($csv_infos[$id]['width'] != 0) {
-            $nom = $csv_infos[$id]['nom'];
-
-            $entete[$k] = $nom;
-
-            $k++;
-          }
-        } else {
-          echo "Colonne '$id' non supportée.\n";
-        }
-      }
-    } else {
-      $ref_prefix2 = substr($row[$col_id_to_num[DESIGNATOR_COL_NAME]], 0, 2);
-      $company_pn = substr($row[$col_id_to_num[COMPANY_PN_COL_NAME]], 0, 1); /* Pour les vieux BOMs qui n'ont pas
-                                                                 * l'attribut NOPOP. */
-      if (($ref_prefix2 == "MH") ||
-          ($ref_prefix2 == "TP") ||
-          ($ref_prefix2 == "FI") ||
-          (array_key_exists(ASSEMBLY_COL_NAME, $col_id_to_num) && ($row[$col_id_to_num[ASSEMBLY_COL_NAME]] == DO_NOT_POPULATE_KEYWORD)) ||
-          ($company_pn == "*")) {
-        /* Enlève les composants non désirés. */
-        continue;
-      }
-
-      $ref_prefix = substr($ref_prefix2, 0, 1);
-      $row[$col_id_to_num['Type']] = $ref_prefix;
-      $data[] = $row;
-    }
-
-    $row_num++;
-  }
-  fclose($handle);
-}
+/* Read and import BOM source file. */
+bom_import_source($src);
 
 /* Combinaison de plusieurs lignes en une seule pour PCAD. */
 refdes_combine($data, $num, $col_num_to_id, $col_id_to_num);
 
+$voltage_present = false;
+
 /* Génère une liste des colonnes pour le tri. */
 foreach ($data as $key => $row) {
   $sort_type[$key]  = $row[$col_id_to_num['Type']];
   $sort_desc[$key] = $row[$col_id_to_num['Description']];
   $sort_val[$key] = $row[$col_id_to_num['Value']];
-  $sort_volt[$key] = $row[$col_id_to_num['Voltage']];
+
+  if (isset($col_id_to_num['Voltage'])) {
+    $voltage_present = true;
+    $sort_volt[$key] = $row[$col_id_to_num['Voltage']];
+  }
 }
 
 /*
  * Triage des lignes selon la référence (colonne DESIGNATOR_COL_NAME),
  * et ensuite selon la description, la valeur et enfin le voltage.
  */
-array_multisort($sort_type, SORT_ASC, SORT_STRING,
-                $sort_desc, SORT_ASC, SORT_STRING,
-                $sort_val,  SORT_ASC, SORT_NUMERIC,
-                $sort_volt, SORT_ASC, SORT_NUMERIC,
-                $data);
+if ($voltage_present) {
+  array_multisort($sort_type, SORT_ASC, SORT_STRING,
+                  $sort_desc, SORT_ASC, SORT_STRING,
+                  $sort_val,  SORT_ASC, SORT_NUMERIC,
+                  $sort_volt, SORT_ASC, SORT_NUMERIC,
+                  $data);
+} else {
+  array_multisort($sort_type, SORT_ASC, SORT_STRING,
+                  $sort_desc, SORT_ASC, SORT_STRING,
+                  $sort_val,  SORT_ASC, SORT_NUMERIC,
+                  $data);
+}
 
 if ($digikey_bom) {
   /* Exportation BOM digikey. */
   $dest .= ".txt";
+  $inventory = array();
+
+  if ($use_inventory) {
+    $inventory = import_inventory($inventory_filename);
+  }
 
-  export_bom_digikey($data, $num, $col_num_to_id, $col_id_to_num, $dest);
+  export_bom_digikey($data, $num, $col_num_to_id, $col_id_to_num, $dest, $inventory);
 } else {
   /* Exportation BOM Excel */
 
@@ -334,7 +219,7 @@ if ($digikey_bom) {
       die($worksheet->getMessage());
   }
 
-  $row_num = DATA_ROW_START;
+  $row_num = XLS_DATA_ROW_START;
 
   /* Écriture des colonnes d'entête. */
   $k = 0;
@@ -421,7 +306,7 @@ if ($digikey_bom) {
     /* Ajout cellule prix total. */
     xls_write_price($row_num, $col_id_to_xls_num["TotalCost"],
                     "=SUM(" . col_to_letter($col_id_to_xls_num["TotalCost"]) .
-                    (DATA_ROW_START + 2) . ":" . col_to_letter($col_id_to_xls_num["TotalCost"]) .
+                    (XLS_DATA_ROW_START + 2) . ":" . col_to_letter($col_id_to_xls_num["TotalCost"]) .
                     $row_num . ")");
   }