From 945900fddbe868c804c60199c9563e89cd87aa15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hildo=20Guillardi=20J=C3=BAnior?= Date: Tue, 30 Jan 2018 21:15:12 -0200 Subject: [PATCH] Finished #73 multifiles --- kicost/spreadsheet.py | 95 +++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/kicost/spreadsheet.py b/kicost/spreadsheet.py index ee97555fa..80379f68e 100644 --- a/kicost/spreadsheet.py +++ b/kicost/spreadsheet.py @@ -178,8 +178,9 @@ def create_spreadsheet(parts, prj_info, spreadsheet_filename, user_fields, varia for i_prj in range(len(prj_info)): # Add project information to track the project (in a printed version # of the BOM) and the date because of price variations. + i_prj_str = (str(i_prj) if len(prj_info)>1 else '') wks.write(next_row, START_COL, - 'Prj{}:'.format(str(i_prj)) if len(prj_info)>1 else 'Prj:', + 'Prj{}:'.format(i_prj_str), wrk_formats['proj_info_field']) wks.write(next_row, START_COL+1, prj_info[i_prj]['title'], wrk_formats['proj_info']) @@ -192,31 +193,36 @@ def create_spreadsheet(parts, prj_info, spreadsheet_filename, user_fields, varia wks.write(next_row+2, START_COL+1, prj_info[i_prj]['date'], wrk_formats['proj_info']) - # Create the cell where the quantity of boards to assemble is entered. + # Create the cell where the quantity of boards to assemble is entered. # Place the board qty cells near the right side of the global info. - wks.write(next_row, next_col - 2, 'Board Qty:', + wks.write(next_row, next_col - 2, 'Board Qty{}:'.format(i_prj_str), wrk_formats['board_qty']) wks.write(next_row, next_col - 1, DEFAULT_BUILD_QTY, wrk_formats['board_qty']) # Set initial board quantity. # Define the named cell where the total board quantity can be found. - workbook.define_name('BoardQty', '={wks_name}!{cell_ref}'.format( - wks_name="'" + WORKSHEET_NAME + "'", - cell_ref=xl_rowcol_to_cell(next_row, next_col - 1, + workbook.define_name('BoardQty{}'.format(i_prj_str), + '={wks_name}!{cell_ref}'.format( + wks_name="'" + WORKSHEET_NAME + "'", + cell_ref=xl_rowcol_to_cell(next_row, next_col - 1, row_abs=True, col_abs=True))) - # Create the row to show total cost of board parts for each distributor. - wks.write(next_row+2, next_col - 2, 'Total Cost:', + + # Create the cell to show total cost of board parts for each distributor. + wks.write(next_row + 2, next_col - 2, 'Total Cost{}:'.format(i_prj_str), wrk_formats['total_cost_label']) # Define the named cell where the total cost can be found. - workbook.define_name('TotalCost', '={wks_name}!{cell_ref}'.format( - wks_name="'" + WORKSHEET_NAME + "'", - cell_ref=xl_rowcol_to_cell(next_row+2, next_col - 1, - row_abs=True, - col_abs=True))) - # Create the row to show unit cost of board parts. - wks.write(next_row+1, next_col - 2, 'Unit Cost:', + workbook.define_name('TotalCost{}'.format(i_prj_str), + '={wks_name}!{cell_ref}'.format( + wks_name="'" + WORKSHEET_NAME + "'", + cell_ref=xl_rowcol_to_cell(next_row + 2*(1+i_prj), + next_col - 1, + row_abs=True, col_abs=True)) ) + + # Create the cell to show unit cost of (each project) board parts. + wks.write(next_row+1, next_col - 2, 'Unit Cost{}:'.format(i_prj_str), wrk_formats['unit_cost_label']) - wks.write(next_row+1, next_col - 1, "=TotalCost/BoardQty", + wks.write(next_row+1, next_col - 1, + "=TotalCost{}/BoardQty{}".format(i_prj_str, i_prj_str), wrk_formats['unit_cost_currency']) next_row += 3 @@ -379,27 +385,19 @@ def remove_column(name): # of BOM files read, see the length of p[?]['manf#_qty']. prj_len = max([len(part.fields.get('manf#_qty',[])) for part in parts]) if prj_len>1: - def add_col(name, base, number, comment): - # Add one column with the `name`, based on the format `format` as - # the column `number` and shift right all the columns necessary - # to this inclusion. - columns[name] = base.copy() - columns[name]['col'] = number - columns[name]['label'] = name - if comment: - columns[name]['comment'] = comment - else: - try: - del columns[name]['comment'] - except: - pass + def add_qty_proj_col(i_proj): + # Add one column to quantify the quantity for each project. + name = 'qty_prj{}'.format(i_proj) + col = columns['qty']['col'] + columns[name] = columns['qty'].copy() + columns[name]['col'] = col + columns[name]['label'] = 'Qty.Prj{}'.format(i_proj) + columns[name]['comment'] = 'Total number of each part needed to assembly the project {}.'.format(i_prj) for k,f in columns.items(): - if f['col']>=number and k!=name: + if f['col']>=col and k!=name: f['col'] += 1 for i_prj in range(prj_len): - add_col('Qty.Prj{}'.format(i_prj), - columns['qty'], columns['qty']['col'], - 'Total number of each part needed to assemble the project {}.'.format(i_prj)) + add_qty_proj_col(i_prj) # Enter user-defined fields into the global part data columns structure. for user_field in list(reversed(user_fields)): @@ -477,7 +475,6 @@ def get_ref_key(part): # Enter total part quantity needed. try: qty = partgroup_qty(part); - print('----',qty)#TODO if isinstance(qty, list): # Multifiles BOM case, write each quantity and after, # in the 'qty' column the total quantity as ceil of @@ -485,12 +482,12 @@ def get_ref_key(part): # compatible function. for i_prj in range(len(qty)): wks.write(row, - start_col + columns['Qty.Prj{}'.format(i_prj)]['col'], + start_col + columns['qty_prj{}'.format(i_prj)]['col'], qty[i_prj].format('BoardQty{}'.format(i_prj)), wrk_formats['part_format']) wks.write_formula(row, start_col + columns['qty']['col'], '=CEILING(SUM({}:{}),1)'.format( - xl_rowcol_to_cell(row, start_col + columns['Qty.Prj0']['col']), + xl_rowcol_to_cell(row, start_col + columns['qty_prj0']['col']), xl_rowcol_to_cell(row, start_col + columns['qty']['col']-1) ), wrk_formats['part_format']) @@ -603,9 +600,29 @@ def get_ref_key(part): row += 1 # Go to next row. # Sum the extended prices for all the parts to get the total minimum cost. + # If have read multiple BOM file calculate it by `SUMPRODUCT()` of the + # board project quantity components 'qty_prj*' by unitary price 'Unit$'. total_cost_col = start_col + columns['ext_price']['col'] - wks.write(total_cost_row, total_cost_col, '=sum({sum_range})'.format( - sum_range=xl_range(PART_INFO_FIRST_ROW, total_cost_col, + if isinstance(qty, list): + unit_price_col = start_col + columns['unit_price']['col'] + unit_price_range = xl_range(PART_INFO_FIRST_ROW, unit_price_col, + PART_INFO_LAST_ROW, unit_price_col) + # Add each project board total. + for i_prj in range(len(qty)): + qty_col = start_col + columns['qty_prj{}'.format(i_prj)]['col'] + wks.write(total_cost_row + 3*i_prj, total_cost_col, + '=SUMPRODUCT({qty_range},{unit_price_range})'.format( + unit_price_range=unit_price_range, + qty_range=xl_range(PART_INFO_FIRST_ROW, qty_col, + PART_INFO_LAST_ROW, qty_col)), + wrk_formats['total_cost_currency']) + # Add total of the spreadsheet, this can be equal or bigger than + # than the sum of the above totals, because, in the case of parcial + # or fractional quantity of one part or subpart, the total quantity + # column 'qty' will be the ceil of the sum of the other ones. + total_cost_row = start_row -1 # Change the position of the total price cell. + wks.write(total_cost_row, total_cost_col, '=SUM({sum_range})'.format( + sum_range=xl_range(PART_INFO_FIRST_ROW, total_cost_col, PART_INFO_LAST_ROW, total_cost_col)), wrk_formats['total_cost_currency'])