Figure 8-1 shows how the BOM ITK can be used.
/* An example program to show a list of a bill of materials using the BOM module @<DEL>*/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unidefs.h> #include <mem.h> #include <iman.h> #include <item.h> #include <bom.h> #include <cfm.h> #include <ps_errors.h>
/* this sequence is very common */
#define CHECK_FAIL if (ifail != 0) { printf ("line %d (ifail %d)\n", __LINE__, ifail); exit (0);}
static int name_attribute, seqno_attribute, parent_attribute, item_tag_attribute;
static void initialise (void);
static void initialise_attribute (char *name, int *attribute); static void print_bom (tag_t line, int depth);
static void print_average (tag_t top_line);
static void find_revision_count (tag_t line, int *count, int *total); static void double_sequence_nos (tag_t line);
static int my_compare_function (tag_t line_1, tag_t line_2, void *client_data);
/*---*/
Product Structure Management
Run this program by:
<program name> -u<user> -p<password> */
extern int ITK_user_main (int argc, char ** argv ) {
int ifail; char *req_item;
tag_t window, window2, rule, item_tag, top_line;
initialise();
req_item = ITK_ask_cli_argument("-i="); ifail = BOM_create_window (&window); CHECK_FAIL;
ifail = CFM_find( "Latest Working", &rule ); CHECK_FAIL;
ifail = BOM_set_window_config_rule( window, rule ); CHECK_FAIL;
ifail = BOM_set_window_pack_all (window, true); CHECK_FAIL;
ifail = ITEM_find_item (req_item, &item_tag); CHECK_FAIL;
if (item_tag == null_tag)
{ printf ("ITEM_find_item returns success, but did not find %s\n", req_item); exit (0);
}
ifail = BOM_set_window_top_line (window, item_tag, null_tag, null_tag, &top_line); CHECK_FAIL;
print_bom (top_line, 0);
double_sequence_nos (top_line); /* we will not use
ifail = BOM_save_window (window); because that would modify the database */
/* now let’s list the results sorted the other way */
ifail = BOM_create_window (&window2); CHECK_FAIL;
ifail = BOM_set_window_config_rule( window2, rule ); CHECK_FAIL;
ifail = BOM_set_window_pack_all (window, false); /* the default, but let’s be explicit */ CHECK_FAIL;
ifail = BOM_set_window_sort_compare_fn (window2, (void *)my_compare_function, NULL); CHECK_FAIL;
ifail = BOM_set_window_top_line (window2, item_tag, null_tag, null_tag, &top_line); CHECK_FAIL; printf ("================================================\n"); print_bom (top_line, 0); print_average (top_line); ITK_exit_module(true); return 0; } /*---*/
Chapter 8 Product Structure Management
static void print_bom (tag_t line, int depth) {
int ifail;
char *name, *sequence_no; int i, n;
tag_t *children;
depth ++;
ifail = BOM_line_ask_attribute_string (line, name_attribute, &name); CHECK_FAIL;
/* note that I know name is always defined, but sometimes sequence number is unset. If that happens it returns NULL, not an error.
*/
ifail = BOM_line_ask_attribute_string (line, seqno_attribute, &sequence_no); CHECK_FAIL;
printf ("%3d", depth); for (i = 0; i < depth; i++)
printf (" ");
printf ("%-20s %s\n", name, sequence_no == NULL ? "<null>” : sequence_no);
ifail = BOM_line_ask_child_lines (line, &n, &children); CHECK_FAIL;
for (i = 0; i < n; i++)
print_bom (children[i], depth);
MEM_free (children); MEM_free (name);
MEM_free (sequence_no); }
/*---*/
static void double_sequence_nos (tag_t line) {
/* just to demonstrate modifying the bill */
int ifail;
char *sequence_no; int i, n;
tag_t *children;
ifail = BOM_line_ask_attribute_string (line, seqno_attribute, &sequence_no); CHECK_FAIL;
/* Top bom lines have no sequence number, and others may also not */ if (sequence_no[0] != ’\0’)
{
char buffer[100];
sprintf (buffer, "%d", 2 * atoi (sequence_no));
ifail = BOM_line_set_attribute_string (line, seqno_attribute, buffer); if (ifail != ITK_ok)
{
char *child_name;
ifail = BOM_line_ask_attribute_string (line, name_attribute, &child_name); CHECK_FAIL;
printf ("==> No write access to %s\n", child_name); MEM_free (child_name);
} else {
Product Structure Management
ifail = BOM_line_ask_child_lines (line, &n, &children); CHECK_FAIL; for (i = 0; i < n; i++) double_sequence_nos (children[i]); MEM_free (children); } /*---*/
static void print_average (tag_t top_line) {
int count = 0, total = 0;
find_revision_count (top_line, &count, &total); if (count <= 0)
{
printf ("impossible error has happened!\n"); }
else {
printf ("lines in bill : %d\naverage revisions of each item : %d\n", count, total / count);
} }
/*---*/
static void find_revision_count (tag_t line, int *count, int *total) {
/* A function to demonstrate going from BOM tags to other IMAN classes */ /* In this case, we get the Item tag for the BOM line, and then use it for an */ /* ITEM call. For a complete list of standard attributes see bom_attr.h, or */ /* use a BOM_list_attributes call to find all current attributes (new note */
/* types define new attributes) */
int ifail;
tag_t item_tag, *revisions, *children; int i, n, revision_count;
char* item_id;
ifail = BOM_line_ask_attribute_tag(line, item_tag_attribute, &item_tag ); CHECK_FAIL;
/* the simplest example call I can think of: */ /* count how many revisions of this Item there are */
ifail = ITEM_list_all_revs (item_tag, &revision_count, &revisions); CHECK_FAIL;
MEM_free (revisions); (*count)++;
(*total) += revision_count;
ifail = BOM_line_ask_child_lines (line, &n, &children); CHECK_FAIL;
for (i = 0; i < n; i++)
find_revision_count (children[i], count, total);
MEM_free (children); }
/*---*/
Chapter 8 Product Structure Management
static int my_compare_function (tag_t line_1, tag_t line_2, void *client_data) {
/* returns strcmp style -1/0/+1 according to whether line_1 and line_2 sort <, = or > */ char *seq1, *seq2;
int ifail, result;
ifail = BOM_line_ask_attribute_string (line_1, seqno_attribute, &seq1); CHECK_FAIL;
ifail = BOM_line_ask_attribute_string (line_2, seqno_attribute, &seq2); CHECK_FAIL;
if (seq1 == NULL || seq2 == NULL) result = 0;
else
result = strcmp (seq2, seq1); /* Doing a reverse sort */
/* note: the default sort function compares Item names if the sequence numbers sort equal but we will not show that here
*/ MEM_free (seq1); MEM_free (seq2); return result; } /*---*/
static void initialise (void) {
int ifail;
/* <kc> exit if autologin() fail */ if ((ifail = ITK_auto_login()) != ITK_ok)
fprintf(stderr,"Login fail !!: Error code = %d \n\n",ifail); CHECK_FAIL;
/* these tokens come from bom_attr.h */
initialise_attribute (bomAttr_lineName, &name_attribute); initialise_attribute (bomAttr_occSeqNo, &seqno_attribute);
ifail = BOM_line_look_up_attribute (bomAttr_lineParentTag, &parent_attribute); CHECK_FAIL;
ifail = BOM_line_look_up_attribute (bomAttr_lineItemTag, &item_tag_attribute); CHECK_FAIL;
}
/*---*/
static void initialise_attribute (char *name, int *attribute) {
int ifail, mode;
ifail = BOM_line_look_up_attribute (name, attribute); CHECK_FAIL;
ifail = BOM_line_ask_attribute_mode (*attribute, &mode); CHECK_FAIL;
if (mode != BOM_attribute_mode_string)
{ printf ("Help, attribute %s has mode %d, I want a string\n", name, mode); exit(0);
} }
Product Structure Management
Occurrences
An occurrence represents the usage of an item or an item revision within the product structure of a parent. You can distinguish between different kinds of occurrences in the BOM and product structure. Refer to Occurrence Sequencing for the BOM and Product Structures in the Integration Toolkit Function Reference manual.