Bug 1803 - Créer un outil de suivi des achats et d'inventaire IPR-ISCR
- ajout de l'application DebtComputer qui permet de calculer l'argent injecté par un utilisateur dans le pot commun, et l'usage dont il en bénéficie nb: les maintenances ne sont pas encore prises en compte
This commit is contained in:
parent
c309da0ef4
commit
8e32bd1bc8
|
@ -34,11 +34,11 @@ def get_investment_over_time(time_value, price, purchase_time):
|
||||||
|
|
||||||
return f3 * price
|
return f3 * price
|
||||||
|
|
||||||
def get_flops_over_time(inventory, time_value, computer_serial_number, purchase_time):
|
def get_flops_over_time(inventory, time_value, computer_id, purchase_time):
|
||||||
"""
|
"""
|
||||||
:param Inventory inventory:
|
:param Inventory inventory:
|
||||||
"""
|
"""
|
||||||
return np.where( time_value < purchase_time, 0.0, inventory.get_computer_dflops(computer_serial_number) )
|
return np.where( time_value < purchase_time, 0.0, inventory.get_computer_dflops(computer_id) )
|
||||||
|
|
||||||
def get_flops_price_over_time(inventory, time_value):
|
def get_flops_price_over_time(inventory, time_value):
|
||||||
"""
|
"""
|
||||||
|
@ -56,11 +56,11 @@ def get_flops_price_over_time(inventory, time_value):
|
||||||
(name, serial_number, affectation, machine_spec_id, command_id, price_ex_vat, pos_x, pos_y, pos_z, inv_number)=row
|
(name, serial_number, affectation, machine_spec_id, command_id, price_ex_vat, pos_x, pos_y, pos_z, inv_number)=row
|
||||||
is_cluster_node = re.match('^simpatix[0-9]+$', name)
|
is_cluster_node = re.match('^simpatix[0-9]+$', name)
|
||||||
if is_cluster_node:
|
if is_cluster_node:
|
||||||
purchase_date = inventory.get_machine_purchase_date(serial_number)
|
purchase_date = inventory.get_machine_purchase_date(name)
|
||||||
if purchase_date is not None:
|
if purchase_date is not None:
|
||||||
# print(name, price_ex_vat)
|
# print(name, price_ex_vat)
|
||||||
purchase_time = matplotlib.dates.date2num(purchase_date.date())
|
purchase_time = matplotlib.dates.date2num(purchase_date.date())
|
||||||
computer_flops = inventory.get_computer_dflops(serial_number )
|
computer_flops = inventory.get_computer_dflops(name)
|
||||||
flops_price = ( price_ex_vat-inventory.get_computer_options_price(name) ) / computer_flops
|
flops_price = ( price_ex_vat-inventory.get_computer_options_price(name) ) / computer_flops
|
||||||
# print ( purchase_date, name, price_ex_vat, computer_flops, flops_price )
|
# print ( purchase_date, name, price_ex_vat, computer_flops, flops_price )
|
||||||
flops_prices.append({'time':purchase_time, 'flops_price':flops_price, 'purchase_date':purchase_date})
|
flops_prices.append({'time':purchase_time, 'flops_price':flops_price, 'purchase_date':purchase_date})
|
||||||
|
@ -75,9 +75,9 @@ def get_flops_price_over_time(inventory, time_value):
|
||||||
|
|
||||||
return flops_price_over_time
|
return flops_price_over_time
|
||||||
|
|
||||||
def get_computer_value_over_time(inventory, computer_serial_number, time_value, flops_price_over_time, purchase_time):
|
def get_computer_value_over_time(inventory, computer_id, time_value, flops_price_over_time, purchase_time):
|
||||||
# print('flops_price_over_time = ', flops_price_over_time)
|
# print('flops_price_over_time = ', flops_price_over_time)
|
||||||
computer_flops = inventory.get_computer_dflops(computer_serial_number)
|
computer_flops = inventory.get_computer_dflops(computer_id)
|
||||||
computer_flops_over_time = np.where(time_value < purchase_time, 0.0, computer_flops)
|
computer_flops_over_time = np.where(time_value < purchase_time, 0.0, computer_flops)
|
||||||
computer_value_over_time = computer_flops_over_time * flops_price_over_time
|
computer_value_over_time = computer_flops_over_time * flops_price_over_time
|
||||||
return computer_value_over_time
|
return computer_value_over_time
|
||||||
|
@ -143,15 +143,15 @@ def draw_cluster_value_over_time_graph(inventory, from_date, to_date, graph_type
|
||||||
(name, serial_number, affectation, machine_spec_id, command_id, price_ex_vat, pos_x, pos_y, pos_z, inv_number)=row
|
(name, serial_number, affectation, machine_spec_id, command_id, price_ex_vat, pos_x, pos_y, pos_z, inv_number)=row
|
||||||
is_cluster_node = re.match('^simpatix[0-9]+$', name)
|
is_cluster_node = re.match('^simpatix[0-9]+$', name)
|
||||||
if is_cluster_node:
|
if is_cluster_node:
|
||||||
purchase_date = inventory.get_machine_purchase_date(serial_number)
|
purchase_date = inventory.get_machine_purchase_date(name)
|
||||||
if purchase_date is not None:
|
if purchase_date is not None:
|
||||||
# print(name, price_ex_vat)
|
# print(name, price_ex_vat)
|
||||||
purchase_time = matplotlib.dates.date2num(purchase_date.date())
|
purchase_time = matplotlib.dates.date2num(purchase_date.date())
|
||||||
item_value_over_time = {
|
item_value_over_time = {
|
||||||
'cluster_cost_over_time':get_investment_over_time(time_value, price_ex_vat, purchase_time),
|
'cluster_cost_over_time':get_investment_over_time(time_value, price_ex_vat, purchase_time),
|
||||||
'cluster_value_over_time':get_computer_value_over_time(inventory, serial_number, time_value, flops_price_over_time, purchase_time),
|
'cluster_value_over_time':get_computer_value_over_time(inventory, name, time_value, flops_price_over_time, purchase_time),
|
||||||
'cluster_dp_gflops_over_time':get_flops_over_time(inventory, time_value, serial_number, purchase_time)}[graph_type]
|
'cluster_dp_gflops_over_time':get_flops_over_time(inventory, time_value, name, purchase_time)}[graph_type]
|
||||||
for ownership in inventory.get_item_ownership(serial_number):
|
for ownership in inventory.get_item_ownership(name):
|
||||||
# print(ownership)
|
# print(ownership)
|
||||||
# print(ownership['owner'], ownership['owner_ratio'])
|
# print(ownership['owner'], ownership['owner_ratio'])
|
||||||
owner = ownership['owner']
|
owner = ownership['owner']
|
||||||
|
|
72
inventory.py
72
inventory.py
|
@ -17,6 +17,20 @@ class Inventory( object ):
|
||||||
def query(self, sql_query):
|
def query(self, sql_query):
|
||||||
return self._sql_reader.query(sql_query)
|
return self._sql_reader.query(sql_query)
|
||||||
|
|
||||||
|
def get_machine_serial_number(self, machine_name):
|
||||||
|
'''
|
||||||
|
returns the serial number of the given machine
|
||||||
|
'''
|
||||||
|
machine_serial_number = self._sql_reader.get_table_attr( 'machines', 'name', machine_name, 'serial_number' )
|
||||||
|
return machine_serial_number
|
||||||
|
|
||||||
|
def get_machine_name(self, machine_serial_number):
|
||||||
|
'''
|
||||||
|
returns the user-friendly name of the given machine
|
||||||
|
'''
|
||||||
|
machine_name = self._sql_reader.get_table_attr( 'machines', 'serial_number', machine_serial_number, 'name' )
|
||||||
|
return machine_name
|
||||||
|
|
||||||
def machine_name_to_machine_spec_id(self, machine_name ):
|
def machine_name_to_machine_spec_id(self, machine_name ):
|
||||||
machine_spec_id = self._sql_reader.get_table_attr( 'machines', 'name', machine_name, 'machine_spec_id' )
|
machine_spec_id = self._sql_reader.get_table_attr( 'machines', 'name', machine_name, 'machine_spec_id' )
|
||||||
return machine_spec_id
|
return machine_spec_id
|
||||||
|
@ -52,8 +66,8 @@ class Inventory( object ):
|
||||||
|
|
||||||
# cluster related methods
|
# cluster related methods
|
||||||
|
|
||||||
def get_machine_purchase_date(self, machine_serial_number):
|
def get_machine_purchase_date(self, machine_id):
|
||||||
ordering_id = self._sql_reader.get_table_attr( 'machines', 'serial_number', machine_serial_number, 'command_id' )
|
ordering_id = self._sql_reader.get_table_attr( 'machines', 'name', machine_id, 'command_id' )
|
||||||
# print(ordering_id)
|
# print(ordering_id)
|
||||||
# handle case of multiple orders
|
# handle case of multiple orders
|
||||||
ordering_id = ordering_id.split('+')[0]
|
ordering_id = ordering_id.split('+')[0]
|
||||||
|
@ -79,10 +93,10 @@ class Inventory( object ):
|
||||||
# print(num_cores, clock_speed, dflops_per_core_per_cycle)
|
# print(num_cores, clock_speed, dflops_per_core_per_cycle)
|
||||||
return clock_speed * dflops_per_core_per_cycle * num_cores
|
return clock_speed * dflops_per_core_per_cycle * num_cores
|
||||||
|
|
||||||
def get_computer_dflops(self, computer_serial_number):
|
def get_computer_dflops(self, computer_name):
|
||||||
# print(computer_serial_number)
|
# print(computer_serial_number)
|
||||||
num_cpus = int(self._sql_reader.get_table_attr( 'computer_to_cpu', 'serial_number', computer_serial_number, 'num_cpu' ))
|
num_cpus = int(self._sql_reader.get_table_attr( 'computer_to_cpu', 'computer_id', computer_name, 'num_cpu' ))
|
||||||
cpu_model = self._sql_reader.get_table_attr( 'computer_to_cpu', 'serial_number', computer_serial_number, 'cpu_model' )
|
cpu_model = self._sql_reader.get_table_attr( 'computer_to_cpu', 'computer_id', computer_name, 'cpu_model' )
|
||||||
flops = num_cpus * self.get_cpu_dflops( cpu_model )
|
flops = num_cpus * self.get_cpu_dflops( cpu_model )
|
||||||
return flops
|
return flops
|
||||||
|
|
||||||
|
@ -92,14 +106,52 @@ class Inventory( object ):
|
||||||
return 7675.0 / 4 * 2 # each of these computers has 2 nvidia fermi C2050 gpus
|
return 7675.0 / 4 * 2 # each of these computers has 2 nvidia fermi C2050 gpus
|
||||||
return options_price
|
return options_price
|
||||||
|
|
||||||
def get_item_ownership(self, item_serial_number):
|
def get_item_container(self, item_id):
|
||||||
|
"""
|
||||||
|
:param str item_id: the identifier of an inventory item (a machine (eg simpa-switch002), a group of machines (ceph), etc.)
|
||||||
|
:return str: the item that contains the given item, None if this item has no contrainer
|
||||||
|
"""
|
||||||
|
container_id = None
|
||||||
|
rows = self._sql_reader.query("SELECT container_id FROM container WHERE part_id='%s'" % item_id)
|
||||||
|
if len(rows) > 0:
|
||||||
|
container_id = rows[0][0]
|
||||||
|
return container_id
|
||||||
|
|
||||||
|
def get_item_price(self, item_id, include_contents=False):
|
||||||
|
"""
|
||||||
|
:param str item_id: the identifier of an inventory item (a machine (eg simpa-switch002), a group of machines (ceph), etc.)
|
||||||
|
:return float: the price of the item exluding taxes
|
||||||
|
"""
|
||||||
|
item_price = self._sql_reader.get_table_attr( 'machines', 'name', item_id, 'price_ex_vat' )
|
||||||
|
if item_price == None:
|
||||||
|
item_price = 0.0
|
||||||
|
else:
|
||||||
|
item_price = float(item_price)
|
||||||
|
if include_contents:
|
||||||
|
# add the price of included parts
|
||||||
|
rows = self._sql_reader.query("SELECT part_id FROM container WHERE container_id='%s'" % item_id)
|
||||||
|
for row in rows:
|
||||||
|
part_id = row[0]
|
||||||
|
item_price += self.get_item_price(part_id, include_contents)
|
||||||
|
#print(u'price of %s : %.2f € HT' % (item_id, item_price))
|
||||||
|
return item_price
|
||||||
|
|
||||||
|
def get_item_ownership(self, item_id):
|
||||||
ownership=[]
|
ownership=[]
|
||||||
|
|
||||||
rows = self._sql_reader.query("SELECT * FROM ownership")
|
rows = self._sql_reader.query("SELECT * FROM ownership WHERE machine_id='%s'" % item_id)
|
||||||
for row in rows:
|
for row in rows:
|
||||||
(serial_number, owner, owner_ratio, comment)=row
|
(machine_id, owner, owner_ratio, comment)=row
|
||||||
if serial_number == item_serial_number:
|
ownership.append({'owner':owner, 'owner_ratio':owner_ratio})
|
||||||
ownership.append({'owner':owner, 'owner_ratio':owner_ratio})
|
|
||||||
return ownership
|
return ownership
|
||||||
|
|
||||||
|
def get_item_use(self, item_id):
|
||||||
|
ownership=[]
|
||||||
|
|
||||||
|
rows = self._sql_reader.query("SELECT * FROM machine_users")
|
||||||
|
for row in rows:
|
||||||
|
(machine_id, user, user_ratio, comment)=row
|
||||||
|
if machine_id == item_id:
|
||||||
|
ownership.append({'user':user, 'user_ratio':user_ratio})
|
||||||
|
return ownership
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue